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

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:

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:

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:

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:

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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →