facett-core 0.1.18

facett — visual kernel: render a node/edge Scene into egui (wgpu fast path to come)
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
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
//! **GPU LANE ATTRIBUTION** — is the app actually rendering through a GPU lane, or
//! is it silently on the CPU painter?
//!
//! [`crate::render::adapter`] answers *which device* was opened. That is only half
//! the question, and answering only that half is how a box with an RTX 4090 spent a
//! whole day painting 60 000 shapes per frame on one core: `renderer_installed()`
//! was `true`, the adapter banner said `discrete/Vulkan`, and **nothing on the GPU
//! lane was ever called**, because the pane's only consumer of it lives in another
//! crate. An About box that reads "wgpu" off the adapter alone would repeat that lie
//! in the UI.
//!
//! So this module records the *other* half, as data:
//!
//! * [`note_installed`] — a lane's renderer went into an egui-wgpu
//!   `RenderState`'s callback resources. Called ONCE, by construction, from the
//!   shared `crate::render::gpu::install_renderer` — so every lane that routes
//!   through the one install writer registers itself with no per-lane wiring.
//! * [`note_reports_frames`] — this lane promises to count encoded frames. Opt-in
//!   per lane, because the frame bump has to sit at the one point in that lane's
//!   `prepare` where real GPU work was genuinely encoded, and only the lane knows
//!   where that is.
//! * [`note_frame`] — one frame of real GPU work encoded.
//!
//! ## Why "unknown" is a first-class answer
//!
//! [`lane_use`] folds the registry into [`GpuLaneUse`]. The interesting case is
//! [`GpuLaneUse::Unknown`]: a lane is installed, no frames have been counted, and at
//! least one installed lane never promised to count any. That is exactly the state
//! where "installed but unused" would be a *guess* — the lane may well be painting
//! every frame and simply not reporting. Guessing there is the failure mode this
//! module exists to prevent, so it reports `unknown` instead and says how many lanes
//! it could not account for.
//!
//! This is lane ATTRIBUTION, not a correctness oracle (the same caveat
//! `facett_flowsim`'s `flow_frames_drawn` carries): a lane that encoded a frame of
//! nothing still bumps the counter. It answers *who painted*, which no pixel diff
//! can, and it is only ever meaningful paired with a pixel assertion.

use std::collections::BTreeMap;
use std::sync::{Mutex, OnceLock};

use super::adapter::{
    gpu_unavailable_json, is_management_display, selected_adapter, AdapterSelection,
};

/// One GPU lane's registration.
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct LaneRecord {
    /// The lane's renderer type path, e.g. `facett_map::gpu::GpuMapRenderer`
    /// (`std::any::type_name`, so it cannot drift from the type it names).
    pub name: String,
    /// A host installed this lane's renderer in this process.
    pub installed: bool,
    /// This lane promises to count encoded frames ([`note_frame`]), so a zero here
    /// MEANS "did not paint" rather than "did not say".
    pub reports_frames: bool,
    /// Frames of real GPU work this lane encoded.
    pub frames: u64,
    /// **WHY this lane sat idle**, in its owner's own words, when it last declined to
    /// paint ([`note_idle_reason`]). `None` = it never said.
    ///
    /// This exists because "installed but UNUSED" is not, on its own, a diagnosis: a
    /// lane that correctly stood aside (a camera it cannot express, nothing of its kind
    /// to draw) and a lane that is BROKEN produce the identical row, and an operator
    /// looking at the product cannot tell them apart. It cost real time on 2026-08-02:
    /// korp reported `installed but UNUSED` on an RTX 4090 and neither the About box nor
    /// several tool calls could say whether that was a correct choice or the bug.
    pub idle_reason: Option<String>,
    /// **The lane's GPU clocks** — upload wall-time/bytes + in-GPU pass time. See
    /// [`LaneClockStats`]. `#[serde(default)]` so a json written before these existed
    /// still deserialises.
    #[serde(default)]
    pub clocks: LaneClockStats,
}

/// **Per-lane GPU timing observables** — the tail of a host's mousewheel→GPU TRACE
/// line. The CPU legs are clocked host-side (korp); these are the two legs only the
/// lane itself can see:
///
/// * **upload wall-time** — the `write_buffer`/`create_buffer_init` work a lane's
///   `prepare` does when geometry changes. Wall clock, because that is the time the
///   frame actually paid on the CPU handing bytes to the driver.
/// * **in-GPU pass time** — measured with `wgpu` TIMESTAMP_QUERY where the device has
///   the feature. `last_gpu_pass_us` is `None` until a real sample resolves, and
///   STAYS `None` on a device without the feature — an adapter that cannot measure
///   reports "cannot measure", never `0` (a faked zero is indistinguishable from a
///   free pass, which is the identity-value trap LAW 2 names).
///
/// One struct, one writer set (`note_upload` / `note_gpu_pass` /
/// `note_gpu_timestamps`), read through [`clock_stats_of`] — so korp's TRACE line, an
/// About row and a device test all read the same numbers (LAW #5).
#[derive(
    Debug, Clone, Copy, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize,
)]
pub struct LaneClockStats {
    /// Wall-clock microseconds the LAST upload event spent handing bytes to the
    /// device (buffer creation + `write_buffer`). `0` before the first upload.
    pub last_upload_us: u64,
    /// Bytes the last upload event actually moved — the payload streams written to
    /// the device, exactly (a device test asserts equality with the payload it fed).
    pub last_upload_bytes: u64,
    /// Upload events since process start. The 2D lane re-uploads on geometry change
    /// only; the 3D lane on a new `GpuGeometry::generation` stamp — so this counts
    /// re-bakes, not frames.
    pub uploads_total: u64,
    /// In-GPU microseconds of the lane's most recent resolved pass window
    /// (2D: the cull compute pass; 3D: shadow→post aggregate). `None` = no sample
    /// yet OR timestamps unavailable — see [`Self::gpu_timestamps`] to tell which.
    /// Resolved a few frames late by design (non-blocking readback ring).
    pub last_gpu_pass_us: Option<u64>,
    /// Are the pass timestamps REAL? `Some(true)` = the device has TIMESTAMP_QUERY
    /// (+ INSIDE_ENCODERS) and the lane is writing them; `Some(false)` = the device
    /// lacks the feature, so `last_gpu_pass_us` can never fill; `None` = the lane has
    /// not probed yet (no frame prepared).
    pub gpu_timestamps: Option<bool>,
}

impl LaneRecord {
    /// The last `::` segment — what a UI row shows (`GpuMapRenderer`).
    #[must_use]
    pub fn short_name(&self) -> &str {
        self.name.rsplit("::").next().unwrap_or(self.name.as_str())
    }
}

/// **Is a GPU lane actually in use?** The honest fold of the lane registry.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GpuLaneUse {
    /// No lane's renderer was installed in this process — every pane that has a CPU
    /// painter is on it. (A wgpu *device* may still be open: egui itself paints
    /// through wgpu. This is about facett's own compute/instanced lanes.)
    NotInstalled,
    /// A lane encoded `frames` frames of real GPU work.
    InUse {
        /// Frames counted across every reporting lane.
        frames: u64,
    },
    /// Every installed lane reports frames, and all of them are at zero: installed
    /// and genuinely never painted. **This is korp's map facet.**
    InstalledUnused,
    /// A lane is installed but cannot be accounted for — it never promised to count
    /// frames, so neither "in use" nor "unused" is knowable. Says so instead of
    /// picking one.
    Unknown {
        /// How many installed lanes are unaccounted for.
        silent_lanes: usize,
    },
}

