inferencelayer 0.2.9

Kortexya's engine-native inference layer — LLM generation + embedding/encoder family on wgpu (WGSL kernels, any adapter) with a pure-Rust CPU fallback
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
//! `encoder-scoreboard` — the **crown gate**: is the engine actually faster than PyTorch?
//!
//! The decoder's `scoreboard` pins the engine against ITSELF (a regression guard). This one pins
//! it against the thing we claim to beat. Every row carries three numbers — engine-cpu,
//! engine-wgpu, and the torch baseline for the same workload on the same box — and two gates:
//!
//! * **hold** — `measured ≤ pin / 0.97`: a regression against our own best blocks the merge,
//!   exactly as a red test does. (Latency, so worse = larger; the decoder harness gates
//!   throughput, where worse = smaller.)
//! * **crown** — `engine ≤ ratio_max × torch`: the claim itself, as a number. `ratio_max` starts
//!   at the measured status quo, ratchets DOWN as phases land (never up), and the campaign's exit
//!   criterion is **≤ 0.90 on every row** — a 10% margin so box-to-box variance cannot flip the
//!   claim. A row that has never been under 1.0 reports `ASPIRATIONAL` and does not fail the
//!   build, so this harness can merge BEFORE the wins exist and then measure them landing.
//!
//! Torch baselines are not measured here (no Python in the engine): they come from
//! `tests/fixtures/bench_encoders.py --json`, which records provenance (machine, load, thread
//! count, torch version, epoch), and are ingested with `--ingest-torch <file.json>`. A baseline
//! captured on a loaded box is REFUSED, and one from a different machine is flagged stale — a
//! torch number and an engine number are only comparable if the same box produced both.
//!
//! Method: min-of-N (default 30, ≥5 warmups). The mean is a measure of the contention, not of
//! the code — on 2026-07-13 the same GLiNER input measured 29.6 ms and 82.9 ms minutes apart on
//! a box at load 46–209, and two optimization decisions were made on numbers that were noise.
//! The quiet-machine guard (shared with `scoreboard` via `bench_guard`) refuses to measure at
//! all under contention unless `OSFKB_SCOREBOARD_IGNORE_LOAD=1`, and then refuses `--pin`.
//!
//! Rows (checkpoints from env; a missing checkpoint SKIPS its row loudly, never fakes it):
//! * `biolord_embed64` — XLM-R 12L/768h, 64-token text (`OSFKB_BIOLORD_DIR`)
//! * `ce_score192` — CrossEncoder MiniLM 6L/384h, 192-token pair (`OSFKB_CE_DIR`)
//! * `gliner_{11,44,176}w_{2,20}lab` — end-to-end `predict_text` (`OSFKB_GLINER_DIR`)
//! * `claimx_prefill` — ingested via `--record` until the prefill path is wired (P1)
//!
//! ```text
//! encoder-scoreboard                       # measure + gate
//! encoder-scoreboard --ingest-torch t.json # record the baselines
//! encoder-scoreboard --pin                 # advance our pins after an accepted win (quiet box)
//! ```

use anyhow::{Context, Result, bail};
use inferencelayer::EmbedEngine;
use inferencelayer::bench_guard::{
    ensure_quiet_machine, foreign_load, load_average_1m, read_pins, self_cpu_seconds, write_pins,
};
use inferencelayer::encoder_weights::EncBatch;
use inferencelayer::gliner::{Gliner, GlinerDevice};
use inferencelayer::pooling::EmbedOut;
use std::time::Instant;

/// Tolerated regression against our own pin: measured ≤ pin / HOLD_FRACTION passes.
const HOLD_FRACTION: f64 = 0.97;
/// The campaign's exit criterion: every row at or under this fraction of torch.
const CROWN_TARGET: f64 = 0.90;
/// `<<ENT>>` in the deberta-v3 vocab GLiNER extends.
const ENT_TOKEN_ID: u32 = 128002;

const SENTENCE: &str = "Barack Obama was born in Hawaii and later worked in Chicago.";
const LABELS_2: [&str; 2] = ["person", "location"];
const LABELS_20: [&str; 20] = [
    "person",
    "location",
    "organization",
    "date",
    "product",
    "event",
    "disease",
    "drug",
    "gene",
    "protein",
    "company",
    "city",
    "country",
    "award",
    "job title",
    "language",
    "nationality",
    "book",
    "film",
    "law",
];

