fix(server): widen the boot epoch to 64 bits; docstring precision (#881)

token_hex(4) left the epoch equality check — the only thing between a
prior-boot cursor and a silent replay_ok-empty alias — at 2^-32 per
same-node restart-pair; 64 bits puts a fleet-lifetime of restarts
engineered far below threshold (review round 4, classified
design-margin).  Docstring rounds from the same pass: the resume
contract now notes reason=boot_epoch also covers the same-epoch
empty-ring fail-safe (not exclusively foreign epochs), and the collector
ruling says precisely that the staleness CHECK and envelope can never
fire there — the epoch-tagged ids are on the wire, just never read.
This commit is contained in:
Patrick Buckley
2026-07-22 23:01:48 -07:00
parent 58bd607f49
commit 8a67f91d8b
3 changed files with 15 additions and 6 deletions
+1 -1
View File
@@ -398,7 +398,7 @@ def test_epoch_is_hex_and_dashless_by_construction() -> None:
import secrets
for _ in range(64):
assert "-" not in secrets.token_hex(4)
assert "-" not in secrets.token_hex(8)
# And the production init uses token_hex — source-level pin.
import inspect
+3 -2
View File
@@ -284,8 +284,9 @@ class ClusterCollector:
``node_snapshot`` and the collector rebuilds wholesale. That is
this consumer's recovery model (idempotent state-of-world, not
append-only history), it side-steps cursor staleness across node
restarts entirely, and it means the epoch-tagged ids and the
``replay_truncated`` envelope on this stream can never fire here.
restarts entirely, and it means the epoch staleness check and
the ``replay_truncated`` envelope can never fire here — the
epoch-tagged ids themselves are on the wire, just never read.
If a cursor is ever adopted, present the SSE ``id:`` VERBATIM
(opaque ``"{boot_epoch}-{counter}"`` — never parse it) and handle
``replay_truncated`` explicitly; today an unknown event type
+11 -3
View File
@@ -1029,7 +1029,10 @@ async def global_events_sse(request: Request) -> Response:
from any other epoch a prior boot, another node, a pre-#881
bare-int client gets ``replay_truncated`` with
``reason="boot_epoch"`` followed by a fresh ``node_snapshot``, since
the events it missed died with the process that minted it. Clients
the events it missed died with the process that minted it.
``boot_epoch`` is not exclusively a foreign-epoch signal: a
same-epoch cursor over an EMPTY ring (impossible from our own ids
forged or a bug) also draws it via the fail-safe branch below. Clients
treat the cursor as an opaque string; only this handler parses it.
"""
# -- Service-scope gate ---------------------------------------------------
@@ -5172,8 +5175,13 @@ def create_app(
# differs from the live process is stale by construction and draws
# the ``replay_truncated`` + node_snapshot recovery floor in
# :func:`global_events_sse`. Hex nonce (never contains ``-``), so
# ``partition("-")`` splits the id unambiguously.
app.state.global_boot_epoch = secrets.token_hex(4)
# ``partition("-")`` splits the id unambiguously. 64 bits: the
# equality check is the ONLY thing standing between a prior-boot
# cursor and a silent ``replay_ok``-empty alias, and the collision
# event is per same-node restart-pair — 2^-64 keeps a
# fleet-lifetime of restarts engineered far below threshold where
# 32 bits left it merely unlikely (review round 4).
app.state.global_boot_epoch = secrets.token_hex(8)
app.state.skip_permissions = skip_permissions
app.state.jwt_secret = jwt_secret
app.state.auth_storage = auth_storage