LeVCS/crates
Levi Neuwirth 0d2fd6d986 Keep a surviving journal on the identity the manifest implies
The sealing fallback was reaching a journal that seals nothing. A recovery
keeping an empty tail gave it the fallback's generation, but no TailRange
recorded the move — nothing was sealed — so the next open derived the identity
the manifest still implied while the session in between had appended frames
under the moved one and sealed a run over them. The guard searched published
runs for the derived generation, found none, and let the store open with the
run unresolvable. Review confirmed it: empty tail plus an orphan at 1, reopen
taking 2, frames and a run at 2, an orphan at 2, then an open at 3 with
`object_source(0, 2) == None`.

`RecoveryGenerations` carries a third number. `tail` is what a surviving
journal keeps and is always the tail's own identity: segment-name occupancy is
a fact about `segments/`, and a journal that seals nothing does not go there.
`logical` remains the sealing identity and still falls back under the guard.

That restores the invariant the split rests on — the active tail's identity is
always derivable from the manifest — so the guard and the frames are always
naming the same generation. A tail may keep a generation an orphan occupies;
the collision is only real when frames are sealed under that name, and it is
refused then, with the run in hand.

The regression follows the reported sequence and reads the run's generation out
of the run rather than assuming it, since which identity the frames ended up
with is the thing under test. Mutation-checked in both places it can fail: the
run drifts to generation 2, and with the mid-assertion relaxed the open
succeeds with None pinned there, reproducing the report exactly. The shared
helper now reports the run's own generation, so all three refusal paths fail
legibly rather than against a hard-coded number.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XKzM69CHmBuDcA3qN1jFdh
2026-07-30 17:12:16 -04:00
..
levcs-cli Robustness fixes 2026-05-03 20:56:46 -04:00
levcs-client integrate CI and docs 2026-05-01 11:29:18 -04:00
levcs-core integrate CI and docs 2026-05-01 11:29:18 -04:00
levcs-identity Freeze Wave A: Phase 1 storage spine 2026-07-26 19:47:03 -04:00
levcs-instance Robustness fixes 2026-05-03 20:56:46 -04:00
levcs-merge integrate CI and docs 2026-05-01 11:29:18 -04:00
levcs-protocol Condition benchmark claims on the run that produced them 2026-07-29 17:38:03 -04:00
levcs-store Keep a surviving journal on the identity the manifest implies 2026-07-30 17:12:16 -04:00
levcs-tui integrate CI and docs 2026-05-01 11:29:18 -04:00