monetize-embed 0.3.1

The thin client a monetized product compiles in: an Ed25519-verified entitlement cache with nanosecond verdicts that keeps answering while the licence server is unreachable. No network, no ledger — the product feeds it signed facts and asks.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
//! **The pull channel's signed forms** (5.4, G1-pull): monetize never calls INTO an
//! estate; every estate calls monetize (`Fleet.Report`, `Fleet.Orders`, `Fleet.Ask`) and
//! monetize answers with [`SignedOrder`]s the box verifies under `monetize_pubkey`.
//!
//! Two forms, each a fixed binary layout (not JSON) so the estate's verifier
//! (`gunnar_repair::order`) and this crate agree byte for byte with no canonical-JSON
//! rule to share:
//!
//! * [`order_message`]: what monetize signs for ONE order to ONE box (`role`).
//! * [`fleet_call_message`]: what a box signs with its own Ed25519 appliance key for each
//!   call it makes to monetize.
//!
//! An order is only "please run verb V with these arguments": the estate runs it through the
//! SAME function its local admin button and its boot check call, and says how it went in the
//! next [`Report`] ([`OrderAck`]).

use ed25519_dalek::{Signature, VerifyingKey};
use serde::{Deserialize, Serialize};

/// The domain tag every order signature starts with.
pub const ORDER_DOMAIN: &[u8] = b"nordisk-order-v1\0";
/// The domain tag every box's call signature starts with.
pub const CALL_DOMAIN: &[u8] = b"nordisk-fleet-call-v1\0";
/// How far a box's call time may be from monetize's clock.
pub const CALL_FRESH_MS: u64 = 5 * 60 * 1000;
/// How far ahead of the box's clock an order may be dated (the shared pump's and Gunnar's five
/// minutes).
pub const FUTURE_SKEW_MS: u64 = 5 * 60 * 1000;
/// How long `Fleet.Orders` is held open at most before it answers empty.
pub const LONG_POLL_MAX_MS: u64 = 25_000;
/// **How long a front waits on the shop's `SoldEstate.Upgrade`**: the shop's whole keep boot,
/// 2 h, the ONE constant the shop holds its call by (`monetize_product::KEEP_BOOT_WITHIN`; lane
/// G9, A7 row 9, Gunnar b74ca801). A front that gave up first would count a slow keep boot as
/// lost and ask for a Recharge while the shop still works.
pub use monetize_product::KEEP_BOOT_WITHIN;
/// **The shop's words for an Upgrade still running** (`an upgrade of <host> is already running
/// here`, an UNAVAILABLE answer): the front that hears them asks again later (REL-T2-1: the
/// Upgrade is started, then polled). The ONE box says them; the front's door reads them.
pub const UPGRADE_RUNNING: &str = "is already running here";

