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
extern crate alloc;
use BTreeMap;
use ;
pub use Received;
/// A per-peer causal-context tracker.
///
/// For each member of a caller-declared roster it holds the [`DotSet`] this
/// replica can vouch that peer has seen: the *gossip-targeting* half of the
/// imagined knowledge matrix (one carrier down: contexts instead of vectors).
///
/// The dual of [`Stability`](crate::metis::Stability): that folds each
/// member's *delivered cut* and reads their meet ("what may I forget"), this
/// folds each member's *seen context* and reads the per-peer residual ("what
/// do you provably lack"). Same roster-fixed, bottom-defaulting shape over
/// the two carriers. Every peer has a row from birth, at bottom.
///
/// # The row is a lower bound, and that direction is the safety story
///
/// A row grows only by union under evidence and never regresses, so it can
/// only *under*-estimate what the peer holds. The asymmetry is the whole
/// safety story:
///
/// - Under-claiming makes [`owed`](Self::owed) a superset delta, re-shipping
/// dots the peer already has. A liveness cost only, absorbed idempotently
/// by the causal merge. Normal operation is exactly this.
/// - Over-claiming makes `owed` omit dots the peer genuinely lacks, stalling
/// convergence silently. Unsafe, and undetectable here.
///
/// # Evidence discipline, made constructional
///
/// [`note`](Self::note) therefore takes a [`Received`] rather than a bare
/// context, and the only unaudited way to obtain one is
/// [`Composer::absorb`](crate::metis::Composer::absorb), which mints it from
/// a delta the peer actually shipped. A peer cannot ship what it has not
/// seen. A context you merely *hope* the peer has, or one you sent *to* it,
/// does not typecheck. [`Received::trust`] is the single audited door, named
/// for the burden it carries.
///
/// The tracker cannot audit a `trust` claim, exactly as
/// [`Stability`](crate::metis::Stability) cannot audit a cut claim. What it
/// can do is make the accidental over-claims unrepresentable and let the
/// default stale-row mistake fail safe.
///
/// # A context is whole-world evidence
///
/// A note for one peer may carry dots minted by *any* station, since a
/// context records everything that peer has seen from every source. The row
/// accumulates its whole causal past, not a per-peer fiber.
///
/// # The roster is the meaning
///
/// Fixed at construction, off-roster peers refused ([`UnknownStation`]),
/// exactly as [`Stability`](crate::metis::Stability)'s is: an unheralded row
/// would silently widen or narrow the family [`common`](Self::common) meets
/// over. Membership change means a new tracker.
///
/// # Totality
///
/// [`note`](Self::note) folds by union, so it is idempotent, commutative,
/// and monotone: any permutation and duplication of a fixed multiset of
/// notes yields the identical tracker.