impl GpuLaneUse {
    /// Stable token for `state_json`.
    #[must_use]
    pub fn as_str(self) -> &'static str {
        match self {
            GpuLaneUse::NotInstalled => "not_installed",
            GpuLaneUse::InUse { .. } => "in_use",
            GpuLaneUse::InstalledUnused => "installed_unused",
            GpuLaneUse::Unknown { .. } => "unknown",
        }
    }

    /// Frames counted (0 for every non-[`InUse`](Self::InUse) state).
    #[must_use]
    pub fn frames(self) -> u64 {
        match self {
            GpuLaneUse::InUse { frames } => frames,
            _ => 0,
        }
    }
}

// ── the registry ────────────────────────────────────────────────────────────

static LANES: OnceLock<Mutex<BTreeMap<&'static str, LaneRecord>>> = OnceLock::new();

fn lanes_slot() -> &'static Mutex<BTreeMap<&'static str, LaneRecord>> {
    LANES.get_or_init(|| Mutex::new(BTreeMap::new()))
}

fn with_lane(name: &'static str, f: impl FnOnce(&mut LaneRecord)) {
    if let Ok(mut g) = lanes_slot().lock() {
        let rec = g.entry(name).or_insert_with(|| LaneRecord {
            name: name.to_owned(),
            installed: false,
            reports_frames: false,
            frames: 0,
            idle_reason: None,
            clocks: LaneClockStats::default(),
        });
        f(rec);
    }
}

/// Record that a lane's renderer was installed into a `RenderState`.
///
/// Called from the ONE shared install writer (`crate::render::gpu::install_renderer`)
/// with `std::any::type_name::<R>()`, so a new lane that uses the shared install is
/// registered without touching this module.
pub fn note_installed(name: &'static str) {
    with_lane(name, |r| r.installed = true);
}

/// Declare that this lane counts encoded frames via [`note_frame`].
///
/// Without this the lane is *silent*, and [`lane_use`] degrades to
/// [`GpuLaneUse::Unknown`] rather than claiming the lane went unused. Call it next to
/// the lane's install.
pub fn note_reports_frames(name: &'static str) {
    with_lane(name, |r| r.reports_frames = true);
}

/// Count one frame of real GPU work encoded by this lane.
///
/// Put this at the point in the lane's `prepare` where the work has actually been
/// recorded against a real device — *after* every fail-safe early-return, or the
/// counter starts claiming frames the GPU never saw. Implies both
/// [`note_installed`] and [`note_reports_frames`]: a lane cannot encode a frame
/// without being installed, and it is plainly reporting.
pub fn note_frame(name: &'static str) {
    with_lane(name, |r| {
        r.installed = true;
        r.reports_frames = true;
        r.frames += 1;
    });
}

/// **The lane has not been ASKED to draw yet** — nobody has painted the pane that owns
/// it since the process started. Not a declined lane and not a broken one.
///
/// Named here, next to the reader that classifies it, rather than as a string literal in
/// the crate that emits it: [`GpuStatus::lane_line`] has to recognise this exact token to
/// avoid printing a sentence that contradicts the very next row (LAW #5 — one writer for
/// a value two crates agree on).
pub const PANE_NOT_PAINTED_YET: &str = "pane_not_painted_yet";

/// **The lane was CHOSEN this frame and has not encoded yet.** The facet picked the GPU,
/// handed egui the callback, and no frame has come out the other side — a covered,
/// clipped or just-mounted pane produces no GPU work, which is correct.
pub const AWAITING_FIRST_ENCODE: &str = "awaiting_first_encode";

/// The reasons that mean **"nothing has asked this lane to draw"**, as opposed to
/// "the lane was offered the work and declined it".
///
/// The distinction is the whole point: a lane that declined (`rotated_camera`,
/// `no_line_ways`) really did leave the work to the CPU painter, and saying so is
/// accurate. A lane in one of the states below did not — **there is no CPU painter doing
/// its work either, because the pane it belongs to has not been drawn at all**. Printing
/// the same sentence for both is what made korp's About box read as a fault on a healthy
/// RTX 4090; see [`GpuStatus::lane_line`].
pub const NOT_YET_DRAWN_REASONS: [&str; 2] = [PANE_NOT_PAINTED_YET, AWAITING_FIRST_ENCODE];

/// **Say why this lane is not painting**, so "installed but UNUSED" stops being
/// ambiguous. `Some(reason)` when the lane's owner chose another route this frame,
/// `None` when it is painting.
///
/// The reason is the OWNER's, because only the owner knows: `facett_map`'s `MapFacet`
/// reports `rotated_camera` / `no_renderer` / `no_line_ways` / `not_compiled`. A lane
/// that declined for a good reason and a lane that is broken must not render the same
/// row — that ambiguity is what this whole module exists to remove, and leaving it at
/// the lane level would have re-created it one level up.
pub fn note_idle_reason(name: &'static str, reason: Option<&str>) {
    with_lane(name, |r| {
        // Only overwrite with a real reason, or clear it deliberately; a caller that
        // does not know must not erase a reason another writer supplied.
        r.idle_reason = reason.map(str::to_owned);
    });
}

/// The reason ONE lane last gave for standing aside (`None` = it never said).
#[must_use]
pub fn idle_reason_of(name: &str) -> Option<String> {
    lanes_slot().lock().ok().and_then(|g| g.get(name).and_then(|r| r.idle_reason.clone()))
}

/// **One upload event landed**: the lane spent `micros` of wall time moving `bytes`
/// of payload onto the device. Called by the lane's OWN `upload` body (facett-map's
/// `GpuMapRenderer::upload`, facett-map3d's `Map3dRenderer::upload`) — the one
/// writer both the live `prepare` path and every `upload_for_test` hook route
/// through, so a test and the product count the same event (LAW #5).
pub fn note_upload(name: &'static str, micros: u64, bytes: u64) {
    with_lane(name, |r| {
        r.clocks.last_upload_us = micros;
        r.clocks.last_upload_bytes = bytes;
        r.clocks.uploads_total += 1;
    });
}

/// **One in-GPU pass window resolved to `micros`** (device timestamps, converted
/// through `Queue::get_timestamp_period`). Implies timestamps are real — only the
/// pass-clock readback calls this, and it cannot run without the feature.
pub fn note_gpu_pass(name: &'static str, micros: u64) {
    with_lane(name, |r| {
        r.clocks.last_gpu_pass_us = Some(micros);
        r.clocks.gpu_timestamps = Some(true);
    });
}

/// **Say whether this lane's device can measure pass time at all.** `false` = the
/// device was requested without (or the adapter lacks) TIMESTAMP_QUERY, so
/// `last_gpu_pass_us` will honestly stay `None` — never `0`. Recorded once per
/// probe (the lane's pass-clock slot), not per frame.
pub fn note_gpu_timestamps(name: &'static str, real: bool) {
    with_lane(name, |r| r.clocks.gpu_timestamps = Some(real));
}

/// **ONE lane's GPU clocks** — what a host (korp) polls to finish its per-viewport
/// mousewheel→GPU TRACE line. Zero-valued default for a lane that never registered,
/// so the caller can always destructure.
#[must_use]
pub fn clock_stats_of(name: &str) -> LaneClockStats {
    lanes_slot().lock().ok().and_then(|g| g.get(name).map(|r| r.clocks)).unwrap_or_default()
}