/// The order kinds. The body is JSON; unknown fields are ignored. The relay products' guardian
/// kinds ([`kind::GUARDIAN`], gunnar-repair's verbs) are defined here; the core's kinds are
/// `monetize_product::pull`'s one list (A28 M25), re-exported here under their old names.
pub mod kind {
    /// `{main, twin, accept_lost, epoch, case?}`: the twin (or a fresh main) pumps the twin's
    /// log into the main. The same verb the local "Recharge" button and the boot check run.
    pub const RECHARGE_FROM_TWIN: &str = "recharge_from_twin";
    /// `{primary, epoch, case?}`: the old primary may not serve past `epoch`.
    pub const FENCE_PRIMARY: &str = "fence_primary";
    /// `{twin, principal, case?}`: the primary takes the box at `twin` as its twin.
    pub const ADOPT_TWIN: &str = "adopt_twin";
    /// `{case?}`: the box reviews its twin and reports the `TwinReview`.
    pub const REVIEW_TWIN: &str = "review_twin";
    /// `{snapshot, case?}`: the money put back on a recharged main. `snapshot` is a
    /// [`crate::Snapshot`] signed by monetize's key — what monetize's books hold for the
    /// product. The box verifies it and every fact in it (`signing::verify_snapshot`), applies
    /// each fact only if newer than the one it holds (a same fact is a no-op), deletes
    /// nothing, and runs it only while it serves as the primary.
    pub const RESTATE_ENTITLEMENTS: &str = "restate_entitlements";
    /// [`super::GrowGoAhead`]: **a sold estate's paid data step** (G16-d, G1-pull row 17),
    /// queued to the estate's main AND its twin once the step's money is captured. The box
    /// verifies `go_ahead` under monetize's key (`signing::verify_estate_growth`: its estate,
    /// good until `until_unix_ms`), then grows its own data disks to `data_gib` a disk: drain,
    /// unmount, `Fleet.Ask{kind: ask::GROW_SET}` (monetize resizes them at the provider), look
    /// again, remount. The twin first — its disk holds main's whole set. A newer go-ahead
    /// supersedes an unacked older one; a growth already done is acked ok, nothing moved.
    pub use monetize_product::pull::order::GROW_GO_AHEAD;
    /// [`super::SignInAgain`]: **a sold estate's RESEND sign-in link** (S10, owner 2026-10-11
    /// 05:53Z), queued to the estate's main when its buyer asks (`EstateOrder.SendSignInAgain`).
    /// The order names whose passkey, which address and which console host — NO secret: the
    /// main mints the fresh invite itself (only while the account holds no passkey) and mails
    /// `https://{host}/login?invite=…&user=…` itself. The shop never holds a resend's login
    /// secret (the FIRST link stays shop-minted at install, OM-21 decision A). A newer ask
    /// supersedes an unacked older one.
    pub use monetize_product::pull::order::SIGN_IN_AGAIN;
    /// [`super::Refeed`]: **estate keys fed again to an already-laid estate** (MAIL-RELAY +
    /// NIGHT-PUBREPO, 2026-10-28), queued to the estate's main and twin when the operator asks
    /// (`EstateOrder.Refeed`). The box takes each key it knows by name ([`super::refeed`]) and
    /// refuses the order by name otherwise. The body may CARRY A SECRET (the relay's token): never
    /// logged; a newer one supersedes an unacked older one.
    pub use monetize_product::pull::order::REFEED;

    /// **The relay products' guardian kinds** (the twin's repair verbs): not core kinds; a
    /// product whose guardian runs no twin never gets one.
    pub const GUARDIAN: [&str; 5] = [RECHARGE_FROM_TWIN, FENCE_PRIMARY, ADOPT_TWIN, REVIEW_TWIN, RESTATE_ENTITLEMENTS];
}

/// The `Fleet.Ask` kinds that are not a remedy: answered at once, no case opened.
/// A product's own order ([`ProductOrder`]) and the file it may carry ([`Fetch`]), MONETIZE-FIX.
pub use monetize_product::pull::{Fetch, FetchAsk, ProductOrder};

pub mod ask {
    /// [`super::GrowSetAsk`]: **size the calling box's own data disks** at monetize's provider
    /// (G16-d, G1-pull row 18) — no more than is paid for its role, never smaller. The main
    /// sizes main's disks, the twin (its own key, `role = twin`) the twin's.
    pub use monetize_product::pull::ask::GROW_SET;
    /// `monetize_product::pull::FetchAsk` `{id}`: **the box pulls the file a product order
    /// carries** (MONETIZE-FIX); the bytes come back in `FleetAskAnswer.answer`.
    pub use monetize_product::pull::ask::FETCH;
    /// [`super::FrontAsk`] `{role, done}`: **the shop boots ONE standing box once from the
    /// release's keep medium** (was `SoldEstate.Upgrade`; plan §8, A24 §5.1 row 27). Asked by
    /// the estate's front; the answer is `EstateUpgradeResponse` in `FleetAskAnswer.answer`.
    pub const UPGRADE: &str = "upgrade";
    /// [`super::FrontAsk`] `{role, seed, done}`: **the shop lays ONE lost box again** (was
    /// `SoldEstate.Recharge`, row 29); the answer is `EstateRechargeResponse`. Not the guardian's
    /// `recharge_from_twin` remedy: this one is the cloud half, asked by the front.
    pub const RECHARGE: &str = "recharge";
    /// [`super::FrontAsk`] `{done}`: **the estate takes its own installer material** (was
    /// `SoldEstate.TakeMaterial`, row 28); the answer is `EstateTakeMaterialResponse`.
    pub const MATERIAL: &str = "material";
    /// [`super::FrontAsk`] `{}`: **the front takes the open update** (was
    /// `SoldEstate.UpdateTake`, row 25); the answer is `EstateUpdateTakeResponse`.
    pub const UPDATE_TAKE: &str = "update_take";
    /// [`super::FrontAsk`] `{role, carries}`: **the front reports one box's update step** (was
    /// `SoldEstate.UpdateReport`, row 26); the answer is `EstateUpdateReportResponse`.
    pub const UPDATE_REPORT: &str = "update_report";
    /// **The front's asks** — the five `SoldEstate` calls folded into `Fleet.Ask` (plan §8,
    /// decided 2026-10-24). Answered at once, no case opened; asked only by the estate's front.
    pub const FRONT: [&str; 5] = [UPGRADE, RECHARGE, MATERIAL, UPDATE_TAKE, UPDATE_REPORT];