fn main() {
    match run(&std::env::args().skip(1).collect::<Vec<_>>()) {
        Ok(true) => {}
        Ok(false) => std::process::exit(1),
        Err(e) => {
            eprintln!("encoder-scoreboard: {e:#}");
            std::process::exit(2);
        }
    }
}

struct Opts {
    pins_path: String,
    write_pins: bool,
    ingest_torch: Option<String>,
    records: Vec<(String, f64)>,
    rows: Vec<String>,
    reps: usize,
    devices: Vec<Device>,
}

#[derive(Clone, Copy, PartialEq, Eq)]
enum Device {
    Cpu,
    Wgpu,
}

impl Device {
    fn tag(self) -> &'static str {
        match self {
            Device::Cpu => "cpu",
            Device::Wgpu => "wgpu",
        }
    }
}

fn parse_opts(args: &[String]) -> Result<Opts> {
    let mut o = Opts {
        pins_path: "bench/encoder_scoreboard_pins.json".into(),
        write_pins: false,
        ingest_torch: None,
        records: vec![],
        rows: vec![],
        reps: 30,
        devices: vec![Device::Cpu, Device::Wgpu],
    };
    let mut it = args.iter();
    while let Some(a) = it.next() {
        let mut val = |name: &str| {
            it.next()
                .cloned()
                .with_context(|| format!("{name} needs a value"))
        };
        match a.as_str() {
            "--pins" => o.pins_path = val("--pins")?,
            "--pin" => o.write_pins = true,
            "--ingest-torch" => o.ingest_torch = Some(val("--ingest-torch")?),
            "--rows" => o.rows = val("--rows")?.split(',').map(str::to_string).collect(),
            "--reps" => o.reps = val("--reps")?.parse().context("--reps")?,
            "--devices" => {
                o.devices = val("--devices")?
                    .split(',')
                    .map(|d| match d {
                        "cpu" => Ok(Device::Cpu),
                        "wgpu" => Ok(Device::Wgpu),
                        other => bail!("unknown device {other:?} (cpu|wgpu)"),
                    })
                    .collect::<Result<_>>()?;
            }
            "--record" => {
                let kv = val("--record")?;
                let (k, v) = kv
                    .split_once('=')
                    .with_context(|| format!("--record wants row=value_ms, got {kv:?}"))?;
                o.records
                    .push((k.to_string(), v.parse().context("--record value")?));
            }
            other => bail!("unknown flag {other:?}"),
        }
    }
    Ok(o)
}

fn run(args: &[String]) -> Result<bool> {
    let o = parse_opts(args)?;
    let quiet = ensure_quiet_machine()?;
    if o.write_pins && !quiet {
        bail!(
            "--pin refused: the quiet-machine guard was overridden, so these numbers carry \
             contention and must never become the reference every later run is judged against."
        )
    }
    let mut pins = read_pins(&o.pins_path)?;

    if let Some(path) = &o.ingest_torch {
        ingest_torch(&mut pins, path, quiet)?;
        write_pins(&o.pins_path, &pins)?;
        eprintln!("ingested torch baselines from {path}{}", o.pins_path);
        return Ok(true);
    }

    // Measure every row that has a checkpoint, on every requested device.
    let load_before = load_average_1m();
    let t_start = std::time::Instant::now();
    let cpu_start = self_cpu_seconds();
    let mut measured: Vec<(String, f64)> = o.records.clone();
    for dev in &o.devices {
        measured.extend(measure_device(*dev, &o)?);
    }
    if measured.is_empty() {
        bail!(
            "nothing measured: set OSFKB_GLINER_DIR / OSFKB_BIOLORD_DIR / OSFKB_CE_DIR, or pass \
             --record <row>=<ms>"
        );
    }

    // The guard used to check the load ONCE, before the first row. But a full sweep takes minutes,
    // and this box goes from quiet to loaded inside one. Two nominally-quiet runs of the SAME binary
    // disagreed by 30% (gliner_176w_2lab.wgpu: 35.4 ms then 47.9 ms) and the second one "failed" a
    // gate the first one set — which is not a gate, it is a coin flip. min-of-N cannot save a row
    // whose every rep ran under contention. So: the box must still be quiet at the END, or the run
    // is exploratory and gates nothing.
    let quiet = quiet && still_quiet(load_before, t_start, cpu_start);
    if o.write_pins && !quiet {
        bail!(
            "--pin refused: the machine did not stay quiet for the whole sweep, so these numbers \
             carry contention and must never become the reference every later run is judged against."
        )
    }

    let ok = report_and_gate(&mut pins, &measured, &o, quiet)?;
    if !quiet {
        eprintln!(
            "\nEXPLORATORY: the machine was not quiet for the whole sweep — the rows above are \
             indicative, and the gates are NOT enforced. Re-run on a quiet box before believing a \
             REGRESSION or a CROWN."
        );
        return Ok(true);
    }
    Ok(ok)
}

