Automatic desync reports
The current protocol 9 candidate collects a report when the relay emits its existing persistent-mismatch notice. It freezes the opaque session, original connection IDs for every admitted slot, compared hashes, receipt sequences/times and comparison sequence. The agreeing friend also participates. Receipt counts are relay observations, not proof of fresh native frames or completed room arrival.
Every expected runtime copies its own bounded metadata, runtime output tail, explicitly registered inject-log tail and one screenshot. It uploads actual bytes over authenticated ENet connections; the relay never follows peer paths. Diagnostic packets 30/31/32 use reliable channel 2; gameplay keeps channels 0/1. Protocol 6 introduced these diagnostics; protocols 7 through 9 retain their layouts. Protocol 7 added ordered enemy HP (HP_ORDERING.md); protocol 8 introduced the separate forced-resync transaction (FORCED_RESYNC.md). All components need matching protocol 9. AvatarBridge 2 and CaptureChannel 1 remain unchanged; WorldBridge 11 carries captured world context and the separate operator mailbox. Diagnostic collection itself does not mutate native world state.
The server defaults to build/rig/desync; --desync-dir <path> changes its
aggregate root. Runtime defaults to build/rig/desync-local; its
--desync-dir <path> changes the local spool. Pass --inject-log <exact-path>
from the launch result. INI keys are desync_dir and inject_log. Missing
registration produces an explicit unavailable artifact; there is no environment
dump, directory scan or guessed PID log. The scenario runner registers each
owned launch log and supplies separate aggregate/local directories within its run.
The relay writes <root>/<session>/<report-id>/trigger.json, relay.log,
manifest.json and numeric peer artifact filenames. It persists the initial
trigger before emitting requests, then publishes a final manifest. A killed
relay may leave a collecting manifest; scenario linkage presents it as partial.
Per-session suppression-summary.json separately records skipped triggers,
bounded witnesses, overflow and storage/backpressure facts. It does not certify
a report or change a finalized manifest. Filesystem failures are surfaced in
relay status/logs even if no artifact could be written.
The summary has one asynchronous writer and one coalesced pending snapshot; it can lag the latest trigger. It retains the first 16 witnesses with overflow counts. A dirty summary for an earlier session cannot be silently replaced: cross-session triggers that cannot be retained increment the lost-trigger count and preserve the last lost key/time. Arbitrary session churn is not loss-free.
Collection has a fixed 30-second relay deadline. Time spent persisting the trigger reduces the request's remaining lifetime. Peer clocks are independent; waiting for a matching roster or finishing local collection grants no extra time. One report is active at a time, with a 60-second start cadence and eight reports per session. Extra trigger witnesses are bounded to 16 with overflow counts. Each peer has a 512 KiB aggregate log/metadata allowance and a 16 MiB raw PNG allowance. Uploads emit at most four 16 KiB chunks per 16 ms without catch-up bursts. Byte counts, contiguous offsets, descriptor ranges and exact raw-byte SHA-256 are checked; conflicting or incomplete data remains partial.
Capture uses only the runtime's attached PID and existing CaptureChannel. Automatic collection and CLI capture/clip share a per-PID named caller mutex. Busy or abandoned ownership is explicit. The lease spans submission through completion/timeout; an outstanding timed-out mailbox sequence prevents reuse. The requester does not replace that request or force an overlay. Capture requires the exact checked request/done sequence, success status, one frame, dimensions and its generated output file. Attempt metadata retains those witnesses, including renderer/format and failure facts. Missing attachment or generation still permits logs/metadata, with screenshot unavailable.
Local work uses one owned collector thread. The default local deadline is five seconds, bounded to eight and the original request lifetime, leaving time to upload. Tick never waits for disk/capture. If OS I/O outlives that deadline, Tick publishes timeout status and leaves the one worker busy until it returns. Late raw files stay local and cannot upgrade the final contribution. Shutdown joins owned work; a stalled OS operation can delay shutdown. Relay persistence and coalesced suppression-summary writes are also bounded asynchronous work.
complete means every original participant supplied all required artifacts
with checked transfer integrity and bounded PNG structure/CRC. PNGs are not
decompressed by the relay. Truncated tails are identified by ranges and source
sizes; they are not whole histories. Screenshots and metadata are not an atomic
cross-machine snapshot. Transport integrity and a claimed capture witness do
not establish native provenance, convergence or multi-PC acceptance.
Offline controls use the production collector, uploader, relay and actual ENet
senders with owned temporary logs, synthetic mailboxes/providers and real PNG
bytes. kh2coop_desync_test checks assembly, framing, identity and lifecycle;
Windows kh2coop_desync_collector_test checks capture/lease handling. The actual
runtime smoke uses --pid 0, which returns before process enumeration or
OpenProcess, and verifies its transferred logs/metadata plus unavailable PNG.
Prepared scenario linkage controls invoke no CLI. The frozen protocol 6
build/test evidence is recorded in build/rig/desync_offline_receipt_20261003.json.
In that frozen protocol 6 result on 2026-10-03, Release and Windows ASan each passed 1,353 controls: 596 desync, 119 capture/lease, 202 world, 127 recovery, 146 avatar, 85 simulation, 61 bridge and 17 activation. Portable ASan+UBSan passed 1,027 controls (596 desync, 202 world, 127 recovery, 85 simulation and 17 activation); Windows mailbox and avatar/bridge controls are excluded there. All three actual runtime smoke checks passed, as did nine prepared scenario linkage cases. No sanitizer finding was observed. Builds included current runtime/relay, tools and both Windows DLLs; no DLL was installed or exercised against KH2. Source reviews and retained initial compilation/test failures are part of the receipt evidence.
The frozen protocol 7 HP ordering receipt is
build/rig/hp_order_offline_receipt_20261003.json. It re-executed all 596 desync
controls in Release, Windows ASan and portable ASan+UBSan, plus 119 Windows
capture/lease controls per Windows configuration, nine scenario linkage cases
and all three actual unattached runtime reporting smoke checks. No sanitizer
finding was observed; native/remote limits are unchanged.
Local native renderer evidence, 2026-10-03
The automatic report in
build/scenarios/20261003-135207_net_forced_resync_native_shadows_1/
retained all three original local peers, connections 1/2/3. Each supplied a
1920x1080 native renderer PNG with nonzero attached PID, stable generation and
matching request/done sequence. Saved local and relay copies matched all twelve
artifact byte counts and SHA-256 digests. Independent PNG framing, CRC and
bounded decompression checks passed; visual inspection shows the courtyard and
Shadows on all three captures. These captures are sampled observations, not an
atomic gameplay comparison or proof of health/population agreement.
The final aggregate correctly remained partial: slot 1's inject log changed
during capture and retains Interrupted status. The intact transferred bytes
do not establish a stable source tail. No participant was removed to complete
the denominator. See build/rig/resync_shadows_auto_report_review_20261003.md.
The enclosing scenario remains failed at positive point stability before any
forced-resync command; automatic diagnostics do not imply automatic recovery.
The later passing population run 20261003-140717 supplied a separate
complete report 1 from its original connections 1/2/3. All twelve bounded
metadata/log/PNG artifacts had complete source status, matching local/relay
bytes and digests, and successful native capture witnesses. All three 1920x1080
PNGs passed independent integrity/decompression checks. The run-level index
correctly remains partial because one active and two cadence-limited triggers
were suppressed; those witnesses remain visible. A complete original request
does not erase skipped later requests or prove whole-run log history.
See build/rig/resync_population_captures_review_20261003.md.
That run also saved three final explicit PNGs after native resync checks. Their stored step results contain only path and PASS, so final request/done sequence and renderer receipts are unavailable. Earlier automatic capture witnesses cannot supply those missing final-capture facts.
The progress-fault retry 20261003-152248 provides a further complete report
1 with the same original three local connections 1/2/3. All twelve bounded
artifact descriptors, local copies, hashes and native capture witnesses match.
Each automatic screenshot has matching request/done sequence 35 and stable
observed generation 2. The enclosing index remains partial for five
cadence-suppressed triggers; report completeness does not erase those gaps.
Its three separate final explicit captures retain the new CLI completion
receipts: exact native PID/path, request/done 36, status 0, one frame, renderer
12, format 87 and 1920x1080. All six distinct final/automatic PNGs pass independent
CRC, exact-end and bounded decompression checks. These sequential captures
carry no native frame or world-generation attestation; the earlier automatic
metadata cannot fill those fields. See
build/rig/resync_progress_native_captures_review_20261003.md.
This establishes three local renderer contributions and one complete bounded automatic transaction on one loopback rig. Physical remote delivery and full native recovery remain open. This feature does not resync gameplay or remove the fresh-actor anti-refill guard.
