Record a defect packet slicing found: the tie block terminator is early

Range measured: every tie LOD block on the disc, 2,177 blocks.

The last packet's end is known two ways. Its length comes from its record's
packet_quadwords, and every other record's length is confirmed by the next
record's pointer -- so only the last packet of each table is unconfirmed.
Comparing its computed end against where parse_tie_block stopped: the last
packet's computed end lands 2 to 16 bytes past the located 0xf6, on all 2,150
blocks measured.

Two readings fit. Either the terminator was located too early -- inside the
last packet's data -- or the last packet's length over-predicts by a small
amount. The first is likelier: a length error on the last record of every table
would have to be a coincidence. Neither is settled here, and the test asserts
the measurement rather than the reading.

Why the existing test missed it: "2,177 of 2,177 blocks end on 0xf6" is
satisfied by a false terminator exactly as well as a true one -- it checks
that the byte found IS a 0xf6, not that it is the block's end. A test that
confirms the shape it walked to will pass on the wrong byte.

The cost: the block extent is short by that much, so payload and padding
under-report and anything computed from them is correspondingly short. The
block starts are unaffected and RAM-confirmed.

Recorded as a limitation with the measurement attached, not fixed. A terminator
packet data cannot imitate is its own task, and guessing one would be the
plausible-sounding alternative this project has been bitten by. A packets()
accessor was tried and removed for the same reason: with the extent short it
silently yields the wrong answer, and an API that is quietly wrong is worse
than no API.
This commit is contained in:
2026-10-13 17:40:31 +02:00
parent 1cfe744501
commit 572cd1898d
3 changed files with 119 additions and 0 deletions
+6
View File
@@ -283,6 +283,12 @@ Phase 1 hands over the extents; this phase works out what each one contains.
R&C1 carries the same quadruple at `+0x20` and it is not an offset on
R&C2. The fourth byte is unidentified and is *not* the shader total
(disagrees on 1,827 of 1,864).
- [~] The tie block's **located `0xf6` terminator is inside the last packet's
data** -- the last packet's computed end lands 2 to 16 bytes past it on
all 2,150 blocks measured. So the block's *extent* is short by that much
(the `0xf6` test could not see it: a false terminator passes that test).
The block *starts* are unaffected and RAM-confirmed. The packet lengths
themselves are verified for every record but the last.
- [x] `tie` — **fully chained.** `resolve_tie_class` walks both indirections: the
class table is in `core_index.bin`, and the entry's `offset_in_asset_wad`
addresses `core_data.bin` (not `core_data.wad`). All **1,864** tie classes