sots-re/campaign/research/research-completion-abi.md

8.3 KiB

Completion record ABI recovery

Static handoff only. The provenance index is verify/results/research-completion-abi/reva-2026-09-09-index.md; the regenerated instruction capture and interpretation are respectively verify/results/research-completion-abi/objdump-2026-09-09-ownership.txt and verify/results/research-completion-abi/recovered-static.md. The complete dedup/helper repair is verify/results/research-completion-abi/objdump-2026-09-09-dedup-helper.txt; its first-window raw provenance is superseded by the paired captures and identity record in verify/results/research-completion-abi/objdump-2026-09-10-boundary-repair.md under Astra decision d-d2a9b8be6399a6abaa0e05a5. Input identity is dumps/sots.exe, SHA-256 970b7de729956a53094c7eb98aba4270aee98e2fed5daf0d39e290013c90c841 / MD5 9969481c39f4b33a8a21c48b62abee4c.

The ownership archive's terminal-byte provenance is likewise superseded by the complete package verify/results/research-completion-abi/run-79357a65226f61d6a86c042d/ under Astra decision d-d4c494ba02ada278030ef473. Its six narrow/wide pairs, raw section-byte checks and full ten-window audit establish the encoded return immediates while preserving the static-only limitation. The package found three additional truncated historical stops (ObservedTech append/reallocator and string allocation/replacement); their widened streams are now the byte authority. No archive production-history inference or live-safety claim is made.

The TurnEvents correction's historical-session boundary authority is verify/results/research-completion-abi/run-9daf5c3b75547271d5c3b4ed/. It superseded the stale-session attribution and truncated nested-copy stream invalidated by decisions d-fd5aff1eaf78a8c15d96723c and d-0bb927e63b915c87a58d4257. The package binds the actual session and a fail-if-used output directory; captures complete helper authority through 0x0077992f; and retains 0x00779a20 as an expected-failing boundary beside complete 0x00779a21, 0x00779a23, and 0x00779a28 controls plus raw bytes. It is analyst static evidence awaiting a fresh independent verifier, not restored acceptance. Astra decision d-e9d6d48cd77538556d1a1c1f later barred reuse of that package against changed source. The current-source remeasurement is verify/results/research-completion-abi/run-35e59053176da458d8b46fea-repair1/, with preflight, plan, recipe and interpretation in the sibling run-35e59053176da458d8b46fea-preflight.json, plan-run-35e59053176da458d8b46fea.md, capture_run_35e59053176da458d8b46fea.py, and report-run-35e59053176da458d8b46fea.md. The unsuffixed run directory preserves a failed recipe predicate and is not authority. The new package is analyst static evidence awaiting fresh independent reproduction, not restored acceptance.