    /// Pure: **is `kind` one of the front's asks** ([`FRONT`])?
    pub fn is_front(kind: &str) -> bool {
        FRONT.contains(&kind)
    }
}

/// The calls a box makes ([`FleetCall::call`]).
pub mod call {
    pub const REPORT: &str = "report";
    pub const ORDERS: &str = "orders";
    pub const ASK: &str = "ask";
}

/// **One order to one box**, signed by the product's monetize key.
#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)]
pub struct SignedOrder {
    /// Per instance, strictly rising; the box refuses any `seq` at or below the last it ran.
    pub seq: u64,
    pub product: String,
    pub instance: String,
    /// The box the order is for: `main` | `twin` | `front`. Signed, so an order for the twin
    /// is never run by the main.
    pub role: String,
    pub kind: String,
    /// JSON text.
    pub body: String,
    pub issued_unix_ms: u64,
    pub not_after_unix_ms: u64,
    /// 64-byte Ed25519 over [`order_message`].
    #[serde(default)]
    pub signature: Vec<u8>,
}

/// Why a box refuses an order.
#[derive(Clone, PartialEq, Eq, Debug, thiserror::Error)]
pub enum OrderRefusal {
    #[error("the order is not signed by monetize")]
    Signature,
    #[error("order {seq} is not newer than {last}")]
    Replayed { seq: u64, last: u64 },
    #[error("order {0} has expired")]
    Expired(u64),
    #[error("order {0} is for {1}, not this box")]
    NotForMe(u64, String),
    #[error("order {0} is dated more than five minutes ahead of this box's clock")]
    Ahead(u64),
}

fn field(out: &mut Vec<u8>, bytes: &[u8]) {
    out.extend_from_slice(&(bytes.len() as u32).to_be_bytes());
    out.extend_from_slice(bytes);
}

/// The bytes an order's signature covers: [`ORDER_DOMAIN`] ‖ seq ‖ issued ‖ not_after (u64 BE)
/// ‖ then product, instance, role, kind, body, each as u32 BE length ‖ bytes.
pub fn order_message(o: &SignedOrder) -> Vec<u8> {
    let mut out = ORDER_DOMAIN.to_vec();
    out.extend_from_slice(&o.seq.to_be_bytes());
    out.extend_from_slice(&o.issued_unix_ms.to_be_bytes());
    out.extend_from_slice(&o.not_after_unix_ms.to_be_bytes());
    for f in [&o.product, &o.instance, &o.role, &o.kind, &o.body] {
        field(&mut out, f.as_bytes());
    }
    out
}

/// **The box's check**, as strict as the shared pump's (`monetize_estate_side::pump::check`):
/// signed under `key` with STRICT Ed25519 (no small-order key or `R`), checked first, so a
/// forged order is always [`OrderRefusal::Signature`] and never moves the box's sequence; then
/// for `(product, instance, role)`, newer than `last_seq`, inside its window at `now_unix_ms`
/// (`not_after` 0 = none), and dated no more than [`FUTURE_SKEW_MS`] ahead of the box's clock.
pub fn verify_order(o: &SignedOrder, key: &VerifyingKey, me: (&str, &str, &str), now_unix_ms: u64, last_seq: u64) -> Result<(), OrderRefusal> {
    let (product, instance, role) = me;
    if !check(key, &order_message(o), &o.signature) {
        return Err(OrderRefusal::Signature);
    }
    if o.product != product || o.instance != instance || o.role != role {
        return Err(OrderRefusal::NotForMe(o.seq, o.role.clone()));
    }
    if o.seq <= last_seq {
        return Err(OrderRefusal::Replayed { seq: o.seq, last: last_seq });
    }
    if o.not_after_unix_ms != 0 && now_unix_ms > o.not_after_unix_ms {
        return Err(OrderRefusal::Expired(o.seq));
    }
    if o.issued_unix_ms > now_unix_ms.saturating_add(FUTURE_SKEW_MS) {
        return Err(OrderRefusal::Ahead(o.seq));
    }
    Ok(())
}

