# How the Native SDK Deterministic Record/Replay System Works for Testing and Debugging

> Understand how the Native SDK's deterministic record replay system captures user interactions and events for byte-identical testing and debugging without host OS interference.

- Repository: [Vercel Labs/native](https://github.com/vercel-labs/native)
- Tags: internals
- Published: 2026-07-18

---

**The Native SDK's deterministic record/replay system captures every user interaction, framework-level effect, and platform event into a binary journal, then replays that journal to drive byte-identical execution paths without any host OS interference.**

The `vercel-labs/native` repository implements this engine in Zig as a foundational tool for reliable end-to-end testing and debugging. By serializing the complete timeline of runtime effects and re-injecting them during replay, the system eliminates nondeterministic host behavior and enables reproducible snapshot validation across platforms.

## Core Architecture of the Deterministic Record/Replay System

The deterministic record/replay system is composed of several tightly integrated modules across the runtime, app launcher, and test harnesses.

- **`src/runtime/session_record.zig`** implements the `SessionRecorder` struct, which writes events, checkpoints, screenshots, and effects to a `RecorderSink`. It exposes `finish()` and `fail()` helpers to guarantee a clean shutdown of the recording session.
- **`src/runtime/api.zig`** stores a nullable `session_recorder` pointer in the runtime options. When this pointer is set, all high-level API calls delegate to the recorder for automatic logging.
- **`src/app_runner/root.zig`** initializes the recorder via `setupSessionRecorder` at app startup and tears it down via `finishSessionRecorder`. The recorder is attached to `AppInfo` so the entire app lifecycle participates in the journal.
- **`tools/native-sdk/automation.zig`** exposes the CLI entry point `native automate`. It parses `record` and `replay` subcommands, injects the `NATIVE_SDK_SESSION_RECORD` environment variable, and forwards the app command to the launcher.
- **End-to-end test suites** in files such as `tests/ts-core/system_monitor_e2e_tests.zig`, `soundboard_e2e_tests.zig`, and `markup_e2e_tests.zig` create a `SessionRecorder`, drive a deterministic UI flow, and assert that a second replay yields exactly the same snapshot using `expectEqualDeep`.

## How the Deterministic Record/Replay System Guarantees Determinism

The system enforces strict reproducibility through four core mechanisms.

- **Full Capture** – Every `platform.Event` and `runtime_effects.EffectResultRecord` is serialized into the journal with a prefixed `RecordKind` enum, ensuring no interaction is lost between record and replay.
- **No Host Calls** – During replay, the engine never touches the host OS. All external side effects are re-injected from the recorded binary journal, preserving the identical sequence of calls.
- **Byte-Identical Snapshots** – Tests compare snapshots taken after a record run with snapshots taken after a replay run via `expectEqualDeep`. These snapshots include frame counts, effect results, and screenshot hashes to prove exact reproducibility.
- **Checkpoint / Fingerprint** – The recorder injects deterministic checkpoints via `recordCheckpoint`, allowing the replay engine to verify mid-flight that execution remains on the expected path.

## Recording and Replaying Sessions

Developers can interact with the deterministic record/replay system through CLI commands or by embedding the recorder directly into Zig test code.

### Recording a Session from the CLI

To capture a session, run the `native automate record` command and specify an output journal file:

```bash
native automate record --out my-session.journal -- ./zig-out/bin/my-app

```

The `automation.zig` source detects record mode, sets the `NATIVE_SDK_SESSION_RECORD` environment variable, and calls `setupSessionRecorder` before the app starts. The recorder writes a header containing the platform name, app name, and window dimensions, followed by every subsequent event.

### Replaying a Session from the CLI

To replay a previously captured journal, use the `replay` subcommand:

```bash
native automate replay --in my-session.journal -- ./zig-out/bin/my-app

```

During replay, the runtime reads the binary journal and feeds each stored event back into the engine. No real user input is required, and the app executes the exact same code path as the original session.

### Embedding the Recorder in Zig Tests

You can attach a `SessionRecorder` directly to a test harness for programmatic validation. The following pattern, derived from `system_monitor_e2e_tests.zig`, demonstrates how to initialize the recorder, drive a UI flow, and flush the journal:

```zig
const SessionRecorder = native_sdk.runtime.SessionRecorder;

fn recordSession(buffer: *JournalBuffer) !MySnapshot {
    const recorder = try std.heap.page_allocator.create(SessionRecorder);
    defer std.heap.page_allocator.destroy(recorder);
    recorder.* = SessionRecorder.init(buffer.sink());

    recorder.begin(.{
        .platform_name = "test",
        .app_name = "my-test-app",
        .window_width = 800,
        .window_height = 600,
    });

    const harness = try Harness.createRecorded(recorder);
    defer harness.deinit();

    recorder.finish();
    try std.testing.expect(!recorder.failed);
    return MySnapshot.take();
}

```

## Verifying Byte-Identical Results in End-to-End Tests

The definitive proof of determinism comes from recording the same flow twice and asserting that both runs produce identical snapshots, as shown in the soundboard end-to-end tests:

```zig
test "deterministic replay of a soundboard session" {
    const recorded = try recordSession(buffer);
    const recordedAgain = try recordSession(secondBuffer);
    try std.testing.expectEqualDeep(recorded, recordedAgain);
}

```

Because the journal contains every effect and event, `expectEqualDeep` confirms that frame counts, effect results, and internal state match perfectly between the original recording and the replay.

## Summary

- The Native SDK deterministic record/replay system is implemented across `src/runtime/session_record.zig`, `src/runtime/api.zig`, `src/app_runner/root.zig`, and `tools/native-sdk/automation.zig`.
- It captures all platform events and runtime effects into a binary journal prefixed by `RecordKind` headers.
- Replay re-injects the journal directly into the engine without contacting the host OS, ensuring identical execution.
- End-to-end tests in `tests/ts-core/` validate determinism by comparing deep snapshots via `expectEqualDeep`.

## Frequently Asked Questions

### What file format does the Native SDK use for recorded sessions?

The Native SDK writes a binary journal file that consists of a header followed by sequential records. Each record is prefixed with a `RecordKind` enum value such as `event`, `checkpoint`, `screenshot`, or `effect`, and the entire stream is flushed to disk via the `RecorderSink` defined in `src/runtime/session_record.zig`.

### How does replay avoid nondeterministic host behavior?

During replay, the runtime disables all live host OS calls. Instead, it reads the stored journal and pushes each serialized `platform.Event` and `runtime_effects.EffectResultRecord` back into the engine. Because the execution tree consumes only pre-recorded inputs, external timing or hardware differences cannot alter the outcome.

### Which source files should I read to understand the record/replay implementation?

The core logic lives in `src/runtime/session_record.zig`, which defines `SessionRecorder` and `RecorderSink`. Runtime hook integration is in `src/runtime/api.zig`, app lifecycle setup is in `src/app_runner/root.zig`, and the CLI interface is in `tools/native-sdk/automation.zig`.

### Can this deterministic record/replay system be used for visual regression testing?

Yes. Because the recorder captures screenshot hashes and frame counts inside the journal, end-to-end tests can assert byte-identical rendering across record and replay runs. The test suites in `tests/ts-core/system_monitor_e2e_tests.zig` and related files already use this property to validate stable visual output across platforms.