/// Did the box stay quiet for the whole sweep — ignoring the load WE caused?
///
/// The start-of-run guard checks the load once, before the first row. But a full sweep takes minutes
/// and this box goes from quiet to loaded inside one: two nominally-quiet runs of the same binary
/// disagreed by 82% (gliner_176w_2lab.cpu: 56.6 ms, then 102.9 ms). min-of-N cannot rescue a row
/// whose every rep ran under contention, so the box has to still be quiet at the END.
///
/// The subtlety is that a 16-thread benchmark drives the 1-minute load average up by most of a core
/// count all by itself. Comparing the raw load average before and after therefore flags every run,
/// including the honest ones. So we subtract our own average core occupancy (CPU seconds burned /
/// wall seconds elapsed) and judge only the contention we did not cause.
fn still_quiet(before: Option<f64>, t_start: std::time::Instant, cpu_start: Option<f64>) -> bool {
    let cores = std::thread::available_parallelism()
        .map(|c| c.get() as f64)
        .unwrap_or(8.0);
    let limit = cores / 2.0;

    let self_cores = match (cpu_start, self_cpu_seconds()) {
        (Some(a), Some(b)) => (b - a) / t_start.elapsed().as_secs_f64().max(1e-3),
        _ => 0.0,
    };
    let Some(after) = foreign_load(self_cores) else {
        return true; // no load signal here; the start-of-run guard already said so
    };

    if after >= limit {
        eprintln!(
            "quiet-machine guard: FOREIGN load rose to {after:.2} (≥ {limit:.1}; we were using \
             {self_cores:.1} cores) — the later rows were measured on a busier box than the earlier \
             ones."
        );
        return false;
    }
    if let Some(b) = before
        && after > b * 1.75
        && after > 2.0
    {
        eprintln!(
            "quiet-machine guard: foreign load drifted {b:.2}{after:.2} during the sweep — the \
             rows are not comparable to each other, let alone to a pin."
        );
        return false;
    }
    eprintln!(
        "quiet-machine guard: foreign load {after:.2} at the end (we used {self_cores:.1} cores) — ok"
    );
    true
}

