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
// Copyright (c) 2026 Mike Grier
//! Absence with its reason attached.
//!
//! [`Observed`] is the vocabulary [D-13](../DESIGN-NOTES.md) asks for: an
//! `Option` spells three different facts identically, and a consumer that
//! cannot tell them apart will eventually read one as the other.
/// A value that may be absent, saying **which** absence it means.
///
/// # Why not `Option`
///
/// `Option<T>` has one `None` and this crate has three distinct facts to put
/// in it (D-13):
///
/// - **not observed** -- nothing asked, so the value may well exist;
/// - **observed and absent** -- something asked, and the answer was "none";
/// - **a negative result** -- not an absence at all, but a computed answer
/// whose value happens to be "no".
///
/// The third is deliberately **not** a variant here. It is not an absence, so
/// giving it one would re-create the conflation this type exists to remove: a
/// computed "no" is an ordinary value and belongs in `T`, or in an `Option`
/// documented as meaning exactly that. This type covers the two that are
/// genuinely about *whether we know*.
///
/// # Why this matters more than it looks
///
/// Both confusions are silent and both invent something. Reading "we did not
/// look" as "there is none" invents a fact about the machine; reading "there
/// is none" as "we did not look" sends a caller off to re-derive something
/// already settled. Neither fails a test that only checks the happy path.
///
/// # The contested case
///
/// Per [D-19](../DESIGN-NOTES.md), a subject the two Win32 sources genuinely
/// disagreed about is one the unified view does not cover -- which is
/// [`Observed::NotObserved`], not a fourth state.
///
/// [D-16](../DESIGN-NOTES.md)'s retry runs before anything is represented, and
/// removes the transient case it can settle: two enumerations describing
/// different sets of processors because the machine changed between the calls.
/// What it deliberately does not retry is a disagreement about how processors
/// are *grouped*, which [D-17](../DESIGN-NOTES.md) establishes is persistent in
/// the field -- re-reading cannot settle those, so they are carried as separate
/// per-source observations instead. Either way "we cannot say" is the honest
/// answer, and [`crate::Coherence`] on the topology says which of the two
/// happened during collection.