/// Every registered lane, name-ordered.
#[must_use]
pub fn lanes() -> Vec<LaneRecord> {
    lanes_slot().lock().map(|g| g.values().cloned().collect()).unwrap_or_default()
}

/// **Frames ONE lane has encoded** — `0` for a lane that never registered.
///
/// The cheap read: [`lanes`] clones every record's `String` name, which is fine for an
/// About box and wasteful for something a per-frame paint path consults. And a paint
/// path genuinely needs it: `facett_map::layer::MapFacet` latches its upload-once VRAM
/// bake on "has a frame actually been encoded since I handed the geometry over", because
/// egui may DISCARD the frame a payload rode on (a sizing pass is one) — and a host that
/// latched on the *handover* would never re-send it, leaving the lane at zero frames
/// forever. That is the [`GpuLaneUse::InstalledUnused`] disease reappearing one level
/// down, so the ack is read from the same counter the About box reports.
#[must_use]
pub fn frames_of(name: &str) -> u64 {
    lanes_slot().lock().map(|g| g.get(name).map_or(0, |r| r.frames)).unwrap_or(0)
}

/// **THE fold**: is a GPU lane in use, installed-but-unused, absent — or unknowable?
#[must_use]
pub fn lane_use() -> GpuLaneUse {
    fold_lane_use(&lanes())
}

/// The pure fold [`lane_use`] applies, so the policy is testable without touching
/// the process-global registry.
#[must_use]
pub fn fold_lane_use(lanes: &[LaneRecord]) -> GpuLaneUse {
    let live: Vec<&LaneRecord> = lanes.iter().filter(|l| l.installed || l.frames > 0).collect();
    if live.is_empty() {
        return GpuLaneUse::NotInstalled;
    }
    let frames: u64 = live.iter().map(|l| l.frames).sum();
    if frames > 0 {
        return GpuLaneUse::InUse { frames };
    }
    let silent = live.iter().filter(|l| !l.reports_frames).count();
    if silent == 0 {
        GpuLaneUse::InstalledUnused
    } else {
        GpuLaneUse::Unknown { silent_lanes: silent }
    }
}

/// **WHICH LANE DREW — the on-screen flag, in THREE states.**
///
/// Rickard, 2026-08-23: *"PLEASE add a flag saying GPU or CPU when rendering osm 2d and
/// 3d, so i know whats being used"*. This is the one writer of that answer's text, so a
/// pane, a log line and a `state_json` block cannot disagree about it (LAW 5).
///
/// # Why THREE and not two
///
/// Because [`Pending`](Self::Pending) is a real and common state, and rendering it as
/// `CPU` is the exact lie this whole module exists to stop. `Map3D::used_gpu_observed()`
/// is `None` until a frame has been through the backend, and the 2D lane can have its
/// callback placed with nothing yet out of the device
/// ([`AWAITING_FIRST_ENCODE`]). Both are "nobody has measured", not "the CPU painter
/// drew it".
///
/// This is the same trap that was caught on this codebase twice on one day: a `gpu=false`
/// read before the first paint (korp's `log_map3d_lane`, 2026-08-06 — read as the genuine
/// defect by three people) and `paint_order_pixels` passing on the CPU painter while the
/// device lane was wrong. A two-state flag would put a confident `CPU` on the screen for
/// every pane that simply has not painted yet.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum LaneFlag {
    /// A frame really went through the GPU lane.
    Gpu,
    /// A frame really went through the CPU painter. A first-class outcome, not a failure.
    Cpu,
    /// **No measurement exists yet.** Never render this as `CPU`.
    Pending,
}

impl LaneFlag {
    /// From an OBSERVATION of the lane: `Some(true)` GPU, `Some(false)` CPU, `None`
    /// nothing has painted yet.
    ///
    /// Takes `Option<bool>` and not `bool` on purpose — the `bool`-shaped readers
    /// (`Map3D::used_gpu`) collapse "not measured" into `false`, which is how a pane on an
    /// RTX 4090 came to report the CPU painter.
    #[must_use]
    pub fn from_observed(observed: Option<bool>) -> Self {
        match observed {
            Some(true) => Self::Gpu,
            Some(false) => Self::Cpu,
            None => Self::Pending,
        }
    }

    /// **The short label a pane shows.** `GPU` · `CPU` · `—` (an em dash: visibly not a
    /// verdict, and the same width-ish glyph in a monospace chip).
    #[must_use]
    pub fn label(self) -> &'static str {
        match self {
            Self::Gpu => "GPU",
            Self::Cpu => "CPU",
            Self::Pending => "",
        }
    }

    /// The stable token for `state_json` and log lines — the machine-readable twin of
    /// [`Self::label`], from the same match so the two cannot drift.
    #[must_use]
    pub fn token(self) -> &'static str {
        match self {
            Self::Gpu => "gpu",
            Self::Cpu => "cpu",
            Self::Pending => "pending",
        }
    }

    /// `(foreground, opaque plate)` for the chip.
    ///
    /// The plate is **fully opaque** for the reason `crate::devid::chip_colors` records
    /// and measured: this is an overlay on a pane that has already drawn there, so a
    /// translucent plate superimposes two strings in the same pixels instead of putting
    /// the flag on the pane.
    ///
    /// GPU reads cool/confident, CPU reads warm (it is the answer a user may want to act
    /// on), and `Pending` is deliberately DIM — it must not look like a verdict.
    #[must_use]
    pub fn colors(self) -> (egui::Color32, egui::Color32) {
        match self {
            Self::Gpu => (egui::Color32::from_rgb(140, 230, 170), egui::Color32::from_rgb(10, 22, 14)),
            Self::Cpu => (egui::Color32::from_rgb(255, 200, 120), egui::Color32::from_rgb(26, 18, 8)),
            Self::Pending => (egui::Color32::from_gray(130), egui::Color32::from_rgb(20, 20, 22)),
        }
    }
}

/// The a11y atom prefix every lane flag is emitted under — what a headless test and the
/// robot driver match on.
///
/// The flag is painted as a real a11y node and not as bare glyphs for the reason
/// `crate::devid::badge` states in so many words: *"Painted-only text is invisible to
/// every check we have — which is how a badge ships green and never appears."*
pub const LANE_FLAG_ATOM: &str = "lane:";

/// **The full atom label for a flag** — `lane: GPU`. One writer, so the test matches what
/// the pane emits by construction rather than by two people spelling it the same way.
#[must_use]
pub fn lane_flag_atom(flag: LaneFlag) -> String {
    format!("{LANE_FLAG_ATOM} {}", flag.label())
}

