All inputs are synthetic ASCII bytes with LF endings.
memo.txt = hello + LF = 5 + 1 = 6 bytes
table.csv = item,qty + LF (9) + A1,2 + LF (5) + B2,3 + LF (5) = 19 bytes
notes.txt = done! + LF = 5 + 1 = 6 bytes
main ZIP file count = 3; declared total = 6 + 19 + 6 = 31 bytes
main.zip uses STORED: compressed payload also 31 bytes, not the entire archive.
main archive = EOCD 22 + 3*(local 30 + central 46) + 2*(8+9+9) filename bytes + 31 payload = 333 bytes
main CRC observed success: entries 3; observed bytes 6+19+6=31
CRC corrupt last payload: first two entries passed, returned bytes 6+19=25; failed read returns no third block to caller
Duplicate same.txt: two entries, 1+1=2 declared bytes; exact name duplicate, no content read
Total limit: 4096+4096+1=8193 exceeds 8192 by 1; all individual files at most 4096
Too many: 17 one-byte entries exceeds default count 16; declared total=17
Ratio fixture: declared 2000; compressed data 17; 2000 > 100*17
Misdeclared large: a.txt payload ABC is 3 bytes but headers declare 4; observed 3 differs from declared 4
Known limitation: spoofed_prefix.zip contains physical ABC but declares size 2 and CRC(AB). ZipExtFile returns AB and this narrow check reports PASS with observed 2; it does not prove the entire physical payload length.
Encryption fixture is only a bit-0 header patch, not a real encrypted archive.
Unsupported method fixture is only method-99 header patch, not a real codec output.
Misdeclared/CRC/header patches are deliberately tiny teaching counterexamples.
Never extract nested fixture ZIPs or execute their members.
Expected JSON values were authored from these contracts, not saved program outputs.
source_sha256 is excluded from expected JSON; check it independently against fixture bytes and SHA256SUMS.txt.
