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.zigimplements theSessionRecorderstruct, which writes events, checkpoints, screenshots, and effects to aRecorderSink. It exposesfinish()andfail()helpers to guarantee a clean shutdown of the recording session.src/runtime/api.zigstores a nullablesession_recorderpointer 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.ziginitializes the recorder viasetupSessionRecorderat app startup and tears it down viafinishSessionRecorder. The recorder is attached toAppInfoso the entire app lifecycle participates in the journal.tools/native-sdk/automation.zigexposes the CLI entry pointnative automate. It parsesrecordandreplaysubcommands, injects theNATIVE_SDK_SESSION_RECORDenvironment 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, andmarkup_e2e_tests.zigcreate aSessionRecorder, drive a deterministic UI flow, and assert that a second replay yields exactly the same snapshot usingexpectEqualDeep.
How the Deterministic Record/Replay System Guarantees Determinism
The system enforces strict reproducibility through four core mechanisms.
- Full Capture – Every
platform.Eventandruntime_effects.EffectResultRecordis serialized into the journal with a prefixedRecordKindenum, 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, andtools/native-sdk/automation.zig. - It captures all platform events and runtime effects into a binary journal prefixed by
RecordKindheaders. - 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 viaexpectEqualDeep.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →