Drop only the field when compressed DATA cannot be decoded
Stacked on #27 (SOW-0176). Merge after it.
A compressed DATA object that cannot be decoded now costs only its field, not the whole entry, in Go and Rust:
- Entry reads, payload visitors, entry enumeration, facade data getters, Explorer/Netdata facets and the Rust log-query row projection skip the field.
- Unique-value enumeration and
--verifystill report the damage, as systemd does. - Rust: the "bad DATA behind one entry item" rule moves to
JournalError::is_recoverable_entry_datainjournal-core, so the SDK andjournal-engineshare one owner.
Behavior against a systemd 262 oracle on files with one corrupted compressed field:
| Codec | systemd 262 | Go and Rust |
|---|---|---|
| zstd, lz4 | rows kept, field dropped | same |
| xz | read fails (Cannot allocate memory) | rows kept, field dropped (intended difference, documented) |
run_reader_hardening.py now expects stock's rows for the corrupt and oversized zstd streams and checks them against stock -o export; strict verification still rejects those files.
Validation: Go and Rust unit tests, reader hardening, compression, verify, mixed directory, live and query matrices, docs examples and the duplication gate.
Summary by cubic
A compressed DATA object that cannot be decoded now costs only its field, not the whole entry, matching systemd 262 for zstd and lz4. Entry reads, payload visitors, entry enumeration, facade data getters, Explorer/Netdata facets, and the Rust log-query row projection skip the damaged field, while unique-value enumeration and --verify still report it; corrupt xz drops the field where systemd fails the whole read (documented difference).
Refactors
- The Rust bad-DATA rule moved to
JournalError::is_recoverable_entry_datainjournal-core, giving the SDK andjournal-enginea single owner. - The Rust tests share the damaged compressed entry setup between the field-drop and Explorer tests.
Bug Fixes
- The hardening oracle now parses stock
-o exportoutput and compares per-row realtime and payloads instead of row counts, asserting the damaged MESSAGE field is dropped.