0.13.4 — sealing a row is not erasing it
Completes the remediation begun in 0.13.2. See GHSA-84vx-5fgq-5p59.
If you enabled encryption and ran the 0.13.2 or 0.13.3 migration, upgrade to 0.13.4 and open the database once.
The 0.13.2 migration sealed every pre-fix oplog payload with UPDATE, which writes the ciphertext to a new page and frees the old one — the plaintext survived in the file until that page was reused. Measured on a 111,590-row oplog: after the migration oplog_plaintext_rows() returned 0 while a raw byte scan still found the recorded content. The remedy had the shape of the bug it fixed: a verification surface reporting a guarantee the storage did not provide.
- The migration now rewrites the database (
VACUUM) and truncates the WAL. Order matters — checkpoint-then-vacuum leaves residue in the main file; measured both ways. - It logs
STARTING(with row count) andCOMPLETE(with elapsed), so a large migration reads as progress rather than a hang. Roughly 8s per 100k rows plus the rewrite. oplog_plaintext_rows()now documents that it counts rows, not bytes — a raw byte scan is the only sufficient verification.- New test
migration_erases_freed_pages_not_merely_live_rowsfails with theVACUUMremoved and passes with it — the sensitivity demonstrated in the same run.
Independently verified by the yantrikdb-hermes-plugin gate with a two-engine test: the same fixture shows residual plaintext after the 0.13.3 migration and a clean file after 0.13.4. 1822 tests full, 1739 slim, clippy clean.