/// **Paint the lane flag in the top-LEFT of `rect`**, as a real a11y atom.
///
/// Top-left, not top-right, because `crate::devid::badge` already owns the top-right band
/// and the two must not land in the same pixels — the dev-id chip's own doc records what
/// overlapping overlay text costs to read.
///
/// `Sense::hover()` only, never `click`: measured 2026-08-21, a clicking overlay chip in a
/// pane's own control band ate every click on the Git pane's `Log` toggle. A debug overlay
/// must never steal input from the pane it labels.
///
/// **Not gated on a debug build.** `devid::badge` is a no-op in release because a dev-id is
/// for developers; this one answers a question Rickard asks of the shipped binary, so it
/// paints in every profile.
pub fn paint_lane_flag(ui: &mut egui::Ui, rect: egui::Rect, flag: LaneFlag) {
    let text = flag.label();
    let (fg, bg) = flag.colors();
    let font = egui::FontId::monospace(10.0);
    let galley = ui.painter().layout_no_wrap(text.to_string(), font.clone(), fg);
    let size = galley.size();
    let chip = egui::Rect::from_min_size(egui::pos2(rect.left() + 4.0, rect.top() + 4.0), size)
        .expand2(egui::vec2(4.0, 2.0));
    let label = lane_flag_atom(flag);
    let resp = crate::a11y::node(
        ui,
        ui.id(),
        ("lane_flag", text),
        egui::Sense::hover(),
        chip,
        crate::a11y::Semantics::button(label),
    );
    let p = ui.painter();
    p.rect_filled(chip, 3.0, bg);
    p.text(chip.center(), egui::Align2::CENTER_CENTER, text, font, fg);
    resp.on_hover_text(match flag {
        LaneFlag::Gpu => "This pane's last frame was drawn by its GPU lane.",
        LaneFlag::Cpu => "This pane's last frame was drawn by the CPU painter.",
        LaneFlag::Pending => {
            "No frame has reached this pane's renderer yet — this is NOT 'the CPU drew it'."
        }
    });
}

/// **The three states must be three, and `None` must never read as CPU.**
///
/// RED: make `from_observed` map `None => Self::Cpu` (the collapse every `bool`-shaped
/// reader in this codebase has made at least once) and the third assertion fires; make
/// `label`/`token` share one match arm across two variants and the distinctness
/// assertions fire.
#[cfg(test)]
mod lane_flag {
    use super::*;

    #[test]
    fn the_three_states_are_three_and_pending_is_not_cpu() {
        assert_eq!(LaneFlag::from_observed(Some(true)), LaneFlag::Gpu);
        assert_eq!(LaneFlag::from_observed(Some(false)), LaneFlag::Cpu);
        assert_eq!(LaneFlag::from_observed(None), LaneFlag::Pending);

        // The labels a human reads are DISTINCT, and the pending one is not a verdict.
        let labels = [LaneFlag::Gpu.label(), LaneFlag::Cpu.label(), LaneFlag::Pending.label()];
        assert_eq!(
            labels.iter().collect::<std::collections::HashSet<_>>().len(),
            3,
            "three states must produce three labels, got {labels:?}"
        );
        assert_ne!(
            LaneFlag::Pending.label(),
            LaneFlag::Cpu.label(),
            "a pane that has not painted must NOT read as the CPU painter — that is the \
             exact lie this type exists to prevent"
        );
        // …and the machine tokens too, so a state_json consumer can tell them apart.
        let tokens = [LaneFlag::Gpu.token(), LaneFlag::Cpu.token(), LaneFlag::Pending.token()];
        assert_eq!(tokens.iter().collect::<std::collections::HashSet<_>>().len(), 3);
        assert_eq!(tokens, ["gpu", "cpu", "pending"]);
    }

    /// The atom label is what a headless test matches on, so it is pinned here rather
    /// than spelled a second time in every consumer's test.
    #[test]
    fn the_atom_label_carries_the_flag() {
        assert_eq!(lane_flag_atom(LaneFlag::Gpu), "lane: GPU");
        assert_eq!(lane_flag_atom(LaneFlag::Cpu), "lane: CPU");
        assert_eq!(lane_flag_atom(LaneFlag::Pending), "lane: —");
    }

    /// The plate must be OPAQUE — the chip sits over a pane that has already drawn there.
    /// RED: drop the alpha in any `colors()` arm.
    #[test]
    fn every_plate_is_opaque_so_the_flag_does_not_superimpose_two_strings() {
        for f in [LaneFlag::Gpu, LaneFlag::Cpu, LaneFlag::Pending] {
            let (fg, bg) = f.colors();
            assert_eq!(bg.a(), 255, "{f:?}: the plate must be fully opaque, got alpha {}", bg.a());
            assert_eq!(fg.a(), 255, "{f:?}: the text must be fully opaque, got alpha {}", fg.a());
        }
    }
}

/// **The `unknown` row must name the SILENT lane, not the roster.**
///
/// Reported live 2026-08-08 on a 4090: `GPU lane: unknown — 1 installed lane(s)
/// (CloudRenderer, Map3dRenderer, GpuMapRenderer) do not report frames`. One silent lane,
/// three renderers accused, and no way to tell from the row which to fix.
///
/// RED direction: put `names(false)` back in the `Unknown` arm and the row names lanes that
/// are counting.
#[cfg(test)]
mod silent_lane_naming {
    use super::*;

    fn rec(name: &'static str, reports: bool) -> LaneRecord {
        LaneRecord {
            name: name.to_string(),
            installed: true,
            reports_frames: reports,
            frames: 0,
            idle_reason: None,
            clocks: LaneClockStats::default(),
        }
    }

    #[test]
    fn the_unknown_row_names_only_the_lanes_that_do_not_count() {
        let lanes = vec![
            rec("a::CloudRenderer", true),
            rec("b::Map3dRenderer", false),
            rec("c::GpuMapRenderer", true),
        ];
        let g = GpuStatus {
            notes: Vec::new(),
            adapter: None,
            unavailable: None,
            lane: fold_lane_use(&lanes),
            lanes,
        };
        assert_eq!(g.lane, GpuLaneUse::Unknown { silent_lanes: 1 }, "precondition");
        assert_eq!(g.silent_lane_names(), "Map3dRenderer", "only the silent one is named");
        let line = g.lane_line();
        assert!(line.contains("Map3dRenderer"), "the row names the lane to fix: {line}");
        for innocent in ["CloudRenderer", "GpuMapRenderer"] {
            assert!(
                !line.contains(innocent),
                "a lane that IS counting must not be accused: {line}",
            );
        }
        assert!(line.contains("1 installed lane(s)"), "count and names must agree: {line}");
    }

    #[test]
    fn a_registry_with_nothing_silent_never_reaches_the_unknown_row() {
        let lanes = vec![rec("a::CloudRenderer", true), rec("c::GpuMapRenderer", true)];
        assert_eq!(
            fold_lane_use(&lanes),
            GpuLaneUse::InstalledUnused,
            "every lane counting ⇒ a zero is a real zero, not an unknown",
        );
    }
}

/// Clear the registry. **Tests only** — the registry is a process-global and a test
/// that asserts a fold needs a known starting point.
#[doc(hidden)]
pub fn reset_for_test() {
    if let Ok(mut g) = lanes_slot().lock() {
        g.clear();
    }
}

// ── the whole GPU story, as one value ───────────────────────────────────────

// ── Live STATUS NOTES: one-line facts other crates want on the About card ────
//
// The GPU rows are the ONE writer of "what is this app rendering on"
// (`GpuStatus::rows`), and facett-core cannot depend on the crates that own
// adjacent facts (facett-map's baked-vertex store lives ABOVE this crate). So a
// crate registers a CALLBACK returning its one live line, and `probe()` reads
// them all — the row set stays one writer, the fact stays with its owner, and a
// host (korp, holger, dwarves-ui) adds nothing. A callback returning `None`
// contributes no row (honest absence: "no store installed" is silence, not a
// zeroed reading).
static STATUS_NOTES: OnceLock<Mutex<Vec<fn() -> Option<String>>>> = OnceLock::new();