Implementable machine boundaries recovered

  • 0x008562a0: ObservedTech default constructor, ECX receiver, EAX return, plain ret.
  • 0x007b7320: ObservedTech vector append, ECX receiver plus one stack word, ret 4; stride 0x2c. Its copy helper is 0x0079a150 (cdecl-style allocator/destination/source stack arguments), which copy-constructs the embedded string rather than copying a vector element header. Capacity growth is 0x007b5820 -> 0x007b34e0 -> 0x0057e590.
  • 0x0057e590 calls 0x00924fb6 with count * 0x2c; reallocation destroys every old element via virtual slot 0 with zero and frees the array through 0x00924faa. These are MSVCR100 scalar-new and scalar-delete import thunks, not clean-room allocator operations.
  • 0x0086c580: PlayerEvent vector append, ECX receiver plus one stack word, ret 4; stride 0x74. It grows via 0x00869500 and copy-constructs through 0x007693f0 (ECX destination, stack source, EAX destination return, ret 4), independently assigning all three strings. 0x0061ae90 releases each long string via 0x00924faa when capacity is >= 0x10.
  • 0x004249a0 (reached by 0x00425430 assignment) allocates through 0x00924fb6 and releases a prior long destination buffer through 0x00924faa. A temporary long string is therefore not transferable by raw header copy.
  • 0x00885380: get-or-create TurnEvents bucket, ECX EventStorage receiver plus stack turn, EAX bucket return, ret 4. It returns the last existing matching turn. On absence it initializes the stack bucket's vptr and empty nested-vector header but not its EvTurn; 0x00884cb0 copies that incoming stack word and deep-copies the nested vector. After temporary nested-vector cleanup, get/create writes the requested turn into the stored last element and returns it. The transient word is not measured randomness or a zero default. Fresh correction capture: verify/results/research-completion-abi/run-16f8e9b6376b278c4870be09/, governed by d-b51f3f76803e852ed250846a.
  • 0x00884cb0: outer TurnEvents vector append, ECX vector receiver plus stack source, ret 4, stride 0x18. Full-capacity growth is 0x008841a0 -> 0x00883a60; allocation is 0x006e8f50 -> 0x00924fb6 with count * 0x18. Existing buckets are copy-constructed by 0x0077fed0, including an independently allocated/copied nested PlayerEvent vector via 0x00779850 -> 0x0078af40 (count * 0x74) -> 0x007725a0 -> 0x007693f0.
  • TurnEvents virtual slot zero resolves from vtable 0x00a0f07c to 0x0062e120. It destroys the nested vector through 0x00629580; that destroys every 0x74 PlayerEvent, frees the nested block, and zeros its three pointers. Static unwind edges clean partial PlayerEvent and TurnEvents ranges and free the new outer block, but no allocation failure was executed live.

Ordering / visible effects

RecordObservedTech's append predicate is name absence, not capacity. A matching existing record keeps first-turn/name and updates last-turn/with mask. 0x00825d40 scans a bucket's events in 0x74 steps, checking action, location, three floats, message and image before passing both description strings to 0x0046f8c0. Fresh paired-boundary instructions establish that helper as caller-cleaned bool string_not_equal(stored, candidate): it returns one for any byte/length difference and zero for equality, handling each operand's inline/heap representation at capacity 0x10. FindDuplicate reaches the match return only on zero, so EvDsc equality is required and a description-only difference does not deduplicate. This statically contradicts the inherited description-omission claim; decision d-2ff30c9f5355116bea822924 required the now-archived complete branch/helper repair. The later provenance correction does not itself prove these semantics: an independent verifier must reproduce the repaired package and predeclared falsifiers. The wrapper returns the first element equal in all fields and writes nothing. 0x00879eb0 prunes only a leading stale run (EvTurn < turn-50), deep-shifts from the run's last stale element, and therefore removes n-1: one stale bucket survives, a single stale bucket causes no write, and stale buckets after a fresh bucket are not inspected. The no-duplicate EventStorage path remains distinct from event-vector capacity: it is the path that appends a 0x74 PlayerEvent and changes IDs/vector contents. Caller text/position/action/defaulting and the exact PostEvent write order remain required inputs/effects. No RNG draw occurs in the recovered bucket, duplicate, prune, copy, allocation, or destruction boundaries.

Original/runtime dependencies and limits

Any original-assisted allocation, string assignment or deletion must retain allocator-family compatibility: the recovered calls target the original MSVCR100 import thunks. A standalone replacement needs its own coherent allocation/destruction boundary; calling these original helpers is an original dependency, not independent replacement. Calling 0x0046f8c0 likewise retains an original string-layout/comparison dependency, though its equality behavior is implementable without allocation in a standalone boundary. Required unavailable proof inputs are a safe long-string/full-capacity pre/post fixture (or equivalent archived trace), same-bucket equal/description-only-different event fixtures covering short and long strings, exact exceptional cleanup outcomes under a live throw, and independent reproduction of the named static windows and falsifiers. This handoff makes no live allocator-safety, runtime event-construction, or replacement-acceptance claim.