/// Every row this device can serve. A missing checkpoint skips its rows loudly.
fn measure_device(dev: Device, o: &Opts) -> Result<Vec<(String, f64)>> {
    let mut out = Vec::new();
    let want = |row: &str| o.rows.is_empty() || o.rows.iter().any(|r| r == row);

    if let Some(dir) = env_dir("OSFKB_GLINER_DIR") {
        let gdev = match dev {
            Device::Cpu => GlinerDevice::Cpu,
            Device::Wgpu => GlinerDevice::Auto,
        };
        let mut g = Gliner::load_on(&dir, ENT_TOKEN_ID, gdev)
            .with_context(|| format!("load gliner from {}", dir.display()))?;
        if dev == Device::Wgpu && g.device() == "cpu" {
            eprintln!("SKIP gliner wgpu rows: no usable adapter (auto fell back to cpu)");
        } else {
            eprintln!("gliner on {} ({})", g.device(), dev.tag());
            for (reps, words) in [(1usize, 11usize), (4, 44), (16, 176)] {
                let text = vec![SENTENCE; reps].join(" ");
                for (nlab, labels) in [
                    (
                        2usize,
                        LABELS_2.iter().map(|s| s.to_string()).collect::<Vec<_>>(),
                    ),
                    (20, LABELS_20.iter().map(|s| s.to_string()).collect()),
                ] {
                    let row = format!("gliner_{words}w_{nlab}lab.{}", dev.tag());
                    if !want(&row) {
                        continue;
                    }
                    let ms = min_of_n(o.reps, || g.predict_text(&text, &labels, 0.5).map(|_| ()))?;
                    out.push((row, ms));
                }
            }
        }
    } else {
        eprintln!("SKIP gliner rows: OSFKB_GLINER_DIR unset");
    }

    if let Some(dir) = env_dir("OSFKB_BIOLORD_DIR") {
        let row = format!("biolord_embed64.{}", dev.tag());
        if want(&row) {
            match load_engine(dev, &dir)? {
                None => eprintln!("SKIP {row}: no usable adapter"),
                Some(mut e) => {
                    eprintln!("biolord on {} ({})", e.device(), dev.tag());
                    // 64 tokens is BioLORD's window (sentence_bert_config max_seq_length).
                    let ids: Vec<u32> = (0..64).map(|i| 5 + (i as u32 * 7) % 2000).collect();
                    let batch = EncBatch::from_seqs([ids]);
                    let ms = min_of_n(o.reps, || e.encode(&batch).map(|_| ()))?;
                    out.push((row, ms));
                }
            }
        }
    } else {
        eprintln!("SKIP biolord row: OSFKB_BIOLORD_DIR unset");
    }

    if let Some(dir) = env_dir("OSFKB_CE_DIR") {
        let row = format!("ce_score192.{}", dev.tag());
        if want(&row) {
            // The CrossEncoder now HAS a GPU head (CLS → pooler(tanh) → classifier), so this row
            // runs on whichever device is asked for, through `EmbedEngine` — the same entry point
            // the service uses. It used to skip wgpu with "no GPU head yet (P6)"; that head landed,
            // and `/score` is the ontology-verifier's hot path, so measuring only CPU here hid the
            // whole point.
            //
            // `load_engine` returns None when a wgpu row silently fell back to CPU — which is
            // exactly the lie this harness exists to prevent, so the row is SKIPPED rather than
            // reported as a GPU number.
            if let Some(mut enc) = load_engine(dev, &dir)? {
                eprintln!("cross-encoder on {} ({})", enc.device(), dev.tag());
                // A 192-token pair: 96 tokens of query (segment 0) + 96 of candidate (segment 1).
                // The segment ids are load-bearing — the GPU gather ignored them until this head
                // landed, which silently scored the candidate as if it were part of the query.
                let a: Vec<u32> = (0..96).map(|i| 5 + (i as u32 * 11) % 1500).collect();
                let b: Vec<u32> = (0..96).map(|i| 7 + (i as u32 * 13) % 1500).collect();
                let batch = EncBatch::from_pairs(vec![(
                    a.iter().chain(&b).copied().collect::<Vec<u32>>(),
                    a.iter()
                        .map(|_| 0u32)
                        .chain(b.iter().map(|_| 1u32))
                        .collect::<Vec<u32>>(),
                )]);
                let ms = min_of_n(o.reps, || {
                    enc.encode(&batch).map(|o| match o {
                        EmbedOut::Pooled(_) | EmbedOut::PerToken(_) => (),
                    })
                })?;
                out.push((row, ms));
            } else {
                eprintln!("SKIP {row}: no GPU adapter (would have measured the CPU path)");
            }
        }
    } else {
        eprintln!("SKIP ce row: OSFKB_CE_DIR unset");
    }

    Ok(out)
}

fn load_engine(dev: Device, dir: &std::path::Path) -> Result<Option<EmbedEngine>> {
    let e = match dev {
        Device::Cpu => EmbedEngine::cpu(dir)?,
        Device::Wgpu => {
            let e = EmbedEngine::auto(dir, 8192)?;
            if e.device() == "cpu" {
                return Ok(None);
            }
            e
        }
    };
    Ok(Some(e))
}

fn env_dir(key: &str) -> Option<std::path::PathBuf> {
    let p = std::path::PathBuf::from(std::env::var(key).ok()?);
    if p.is_dir() {
        Some(p)
    } else {
        eprintln!("{key} = {} is not a directory", p.display());
        None
    }
}

/// Min-of-N milliseconds after 5 warmups. The MINIMUM, not the mean: on a box with any ambient
/// load the mean measures the contention. The minimum is the closest thing to the uncontended
/// cost that a real machine will give you, and it is what the torch side records too.
fn min_of_n(reps: usize, mut f: impl FnMut() -> Result<()>) -> Result<f64> {
    for _ in 0..5 {
        f()?;
    }
    let mut best = f64::MAX;
    for _ in 0..reps.max(1) {
        let t0 = Instant::now();
        f()?;
        best = best.min(t0.elapsed().as_secs_f64());
    }
    Ok(best * 1e3)
}

