Commit 32220e2
committed
fix(seed): carry redis values as bytes and write them as RESP
A replay pruned sixty-seven calls out of its comparison because two seeds
never landed. The certificate said why, in the entry for the key that was
missing:
materialization: failed
readback: could not run seed_redis SET: nul byte found in provided data
The seeder writes through `redis-cli <args…>`, and a process argument
cannot carry a zero byte — the standard library refuses to spawn. The
value in question is an encrypted payment-method payload out of the
locker, so zero bytes are ordinary rather than exotic. Every such seed
failed, the reads that depended on them returned Null, and each of those
took its subtree out of the run.
The write is now RESP on stdin, through `redis-cli --pipe`. RESP frames
each argument by its declared length, so a value is carried by its byte
count and never by a delimiter: zero bytes, newlines and quotes all
survive. `--pipe` exits zero even when the server rejected a command, so
the reply is inspected rather than the exit status.
Behind that failure sat a quieter one. The payload was a `String`, filled
by `to_redis_string`, which decodes bulk bytes with `from_utf8_lossy` —
so a non-UTF-8 value was already rewritten before the transport ever saw
it. The readback then decoded the same way and compared the two, which
made it agree with itself for the wrong reason: a corrupted seed read
back as `matched`. A value carrying a zero byte failed loudly; a binary
value without one was silently wrong and certified correct.
So the payload carries `Vec<u8>` end to end, `to_redis_bytes` is added
beside `to_redis_string` on the wire type, and the readback compares
bytes. The lossy rendering survives in exactly one place — the
certificate field and the log line a person reads — where nothing
downstream compares it.
One limitation is left standing rather than papered over: the READ side
is still `redis-cli --raw`, which is newline-delimited, so an element
containing a newline cannot be told from two elements. The write carries
it correctly; the readback cannot yet verify it. The test says so, and
checks the byte-exactness claim on a newline-free value rather than
asserting something the read transport cannot support.1 parent 03ed73e commit 32220e2
2 files changed
Lines changed: 302 additions & 70 deletions
0 commit comments