fix(state): own zakura header-store mutations with a single suffix-replacement primitive#495
Draft
p0mvn wants to merge 1 commit into
Draft
fix(state): own zakura header-store mutations with a single suffix-replacement primitive#495p0mvn wants to merge 1 commit into
p0mvn wants to merge 1 commit into
Conversation
|
Note Complete: Audit complete. No review-worthy issues remain after automatic triage. One finding was auto-invalidated. Open the full results here. Analyzed five files, diff |
…placement primitive
p0mvn
force-pushed
the
zakura-canonical-suffix
branch
from
July 7, 2026 17:01
df1774e to
1be9f3c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Pillar 1 of
REORG_PLAN.md(§2), stacked on #494. The §0 diagnosis of the reorg-corruption bug class is a multi-writer mutable chain view with no owner and no enforced invariants: four independent writers each ran their own bounded delete loop over the five zakura header column families, and every proven corruption shape came from one writer preserving the invariants only under assumptions about the others. #491 patched the three proven holes narrowly; this PR restructures the write path so the invariants hold by construction. It also lands the deferred half of Pillar 3: the after-every-reorg-batch audit hook.Solution
New
canonical_suffixmodule:DiskWriteBatch::set_canonical_suffix(fork_point, new_rows)is now the only way any path changes which headers the zakura store considers canonical above a height. In one atomic batch it deletes every row strictly above the fork in all five column families and writes the new suffix. Contract (all hard errors, nothing staged on failure):new_rows[0]must link to the fork row (which must be the row on disk), and every row to its predecessor; row hashes are computed inside the primitive, so a caller cannot stage a hash that disagrees with its header (bug-1 class closed at the mechanism level, not as a caller obligation).All three writers route through it (per the §2 contract additions):
prepare_header_range_batch_with_roots: validation/policy unchanged (contextual difficulty, checkpoints, most-work gate, reorg depth); the mutation tail is now fork decision + one primitive call. The fork is the first conflicting height − 1, or the stored tip for pure extensions — matching the Phase-1 oracle'sapply_header_range(total suffix replacement above the first conflict) exactly, including the property that a non-conflicting redelivery must not truncate stored rows above the range end. Advisory refreshes of matching re-delivered rows (body-size hint merge, roots re-staging) never change chain membership and stay outside the primitive.height − 1, matching the oracle'sapply_seed(truncate-from-height on any non-identical seed). The identical-row early return and the fix(state): validate linkage in zakura header-store writers #491 unlinked-seed refusal are unchanged.new_rows = []skips the fork-row read because the full-block row at the fork is staged in the same batch); the at-height frontier trim is unchanged.After-every-reorg-batch audit hook (Pillar 3's deferred half):
DiskWriteBatchcounts the rows its suffix replacements delete; the three write sites (range commit, seed, body commit) runaudit_and_repair_zakura_header_store()after committing any batch with a nonzero count. A pure append deletes nothing, so the steady-state extension path never pays the audit. The audit's log wording drops "startup" since it now runs at both points (the t4 watcher grep gets updated when this deploys).Scope: Pillar 1 only. Pillar 1a's explicit switch orchestration for body-backed switches (candidate assembly → work decision → body invalidation → header rewrite → frontier notification) is the next change; its step-4 safety interlock and crash-recovery backstop (startup audit) are already in place via this stack.
Tests
primitive.rscontract suite: unlinked rows / stale fork row / fork below finalized tip / body-above-fork interlock all reject with the right variant and stage nothing (zakura_suffix_replaced_rows() == 0, dump-identical store); truncation is total-above-fork including hand-planted strays and rows stranded above a gap; an empty replacement truncates to the fork; a pure append reports zero replaced rows.header_store_coherenceharness (oracle-checked scenarios + reads + startup audit) passes unchanged against the rerouted writers: 42/42 — the oracle is the replacement-semantics spec, so this is the primary evidence the refactor preserves specified behavior.prop_random_sequences_uphold_invariantssustained atPROPTEST_CASES=1024(release), clean.cargo test -p zebra-state— 343 passed, 0 failed.cargo fmt --all -- --check,cargo clippy -p zebra-state --all-targets -- -D warnings,cargo check -p zebrad— clean.Specifications & References
REORG_PLAN.md§2 Pillar 1 (contract additions from Phase 1), §3 row 3; oracle semantics inheader_store_coherence/oracle.rs(apply_header_range,apply_seed).Follow-up Work
passed its startup coherence audit→passed its coherence audit) when a binary with this change deploys.AI Disclosure
PR Checklist
REORG_PLAN.md)