Legacy capability early exit: missing fixture host bootstrap

The independently proven defect was in the JavaScript fixture harness: it omitted init_dx_com_thunks() after load_pe(). The single corrected qualification passed all 47 calls / 45 descriptors, with the original PE, original oracle and original production module. No production change is needed for this failure.

Identity and scope

Causal diagnosis

The diagnostic used an external observer, the unchanged original fixture and its actual x86 instructions. It advanced run(1) and captured registers, object/vtable/slot values, stack words, completion and all original oracle inputs. No COM return, pointer, descriptor, module or guest instruction was patched. The first three calls returned, including DirectDrawCreate HRESULT 0. Its output at 0x410044 was object 0x08221000, whose first word was zero.

The generated instruction sequence is:

0040306a  push 8
0040306f  push 0
00403074  push dword ptr [00410044]
0040307a  mov eax,[00410044]
0040307f  mov eax,[eax]
00403081  call dword ptr [eax+50h]
00403087  mov [00410054],eax

This correctly dereferences the object and vtable and selects IDirectDraw slot 20. With lpVtbl=0, however, the call reads address 0x50, observed as zero. Terminal EIP was 0, EAX 0, ESP 0x429838, versus entry ESP 0x429848. The stack held [0x403087, 0x08221000, 0, 8]: return address, this, HWND, flags. The last observed block began at 0x40306a; disassembly and the pushed return address identify its terminating call at 0x403081. This is block-boundary observation plus instruction/stack evidence, not a per-instruction trace. Completion remained zero. Record four remained 0xa5a5a5a5; it is untouched poison, not a SetCooperativeLevel HRESULT.

At canonical source 1262cbfc, both host.js and test/run.js call init_dx_com_thunks after loading the PE. The DirectX implementation explicitly documents this host initialization requirement. Its generated initializer sets DX_VTBL_DDRAW using init_com_vtable(978,23). DirectDrawCreate passes that global to dx_create_com_obj, which writes it into the wrapper's first word. API dispatch's worker-vtable synchronization restores existing shared registry entries; it does not replace initial host construction of that registry. The fixture skipped the construction step. Exact line-numbered excerpts are preserved in implementation-excerpts.txt.

The DirectDrawCreate contract requires a valid IDirectDraw pointer on success and documents the explicit LoadLibrary/GetProcAddress route used here. The SetCooperativeLevel contract allows null HWND with DDSCL_NORMAL. The previously recovered public headers and independent slot/ABI review remain the slot-20 reference. No invalid PUSH order, vtable displacement or stdcall cleanup was found in these emitted instructions. The null pointer arose from omitted emulator host bootstrap, before this valid public call could execute.

Correction and regression evidence

The functional change is exactly one bootstrap call after successful load_pe and before guest allocation/execution. Additional observation fields retain terminal ESP, previous EIP and resolved output objects/vtables/slots. The fixture generator, verify() and synthetic negative controls are byte-for-byte unchanged; no expected mask or call/descriptor assertion was weakened.

One diagnostic and one corrected qualification were executed, each guarded by timeout --kill-after=5s 120s. Diagnostic receipt cmd_ details are retained in execution-transport.json; qualification details are in qualification-transport.json. Qualification ran at 13:33:01–13:33:02 UTC, exit 0:

Evidence Baseline diagnostic Corrected qualification
DD object 0x08221000 0x08221000
DD vtable 0 0x0041986c
Slot 20 target 0 0x075001d8
Returned call records 3 / 47 47 / 47
Completion 0 1
Entry / terminal ESP 0x429848 / 0x429838 0x42b958 / 0x42b95c
EnumDevices counts 0/0/0/0 3/3/2/1
Original oracle expected failure at record 4 PASS

The corrected outer RET restores the expected stack-16; each call's recorded ESP equals entry ESP. All 45 descriptor assertions, 55 guard pairs, public outputs and callback contexts passed. Texture masks remain 0xf7df, filter masks 0xc3 / 0x030003c3, address mask 0xf7, and Device7 operations 0x3ff. The independent offline replay verifies baseline failure and corrected success from recovered words, plus identical PE and oracle and 1,053 synthetic negative controls. Offline controls are distinct from the two actual executions.

node scratch/runs/20261020-legacy-caps-early-exit/verify-evidence.js
node test/test-legacy-texture-caps-native.js --offline
node --check test/test-legacy-texture-caps-native.js
git diff --check

Preflight checked accessibility, disk, all 6,441 canonical source identities, module hash and existing host dependencies. Postflight verified those source files, all 29,620 files in the previous preservation manifest, original fixture pins and archive hash; no task execution process remained. Evidence was recovered before runtime release at 13:34:28 UTC, leaving the box running with TTL 15:53 UTC. Local task expansion is below 6 MiB and disk remains above 2 GiB + 60 MiB. See RECOVERY.md for exact references without duplicate module or archive storage.

This qualifies the public COM capability fixture on the pinned emulator module. It does not qualify Windows-native behavior, rendering or gameplay. No screenshot, per-instruction trace or engine-native disassembly was captured; those artifacts are explicitly unavailable. No production changes, main integration, workers, build/install, browser or laptop activity occurred.