Remediate Ε-W3-T1 package-compat-fixtures review findings
Freeze *.rsbank as binary via .gitattributes; add a truncated additive_forward fixture proving the exact-size proof beats TooNew; enumerate the fixture dir to catch orphaned files; make fixture-size checks fatal instead of just logged; pin fixture version asserts as literals, not build-relative.
This commit is contained in:
+28
-11
@@ -12,20 +12,29 @@ The reason is the whole point of the corpus. These bytes exist to catch a format
|
||||
that quietly breaks a compatibility direction. A fixture regenerated by the build that
|
||||
broke it agrees with that build by construction and catches nothing — which is exactly
|
||||
the failure mode a version ladder exists to prevent. The same argument forbids a test
|
||||
that builds its own fixture at run time.
|
||||
that builds its own fixture at run time. The repo-root `.gitattributes` (`*.rsbank
|
||||
binary`) keeps this mechanical: without it, git's NUL-sniffing heuristic could
|
||||
text-classify a future short/ASCII fixture and CRLF-mangle a line ending on a Windows
|
||||
checkout, silently breaking the frozen-bytes premise.
|
||||
|
||||
If a fixture stops decoding, the answer is never to re-cut the fixture. Either the format
|
||||
change was structural (bump `minReaderVersion`, add a new fixture, and leave the old one
|
||||
asserting the refusal) or it is a regression.
|
||||
A fixture's BYTES are frozen forever; a fixture's ASSERTION is not. `additive_forward.rsbank`
|
||||
and `refuse_structural.rsbank` carry version pairs one step past THIS build's ladder (2/1
|
||||
and 2/2). When a future build's own `kPackageFormatVersion` reaches 2, `refuse_structural.rsbank`
|
||||
classifies `Readable` under the new ladder — its bytes never claimed to need more than
|
||||
format 2 — so that build re-aims the assertion (and adds a new synthetic pair one step
|
||||
past the NEW ladder); it never re-cuts the fixture. If a truncation or hostile-name
|
||||
fixture ever changes classification, that is a regression, never a ladder consequence.
|
||||
|
||||
## Provenance
|
||||
|
||||
`v1_shipping.rsbank` was produced by running this repo's own export verb (`exportBank`)
|
||||
at version **1.4.0** over a one-sample bank, and copying the emitted file here verbatim.
|
||||
Every other fixture is derived from those bytes: the truncations are prefixes of them,
|
||||
and the synthetic packages reuse their manifest region under different version integers
|
||||
or a hand-written hostile manifest (the encoder refuses to write one, which is why those
|
||||
could not come from the verb).
|
||||
Every other fixture is derived from those bytes: eight of the nine truncations are
|
||||
prefixes of `v1_shipping.rsbank` (the ninth, `trunc_additive_forward.rsbank`, is a prefix
|
||||
of `additive_forward.rsbank` itself — a prefix of a prefix, still frozen bytes, never
|
||||
regenerated), and the synthetic packages reuse their manifest region under different
|
||||
version integers or a hand-written hostile manifest (the encoder refuses to write one,
|
||||
which is why those could not come from the verb).
|
||||
|
||||
Payloads are one 300-byte 16-bit mono WAV. The properties under test are structural —
|
||||
version integers, framing arithmetic, name validation — so a larger payload proves
|
||||
@@ -46,9 +55,10 @@ build, exactly as this one was, and recording the build's version here.
|
||||
|
||||
### Truncation — one file per distinct decode failure site
|
||||
|
||||
Each is a prefix of `v1_shipping.rsbank` (907-byte prefix + 300-byte payload = 1207
|
||||
bytes). All classify `Malformed`; none may classify `TooNew`, since "install a newer
|
||||
build" does not fix a partial download.
|
||||
The first eight are prefixes of `v1_shipping.rsbank` (907-byte prefix + 300-byte payload
|
||||
= 1207 bytes), so `formatVersion` never exceeds this build's on that path. All classify
|
||||
`Malformed`; none may classify `TooNew`, since "install a newer build" does not fix a
|
||||
partial download.
|
||||
|
||||
| File | Bytes | Site the cut lands in |
|
||||
|---|---|---|
|
||||
@@ -61,6 +71,13 @@ build" does not fix a partial download.
|
||||
| `trunc_payload_middle.rsbank` | 1057 | Inside the first payload. |
|
||||
| `trunc_one_short.rsbank` | 1206 | One byte short of the total. |
|
||||
|
||||
`trunc_additive_forward.rsbank` is the ninth: a 983-byte prefix of `additive_forward.rsbank`
|
||||
(25-byte frozen header/manifest-length region + 958-byte manifest = 983), cut exactly at
|
||||
ITS payload boundary. `formatVersion` here is 2 — one past this build's — so this is the
|
||||
one truncation that proves the exact-size-proof failure stays `Malformed` even when
|
||||
`formatVersion > kPackageFormatVersion`, rather than relabeling to `TooNew` (the parse
|
||||
branch is the only one that relabels — see `src/core/package/CLAUDE.md`).
|
||||
|
||||
### Hostile names — refused at decode, before any planner
|
||||
|
||||
The two naming fields carry different rules (`src/core/package/CLAUDE.md`), so each
|
||||
|
||||
Reference in New Issue
Block a user