#48 gave the suite a container make check can reach at index_bits 6,
closing a gap CLAUDE.md warns about by name: before it, every green run
covered VQ3R and nothing covered VQ4P, on any platform. That part is real
and it stays.
What it also did is write the VQ4P packing a second time.
block_indices_packed6 in tools/make_test_container.py:249 reimplements
what block_indices_packed in tools/convert.py:445 produces, and says so:
byte-for-byte the packing tools/convert.py's block_indices_packed
writes, so the engine's P6_J0..P6_J3 unpack recovers the stages in order
I checked that claim by reading both and it holds today. The bit expressions
are identical —
b0 = (s[0] | (s[1] << 6)) & 0xFF # convert.py:465-467
b1 = ((s[1] >> 2) | (s[2] << 4)) & 0xFF
b2 = ((s[2] >> 4) | (s[3] << 2)) & 0xFF
— and both lay a row down at ((b * nvr + v) * B + r) * 3, which is what
block_indices' [nb, nvr, B, stages] flattens to. Reading is not proof,
and nothing re-checks it.
Why the arm cannot catch the drift
The VQ4P block (tests/run.sh:1051) compares the engine against itself:
chunked vs sequential, SIMD vs CPU baseline, cache vs no cache. Every one of
those runs the same unpack — P6_J0..P6_J3, src/simd.h:73-76 — over the
same bytes.
So if the generator ever packs differently from the converter, the engine
decodes the generator's bytes as some set of indices, both backends decode
them the same wrong way, and all four checks pass. The arm would be green
and testing a layout no converter produces. The PR is honest that there is
"no oracle, but the engine is compared against itself"; this is the specific
thing that costs.
That is not hypothetical drift-bait either: the two live in different files,
one is exercised on every make check and the other only by a real
conversion, so a change to convert.py's blocking would be caught by
nothing here.
What would close it
Roughly in order of cost:
- Compare the two functions directly on random input — the strongest and
the most awkward, because convert.py's block_indices goes through
torch, so this is a uv-gated check like the existing oracles rather
than part of the default run.
- Have the generator import the converter's function instead of
carrying its own, gated so make_test_container.py still runs without
torch (falling back to a SKIP of the VQ4P arm rather than to a second
implementation).
- Pin the layout with a fixture: a few packed rows, checked in, and both
sides asserted against them. Cheap, no torch, catches either side moving
— but it pins the bytes rather than proving the two agree, so a change
that legitimately alters the layout has to update the fixture and can be
made to agree with itself.
(1) or (2) is the real fix; (3) is worth having anyway, and is the only one
of the three that runs on a host with no uv.
Not a reason to hold anything
The arm as merged is a genuine improvement over no coverage at all, and its
own comment already bounds what a green run means — 4 layers, 3 MoE, "does
not and cannot bound the depth-amplified discontinuity mode". This issue is
about the one bound the comment does not state: that the container it
builds is only as trustworthy as an unverified copy of the converter's
packing.
#48 gave the suite a container
make checkcan reach atindex_bits 6,closing a gap
CLAUDE.mdwarns about by name: before it, every green runcovered VQ3R and nothing covered VQ4P, on any platform. That part is real
and it stays.
What it also did is write the VQ4P packing a second time.
block_indices_packed6intools/make_test_container.py:249reimplementswhat
block_indices_packedintools/convert.py:445produces, and says so:I checked that claim by reading both and it holds today. The bit expressions
are identical —
— and both lay a row down at
((b * nvr + v) * B + r) * 3, which is whatblock_indices'[nb, nvr, B, stages]flattens to. Reading is not proof,and nothing re-checks it.
Why the arm cannot catch the drift
The VQ4P block (
tests/run.sh:1051) compares the engine against itself:chunked vs sequential, SIMD vs CPU baseline, cache vs no cache. Every one of
those runs the same unpack —
P6_J0..P6_J3,src/simd.h:73-76— over thesame bytes.
So if the generator ever packs differently from the converter, the engine
decodes the generator's bytes as some set of indices, both backends decode
them the same wrong way, and all four checks pass. The arm would be green
and testing a layout no converter produces. The PR is honest that there is
"no oracle, but the engine is compared against itself"; this is the specific
thing that costs.
That is not hypothetical drift-bait either: the two live in different files,
one is exercised on every
make checkand the other only by a realconversion, so a change to
convert.py's blocking would be caught bynothing here.
What would close it
Roughly in order of cost:
the most awkward, because
convert.py'sblock_indicesgoes throughtorch, so this is a
uv-gated check like the existing oracles ratherthan part of the default run.
carrying its own, gated so
make_test_container.pystill runs withouttorch (falling back to a SKIP of the VQ4P arm rather than to a second
implementation).
sides asserted against them. Cheap, no torch, catches either side moving
— but it pins the bytes rather than proving the two agree, so a change
that legitimately alters the layout has to update the fixture and can be
made to agree with itself.
(1) or (2) is the real fix; (3) is worth having anyway, and is the only one
of the three that runs on a host with no
uv.Not a reason to hold anything
The arm as merged is a genuine improvement over no coverage at all, and its
own comment already bounds what a green run means — 4 layers, 3 MoE, "does
not and cannot bound the depth-amplified discontinuity mode". This issue is
about the one bound the comment does not state: that the container it
builds is only as trustworthy as an unverified copy of the converter's
packing.