LeVCS/crates
Levi Neuwirth bff8e8a5e5 Make a checkpoint prove what it claims before it suppresses replay
Five review findings against 5462952.

Adoption was content-blind: it compared the path and the committed sequence,
so a different checkpoint at the right name was adopted and published. That is
silent logical deletion rather than a wedge — the manifest suppresses replay of
the frames the checkpoint covers, so an empty catalog at the live sequence
makes the namespace disappear at the next open with nothing reporting a fault.
Adoption now requires logical equivalence to the checkpoint this call would
have written, created_at_micros excepted, and refuses anything else without
poisoning, since nothing durable has moved. The test reopens and reads catalog,
ref and receipt back through the public surface.

Checkpointing did not relieve the replay ceiling. replayable_index summed every
sealed-run entry and every namespace regardless of the horizon, so a shard at
the ceiling checkpointed and was then refused its next single-object
transaction. The writer tracks what the newest checkpoint made unreplayable —
from recovery at open, from itself thereafter — and subtracts it. Subtracting
rather than dropping the accounting: runs sealed after a checkpoint cover
frames a reopen does replay. Removing the subtraction reproduces observed: 4,
allowed: 3.

checkpoint::install wrote through symlinks. Survivable while nothing production
could reach it; not once this dispatch gave it a caller. It goes through the
no-follow funnel now, and an occupied final name is type-checked before
adoption.

Checkpoint pins grew by a file per checkpoint while the manifest trimmed to
checkpoint_retain, keeping pruned inodes alive for the life of the process. The
successor pins exactly the rows its manifest publishes.

Refs and receipts are sorted before encoding, which the equivalence guard also
depends on.

Disclosed: the adoption success path has no test. Building an equivalent image
from outside the engine needs a failpoint seam or a test-only accessor, and
neither belongs here. The refusal path, which is the one that can lose data, is
covered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XKzM69CHmBuDcA3qN1jFdh
2026-07-30 20:21:26 -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 Make a checkpoint prove what it claims before it suppresses replay 2026-07-30 20:21:26 -04:00
levcs-tui integrate CI and docs 2026-05-01 11:29:18 -04:00