BT410: bank the plane-write hypothesis ledger and the instrument to use next

Four hypotheses tried and killed by measurement, recorded so the next session
does not repeat them: misrouted eng port (traced -- resolves correctly),
OneOfSeveral's DrawPixelMap8 branch (only OneOfSeveralPixInt uses it, and all
four instances are on the 6-bit colour port where it is correct), an 8-bit
value overflowing a 6-bit field (the bits are far too high), and a displaced
copy from elsewhere in the buffer (the rows appear nowhere else).

Observed structure: constant low byte, varying high byte -- one field written
correctly while another is garbage.

The next move is an instrument, not a fifth hypothesis: trace at the VIEW
layer and log every draw whose absolute position lands in the artifact rect,
with port, colour and call site.  The rect is tiny so the log is short.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-27 13:42:26 -05:00
co-authored by Claude Fable 5
parent c8350408fc
commit 90daf5e9b7
@@ -984,7 +984,36 @@ WHAT THIS DOES AND DOES NOT INVALIDATE:
believed. Shipped is stable, so a shipped baseline can be captured once;
ours must be captured at least twice and the counts compared.
NEXT STEP: find the write path that emits an unmasked word. Both known
HYPOTHESES TRIED AND KILLED (recorded so the next session does not repeat
them -- each was killed by measurement, not argument):
1. Misrouted engineering port. TRACED: eng1/eng2/eng3 resolve correctly to
ports 3/5/7 on a dirty run. Not it.
2. OneOfSeveral taking its DrawPixelMap8 branch on a 1-bit plane. That
branch is real and IS change-driven (matching the intermittency), but
the only subclass using it is OneOfSeveralPixInt, and the widget map
puts all four instances on port 0 (sec), the 6-bit colour port where
PixelMap8 is correct. Not it.
3. A raw 8-bit pixel value overflowing a 6-bit field. The garbage words
set bits 9, 11, 14 and 15 -- far above anything an 8-bit value reaches
through a shift-0 port. Not it.
4. A displaced copy of packed pixels from elsewhere in the framebuffer (a
view-record save/restore landing at the wrong address). SEARCHED: the
artifact's 13-word rows appear nowhere else in the frame. Not it.
Observed structure, for whoever picks this up: the words hold a CONSTANT low
byte with a varying high byte (0xCFC0 / 0xCAC0 / 0x8AC0 / 0x8BD6 -- low byte
0xC0 is the overlay pair, high byte moves). That looks like one field being
written correctly while another is garbage, not a wholesale wrong value.
NEXT INSTRUMENT (do this rather than a fifth hypothesis): trace at the VIEW
layer, not the widget layer -- log every localView draw whose absolute
position lands inside the artifact rect (fb x 526..538, y 228..279), with the
port index, the current colour and the call site. The rect is tiny, so the
log will be short, and it names the culprit directly. Reproduce by launching
repeatedly until Eng1 reads 19011 instead of 17981 (roughly one run in
several; check the count BEFORE trusting any capture).
ORIGINAL NEXT STEP: find the write path that emits an unmasked word. Both known
instances are on the Heat/coolant column and the generator-select button, and
the engPort resolution is NOT the cause (traced: eng1/eng2/eng3 resolve
correctly to 3/5/7). Suspect the tile/strip blit for VertTwoPartBar-family