/// **One call from a box to monetize**, signed by the box's own appliance key.
#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)]
pub struct FleetCall {
    pub product: String,
    pub instance: String,
    pub role: String,
    /// [`call::REPORT`] | [`call::ORDERS`] | [`call::ASK`].
    pub call: String,
    /// JSON text: a [`Report`], an [`OrdersAfter`] or an [`Ask`].
    pub body: String,
    pub at_unix_ms: u64,
}

/// Why monetize refuses a box's call.
#[derive(Clone, PartialEq, Eq, Debug, thiserror::Error)]
pub enum CallRefusal {
    #[error("the call is not signed by the box's key")]
    Signature,
    #[error("the call's time is too far from monetize's clock")]
    Stale,
}

/// The bytes a box's call signature covers: [`CALL_DOMAIN`] ‖ at (u64 BE) ‖ then product,
/// instance, role, call, body, each as u32 BE length ‖ bytes.
pub fn fleet_call_message(c: &FleetCall) -> Vec<u8> {
    let mut out = CALL_DOMAIN.to_vec();
    out.extend_from_slice(&c.at_unix_ms.to_be_bytes());
    for f in [&c.product, &c.instance, &c.role, &c.call, &c.body] {
        field(&mut out, f.as_bytes());
    }
    out
}

/// Verify a box's call under its appliance `key`, fresh at `now_unix_ms`.
pub fn verify_fleet_call(c: &FleetCall, signature: &[u8], key: &VerifyingKey, now_unix_ms: u64) -> Result<(), CallRefusal> {
    if !check(key, &fleet_call_message(c), signature) {
        return Err(CallRefusal::Signature);
    }
    if c.at_unix_ms.abs_diff(now_unix_ms) > CALL_FRESH_MS {
        return Err(CallRefusal::Stale);
    }
    Ok(())
}

/// STRICT Ed25519 (`verify_strict`): a small-order key or `R` never verifies (T16, A28 M11).
fn check(key: &VerifyingKey, msg: &[u8], sig: &[u8]) -> bool {
    Signature::from_slice(sig).map(|s| key.verify_strict(msg, &s).is_ok()).unwrap_or(false)
}

/// What a box says ran (or did not) — sent back in its next [`Report`].
#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct OrderAck {
    pub seq: u64,
    pub ok: bool,
    pub detail: String,
    /// gunnar_repair's `Receipt` / `TwinReview`, JSON text; empty when none.
    pub receipt_json: String,
}

/// **The box's heartbeat** (`Fleet.Report` body). Its arrival time is the liveness signal.
#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Report {
    pub build: String,
    /// The box's own health words, flat: `serving` (`yes` | `no` | `fenced`), `data` (`ok` |
    /// `lost` | `diverged`), `serves_at` (`host:port`), `twin` (`paired` | `silent` | …),
    /// `epoch`. Unknown words are kept and shown.
    pub health: std::collections::BTreeMap<String, String>,
    pub acked: Vec<OrderAck>,
    /// The product's twin review (gunnar: `gunnar_repair::TwinReview`), JSON text, when it
    /// made one.
    pub twin_review: Option<String>,
    /// **The product's own state** (G1 pull: tenants and owners, usage, servable, the paid
    /// door, the room a raise would find), JSON text of `monetize_product::pull::ProductReport`.
    /// Sent by the box that serves tenants (the main); what monetize used to dial it for.
    pub product: Option<String>,
    pub measured_unix_ms: u64,
}

/// `Fleet.Orders` body: orders after `after`, held up to `wait_ms` (≤ [`LONG_POLL_MAX_MS`]).
#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct OrdersAfter {
    pub after: u64,
    pub wait_ms: u64,
}

