sots-re/verify/results/research-completion-abi/run-9daf5c3b75547271d5c3b4ed/report.md
2026-09-10 01:07:05 -04:00

5.2 KiB

Fresh TurnEvents boundary capture

Session run-9daf5c3b75547271d5c3b4ed; analyst static measurement only. This package implements decisions d-fd5aff1eaf78a8c15d96723c and d-0bb927e63b915c87a58d4257. It does not execute the game, allocations, constructors, destructors, exception paths, event posting, or RNG.

Provenance and positive execution

capture.py requires the actual session and matching output directory and fails if the directory contains anything except the recipe. Before capture it positively rejected missing and stale session IDs, a stale output path, and a simulated reused location. The recipe is intentionally not reusable unchanged by a later campaign session.

The manifest records 12 subprocess executions. Every command returned zero, emitted nonempty stdout, and emitted empty stderr. Before and after source bindings are identical: engine ccd8e02083e8d2e2b3e97976ace2273c8f924dfc02a39e919004eaf3544c50fd, RE 6696fd5201e144843617cbf6d78b41b5287ad5dcc9fa1e8aaa861d52b64e72e8. Fresh input identities are:

  • owner-supplied dumps/sots.exe: 7,898,624 bytes, SHA-256 970b7de729956a53094c7eb98aba4270aee98e2fed5daf0d39e290013c90c841;
  • /usr/bin/objdump: 373,888 bytes, GNU Binutils 2.38, SHA-256 1eaaef2e7f57c4c7f69115c495e2466f5a8c8e5f3bc42221d092382f30f9d4cd.

Measured observations

  1. The known-bad stop 0x00779a20 returns zero but displays only byte 74 for the instruction at 0x00779a1f. It is an explicit negative control, not a passing stream.
  2. Stop 0x00779a21 displays the complete 74 10 conditional jump; stop 0x00779a23 additionally displays complete 8b cf; stop 0x00779a28 additionally displays complete e8 28 6a ff ff. Raw section bytes over 0x00779a1f..0x00779a28 are 74 10 8b cf e8 28 6a ff ff. The resolver's three boundary predictions therefore held.
  3. The separately bounded 0x00779850..0x00779930 authority capture includes destination nested- vector pointer initialization, empty/nonempty branching, allocation/range-copy calls, normal ret 4 at 0x00779912, unwind cleanup call at 0x00779918, deallocation call at 0x00779921, and padding through 0x0077992f. It excludes the later routine at 0x00779a10.
  4. Get/create 0x00885380..0x0088544a, outer append 0x00884cb0..0x00884d8f, and nested destruction 0x00629580..0x006295ca end respectively in complete ret 4, ret 4, and ret instructions. Their wider controls preserve those rows and add padding or a subsequent prologue.

Bounded static interpretation

For valid input containers and normally returning callees, the instruction facts support this order:

  • get/create scans all existing 0x18 TurnEvents elements and retains the last matching EvTurn; this existing-match path returns without element construction;
  • a miss initializes a temporary vptr and three empty nested-vector pointers, but not temporary EvTurn; outer append copies source +4, then deep-copies the nested vector, then advances outer _Mylast by 0x18;
  • nested copy first nulls all destination pointers. Empty source returns without allocation; nonempty source enters allocation and 0x74-stride PlayerEvent range-copy construction;
  • get/create cleans the temporary nested vector before writing requested turn into the stored final element and returning that element;
  • nested destruction skips element/free work for null storage. Otherwise it invokes every PlayerEvent virtual destructor, frees the nested block via 0x00924faa, and then zeros all three pointers.

The uninitialized transient scalar is not a random draw and should not be reproduced as intentional undefined behavior. No event record, event ID, text, outer EventStorage next-ID, or RNG state is written by the bounded helper itself. Static decoding does not demonstrate live allocator-family safety, exception cleanup outcomes, or observable transient behavior.

Original dependencies, missing runtime inputs, and verifier falsifiers

Original-assisted use depends on the binary's coherent MSVCR100 family: allocation thunk 0x00924fb6, deletion thunk 0x00924faa, nested allocation chain 0x00779850 -> 0x0078af40, PlayerEvent range/copy chain 0x007725a0 -> 0x007693f0, and virtual PlayerEvent destruction. A standalone implementation must replace the entire allocation/copy/destruction family; mixing raw headers with original-owned storage is not independent replacement.

Missing live inputs are pre/post spare- and full-capacity outer vectors, empty and nonempty nested vectors with owned short/long strings, distinct stack sentinels, forced allocation failure/throw, and observers capable of detecting the transient source word. No such fixture was available or run.

An independent verifier should use its own real session and fail-if-exists directory, freshly hash source/tool/input, reproduce all authority windows, and hold out at least one complete terminal boundary. It should require the 0x00779a20 control to fail completeness despite exit zero, compare raw bytes against decoded lengths, and check distinct existing-last-match, miss/spare, miss/full, empty/nonempty nested, and unwind states. Archived event records remain a separate validation input; this package does not prove their field semantics or promote either contract criterion.