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
//! Where the incarnation stream's history is bounded by policy.
//!
//! One estate-global append-only stream replayed from genesis makes a
//! regressing scalar header unrepresentable, and costs a boot every row the
//! estate ever wrote. This module keeps the first property and pays a bounded
//! price for it, by rotating each server incarnation into its OWN stream:
//!
//! ```text
//! liminal/participant/incarnation/v2 genesis (pre-fix)
//! liminal/participant/incarnation/v2/incarnation/{n} epoch of incarnation n
//! liminal/participant/incarnation/v2/anchor CAS value naming n
//! ```
//!
//! **No event in any epoch carries a header.** An epoch's resume seed is read
//! off its own KEY — epoch `n` replays from the header `(n - 1, no ordinal, not
//! exhausted)` and its first row is the Startup that the protocol's own
//! [`prepare_server_incarnation_startup`](liminal_protocol::lifecycle::prepare_server_incarnation_startup)
//! turns into exactly `n`. The header is still a consequence of protocol
//! transitions applied to canonical inputs; the rotation only moves where those
//! inputs start, so the grammar has gained no field a writer could regress.
//!
//! What names the key is the anchor, and what makes the anchor safe is that it
//! is only ever read as a HINT and only ever rolled FORWARD. A boot walks from
//! the anchor over every successor epoch that actually exists in the store and
//! adopts the highest, so an anchor that lags — a crash between the epoch's
//! fsync and the anchor's compare-and-swap — is repaired, and an anchor that
//! names an incarnation below durable history is overruled by that history.
//! Regressing the resume point therefore requires DESTROYING durable epochs,
//! not merely writing a value; and an epoch whose canonical inputs do not
//! produce the incarnation its key names is refused outright
//! ([`IncarnationStreamError::EpochHeaderMismatch`]).
//!
//! What is traded is stated in
//! `docs/design/INCARNATION-STREAM-BOUND-2026-08-29.md`: epochs below the
//! anchored one become dead history for the store vacuum to reclaim, and this
//! module never deletes a durable row.
use ;
use NonZeroU64;
use Arc;
use DurableStore;
use ConnectionIncarnationAllocatorRestore;
use IncarnationStreamError;
/// The pre-rotation estate-global stream. Anchor absent means this is the
/// state of record, which is true of every store written before this fix.
pub const GENESIS_STREAM_KEY: &str = "liminal/participant/incarnation/v2";
/// Compare-and-swap value naming the server incarnation whose epoch is of
/// record. A hint, never an authority: see this module's own documentation.
pub const EPOCH_ANCHOR_KEY: &str = "liminal/participant/incarnation/v2/anchor";
/// Prefix each epoch stream's key is built from.
const EPOCH_STREAM_KEY_PREFIX: &str = "liminal/participant/incarnation/v2/incarnation/";
/// The one sequence an epoch's Startup row may occupy.
///
/// Appending it at exactly this sequence is what makes a pre-existing epoch a
/// loud append conflict instead of a silent second history.
pub const EPOCH_STARTUP_SEQUENCE: u64 = 0;
/// The durable stream a boot replays, and the seed it replays it from.
pub
/// The durable stream key holding one server incarnation's canonical inputs.
pub
/// Reads the anchor hint. An absent key is zero by the store's own contract.
///
/// # Errors
///
/// Returns [`IncarnationStreamError`] when the store cannot be read.
pub async
/// Whether an epoch for `server_incarnation` was ever durably started.
///
/// One point read of one row. The Startup row at
/// [`EPOCH_STARTUP_SEQUENCE`] is what "this incarnation exists" MEANS, so this
/// asks the store rather than trusting the anchor.
///
/// # Errors
///
/// Returns [`IncarnationStreamError`] when the store cannot be read.
pub async
/// Moves the anchor from `from` to `to` and flushes it.
///
/// Compare-and-swap, so a concurrent mover is a refusal rather than a lost
/// update, and every caller here supplies a strictly greater `to`.
///
/// # Errors
///
/// Returns [`IncarnationStreamError`] when the store refuses the swap or the
/// flush — including when another process has already moved the anchor.
pub async
/// Walks the anchor up over every successor epoch the store actually holds.
///
/// This is the whole of the non-regression argument at boot, and it is told by
/// the store: it stops at the first successor that does not exist, and it never
/// moves down. A crash between an epoch's Startup fsync and its anchor swap is
/// repaired here — the incarnation that epoch published is ADOPTED, never
/// re-minted — and an anchor that has somehow come to name an incarnation below
/// durable history is overruled by the epochs above it.
///
/// # Errors
///
/// Returns [`IncarnationStreamError`] when the store cannot be read or the
/// anchor swap is refused.
pub async