Files
reverse-engineering-anything/docs/verification/investigation-lifecycle.md
T
gensokyo-dev f72638f6b1 feat(investigation)!: retain records across engine cleanup (#8361)
Separate engine cleanup, investigation reset and terminal disposal in the shared application owner. Keep stable Evidence IDs and full Unknown revision history through engine close and target changes; serialize reset with all record writers and cleanup owners, optionally acknowledging a complete checkpoint before clearing. Bound retained representation without eviction.

Validation: 43 focused files / 533 distinct tests, source/type/lint/schema/documentation checks, nine genuine source cases across eight families, real Ghidra session identity and cleanup, and nine actual local Codex CLI terra/high runs with independent full-result and checkpoint audits. See docs/verification/investigation-lifecycle.md for measurements, partial attempts and verification limits.

Fixes #8347.

BREAKING CHANGE: close_binary retains investigation records. Use reset_investigation to clear them. Cross-process recovery requires an explicitly acknowledged Evidence bundle checkpoint.

Assisted-by: Suika (gensokyo-skills:suika-scatter-gather-planning)
2026-10-31 21:34:45 +00:00

19 KiB

Investigation record lifetime verification

Verified on Linux with Node v24.22.1 and local Codex CLI 0.165.0 for #8347. The final production revision is 40ec9fe79b221b7550bf6a652f55389ea0b7e54f, including main d54a4661da20382ad8456564a08569fdd24131c5. Its runtime manifest SHA-256 is f4e55abdc5cb9fc2a86efcec5c410f2b5bc3eb5a7109a8d5ab88f07f8511c48b. Earlier measurements below identify their older revisions explicitly. Documentation was being updated during final qualification; production sources and runtime remained unchanged.

The MCP contract separates engine cleanup, investigation reset and explicit checkpointing. Automatic journaling remains tracked in #4809.

Response publication qualification

The request-publication correction is pinned to 40ec9fe79b221b7550bf6a652f55389ea0b7e54f. An MCP request now retains its originating session admission through handler cleanup and physical send settlement. Nested operations borrow that admission, avoiding reentry behind a queued reset. Cancellation before a suppressed send and during an already-started send have separate completion rules. Outgoing server requests cannot acknowledge an incoming tool response merely because their IDs coincide.

All nine genuine saved-source workflows were repeated: 313 MCP calls and 19 CLI checks, 114.210 s guarded elapsed, 109.411889 s CPU and 1,055,035,392 B maximum family peak. Complete original public results and source identities matched through close, checkpoint refusal, reset and same/fresh-process recovery; all Unknown histories were preserved. No producer replay, source/runtime changes, OOM or unresolved owned cleanup occurred. These runs have uncontrolled OS caches and are not a paired timing comparison with the earlier cohorts below.

A new local Codex CLI task requested gpt-6.1-terra/high with the scoped four-domain profile. It completed 25 MCP calls, including four expected missing-reference controls, with no producer replay. Usage was 232,677 input tokens including the 199,552 cached subset, 3,613 output tokens and 195 separately reported reasoning tokens; elapsed was 61.466 s, local CPU 11.031356 s and peak 806,146,048 B. Requested aliases do not establish the server-resolved model identity, and remote model compute is unmeasured.

An independent fresh stdio process authenticated that task's 21-record, three-revision checkpoint: 16,138,657 B, SHA-256 a4395246473397cdc9040cb643e3175fd6f8b24db40597f8b680f0e065643df5. Nine calls reproduced all four complete original results and source records and reexported byte-identical bundle bytes. This took 6.353 s elapsed, 6.060161 s CPU and 592,621,568 B peak, with verified cleanup and no OOM. Independent full-result/source/history authentication and manual answer review supported the model's stated conclusions. No task or model retry was needed in this cohort; separate checker and report-aggregation CPU was not measured.

The actual Ghidra healthy-engine control also passed on this runtime: 49 calls, 51.115 s elapsed, 50.000976 s CPU and 1,124,110,336 B peak. The verifier-owned JVM PID/start identity/process group, public analysis run and MCP client were the same across reset. Two explicit address_name queries returned identical Evidence; no dossier, inventory or decompile producer was replayed. Full checkpoint/history recovery and owned cleanup passed, with no OOM. This observes retained-engine behavior rather than a before/after speedup.

Across all three model cohorts, nine actual runs plus one prelaunch failure used 2,771,744 input tokens including the 2,468,608 cached subset, 23,334 output tokens and 1,035 separately reported reasoning tokens. Guarded elapsed totals 480.694 s and local CPU 87.103671 s; maximum family peak is 922,148,864 B. All earlier failed/partial attempts remain included. These are execution costs, not a paired model-token savings claim.

All nine controlled success/error publication cases passed. Reinstating only the old admission factory made both successful-publication cases fail at the original admission boundary; the corrected source was restored and all nine passed again. The final boundary run used 12.872 s elapsed, 12.647482 s CPU and 941,723,648 B peak. Existing lifecycle/deferred/shutdown tests passed 79/79; the full HTTP suite passed 74/74. These controlled seams establish ordering, separately from real application behavior.

CI also exposed the 1500-file JavaScript timeout fixture's retention headroom. At a 512 MiB parent heap, the original timeout exceeded the 10 MiB wire budget; fallback authentication projected 771,325,184 B against 411,666,312 B available and correctly refused. The transport/timeout fixture now uses a finite 1536 MiB parent heap while retaining all 1500 files and every recovery/query assertion. Its worker remains at 128 MiB; the separate memory-pressure case retains its 512 MiB parent. All three tests passed in 23.556 s elapsed, 22.989758 s CPU and 1,064,308,736 B peak, including a public assertion that retained records fit the fixed allowance. No production limit was raised for this fixture.

Earlier review qualification

Review corrections were qualified at clean 6d875b3ff73d40b365a713cf4ba69a10cca257b7, with runtime manifest SHA-256 328f05dc2d7b114c33dc0406e488c3046a43e1c12187e15ad9263be65df7cbaa. SDK error Evidence retention and reply publication now share session admission; reset retries the MCP artifact scope alongside process cleanup before saving or clearing. Controlled public MCP regressions cover both publication orderings, queued cancellation, terminal shutdown, ordinary export cleanup failure, mixed cleanup outcomes and scope reuse. Reinstating the former wiring made four of the five new regression cases fail; all five pass with the correction. Controlled waits also use bounded acknowledgements and release/join held work in finally.

The nine genuine saved-source cases below were repeated against this runtime: 313 MCP calls and 19 CLI checks, 118.510 s guarded elapsed, 114.859544 s CPU, and 1,065,390,080 B maximum kernel-family peak. Every complete original result, ID, source, coverage and Unknown revision chain matched through close, checkpoint collision refusal, reset, same-process import and fresh-process recovery. No producer or target open was replayed in this cohort. Input/checkpoint/runtime immutability and owned cleanup were verified, with no OOM. These normal workflows complement the controlled error/cleanup timing regressions; they do not reproduce those timing faults themselves.

One further local Codex CLI task requested gpt-6.1-terra/high with the scoped four-family code-mode profile. Its 25 MCP calls included four expected missing-reference controls and no unexpected model errors or producer replay. Independent full-result/source/history authentication and answer review supported the answer within its stated scope; it did not claim to query every other Unknown. The run used 58.269 s elapsed, 9.837083 s local CPU and 885,448,704 B peak, with 239,931 input tokens including 215,168 cached, 3,721 output tokens and 277 separately reported reasoning tokens.

A real fresh stdio client restored that same new checkpoint: 21 records and three Unknown revisions in 16,138,749 B, SHA-256 760fc74951abc292a3ff2fe1771391ac0d4345416b2345dfa4e85cbb6ce96181. Nine calls reproduced all four complete original results and source records, then reexported byte-identical bundle bytes. This took 5.443 s elapsed, 5.253212 s CPU and 595,218,432 B peak, with verified cleanup and no OOM. Two external-checker failures were preserved and corrected against actual event ordinals and query filter/paging semantics; neither required model or backend replay. Separate checker CPU and remote model compute were not measured.

Across those two earlier cohorts, eight actual model runs plus one prelaunch failure used 2,539,067 input tokens including the 2,269,056 cached subset, 19,721 output tokens, and 840 separately reported reasoning tokens. Guarded elapsed totals 419.228 s and local CPU 76.072315 s; maximum family peak remains 922,148,864 B. Initial failed/partial attempts below remain included. This is execution accounting, not a paired model-token performance comparison.

That runtime also repeated the actual Ghidra healthy-engine control: 49 calls, 44.333 s elapsed, 43.348651 s CPU and 1,093,464,064 B peak. The same verifier-owned JVM PID/start identity/process group, public analysis run and MCP client survived reset; two address_name queries returned identical Evidence. Startup-inclusive and warm requests took 24,953.573 ms and 6.762 ms respectively, without dossier, inventory or decompile replay. These are startup/reuse observations rather than a PR before/after speedup. Full checkpoint/history recovery and owned cleanup passed, with no OOM.

Initial main-integration workflows

Main was integrated in 4e20698b7b9883f659e445c059c011aa0e5de834, with runtime manifest SHA-256 ee23cbaf0ecbf8d896fb5dc7a88317e2ab8eb77bd3a4467bf5793c3471ca9c7d.

Nine genuine saved-source cases covered eight target families:

Family Actual source Saved-source bundle SHA-256
Native jq observations 0a3adad6ab39bfe29320e1f070a8e598382d2f17c4d6c19079bd6ff16dfe0937
JavaScript agent-browser 0.27.0 66232b6eb01b3dbf435949a1cd94cb2532b7f989b91cdf952a105b3cee231bda
Managed NuGet CLI, SDK 8.0.427 11ac63842299c0ac641a320ec9b2a5161b454a8a322d57724fd5f2ffb2fddfa4
Android NewPipe 0.29.1 fa499d0464a40ddc2f5159c893d68b8f50aa8e6d2b0080de22f2f3e5fc326825
Harmony Shark 1.0.8 APP 3a526ab0113f80ada26ff5a0631fc95dac91485946f20584fc5a76f5ee8eb880
Harmony Shark inner HAP 3431c0a347f331c3effacf7984ecb890f3fef46d8b00b03b50980023b065cd4a
Apple Rectangle 2.0.4 8daa6286b28aadf5ba0d41038046805e5c69874eaa0bc5daf0e265360fcae79d
WASM tree-sitter-css acb0cb6c3e0d520f83144e106e171c3ecebba70c5c0498bbb0113185a3e4bf95
Process Controlled jq captures 55da0f130dc2265aae54261d49949471e5c929163c2b7314b42e95df3325b739

Each case imported authenticated observations, composed exact retained references, closed without an active target, refused an existing checkpoint destination, saved and reset, checked missing references, and restored into the same process and a fresh public stdio MCP process. Complete original public results, source links, coverage and Evidence IDs matched throughout. Every case included an explicit analyst question with revisions 1→2; complete revision histories and mutation Evidence authenticated after recovery. Bundle hashes above identify the saved observations rather than release binaries. The actual jq target was /usr/bin/jq, SHA-256 90b1eef4498f31836342898fc6e97cfeb8a197c4366773a0fb120ae02a45ea52.

That cohort completed 313 MCP calls and 19 public CLI checks, without source producer replay. Summed guarded elapsed was 119.445 s and CPU was 115.040362 s; maximum kernel cgroup-family peak was 1,047,826,432 B. All pinned input/runtime hashes stayed unchanged, owned cleanup was verified, and no resource stop or OOM occurred.

A separate actual Ghidra 12.1.4 control reset while its jq engine remained open. The same verifier-owned JVM PID/start identity/process group, reported analysis run and MCP client survived reset. Two identical address_name queries at 0x104500 returned the same Evidence. The first request including startup took 21,023.963 ms; the post-reset request took 6.672 ms. This observes startup versus reuse, rather than a PR before/after speedup. No function dossiers or procedure inventories were regenerated. The complete close/checkpoint/import/fresh-process control used 49 calls, 39.351 s elapsed, 38.222523 s CPU and 1,094,340,608 B peak; reset acknowledged 15 records and three Unknown revisions with retained_target.

Earlier actual-provider controls also passed Ghidra→Rectangle provider-family switching and Rectangle→NewPipe target switching, with reset retaining the healthy second target. Those pre-sync runs preserved their complete original results and histories; they are separate from the latest-runtime qualification above.

Equivalent completed-task measurements

These pairs used exact baseline 60149282fcfc05ac32fbc94434c107710120da6f and implementation 3c9fb7f44a4496d18d893beb903c5f2ba68c06b4, before the later main integration. The baseline exported, closed and imported before reference composition; the candidate closed and reused references directly. Both returned the same complete original result for the same authentic inputs.

Saved source MCP calls, before→after Elapsed s CPU s Kernel-family peak B
Native 9→7 5.846→4.938 5.609106→4.760475 582,672,384→511,090,688
JavaScript 8→6 3.529→3.333 3.371675→3.163932 394,170,368→387,428,352
WASM 7→5 4.236→3.731 4.035871→3.520731 658,063,360→492,548,096

Each row is one sequential pair in fresh isolated processes. OS caches were uncontrolled; builds and fingerprinting were measured separately. These samples establish two fewer necessary calls, rather than statistical speedups or model token savings.

Initial Codex tasks

Local Codex requested gpt-6.1-terra with high reasoning. Native used the full advertised surface without an enabled-tool filter or exact-name guide, both before and after the latest main integration. JavaScript, packages and the mixed managed/WASM/process/Harmony task used explicit scoped diagnostic profiles. The mixed task used the existing experimental client code mode; its development warning was retained.

All four task scopes passed independent canonical bundle/history authentication, complete original-result comparison and final-answer review. These conclusions were checked separately from process exit and token accounting. Native's final 12 calls preserved the original comparison, acknowledged a 14-record/three-revision checkpoint, observed the expected missing-reference control, and restored both Unknown heads. The mixed model used 25 calls; a separate latest-runtime fresh stdio verifier used nine calls to restore its same 21-record/three-revision checkpoint, reproduce all four complete originals, and reexport byte-identical bundle bytes.

The initial cohort table includes all attempts, partial runs and the native task repeated after main integration:

Task/profile Input tokens (cached subset) Output tokens Elapsed s / CPU s Kernel-family peak B
Native, full discovery 841,133 (769,536) 4,326 101.845 / 18.383645 888,786,944
JavaScript, scoped 531,546 (452,224) 3,421 88.236 / 14.456771 922,148,864
Rectangle→NewPipe, scoped 629,186 (567,424) 4,384 108.062 / 22.589319 878,800,896
Four-family mixed, scoped code mode 297,271 (264,704) 3,869 62.816 / 10.805497 914,604,032

Seven actual model runs plus one prelaunch failure consumed 2,299,136 input tokens including the 2,053,888 cached subset, and 16,000 output tokens. Input already includes cached input. Reported reasoning output was 563 tokens, recorded separately. Canonical verification costs are separate from client/model costs. The latest SDK catalog had 234 tools and 3,919,838 JSON bytes; those representation bytes are not model tokens. No paired baseline model cohort ran, so these counters do not establish causal whole-task token savings.

Three failed or partial attempts were preserved:

  • Native's first attempt stopped before model/MCP launch because of a redundant template-only harness argument. Its 0.718 s/0.473821 CPU s remains included.
  • JavaScript saved its six-record/two-revision checkpoint before the isolated client denied binary_session. The harness approval was corrected; a new process restored the same checkpoint and identical trace without another producer or reset. Joint accounting includes 16 client attempts, 15 served calls and the client denial.
  • The package model selected an unsupported generic view for a derived Apple projection and stopped before checkpointing. Its continuation rehydrated original authenticated saved inputs after matching current IDs and observed summaries/projections, then used the correct projectors. Two inventory producers ran once total; one additional NewPipe metadata reopen restored active state. This qualifies explicit saved-source recovery. The first run's unsaved full inventory body was not directly transported or checkpointed.

Resource and regression boundaries

The genuine multi-domain/model workflows used --max-old-space-size=512 for MCP/CLI Node children; retention had no quota override. The controlled timeout fixture's separate parent allowance is documented above. An earlier cumulative default-policy control admitted all nine genuine bundles: 34 records, 87,532,230 estimated representation bytes against its observed 150,244,580-byte allowance. Exact duplicates did not grow committed state. This corpus did not reach default capacity; injected-policy regressions establish atomic refusal, metadata replacement accounting and budget release on reset.

Local checks passed across 43 focused source/public-boundary files, 533 distinct tests using each file's latest passing run, and 93 Python tests. The main integration specifically reran eight lifecycle/recovery files with 61 passing tests, including retained candidate cleanup failure/recovery and healthy-client preservation. Typecheck, bounded lint, formatting, module/architecture guards, documentation and production reachability passed. Controlled providers and failure seams qualify cancellation, late work and cleanup orderings separately from actual-provider observations.

Heavy tasks ran serially with one CPU, 4 GiB hard memory, 3 GiB early stop, zero swap and 192 tasks maximum. Kernel CPU and memory.peak were observed at payload exit while a cgroup observer remained alive. They include drivers/helpers and the observer, exclude preflight outside the guard, and are distinct from process RSS and retained-representation estimates. Failed model attempts, partial results, assessments and raw receipts remain local; binaries and authentication data are excluded from the repository.

Explicit acknowledged checkpoints qualify cross-process recovery. Uncheckpointed process loss, automatic journaling, parent-directory power-loss recovery, Windows, IDA/Hopper and a second actual deep engine were not qualified here.