fn status_note_slot() -> &'static Mutex<Vec<fn() -> Option<String>>> {
    STATUS_NOTES.get_or_init(|| Mutex::new(Vec::new()))
}

/// Register a live status-note callback (idempotent per function pointer, so an
/// install path that runs twice does not double its row).
pub fn register_status_note(f: fn() -> Option<String>) {
    if let Ok(mut g) = status_note_slot().lock() {
        if !g.iter().any(|&h| std::ptr::fn_addr_eq(h, f)) {
            g.push(f);
        }
    }
}

/// Every registered note's CURRENT line, in registration order.
fn status_notes() -> Vec<String> {
    status_note_slot().lock().map(|g| g.iter().filter_map(|f| f()).collect()).unwrap_or_default()
}


/// **What a UI shows about the GPU**: which adapter, which backend, which device
/// class, how many adapters were enumerated, and whether a GPU lane is really being
/// used.
///
/// One value so the About card, a status bar and a robot assertion all read the same
/// facts through the same formatting (LAW #5), instead of each re-deriving "is this
/// software?" from `AdapterInfo` and getting it subtly differently.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GpuStatus {
    /// The adapter selection the host recorded at startup; `None` when no GPU
    /// backend was brought up in this process (a CPU-painter build, or headless).
    pub adapter: Option<AdapterSelection>,
    /// A recorded bring-up FAILURE (`facet-gpu-<n>` + remedy), if there was one.
    pub unavailable: Option<serde_json::Value>,
    /// The lane fold.
    pub lane: GpuLaneUse,
    /// Every registered lane (what the fold was computed from).
    pub lanes: Vec<LaneRecord>,
    /// Live one-line facts other crates registered ([`register_status_note`]) —
    /// e.g. facett-map's baked-vertex cache hit line. Painted after the GPU rows,
    /// in `state_json` as `"notes"`.
    pub notes: Vec<String>,
}

impl GpuStatus {
    /// Read the live process globals: the recorded adapter selection, any recorded
    /// bring-up failure, and the lane registry.
    #[must_use]
    pub fn probe() -> Self {
        let lanes = lanes();
        let un = gpu_unavailable_json();
        Self {
            adapter: selected_adapter(),
            unavailable: if un.is_null() { None } else { Some(un) },
            lane: fold_lane_use(&lanes),
            lanes,
            notes: status_notes(),
        }
    }

    /// A status with nothing recorded — what a headless CPU build honestly reports.
    #[must_use]
    pub fn none() -> Self {
        Self {
            adapter: None,
            unavailable: None,
            lane: GpuLaneUse::NotInstalled,
            lanes: Vec::new(),
            notes: Vec::new(),
        }
    }

    /// Build a status from an explicit selection + lane list (tests, and a host that
    /// wants to show a decision it has in hand rather than the global).
    #[must_use]
    pub fn of(adapter: Option<AdapterSelection>, lanes: Vec<LaneRecord>) -> Self {
        Self { adapter, unavailable: None, lane: fold_lane_use(&lanes), lanes, notes: Vec::new() }
    }

    /// **Is the app rendering on a CPU software rasteriser?** Taken from the
    /// selection's `software` flag, which is computed by name AND device class — so
    /// llvmpipe reporting itself as `DiscreteGpu` is still software here. Never read
    /// `kind` alone for this question.
    #[must_use]
    pub fn is_software(&self) -> bool {
        self.adapter.as_ref().is_some_and(|s| s.software)
    }

    /// How many adapters the host enumerated (0 when no backend came up).
    #[must_use]
    pub fn adapter_count(&self) -> usize {
        self.adapter.as_ref().map_or(0, |s| s.considered.len())
    }

    /// The device class as a UI shows it: **`SOFTWARE (CPU rasteriser)`** for
    /// llvmpipe/lavapipe/SwiftShader whatever they claim to be, `management console
    /// (BMC)` for an ASPEED/Matrox framebuffer, else the adapter's own class.
    #[must_use]
    pub fn device_class(&self) -> String {
        match &self.adapter {
            None => "none".to_owned(),
            Some(s) if s.software => "SOFTWARE (CPU rasteriser)".to_owned(),
            Some(s) if is_management_display(&s.chosen) => "management console (BMC)".to_owned(),
            Some(s) => s.chosen.kind.as_str().to_owned(),
        }
    }

    /// Row 1 — the adapter name.
    #[must_use]
    pub fn adapter_line(&self) -> String {
        match &self.adapter {
            Some(s) => format!("GPU: {}", s.chosen.name),
            None => "GPU: none — no adapter was brought up in this process".to_owned(),
        }
    }

    /// Row 2 — backend · device class · how many adapters were enumerated.
    #[must_use]
    pub fn detail_line(&self) -> String {
        match &self.adapter {
            Some(s) => format!(
                "{} · {} · {} adapter(s) enumerated{}",
                if s.chosen.backend.is_empty() { "?" } else { s.chosen.backend.as_str() },
                self.device_class(),
                s.considered.len(),
                if s.forced { " · FORCED" } else { "" },
            ),
            None => "no backend · no adapter enumerated".to_owned(),
        }
    }

    /// Row 3 — the honest lane answer.
    #[must_use]
    pub fn lane_line(&self) -> String {
        let names = |only_used: bool| -> String {
            let v: Vec<&str> = self
                .lanes
                .iter()
                .filter(|l| if only_used { l.frames > 0 } else { l.installed })
                .map(LaneRecord::short_name)
                .collect();
            if v.is_empty() { "".to_owned() } else { v.join(", ") }
        };
        match self.lane {
            GpuLaneUse::InUse { frames } => {
                format!("GPU lane: IN USE — {frames} frame(s) encoded by {}", names(true))
            }
            // **"the CPU painter is doing the work" is a CLAIM, and it is false whenever
            // nothing has drawn the pane.** MEASURED 2026-08-03 on the shipped korp-ui, in
            // the posture a human lands in (korp opens on 🧊 Tables, and the map lane
            // belongs to the 🗺 Map pane):
            //
            //   GPU lane: installed but UNUSED — CloudRenderer, GpuMapRenderer drew 0
            //             frames (the CPU painter is doing the work)
            //   idle because — GpuMapRenderer: pane_not_painted_yet
            //
            // Two adjacent rows contradicting each other: no CPU painter was doing that
            // lane's work, because no map was being drawn by anything. That headline is
            // the exact sentence Rickard has been reading all day and reasonably taking
            // for a broken GPU on a 4090.
            //
            // So the claim is made only when it is TRUE — when at least one idle lane
            // actually DECLINED the work (`rotated_camera`, `no_line_ways`, …). When every
            // idle lane is merely un-drawn ([`NOT_YET_DRAWN_REASONS`]) the row says that
            // instead, and the `idle because` row below still names which lane and why.
            GpuLaneUse::InstalledUnused if self.every_idle_lane_is_undrawn() => format!(
                "GPU lane: installed, NOT YET DRAWN — {} has not been asked to paint (no CPU painter is doing its work either)",
                names(false)
            ),
            GpuLaneUse::InstalledUnused => format!(
                "GPU lane: installed but UNUSED — {} drew 0 frames (the CPU painter is doing the work)",
                names(false)
            ),
            GpuLaneUse::NotInstalled => {
                "GPU lane: not installed — the CPU painter owns every pane".to_owned()
            }
            // **Name the SILENT lanes, not every installed one.** This printed
            // `names(false)` — the whole installed roster — beside a count of the silent
            // subset, so a registry with one silent lane read
            //
            //     GPU lane: unknown — 1 installed lane(s)
            //     (CloudRenderer, Map3dRenderer, GpuMapRenderer) do not report frames
            //
            // Three renderers named for one lane's omission, and the two counting faithfully
            // accused alongside it. Rickard read exactly that on a 4090, 2026-08-08. A row
            // whose count and whose names disagree cannot be acted on: it does not say which
            // lane to go and wire.
            GpuLaneUse::Unknown { silent_lanes } => format!(
                "GPU lane: unknown — {silent_lanes} installed lane(s) ({}) do not report \
                 frames; the rest are counting",
                self.silent_lane_names()
            ),
        }
    }