/// Body of a [`kind::GROW_GO_AHEAD`] order.
#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct GrowGoAhead {
    /// The [`crate::signing::EstateGrowth`] JSON, signed by monetize's key.
    pub go_ahead: String,
    /// GB a data disk THIS box's role is paid to (main: the step; twin: main's whole set).
    pub data_gib: u64,
}

/// Body of a [`kind::SIGN_IN_AGAIN`] order. Never a secret.
#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct SignInAgain {
    /// The account whose first passkey the invite enrols (the order's account).
    pub account: String,
    /// The order's address: where the estate mails the link.
    pub to: String,
    /// The console's relying-party host the link points at (`<company>.<apex>`).
    pub host: String,
    /// How long the invite lives.
    pub ttl_secs: u64,
}

/// **The estate keys a [`kind::REFEED`] order may carry**, in the words of the feed a box is
/// laid with: the mains' mail relay (`secret.smtp_url`, `secret.smtp_from`, and `secret.smtp_ca`
/// for a relay on a private CA; monetize-mail `FEED_SMTP_*`) and a site's public repositories
/// (`public_repositories`, comma-separated). A box takes the ones it knows and refuses any
/// other by name.
pub mod refeed {
    pub const SMTP_URL: &str = "secret.smtp_url";
    pub const SMTP_FROM: &str = "secret.smtp_from";
    pub const SMTP_CA: &str = "secret.smtp_ca";
    pub const PUBLIC_REPOSITORIES: &str = "public_repositories";
    /// The site's public-site switch, `on` | `off` (GRS-PUBLIC 2026-10-28; the lay's own front
    /// feed word, monetize-shop-pairing `contract::FEED_PUBLIC_SITE`).
    pub const PUBLIC_SITE: &str = "console_public_site";
    /// Every key a refeed may carry.
    pub const KNOWN: [&str; 5] = [SMTP_URL, SMTP_FROM, SMTP_CA, PUBLIC_REPOSITORIES, PUBLIC_SITE];
    /// The keys whose values are secrets (never shown).
    pub fn is_secret(key: &str) -> bool {
        key.starts_with("secret.")
    }
}

/// Body of a [`kind::REFEED`] order (MAIL-RELAY + NIGHT-PUBREPO, 2026-10-28): the estate keys
/// fed again, key → value. **A `secret.` value is a secret**: the `Debug` names the keys only.
#[derive(Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Refeed {
    pub keys: std::collections::BTreeMap<String, String>,
}

impl std::fmt::Debug for Refeed {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("Refeed").field("keys", &self.keys.keys().collect::<Vec<_>>()).finish()
    }
}

/// `Fleet.Ask` body of [`ask::GROW_SET`]: the box's own data disks to `gib` a disk. No
/// `members` = every laid data disk of the calling box; `gib` 0 = what its role is paid to.
#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct GrowSetAsk {
    pub members: Vec<String>,
    pub gib: u64,
}

/// **The body of a front's ask** ([`ask::FRONT`]): the fields the old `SoldEstate` request
/// carried, less the company and the signature — the `FleetSigned` call names the estate
/// (`instance`) and the box (`role = front`) and is signed by the front's key. `role` is the
/// box the ask is about (`main` | `twin`; for `update_report`, the box whose step it is);
/// `carries` is the update report's `<outcome>\n<words>`.
#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct FrontAsk {
    #[serde(skip_serializing_if = "String::is_empty")]
    pub role: String,
    #[serde(skip_serializing_if = "std::ops::Not::not")]
    pub done: bool,
    #[serde(skip_serializing_if = "String::is_empty")]
    pub seed: String,
    #[serde(skip_serializing_if = "String::is_empty")]
    pub carries: String,
}

/// `Fleet.Ask` body: a request from the estate (`new_twin`, `new_server`, `recharge`, …).
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Ask {
    pub kind: String,
    pub body: serde_json::Value,
}

#[cfg(test)]
mod tests {
    use super::*;
    use ed25519_dalek::{Signer as _, SigningKey};

