Two gaps in 739a2f5's backfill: - An unreadable height returned before clearing other forks' rows, and was claimed anyway, so a losing block's events survived whenever the winner's could not be read; extrinsics likewise whenever the body read failed. Rows naming another block now go as soon as the canonical hash is known (`Others::KnownOnly`). Legacy rows with no hash go only once a replacement is in hand. - A stale block row whose replacement could not be described (no header, no author digest) made the backfill `break` at that height on every pass, for good. `replace_block` now tells `Transient` from `Permanent`; the second is logged and stepped over. Refs #52 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CKabPYLTYP2G5s7ph7oCpo