    /// **The lanes that never promised to count** — the ones
    /// [`GpuLaneUse::Unknown`](GpuLaneUse::Unknown) counts, by name, so the row says which
    /// renderer to go and wire rather than naming the whole roster.
    #[must_use]
    pub fn silent_lane_names(&self) -> String {
        let v: Vec<&str> = self
            .lanes
            .iter()
            .filter(|l| (l.installed || l.frames > 0) && !l.reports_frames)
            .map(LaneRecord::short_name)
            .collect();
        if v.is_empty() { "".to_owned() } else { v.join(", ") }
    }

    /// **Has EVERY idle lane merely not been drawn yet** (as opposed to having declined
    /// the work)? Drives the [`lane_line`](Self::lane_line) split above.
    ///
    /// `false` when a single idle lane declined for a reason of its own, or stayed silent
    /// — silence is not evidence of un-drawn-ness, and over-claiming here would swap one
    /// wrong sentence for another. `false` on no idle lanes at all, so a live lane never
    /// reaches this arm.
    #[must_use]
    pub fn every_idle_lane_is_undrawn(&self) -> bool {
        let mut idle = self.lanes.iter().filter(|l| l.installed && l.frames == 0).peekable();
        idle.peek().is_some()
            && idle.all(|l| {
                l.idle_reason.as_deref().is_some_and(|r| NOT_YET_DRAWN_REASONS.contains(&r))
            })
    }

    /// Row 4 — a recorded bring-up failure's code + remedy, when there was one.
    #[must_use]
    pub fn unavailable_line(&self) -> Option<String> {
        let u = self.unavailable.as_ref()?;
        Some(format!(
            "{}{}",
            u["code"].as_str().unwrap_or("facet-gpu-?"),
            u["remedy"].as_str().unwrap_or("(no remedy recorded)")
        ))
    }

    /// Every row, in paint order — the ONE writer a UI and a robot both read, so the
    /// assertion cannot drift from the pixels.
    #[must_use]
    pub fn rows(&self) -> Vec<String> {
        let mut v = vec![self.adapter_line(), self.detail_line(), self.lane_line()];
        v.extend(self.idle_reason_line());
        v.extend(self.unavailable_line());
        v.extend(self.notes.iter().cloned());
        v
    }

    /// Row 3b — **WHY each idle lane is idle**, in its owner's words.
    ///
    /// Its OWN row rather than a tail on [`lane_line`](Self::lane_line): that line is
    /// already long enough to reach the edge of korp's About card, and a reason appended
    /// to it was MEASURED clipped off-screen on 2026-08-02 — a diagnosis nobody can read
    /// is no better than the ambiguity it was added to remove.
    ///
    /// `None` when every lane is painting, or when no idle lane has been taught to
    /// explain itself: silence is a truthful "nobody said", never a guess.
    #[must_use]
    pub fn idle_reason_line(&self) -> Option<String> {
        let v: Vec<String> = self
            .lanes
            .iter()
            .filter(|l| l.frames == 0)
            .filter_map(|l| l.idle_reason.as_ref().map(|r| format!("{}: {r}", l.short_name())))
            .collect();
        if v.is_empty() { None } else { Some(format!("idle because — {}", v.join("; "))) }
    }