/// Fold `bench_encoders.py --json` output into the pins ledger's `baselines` section.
fn ingest_torch(pins: &mut serde_json::Value, path: &str, quiet: bool) -> Result<()> {
    let raw = std::fs::read(path).with_context(|| format!("read {path}"))?;
    let doc: serde_json::Value =
        serde_json::from_slice(&raw).with_context(|| format!("parse {path}"))?;
    let rows = doc
        .get("rows")
        .and_then(|r| r.as_object())
        .context("torch json: expected a top-level `rows` object")?;

    // A baseline captured under contention is worse than no baseline: a slow torch number
    // silently LOWERS the bar we claim to clear. This checks the load recorded IN THE BASELINE
    // (when torch ran), which is independent of whether this box is quiet right now.
    let _ = quiet;
    if let Some(load) = doc.get("load_1m").and_then(serde_json::Value::as_f64) {
        let cores = std::thread::available_parallelism()
            .map(std::num::NonZero::get)
            .unwrap_or(8) as f64;
        let overridden = std::env::var("OSFKB_SCOREBOARD_IGNORE_LOAD").as_deref() == Ok("1");
        if load >= cores / 2.0 {
            if !overridden {
                bail!(
                    "torch baseline was captured at load {load:.2} on a {cores:.0}-core box — a \
                     contended torch number would LOWER the bar we claim to clear. Re-run \
                     bench_encoders.py on a quiet box (or set OSFKB_SCOREBOARD_IGNORE_LOAD=1 to \
                     ingest it as exploratory)."
                )
            }
            eprintln!(
                "WARNING: torch baseline captured at load {load:.2} — exploratory, not a crown."
            );
        }
    }
    let machine = doc
        .get("machine")
        .cloned()
        .unwrap_or(serde_json::Value::Null);
    let baselines = pins
        .as_object_mut()
        .context("pins root must be an object")?
        .entry("baselines")
        .or_insert_with(|| serde_json::json!({}));
    for (row, v) in rows {
        let value = v
            .get("value_ms")
            .and_then(serde_json::Value::as_f64)
            .with_context(|| format!("torch row {row}: missing value_ms"))?;
        baselines[row] = serde_json::json!({
            "value_ms": value,
            "by_device": v.get("by_device").cloned().unwrap_or(serde_json::Value::Null),
            "machine": machine,
            "load_1m": doc.get("load_1m").cloned().unwrap_or(serde_json::Value::Null),
            "torch": doc.get("torch").cloned().unwrap_or(serde_json::Value::Null),
            "device": v.get("device").cloned().unwrap_or(serde_json::Value::Null),
            "threads": doc.get("threads").cloned().unwrap_or(serde_json::Value::Null),
            "captured_epoch_s": doc.get("captured_epoch_s").cloned().unwrap_or(serde_json::Value::Null),
            "method": "min-of-n",
        });
        eprintln!("  baseline {row:30} {value:8.1} ms");
    }
    Ok(())
}

/// The torch number an engine row must beat.
///
/// An engine-CPU row is judged against **torch-CPU**, and an engine-wgpu row against torch's *best*
/// device (so a wgpu win is a win over torch-MPS, not just over torch's slow backend). Gating a CPU
/// kernel against torch-MPS — which is what a single collapsed `value_ms` silently did — compares
/// our CPU to their GPU: a bar no CPU kernel can clear, and one the campaign never set. It made the
/// CPU rows read 1.56× when the honest figure against torch-CPU was 1.21×.
///
/// Falls back to the collapsed `value_ms` for baselines captured before `by_device` existed.
fn torch_bar(b: &serde_json::Value, engine_dev: &str) -> Option<f64> {
    let by_dev = b.get("by_device").and_then(serde_json::Value::as_object);
    if engine_dev == "cpu"
        && let Some(cpu) = by_dev
            .and_then(|d| d.get("cpu"))
            .and_then(serde_json::Value::as_f64)
    {
        return Some(cpu);
    }
    b.get("value_ms").and_then(serde_json::Value::as_f64)
}

