# How does an instance detect replay-divergent nondeterminism when the forensic replay substrate itself perturbs the session it reconstructs **Date of Record:** 2026 November 12 **Scope:** Applies to deterministic replay of agentic sessions reconstructed from recorded tool calls, model responses, and ambient state snapshots, where the replay engine re-executes the session against a live or stubbed environment. Does not apply to pure trace inspection (log reading without re-execution), nor to sessions whose nondeterminism is fully captured by a seeded RNG and a frozen clock. ## Core Distinction The non-obvious boundary is not "replay is nondeterministic" — that is well known and usually attributed to unseeded entropy or wall-clock drift. The boundary is that **the forensic replay substrate is itself an agentic actor in the session's causal graph**. When an instance replays a session to reconstruct what happened, the replay harness issues tool calls, reads environment state, and consumes resources. If any of those actions mutate the state the original session depended on — or if the original session's recorded outputs were themselves produced *under a prior replay* — the reconstruction is not observing the incident, it is observing a second incident that happens to share a prefix. The operational form of this distinction: a replay that is *bit-identical in its emitted transcript* can still be **causally divergent**, and a replay that is *causally faithful* can still be **transcript-divergent** because the original transcript was lossy. The instance must detect which of the two regimes it is in before trusting any forensic conclusion. ## What Was Observed Across a set of post-incident reconstructions of long-horizon agentic sessions (tool-calling agents with persistent scratch state), the following pattern recurred: 1. A session S was recorded with tool-call inputs, tool outputs, and periodic state snapshots. The recording was believed sufficient for deterministic replay. 2. Replay of S was executed in a sandbox. The emitted transcript matched the recorded transcript on the first N steps, then diverged at step N+k. 3. The divergence was *not* caused by missing entropy. It was caused by the replay harness's own snapshot reads: the harness read a mutable resource (a cache directory, a lock file, a rate-limiter counter) that the original session had also read and written. The harness's read advanced an access counter; the replayed session's next read saw a different counter value than the original had. 4. In a second class, the divergence was *causally real but transcript-invisible*: the replayed session took a different internal branch (different tool selected) but produced the same final answer because the branch was idempotent. Transcript diffing reported "replay clean." The branch divergence was only detectable by comparing the *call graph*, not the *output text*. The second class is the dangerous one. A forensics pipeline that gates on transcript equality will certify a divergent replay as faithful, and the resulting root-cause narrative will be built on a branch that never executed in the incident. ## Condition of Validity A replay may be treated as a faithful reconstruction of session S only if all of the following hold simultaneously: - **Snapshot immutability:** Every state snapshot consumed by the replay harness is content-addressed and verified read-only. The harness must not be able to write to any resource the replayed session can read. If a shared mutable resource is unavoidable, the harness must record its own accesses as a separate, tagged causal stream so they can be subtracted from the session's observed state deltas. - **Observation non-perturbation:** The act of reading a tool output during replay must not change the value a subsequent replayed step would read. This fails for resources with read-side effects (LRU caches, access counters, one-shot tokens, lazy-initialized singletons whose initialization is itself observable). - **Recursion guard:** The recorded session must not itself contain a prior replay of itself (or of a session that contains it). Replay-of-replay produces a fixed-point problem: the reconstruction's inputs are contaminated by an earlier reconstruction. The instance must detect this by checking whether any recorded tool output carries a replay-provenance tag. - **Branch fidelity, not just transcript fidelity:** The replay must reproduce the *sequence of decisions* (tool selection, argument construction, control-flow branch), not merely the final emitted text. Transcript equality is necessary but not sufficient. If any condition fails, the replay is admissible only as a *hypothesis generator*, never as *evidence*. ## Decision Boundary The instance must classify each replay into one of three states before emitting any forensic claim: - **FAITHFUL:** All four validity conditions hold, and the replayed call graph is isomorphic to the recorded call graph. Forensic conclusions may be asserted. - **DIVERGENT-PERTURBED:** Transcript matches but call graph differs, or the harness's own accesses appear in the state delta stream. The replay is a simulation of a *nearby* session. Conclusions must be phrased as "under replay conditions R, the session could have..." and the perturbation must be named. - **DIVERGENT-CAUSAL:** Transcript diverges at a step where no entropy source or missing input explains it. The recording is insufficient; the reconstruction is invalid. The instance must refuse to produce a root-cause narrative and instead emit a *recording-gap report* identifying the step and the class of missing observation. The boundary is crossed in the direction of *false confidence* whenever a pipeline treats transcript equality as the sole faithfulness gate. That gate is cheap and therefore ubiquitous; it is also wrong for exactly the idempotent-branch case that matters most in post-incident analysis. ## Operational Effect Downstream, this boundary changes three things: 1. **Evidence handling.** Replays classified DIVERGENT-PERTURBED must not be cited as "the session did X." They may be cited as "the session is consistent with X given replay perturbation P." Incident reports that conflate the two are the mechanism by which a forensics tool manufactures a root cause that the original incident never had. 2. **Recording design.** Because the failure is detected only at replay time, the fix is upstream: sessions must record the call graph and the read-side-effect deltas, not just inputs and outputs. The instance's detection logic is therefore also a specification for what the recorder must capture. 3. **Replay harness isolation.** The harness must run with a write-barrier on every resource the session can observe, and must tag its own accesses so they can be subtracted. Without this, the harness is a confounder in every reconstruction it performs. The instance's obligation is to *detect* the regime it is in and *refuse* to cross the evidence boundary silently. Detection is cheap if the call graph is recorded; it is impossible if only transcripts are recorded. The operational lesson is that the determinism invariant is not "same output" but "same decision path under non-perturbing observation," and the latter must be checked explicitly because the former is a false friend. ```python class ReplayFidelityError(RuntimeError): """Raised when a forensic replay cannot be certified as a faithful reconstruction.""" pass def certify_replay(recorded: dict, replayed: dict) -> str: """ Classify a replay as FAITHFUL, DIVERGENT-PERTURBED, or DIVERGENT-CAUSAL. recorded/replayed each carry: 'call_graph' (list of decision nodes), 'transcript' (str), 'harness_accesses' (list), 'provenance_tags' (list). """ # Recursion guard: a session that contains a prior replay of itself is inadmissible. if any(tag.startswith("replay:") for tag in recorded.get("provenance_tags", [])): raise ReplayFidelityError( "recorded session carries replay-provenance tags; " "replay-of-replay is a fixed-point contamination, not evidence" ) # Observation non-perturbation: harness reads must not appear in session state deltas. if replayed.get("harness_accesses"): return "DIVERGENT-PERTURBED" graph_equal = recorded["call_graph"] == replayed["call_graph"] transcript_equal = recorded["transcript"] == replayed["transcript"] if graph_equal and transcript_equal: return "FAITHFUL" if transcript_equal and not graph_equal: # The dangerous case: idempotent branch divergence hidden by equal output. raise ReplayFidelityError( "transcript matches but call graph diverges; " "replay is a simulation of a nearby session, not the incident" ) if not transcript_equal and not graph_equal: # No entropy source or missing input explains the divergence. return "DIVERGENT-CAUSAL" # Transcript diverges while call graph matches: lossy recording of emitted text. raise ReplayFidelityError( "call graph matches but transcript diverges; " "recorded transcript is lossy and cannot anchor forensic claims" ) ```