    /// The `state_json` fragment.
    #[must_use]
    pub fn to_json(&self) -> serde_json::Value {
        serde_json::json!({
            "adapter": match &self.adapter {
                Some(s) => s.to_json(),
                None => serde_json::Value::Null,
            },
            "adapter_count": self.adapter_count(),
            "backend": self.adapter.as_ref().map(|s| s.chosen.backend.clone()),
            "device_class": self.device_class(),
            "software": self.is_software(),
            "lane": self.lane.as_str(),
            "lane_frames": self.lane.frames(),
            "lanes": self.lanes,
            "unavailable": self.unavailable.clone().unwrap_or(serde_json::Value::Null),
            "notes": self.notes,
            "rows": self.rows(),
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::render::adapter::{AdapterFacts, AdapterKind, VENDOR_MESA, VENDOR_NVIDIA};

    fn nvidia() -> AdapterFacts {
        AdapterFacts::new("NVIDIA GeForce RTX 4090", AdapterKind::DiscreteGpu, "Vulkan")
            .with_vendor(VENDOR_NVIDIA)
    }
    fn llvmpipe() -> AdapterFacts {
        AdapterFacts::new("llvmpipe (LLVM 21.1.8, 256 bits)", AdapterKind::Cpu, "Vulkan")
            .with_vendor(VENDOR_MESA)
    }
    fn lane(name: &str, installed: bool, reports: bool, frames: u64) -> LaneRecord {
        LaneRecord {
            name: name.to_owned(),
            installed,
            reports_frames: reports,
            frames,
            idle_reason: None,
            clocks: LaneClockStats::default(),
        }
    }

    /// **RED-when-broken: the headline must not claim a CPU painter is doing work that
    /// nobody is doing.**
    ///
    /// MEASURED on the shipped korp-ui 2026-08-03, in the posture a human actually lands
    /// in (korp opens on 🧊 Tables; the map lane belongs to the 🗺 Map pane), on a real
    /// Xvfb window with the RTX 4090 selected:
    ///
    /// ```text
    /// GPU lane: installed but UNUSED — CloudRenderer, GpuMapRenderer drew 0 frames
    ///           (the CPU painter is doing the work)
    /// idle because — GpuMapRenderer: pane_not_painted_yet
    /// ```
    ///
    /// Two adjacent rows that contradict each other. No CPU painter was drawing that
    /// lane's work — nothing was drawing a map at all. That parenthesis is the sentence
    /// Rickard read all day and reasonably took for a broken GPU. `idle_reason` alone did
    /// not fix it, because the headline is the line the eye lands on first.
    ///
    /// The negative leg matters as much: a lane that genuinely DECLINED
    /// (`rotated_camera`) really did leave the work to the CPU painter, and must keep
    /// saying so — otherwise this "fix" just installs a different wrong sentence.
    #[test]
    fn an_undrawn_lane_is_not_reported_as_the_cpu_painter_doing_the_work() {
        let undrawn = |name: &str, reason: &str| LaneRecord {
            idle_reason: Some(reason.to_owned()),
            ..lane(name, true, true, 0)
        };
        let status = |lanes: Vec<LaneRecord>| GpuStatus {
            notes: Vec::new(),
            adapter: None,
            unavailable: None,
            lane: fold_lane_use(&lanes),
            lanes,
        };

        // korp's exact measured shape: both installed lanes idle, both merely un-drawn.
        let korp = status(vec![
            undrawn("facett_core::render::gpu::graphcloud::cloud::CloudRenderer", PANE_NOT_PAINTED_YET),
            undrawn("facett_map::gpu::GpuMapRenderer", PANE_NOT_PAINTED_YET),
        ]);
        assert!(korp.every_idle_lane_is_undrawn());
        let line = korp.lane_line();
        assert!(
            !line.contains("the CPU painter is doing the work"),
            "nothing was drawing this lane's pane, so nothing was doing its work: {line}",
        );
        assert!(line.contains("NOT YET DRAWN"), "the row must say what is actually true: {line}");
        // The reason row still names WHICH lane and WHY — the headline replaces nothing.
        assert!(
            korp.rows().iter().any(|r| r.contains("GpuMapRenderer: pane_not_painted_yet")),
            "{:?}",
            korp.rows(),
        );

        // A lane chosen this frame that has not encoded yet is the same class of answer.
        let chosen = status(vec![undrawn("facett_map::gpu::GpuMapRenderer", AWAITING_FIRST_ENCODE)]);
        assert!(!chosen.lane_line().contains("the CPU painter is doing the work"));

        // ── THE NEGATIVE LEG. A lane that DECLINED the work left it to the CPU painter,
        //    and that sentence is true and must survive.
        let declined = status(vec![undrawn("facett_map::gpu::GpuMapRenderer", "rotated_camera")]);
        assert!(!declined.every_idle_lane_is_undrawn());
        assert!(
            declined.lane_line().contains("the CPU painter is doing the work"),
            "a declined lane really did hand the work over: {}",
            declined.lane_line(),
        );

        // ── AND A SILENT LANE IS NOT EVIDENCE. One lane that never said why is enough to
        //    withhold the claim in either direction — this is the arm that made me teach
        //    CloudRenderer to speak rather than weaken the predicate.
        let mixed = status(vec![
            lane("facett_core::render::gpu::graphcloud::cloud::CloudRenderer", true, true, 0),
            undrawn("facett_map::gpu::GpuMapRenderer", PANE_NOT_PAINTED_YET),
        ]);
        assert!(
            !mixed.every_idle_lane_is_undrawn(),
            "a lane that never explained itself cannot be counted as un-drawn",
        );
    }

    /// **RED-when-broken: an idle lane's REASON reaches the row a human reads.**
    ///
    /// `installed but UNUSED — … drew 0 frames (the CPU painter is doing the work)` is
    /// every word true of a lane that correctly stood aside AND of a lane that is broken.
    /// On 2026-08-02 korp printed exactly that on an RTX 4090 while nothing was wrong —
    /// the map pane simply had not been painted yet (modal infra chooser, landing tab is
    /// Tables) — and neither Rickard nor a coordinating agent could tell which it was by
    /// looking at the product. A diagnostic that cannot separate "correct" from "broken"
    /// is the same disease this module was written to cure, one level up.
    #[test]
    fn an_idle_lane_names_its_reason_in_the_row_a_human_reads() {
        let mut rec = lane("facett_map::gpu::GpuMapRenderer", true, true, 0);
        let bare = GpuStatus {
            notes: Vec::new(),
            adapter: None,
            unavailable: None,
            lane: fold_lane_use(std::slice::from_ref(&rec)),
            lanes: vec![rec.clone()],
        };
        let bare_rows = bare.rows();
        assert!(bare_rows.iter().any(|r| r.contains("installed but UNUSED")), "{bare_rows:?}");
        assert!(
            !bare_rows.iter().any(|r| r.contains("idle because")),
            "a lane that never explained itself must not have words put in its mouth: {bare_rows:?}"
        );
        assert_eq!(bare.idle_reason_line(), None);

        // Now the lane says why. The SAME fold, the SAME state — only the reason added.
        rec.idle_reason = Some("pane_not_painted_yet".to_owned());
        let told = GpuStatus {
            notes: Vec::new(),
            adapter: None,
            unavailable: None,
            lane: fold_lane_use(std::slice::from_ref(&rec)),
            lanes: vec![rec.clone()],
        };
        let told_rows = told.rows();
        assert_ne!(bare_rows, told_rows, "the reason must CHANGE what a human reads, or it is not reaching them");
        assert!(
            told_rows.iter().any(|r| r == "idle because — GpuMapRenderer: pane_not_painted_yet"),
            "the reason must be its OWN row, naming lane and reason: {told_rows:?}"
        );
        // …and it must NOT be pasted onto the already-edge-reaching lane line, where it
        // was measured clipped off korp's About card.
        assert!(
            !told.lane_line().contains("pane_not_painted_yet"),
            "the reason belongs on its own row: {}",
            told.lane_line()
        );

        // A PAINTING lane must not be slandered with a stale reason, and a mixed process
        // (korp: map lane painting, graph-3D lane idle with no graph open) must report
        // both halves — `InUse` overall, and WHY the other one sat out.
        let painting = lane("facett_map::gpu::GpuMapRenderer", true, true, 7);
        let mut idle_other = lane("facett_graph3d::gpu::CloudRenderer", true, true, 0);
        idle_other.idle_reason = Some("no_graph_open".to_owned());
        let mixed = GpuStatus {
            notes: Vec::new(),
            adapter: None,
            unavailable: None,
            lane: fold_lane_use(&[painting.clone(), idle_other.clone()]),
            lanes: vec![painting, idle_other],
        };
        let mixed_rows = mixed.rows();
        assert!(mixed_rows.iter().any(|r| r.contains("IN USE — 7 frame(s)")), "{mixed_rows:?}");
        assert!(
            !mixed_rows.iter().any(|r| r.contains("GpuMapRenderer: ")),
            "the lane that PAINTED must not be listed as idle: {mixed_rows:?}"
        );
        assert!(
            mixed_rows.iter().any(|r| r == "idle because — CloudRenderer: no_graph_open"),
            "the idle lane's reason must survive alongside a painting one: {mixed_rows:?}"
        );
    }

    /// **RED-when-broken: the four lane states are distinct and none is guessed.**
    ///
    /// The one that matters is the last: a silent installed lane must fold to
    /// `Unknown`, NOT to `InstalledUnused`. Claiming "unused" there is a guess about
    /// a lane that never reported, and it is the exact overstatement an About box
    /// must not make.
    #[test]
    fn the_lane_fold_never_guesses() {
        assert_eq!(fold_lane_use(&[]), GpuLaneUse::NotInstalled);
        // Registered-but-not-installed is still "not installed".
        assert_eq!(fold_lane_use(&[lane("A", false, true, 0)]), GpuLaneUse::NotInstalled);
        // Reporting lane at zero → genuinely unused (korp's map facet).
        assert_eq!(fold_lane_use(&[lane("A", true, true, 0)]), GpuLaneUse::InstalledUnused);
        // Any frame at all → in use, summed across lanes.
        assert_eq!(
            fold_lane_use(&[lane("A", true, true, 7), lane("B", true, true, 5)]),
            GpuLaneUse::InUse { frames: 12 }
        );
        // A SILENT installed lane is unknowable — never "unused".
        assert_eq!(
            fold_lane_use(&[lane("A", true, false, 0)]),
            GpuLaneUse::Unknown { silent_lanes: 1 },
            "a lane that never promised to count frames must fold to unknown, not to unused"
        );
        // Mixed: one reporting-at-zero + one silent is still unknown.
        assert_eq!(
            fold_lane_use(&[lane("A", true, true, 0), lane("B", true, false, 0)]),
            GpuLaneUse::Unknown { silent_lanes: 1 }
        );
        // …but a real frame from the reporting lane settles it.
        assert_eq!(
            fold_lane_use(&[lane("A", true, true, 3), lane("B", true, false, 0)]),
            GpuLaneUse::InUse { frames: 3 }
        );
    }

    /// **RED-when-broken — THE headline: a software adapter can never read as
    /// discrete.** llvmpipe that *reports itself* `DeviceType::DiscreteGpu` (a
    /// lying ICD, and the shape `is_software_rasteriser` exists to catch) must still
    /// show `SOFTWARE` in the row and `software: true` in the json. If this goes red,
    /// the About box tells a 4090 story on a CPU rasteriser — the failure the rows
    /// exist to expose.
    #[test]
    fn a_lying_software_adapter_still_reads_software() {
        let liar = AdapterFacts::new("llvmpipe (LLVM 21.1.8)", AdapterKind::DiscreteGpu, "Vulkan")
            .with_vendor(VENDOR_MESA);
        let st = GpuStatus::of(AdapterSelection::decide(&[liar], None), vec![]);
        assert!(st.is_software(), "llvmpipe is software however it classes itself");
        assert_eq!(st.device_class(), "SOFTWARE (CPU rasteriser)");
        assert!(
            st.detail_line().contains("SOFTWARE"),
            "the row must say SOFTWARE: {}",
            st.detail_line()
        );
        assert!(
            !st.detail_line().contains("discrete"),
            "the row must NOT call a software rasteriser discrete: {}",
            st.detail_line()
        );
        assert_eq!(st.to_json()["software"], serde_json::json!(true));
        assert_eq!(st.to_json()["device_class"], serde_json::json!("SOFTWARE (CPU rasteriser)"));
    }

    /// The real oden enumeration: the rows name the card, the backend, the class and
    /// the adapter count, and the json carries the same facts.
    #[test]
    fn rows_carry_adapter_backend_class_and_count() {
        let st = GpuStatus::of(
            AdapterSelection::decide(&[llvmpipe(), nvidia()], None),
            vec![lane("facett_map::gpu::GpuMapRenderer", true, true, 42)],
        );
        let rows = st.rows();
        assert!(rows[0].contains("NVIDIA GeForce RTX 4090"), "{:?}", rows);
        assert!(rows[1].contains("Vulkan"), "{:?}", rows);
        assert!(rows[1].contains("discrete"), "{:?}", rows);
        assert!(rows[1].contains("2 adapter(s)"), "the count of enumerated adapters: {:?}", rows);
        assert!(rows[2].contains("IN USE") && rows[2].contains("42"), "{:?}", rows);
        assert!(rows[2].contains("GpuMapRenderer"), "the lane is named: {:?}", rows);
        assert!(!st.is_software());

        let j = st.to_json();
        assert_eq!(j["backend"], serde_json::json!("Vulkan"));
        assert_eq!(j["device_class"], serde_json::json!("discrete"));
        assert_eq!(j["adapter_count"], serde_json::json!(2));
        assert_eq!(j["lane"], serde_json::json!("in_use"));
        assert_eq!(j["lane_frames"], serde_json::json!(42));
        assert_eq!(j["rows"].as_array().expect("rows").len(), 3);
    }

    /// No GPU at all: the rows must SAY so rather than going blank, and the json
    /// keys must still exist so a robot can tell "no GPU" from "key missing".
    #[test]
    fn a_gpu_less_process_says_so() {
        let st = GpuStatus::none();
        assert!(st.adapter_line().contains("none"), "{}", st.adapter_line());
        assert!(st.lane_line().contains("not installed"), "{}", st.lane_line());
        let j = st.to_json();
        assert!(j["adapter"].is_null());
        assert_eq!(j["lane"], serde_json::json!("not_installed"));
        assert_eq!(j["software"], serde_json::json!(false));
        assert_eq!(j["adapter_count"], serde_json::json!(0));
    }

    /// **The clock seam, pure**: uploads accumulate a count and replace the last
    /// event; pass time is `None` until a sample lands and never becomes `0` by
    /// omission; an "unavailable" verdict does not invent a number.
    ///
    /// RED direction that matters (LAW 2): make `note_gpu_timestamps(_, false)` set
    /// `last_gpu_pass_us = Some(0)` and the `None` assertions here fail — the exact
    /// fake this seam forbids. Uses its own lane key so parallel tests in this binary
    /// cannot race it.
    /// The two tests below both touch the ONE process-global registry (and one of
    /// them clears it), so they serialise on this rather than racing.
    static REGISTRY_LOCK: Mutex<()> = Mutex::new(());

    #[test]
    fn the_clock_seam_counts_uploads_and_never_fakes_a_pass_time() {
        let _g = REGISTRY_LOCK.lock().unwrap();
        let name = "test::ClockLane";
        let z = clock_stats_of(name);
        assert_eq!((z.uploads_total, z.last_upload_bytes, z.last_upload_us), (0, 0, 0));
        assert_eq!(z.last_gpu_pass_us, None, "no lane, no number");
        assert_eq!(z.gpu_timestamps, None, "unprobed is 'did not say', not 'unavailable'");

        note_upload(name, 120, 4096);
        note_upload(name, 80, 2048);
        let s = clock_stats_of(name);
        assert_eq!(s.uploads_total, 2, "uploads accumulate");
        assert_eq!((s.last_upload_us, s.last_upload_bytes), (80, 2048), "last event replaces");
        assert_eq!(s.last_gpu_pass_us, None, "uploads say nothing about pass time");

        // The unavailable verdict: a flag, NEVER a number.
        note_gpu_timestamps(name, false);
        let s = clock_stats_of(name);
        assert_eq!(s.gpu_timestamps, Some(false));
        assert_eq!(s.last_gpu_pass_us, None, "an adapter without the feature reports None, not 0");

        // A real sample flips the flag and fills the number together.
        note_gpu_pass(name, 37);
        let s = clock_stats_of(name);
        assert_eq!(s.last_gpu_pass_us, Some(37));
        assert_eq!(s.gpu_timestamps, Some(true), "a resolved sample IS the proof of realness");
    }

    /// The registry accumulates through the public notes, and `note_frame` implies
    /// both installed and reporting (a lane cannot encode a frame otherwise).
    #[test]
    fn the_registry_records_what_the_lanes_report() {
        let _g = REGISTRY_LOCK.lock().unwrap();
        reset_for_test();
        note_installed("test::LaneA");
        assert_eq!(lane_use(), GpuLaneUse::Unknown { silent_lanes: 1 });
        note_reports_frames("test::LaneA");
        assert_eq!(lane_use(), GpuLaneUse::InstalledUnused);
        note_frame("test::LaneB");
        assert_eq!(lane_use(), GpuLaneUse::InUse { frames: 1 });
        let recs = lanes();
        let b = recs.iter().find(|l| l.name == "test::LaneB").expect("LaneB registered");
        assert!(b.installed && b.reports_frames && b.frames == 1);
        assert_eq!(b.short_name(), "LaneB");
        reset_for_test();
        assert_eq!(lane_use(), GpuLaneUse::NotInstalled);
    }
}