Skip to content
zit Check-in [9b689ebafe]
Login

Check-in [9b689ebafe]

Overview
Comment:Merge h3-crashsync: run a sync over a store that can tear, across crashes

The storage and network simulations ran off the same seed but never intersected, so no simulated exchange ever crossed a store that could lose its tail. This composes them: the sync client's content is backed by a real log over a tearable file, and between rounds -- on a seeded coin -- the store is crash-restarted mid-persist, reopened to its recovered prefix, and the session resumed with a fresh client. The existing safety and liveness oracles must survive the composition: no corrupt content accepted, the recovered set never exceeds what was held before the crash, and once both the network and the disk heal a fresh session still converges within the bounded window. Green across the gate and a deep 120-seed run; a retained switch that makes recovery accept a torn frame trips the oracle, so the check is not vacuous. The fault-composition follows TigerBeetle's VOPR.

Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 9b689ebafe8b66e504676376413cc2aba053ea252ddbac721145f64e64744db6
User & Date: dmestas on 2026-07-20 04:19:03.840
Other Links: manifest | tags
Context
2026-07-20
04:28
Merge h2-checkout-dst: crash-test the working tree, and a finding it surfaces

The working tree -- the one place a version-control tool can lose a user's data -- had no crash simulation; only the log store did. A new faulty directory layer tears and freezes writes at a seeded crash point, and a sweep replays an update across every crash cut, reopens, and checks four invariants. Three hold: an untracked file the update must preserve is never touched, a crashed update recovers to its target through the undo journal, and the checkout record never names a check-in whose tree did not finish materializing. The fourth does not, and that is the point of the harness: the payload write lands in place rather than through the write-temp-and-rename the metadata already uses, so a crash mid-write can leave a managed file spliced from old and new bytes -- torn, but recoverable. The gate runs the three that hold; the fourth is pinned by a test asserting the splice IS produced, so it flips the day the write is made atomic. Crash-point enumeration follows TigerBeetle's storage model. check-in: 5401ce245f user: dmestas tags: trunk

04:19
Merge h3-crashsync: run a sync over a store that can tear, across crashes

The storage and network simulations ran off the same seed but never intersected, so no simulated exchange ever crossed a store that could lose its tail. This composes them: the sync client's content is backed by a real log over a tearable file, and between rounds -- on a seeded coin -- the store is crash-restarted mid-persist, reopened to its recovered prefix, and the session resumed with a fresh client. The existing safety and liveness oracles must survive the composition: no corrupt content accepted, the recovered set never exceeds what was held before the crash, and once both the network and the disk heal a fresh session still converges within the bounded window. Green across the gate and a deep 120-seed run; a retained switch that makes recovery accept a torn frame trips the oracle, so the check is not vacuous. The fault-composition follows TigerBeetle's VOPR. check-in: 9b689ebafe user: dmestas tags: trunk

04:13
Compose storage and network faults in the sync DST

The sync sweep and the storage sweep ran in disjoint PRNG streams off the same seed and never intersected: no exchange ever ran over a client store that could tear. A partial pull could leave torn frames that recovery accepts but a resumed session never converges past.

runCrashResume backs the client store with a real LogStore over a tearable FaultyFile instead of the pure MemStore, seeded healthy then armed to tear. Between phase-1 rounds, on a seeded coin, it power-cuts the store mid-persist, reopens it, reloads the recovered prefix, and resumes with a fresh Client over the same durable store, mirroring cmd/sync's loadContentStore for wire-name to log-digest identity.

The oracle keeps every existing sync invariant and adds the crash bite: post-recovery contents are a subset of the pre-crash held set, no corrupt frame crosses the boundary, and phase-2 liveness heals both domains before a fresh session converges in the bounded window (sync 3.7). One seeded PRNG stream drives the whole run, so a failure replays from the shared reproduce line.

The composed-fault and liveness-under-faults discipline follows TigerBeetle's VOPR. closed check-in: d2b5f729ef user: dmestas tags: h3-crashsync

04:11
Merge h9-fuzzcov: every fuzz target now guards its own reach

Only two targets asserted that their generator still reaches the interesting outcomes; the other 25 could rot to instant-rejection and pass every no-crash check while testing nothing. Six targets that split into distinct outcomes now carry a reached-outcomes floor above a measured minimum round count -- decode-bounded, target-size, predicates, adversarial sync parsers, logstore open, and unframe each must reach both their accept and reject arms, or the run fails. Thresholds are measured at a fixed seed and re-checked at a second, and each floor is proven to trip when the generator is biased to one arm. Single-outcome round-trip targets carry a one-line exemption instead of a vacuous assert. The measurement also named several generators that under-reach their target's arms; those are recorded for follow-up, not fixed here. check-in: 57d8994848 user: dmestas tags: trunk

Changes