/// Print every row against its pin and its torch baseline; return whether all gates hold.
fn report_and_gate(
    pins: &mut serde_json::Value,
    measured: &[(String, f64)],
    o: &Opts,
    quiet: bool,
) -> Result<bool> {
    let load = load_average_1m();
    let baselines = pins
        .get("baselines")
        .cloned()
        .unwrap_or(serde_json::json!({}));
    let mut ok = true;
    let mut aspirational = 0usize;

    println!(
        "\n{:32} {:>9} {:>9} {:>9} {:>7}  gate",
        "row", "measured", "pin", "torch", "ratio"
    );
    for (row, ms) in measured {
        // ── hold gate: never regress against our own best (latency ⇒ worse is larger)
        let pin = pins
            .get("rows")
            .and_then(|r| r.get(row))
            .and_then(|p| p.get("value_ms"))
            .and_then(serde_json::Value::as_f64);
        let hold_ok = pin.is_none_or(|p| *ms <= p / HOLD_FRACTION);

        // ── crown gate: the claim, as a number. Torch rows are keyed without the device suffix.
        let (base_key, dev) = row
            .rsplit_once('.')
            .map_or((row.as_str(), ""), |(k, d)| (k, d));
        let torch = baselines.get(base_key).and_then(|b| torch_bar(b, dev));
        let ratio = torch.map(|t| ms / t);
        let ratio_max = pins
            .get("ratios")
            .and_then(|r| r.get(row))
            .and_then(serde_json::Value::as_f64);
        let crown_ok = match (ratio, ratio_max) {
            // A row we have never had under 1.0 is ASPIRATIONAL: reported, not fatal — the
            // harness must be mergeable before the wins exist.
            (Some(r), Some(max)) if max <= 1.0 => r <= max,
            (Some(_), _) => {
                aspirational += 1;
                true
            }
            (None, _) => true,
        };
        ok &= hold_ok && crown_ok;

        let gate = match (hold_ok, crown_ok, ratio, ratio_max) {
            (false, _, _, _) => "REGRESSION".to_string(),
            (_, false, Some(r), Some(m)) => format!("CROWN LOST ({r:.2} > {m:.2})"),
            (_, _, Some(r), Some(m)) if m <= 1.0 && r <= CROWN_TARGET => "CROWN ✓".into(),
            (_, _, Some(_r), Some(m)) if m <= 1.0 => format!("holding (target {CROWN_TARGET:.2})"),
            (_, _, Some(r), _) if r > 1.0 => "ASPIRATIONAL (behind torch)".into(),
            (_, _, Some(_), _) => "ASPIRATIONAL (ahead — pin it)".into(),
            _ => "no torch baseline".into(),
        };
        println!(
            "{row:32} {ms:9.1} {:>9} {:>9} {:>7}  {gate}",
            pin.map_or("".into(), |p| format!("{p:.1}")),
            torch.map_or("".into(), |t| format!("{t:.1}")),
            ratio.map_or("".into(), |r| format!("{r:.2}×")),
        );

        if o.write_pins && (pin.is_none() || *ms < pin.unwrap()) {
            pins["rows"][row] = serde_json::json!({
                "value_ms": ms,
                "load_1m": load,
                "quiet": quiet,
                "captured_epoch_s": epoch_s(),
            });
            // Ratchet the crown target DOWN only — a worse ratio must never relax the bar — but
            // never below CROWN_TARGET. Locking the bar to the exact ratio just achieved (0.41×,
            // say) would make the crown a second regression gate with NO slack, on a box whose load
            // average swings 2× between runs; it would fail on noise and teach us to ignore it. The
            // crown answers "do we still beat torch by the margin the campaign set?"; the hold gate
            // (pin × 0.97) is what answers "did this commit make it slower?".
            if let Some(r) = ratio {
                let ratcheted = ratio_max.map_or(r, |m| m.min(r)).max(CROWN_TARGET);
                pins["ratios"][row] = serde_json::json!(ratcheted);
            }
        }
    }

    if o.write_pins {
        write_pins(&o.pins_path, pins)?;
        eprintln!("\npins written to {}", o.pins_path);
    }
    if aspirational > 0 {
        eprintln!(
            "{aspirational} row(s) ASPIRATIONAL — no crown pinned yet (nonfatal). Campaign target: \
             every row ≤ {CROWN_TARGET:.2}× torch."
        );
    }
    // A run that could not be trusted must not print a verdict. Saying FAIL and then "gates are not
    // enforced" two lines later teaches the reader to ignore both.
    println!(
        "\n{}",
        match (quiet, ok) {
            (false, _) => "EXPLORATORY — not a verdict (see the quiet-machine guard above)",
            (true, true) => "PASS",
            (true, false) => "FAIL",
        }
    );
    Ok(ok)
}

fn epoch_s() -> u64 {
    std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .map(|d| d.as_secs())
        .unwrap_or(0)
}