- Second half of the fresh-log seed SEGV: every `*msg = ...` in the fold
was unguarded, and `wo_idx_probe` (table.c:373) borrows with `msg == NULL`
because a candidate that does not fold is simply not a hit; a malformed
record under an index probe was therefore a zero-page write.
- Guard: `const char *sink; if (!msg) msg = &sink;` at the top of the fold;
wal.h documents [msg] as optional. A future malformed record refuses the
candidate by name instead of segfaulting.
- Failing test first: `test_fold_row_at_tolerates_null_msg` (test_wal.c) —
head-only log, fold at offset 0 (schema record) and past the tail with
`msg == NULL` -> -1 both; with a real `msg` the names "record header is
malformed" / "no intact record at that offset" still arrive. Pre-guard:
ASan SEGV `wo_wal_fold_row_at wal.c:1886` from the test.
- Gates: test_wal 6660/0 (was 6650); `make -C runtime test` 21 suites
8462/0 (was 8452); wovm-asan clean; residency `seed` fresh dir + fresh
app.db rc 0 under wovm_asan.
- CODE-LOGIC §Schema migrations bullet extended with the guard + test.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 1b6750d78db991af464994c2188d219519dfe16f)