B4.4 · dive 2 — the bus dies, the lane replays
The bus dies; the lane replays.
D-2 keeps the bus volatile on purpose, so a bus restart erases queued coherence jobs —
Chapter 4.2 stated that ceiling in the open, and the TTL was the floor under the loss. This dive raises
the ceiling without touching the decision. The H3 gate proves the applied memory outlives everything
around it — a replayed old version answers :remembered_stale from the journal alone, no
cache row consulted, none created — and the H4 gate stages D-2's loss itself: fifty obligations on the
lane, twenty applied, the queue flushed, and the journal replaying back exactly 30 uncovered intents
… in seq order under their recorded job ids.
Source: content/bcs4.4.md, quoting bcs_rung_4_4_check.out. This dive
reads the memory derive, H3, the loss derive, and H4 — the derived expectation: a remembered count of
50.
Static walk — 1) the applied memory holds v5; the applied table lives in the
file · 2) the full stop: table and journal, down · 3) the same file reopens against an
empty L1 · 4) a replayed old version answers :remembered_stale from the journal
alone — no cache row consulted, none created · 5) the verdict counters did not move and no row
appeared · 6) the genuinely newer v6 passed through and became the new last word.
The transcript
bcs_rung_4_4_check.out · verbatim · this dive reads the memory derive, H3, the loss derive, H4… (the self-check, the header, H1, and H2 open the record -- frozen on the module hub) derive (memory): the applied table lives in the file, so it survives the table, the node, and the bus; after a full restart with an empty L1, a replayed old version must answer :remembered_stale from the journal alone -- no cache row consulted, none created -- while a genuinely newer version passes through and updates the memory H3 memory ok -- the journal remembered v5 across a full stop of table and journal; the replayed old version answered :remembered_stale without touching the cache -- the table's verdict counters did not move and no row appeared -- and the genuinely newer v6 passed through and became the new last word derive (loss): D-2 keeps the bus volatile, so a bus restart erases queued coherence jobs; 50 intents recorded and enqueued, 20 applied before the loss, the lane's queue keys flushed -- replay must re-enqueue exactly the 30 uncovered intents in seq order, and a consumer must drain them to a remembered count of 50 H4 loss ok -- the bus restart erased the queue and the journal replayed the lane back: exactly 30 uncovered intents re-enqueued in seq order under their recorded job ids, the consumer drained them, and the applied memory closed at 50 of 50 names holding their final versions … (the compaction and the price close the record -- frozen on the module hub)
Each derive line states the expectation before the gate asserts it: the H3 derive demands
:remembered_stale with no cache involvement at all, and the H4 derive computes the replay
set's size from the staging itself — 50 recorded, 20 applied, so exactly 30 uncovered.
The memory across a restart
content/bcs4.4.md · What · DecisionsThe applied table lives in the file, so it survives the table, the node, and the bus.
Without this memory, an empty L1 makes every replayed message look fresh; with it, staleness is a fact
about the lane, not about whichever rows happen to be resident. The drill stops the table and the journal,
reopens the same file against an empty L1, and replays an old version — the gate's verbatim close:
the table's verdict counters did not move and no row appeared -- and the genuinely newer v6 passed
through and became the new last word.
The decision underneath: the memory check runs before the cache.
apply_and_remember consults the journal first and answers :remembered_stale
without an ETS lookup, because the journal's word outlives the cache's rows — the gate proves the counters
do not move. This is newer-wins from
B4.2 · Coherence by Mint Time given a durable floor:
the comparison is the same, the version is still a name, and the only change is where the older side of
the comparison survives.
The loss drill — 50, 20, 30
content/bcs4.4.md · What · Who · BoundariesD-2 keeps the bus volatile, so a bus restart erases queued coherence jobs. The rung stages exactly that — 50 intents recorded and enqueued, 20 applied before the loss, the lane's queue keys flushed — and replay selects by coverage: every intent whose name lacks an applied version at least as new. The twenty already-applied intents are not re-sent; the thirty lost ones are, in seq order, under their recorded job ids, with no acknowledgment bookkeeping anywhere on the hot path.
Static ledger — recorded 50 · applied before the loss 20 · re-enqueued by replay 30, in seq order under their recorded job ids · the consumer drained them and the applied memory closed at 50 of 50 names holding their final versions.
Recovery, after the bus came back empty, is one idempotent verb — and retention is its sibling, both safe to run on a schedule:
{:ok, %{replayed: n, deduplicated: m}} = Journal.replay(:limits_journal, conn)
{:ok, retired} = Journal.compact(:limits_journal)
Boundaries, stated honestly: the journal is per-group and per-node — it restores its own lane's obligations and claims nothing about cross-group ordering, which the lanes never promised anyway. Replay is at-least-once by construction and harmless by comparison — the same two facts, in the same order, as everywhere else in this part. The lease, the reaper, and the volatile substrate under this drill are B3.3 · The State Machine in Lua's machine; the recorded job ids the replay reuses ride B3.2 · Jobs Are Entities's admission dedup. Application on the consumer side is the engine of the sibling module — B4.3 · The Single Writer and the Ring — and the compaction predicate and the price close the module in the next dive.
References
sources · relatedSources
- Richardson — Pattern: Transactional outboxthe at-least-once relay this replay is
- SQLite — Write-Ahead Loggingthe file the applied memory survives in
- Litestream — How it worksrestore by snapshot plus replay — the off-box echo of this drill, named and not built
Related
- B4.4 — The Lane That Remembersthe module hub; the full rung in context
- B4 — EchoCachethe chapter landing; Part IV's arc
- B3.3 — The State Machine in Luathe volatile bus, its lease, and its reaper
- B3.2 — Jobs Are Entitiesthe recorded job ids the replay reuses
- B4.2 — Coherence by Mint Timethe lane being replayed back
- EchoMQ — the coursethe protocol in rung-level depth
- Redis Patterns Appliedthe substrate under the bus
- Functional Programming in Elixirthe umbrella the runtimes live in