    /// A28 M25: the core kinds are defined once, in `monetize_product::pull`; the kinds here
    /// are that list's, and the rest of [`kind`] are the relay products' guardian kinds.
    #[test]
    fn the_core_kinds_here_are_monetize_products_one_list() {
        use monetize_product::pull;
        assert_eq!(kind::GROW_GO_AHEAD, pull::order::GROW_GO_AHEAD);
        assert_eq!(kind::SIGN_IN_AGAIN, pull::order::SIGN_IN_AGAIN);
        assert_eq!(kind::REFEED, pull::order::REFEED);
        assert_eq!(ask::GROW_SET, pull::ask::GROW_SET);
        for k in kind::GUARDIAN {
            assert!(!pull::is_core(k), "{k} is a guardian kind, not a core one");
        }
        assert_eq!(kind::GUARDIAN, [kind::RECHARGE_FROM_TWIN, kind::FENCE_PRIMARY, kind::ADOPT_TWIN, kind::REVIEW_TWIN, kind::RESTATE_ENTITLEMENTS]);
    }

    /// ★ Plan §8 (the SoldEstate → Fleet fold): the front's five asks are named once, none of
    /// them is a guardian remedy or `grow_set`, and their body round-trips through the `Ask`
    /// JSON with only the fields it carries.
    #[test]
    fn the_fronts_asks_are_the_five_soldestate_calls_and_their_body_round_trips() {
        assert_eq!(ask::FRONT, ["upgrade", "recharge", "material", "update_take", "update_report"]);
        for k in ask::FRONT {
            assert!(ask::is_front(k));
        }
        for k in [ask::GROW_SET, kind::RECHARGE_FROM_TWIN, kind::REVIEW_TWIN, "new_twin", "new_server", ""] {
            assert!(!ask::is_front(k), "{k}");
        }
        // The ONE box's own door, not a product's kind: none is one of the core's 8 (A28 M25).
        for k in ask::FRONT {
            assert!(!monetize_product::pull::is_core(k), "{k}");
        }
        let a = FrontAsk { role: "main".into(), seed: "SEED".into(), ..Default::default() };
        let text = serde_json::to_string(&Ask { kind: ask::RECHARGE.into(), body: serde_json::to_value(&a).unwrap() }).unwrap();
        assert_eq!(text, r#"{"kind":"recharge","body":{"role":"main","seed":"SEED"}}"#);
        let back: Ask = serde_json::from_str(&text).unwrap();
        assert_eq!(serde_json::from_value::<FrontAsk>(back.body).unwrap(), a);
        assert_eq!(serde_json::from_value::<FrontAsk>(serde_json::json!({})).unwrap(), FrontAsk::default(), "an empty body is the update take's");
    }

    /// ★ Lane G9, A7 row 9 (Gunnar b74ca801): a front waits on the shop's whole keep boot, 2 h,
    /// the one constant the shop's cloud crate holds its Upgrade call by.
    #[test]
    fn a_front_waits_on_the_shops_whole_keep_boot() {
        assert_eq!(KEEP_BOOT_WITHIN, std::time::Duration::from_secs(2 * 3600));
        assert_eq!(KEEP_BOOT_WITHIN, monetize_product::KEEP_BOOT_WITHIN);
    }

    const GOLDEN_MESSAGE_HEX: &str = "6e6f726469736b2d6f726465722d7631000000000000000003000001a3185c5000000001a3186a0ba00000000667756e6e61720000000461636d65000000047477696e0000001272656368617267655f66726f6d5f7477696e000000517b226163636570745f6c6f7374223a66616c73652c2265706f6368223a352c226d61696e223a2231302e362e302e31303a3530303531222c227477696e223a2231302e362e302e31323a3530303531227d";
    const GOLDEN_SIGNATURE_HEX: &str = "d4a3233158d9a3fbfa42f9aa80fd2ca420666ec2fe9f7fbf1a61abab533c09f6dab60c67367bc771a1d819d1e6bed28c59d6d56187a4748ba9b4b9988d13d50a";

    fn key() -> SigningKey {
        SigningKey::from_bytes(&[7u8; 32])
    }

    fn order() -> SignedOrder {
        SignedOrder {
            seq: 3,
            product: "gunnar".into(),
            instance: "acme".into(),
            role: "twin".into(),
            kind: kind::RECHARGE_FROM_TWIN.into(),
            body: r#"{"accept_lost":false,"epoch":5,"main":"10.6.0.10:50051","twin":"10.6.0.12:50051"}"#.into(),
            issued_unix_ms: 1_800_000_000_000,
            not_after_unix_ms: 1_800_000_900_000,
            signature: Vec::new(),
        }
    }

    fn signed() -> SignedOrder {
        let mut o = order();
        o.signature = key().sign(&order_message(&o)).to_bytes().to_vec();
        o
    }

    /// The golden vector gunnar-repair pastes into its own test: same order, same bytes.
    #[test]
    fn the_order_message_is_the_agreed_binary_layout() {
        let m = order_message(&order());
        assert!(m.starts_with(ORDER_DOMAIN));
        let mut want = ORDER_DOMAIN.to_vec();
        want.extend_from_slice(&3u64.to_be_bytes());
        want.extend_from_slice(&1_800_000_000_000u64.to_be_bytes());
        want.extend_from_slice(&1_800_000_900_000u64.to_be_bytes());
        for f in ["gunnar", "acme", "twin", kind::RECHARGE_FROM_TWIN, &order().body] {
            want.extend_from_slice(&(f.len() as u32).to_be_bytes());
            want.extend_from_slice(f.as_bytes());
        }
        assert_eq!(m, want);
        let sig = key().sign(&m).to_bytes();
        let hex: String = sig.iter().map(|b| format!("{b:02x}")).collect();
        assert_eq!(hex, GOLDEN_SIGNATURE_HEX, "the golden vector moved: tell gunnar_repair::order");
        let mhex: String = m.iter().map(|b| format!("{b:02x}")).collect();
        assert_eq!(mhex, GOLDEN_MESSAGE_HEX);
    }

    #[test]
    fn a_box_runs_only_a_fresh_order_signed_for_it() {
        let pk = key().verifying_key();
        let me = ("gunnar", "acme", "twin");
        let now = 1_800_000_100_000;
        assert_eq!(verify_order(&signed(), &pk, me, now, 2), Ok(()));
        assert_eq!(verify_order(&signed(), &pk, me, now, 3), Err(OrderRefusal::Replayed { seq: 3, last: 3 }));
        assert_eq!(verify_order(&signed(), &pk, me, 1_800_000_900_001, 0), Err(OrderRefusal::Expired(3)));
        assert_eq!(verify_order(&signed(), &pk, ("gunnar", "acme", "main"), now, 0), Err(OrderRefusal::NotForMe(3, "twin".into())));
        let mut forged = signed();
        forged.role = "main".into();
        assert_eq!(verify_order(&forged, &pk, ("gunnar", "acme", "main"), now, 0), Err(OrderRefusal::Signature));
        let other = SigningKey::from_bytes(&[9u8; 32]).verifying_key();
        assert_eq!(verify_order(&signed(), &other, me, now, 0), Err(OrderRefusal::Signature));
    }

    /// ★ **T16 (A28 M11): this check is as strict as the shared pump's** (`monetize_estate_side::
    /// pump::check`, P4c). Under a small-order key (the identity point) the all-zero signature
    /// verifies ANY message with plain `verify`; a strict check refuses it, and a real key's
    /// signature still passes.
    #[test]
    fn a_weak_key_with_the_all_zero_signature_signs_no_order() {
        let (weak, zero) = weak_key_and_zero_signature();
        let mut o = order();
        o.signature = zero;
        let now = 1_800_000_100_000;
        assert_eq!(verify_order(&o, &weak, ("gunnar", "acme", "twin"), now, 0), Err(OrderRefusal::Signature), "a weak key verifies nothing");
        assert_eq!(verify_order(&signed(), &key().verifying_key(), ("gunnar", "acme", "twin"), now, 0), Ok(()));
    }

    /// ★ The same weak key never vouches for a box's call either.
    #[test]
    fn a_weak_box_key_with_the_all_zero_signature_signs_no_call() {
        let (weak, zero) = weak_key_and_zero_signature();
        let c = FleetCall { product: "gunnar".into(), instance: "acme".into(), role: "main".into(), call: call::REPORT.into(), body: "{}".into(), at_unix_ms: 1_800_000_000_000 };
        assert_eq!(verify_fleet_call(&c, &zero, &weak, 1_800_000_000_000), Err(CallRefusal::Signature));
    }

    /// The identity point as a key, and the signature (R = identity, s = 0) that plain `verify`
    /// accepts for every message under it.
    fn weak_key_and_zero_signature() -> (VerifyingKey, Vec<u8>) {
        let mut identity = [0u8; 32];
        identity[0] = 1;
        let weak = VerifyingKey::from_bytes(&identity).expect("the identity point decompresses");
        let mut zero = vec![0u8; 64];
        zero[0] = 1;
        (weak, zero)
    }

    /// ★ Every signed field is covered: one tampered field, a flipped signature bit, a short or
    /// missing signature, or another key is refused as not monetize's.
    #[test]
    fn a_tampered_order_is_not_monetizes() {
        let pk = key().verifying_key();
        let me = ("gunnar", "acme", "twin");
        let now = 1_800_000_100_000;
        type Tamper = Box<dyn Fn(&mut SignedOrder)>;
        let tampered: Vec<(&str, Tamper)> = vec![
            ("seq", Box::new(|o| o.seq += 1)),
            ("kind", Box::new(|o| o.kind = kind::FENCE_PRIMARY.into())),
            ("body", Box::new(|o| o.body = "{}".into())),
            ("issued", Box::new(|o| o.issued_unix_ms -= 1)),
            ("not_after", Box::new(|o| o.not_after_unix_ms += 1)),
            ("bit", Box::new(|o| o.signature[5] ^= 1)),
            ("short", Box::new(|o| o.signature.truncate(63))),
            ("none", Box::new(|o| o.signature.clear())),
        ];
        for (what, f) in tampered {
            let mut o = signed();
            f(&mut o);
            assert_eq!(verify_order(&o, &pk, me, now, 0), Err(OrderRefusal::Signature), "{what}");
        }
    }

    /// ★ The signature is checked FIRST: a forged order addressed to another box is forged (it
    /// never moves the box's sequence), not "not for me".
    #[test]
    fn a_forged_order_for_another_box_is_forged_not_misaddressed() {
        let mut o = signed();
        o.role = "main".into();
        assert_eq!(verify_order(&o, &key().verifying_key(), ("gunnar", "acme", "twin"), 1_800_000_100_000, 0), Err(OrderRefusal::Signature));
    }

    /// ★ `not_after` 0 is no window (as the shared pump reads it), not "expired at the epoch".
    #[test]
    fn an_order_with_no_window_does_not_expire() {
        let mut o = order();
        o.not_after_unix_ms = 0;
        o.signature = key().sign(&order_message(&o)).to_bytes().to_vec();
        assert_eq!(verify_order(&o, &key().verifying_key(), ("gunnar", "acme", "twin"), 1_900_000_000_000, 0), Ok(()));
    }

    /// ★ An order dated more than [`FUTURE_SKEW_MS`] ahead of the box's clock is refused by
    /// name; five minutes of skew is fine.
    #[test]
    fn an_order_dated_ahead_of_the_box_clock_is_refused() {
        let pk = key().verifying_key();
        let me = ("gunnar", "acme", "twin");
        let issued = order().issued_unix_ms;
        assert_eq!(verify_order(&signed(), &pk, me, issued - FUTURE_SKEW_MS, 0), Ok(()), "five minutes of skew");
        assert_eq!(verify_order(&signed(), &pk, me, issued - FUTURE_SKEW_MS - 1, 0), Err(OrderRefusal::Ahead(3)));
    }

    #[test]
    fn a_call_is_signed_by_the_box_and_fresh() {
        let box_key = SigningKey::from_bytes(&[3u8; 32]);
        let c = FleetCall { product: "gunnar".into(), instance: "acme".into(), role: "main".into(), call: call::REPORT.into(), body: "{}".into(), at_unix_ms: 1_800_000_000_000 };
        let m = fleet_call_message(&c);
        assert!(m.starts_with(CALL_DOMAIN));
        let sig = box_key.sign(&m).to_bytes();
        let pk = box_key.verifying_key();
        assert_eq!(verify_fleet_call(&c, &sig, &pk, 1_800_000_060_000), Ok(()));
        assert_eq!(verify_fleet_call(&c, &sig, &pk, 1_800_000_000_000 + CALL_FRESH_MS + 1), Err(CallRefusal::Stale));
        let mut moved = c.clone();
        moved.role = "twin".into();
        assert_eq!(verify_fleet_call(&moved, &sig, &pk, 1_800_000_000_000), Err(CallRefusal::Signature));
        assert_eq!(verify_fleet_call(&c, &sig[..10], &pk, 1_800_000_000_000), Err(CallRefusal::Signature));
    }
}