# Independent cross-check: RecordObservedTech GPT-6 Astra, local instruction stream from fingerprinted `dumps/sots.exe`, 2026-09-09. MD5 `9969481c39f4b33a8a21c48b62abee4c` exactly matches the analyst's ReVa program metadata; the same local file's SHA-256 is `970b7de729956a53094c7eb98aba4270aee98e2fed5daf0d39e290013c90c841`. This closes the previously reported missing ReVa/local fingerprint linkage. Fresh disassembly: `verify/results/research-callback/record-observed-tech-objdump.txt`. ## Corrections to the first analyst pass - The constructor/push path is **name not found**, NOT vector full capacity. The function scans first at observer+0x274 through last at +0x278; +0x27c capacity is not read in this wrapper. Empty list or exhausted search reaches 0x007ba274. Capacity handling belongs to 0x007b7320. - The observer is stack argument 1 (`[ebp+8]`), not argument 2. Stack argument 2 (`[ebp+0xc]`) supplies observation eligibility bytes and the field used to select the with-mask bit. - Stack argument 3 is a TechDef-like object whose string starts at **object+4**. It is not a bare string pointer: source length is object+0x14 and capacity object+0x18. The comparison uses destination string at record+0x0c. Confirm semantic TechDef identity using the caller/schema. ## Pinned instructions / static callable boundary Wrapper 0x007ba1a0 uses this in ECX, three stack arguments, returns with **ret 0x0c** at 0x007ba32b. Its ECX-derived object supplies the 16-bit turn at +0x0c. The owner callback caller prepares ECX from player+8 minus four and pushes (technology, player, player) in reverse argument order. Before searching it requires three non-null arguments and rejects a subject with `NPC && !RebAI` (offsets +0xfb/+0xfc, names cross-checked with the existing serializer/address contract). It then calls 0x0057e6d0 on argument 3; a nonzero result suppresses recording. Fresh disassembly now resolves that helper: read the technology's name string at def+4, find its **first underscore**, and compare the suffix with **`_Root` using `_stricmp`**. The literal is at 0x00a00040; imported comparator IAT is 0x009dd328 (MSVCR100.dll entry 115). Thus root technologies are excluded, case-insensitively. It is not a costly master-tree query; ECX is unused in this helper. Capture: observed-tech-exclusion-objdump.txt and observed-tech-exclusion-literal.txt. The underscore scan has no terminator check in the binary; valid tech-name syntax is a precondition, not evidence of safe arbitrary-string handling. Search increments by **0x2c**, compares full names via 0x004236a0, and preserves an existing element if found. On absence it constructs a stack temporary (0x008562a0), appends via 0x007b7320, then operates on the newly appended element at last-0x2c: - first/last turns are 16-bit offsets **+4/+6**; - name assignment targets the string at **+0x0c** via 0x00425430; - both new and existing paths update last turn **+6** and OR a bit into **+0x28**, using subject+0x28 as the x86 shift count; - existing-path first-turn/name stay unchanged in this wrapper. Append is followed by conditional destruction of the TEMPORARY string when capacity >=16. The temporary lifetime does not permit stealing its buffer into the appended element. Copy/ reallocation/destruction inside 0x007b7320 must be recovered before implementation. These facts are static ABI/ordering evidence. They do not prove live allocation safety.