Record & Replay

HORUS provides a record/replay system for capturing node execution and replaying it with tick-perfect determinism. This enables debugging workflows including time travel, mixed replay, and comparing behavior between runs.

Overview

The record/replay system supports:

  • Full recording: Capture entire system execution
  • Tick-perfect replay: Reproduce exact behavior deterministically
  • Time travel: Jump to any recorded tick
  • Mixed replay: Combine recorded nodes with live execution
  • Playback control: Speed adjustment, tick ranges

Enabling Recording

Via Builder API

Enable recording through builder methods:

use horus::prelude::*;

// Enable recording via builder API
let mut scheduler = Scheduler::new()
    .with_recording();

Via CLI

# Record during a run
horus run --record my_session my_project

When recording is enabled, the scheduler automatically captures each node's inputs, outputs, and timing.

Replaying Recordings

Full Replay

Replay an entire recorded session:

use horus::prelude::*;
use std::path::PathBuf;

// Load and replay an entire scheduler recording
let mut scheduler = Scheduler::replay_from(
    PathBuf::from("~/.horus/recordings/crash/scheduler@abc123.horus")
)?;
scheduler.run()?;

Time Travel

Jump to specific tick ranges during replay:

// Start at a specific tick
let mut scheduler = Scheduler::replay_from(path)?
    .start_at_tick(1500);

// Stop at a specific tick
let mut scheduler = Scheduler::replay_from(path)?
    .stop_at_tick(2000);

// Adjust playback speed (0.01 to 100.0)
let mut scheduler = Scheduler::replay_from(path)?
    .with_replay_speed(0.5);  // Half speed

Mixed Replay

Combine recorded nodes with live execution for what-if testing:

use horus::prelude::*;

let mut scheduler = Scheduler::new();

// Add replay nodes from recordings
scheduler.add_replay(
    PathBuf::from("recordings/Lidar@001.horus"),
    0,  // priority
)?;

// Add live nodes alongside
scheduler.add(live_controller).order(1).build()?;

scheduler.run()?;

Output Overrides

Override specific outputs during replay:

let mut scheduler = Scheduler::replay_from(path)?
    .with_override("sensor_node", "temperature", 25.0f32.to_le_bytes().to_vec());

CLI Commands

Record and replay from the command line:

# Start recording during a run
horus run --record my_session my_project

# List recording sessions
horus record list
horus record list --long  # Show file sizes and tick counts

# Show details of a session
horus record info my_session

# Replay a recording
horus record replay my_session
horus record replay my_session --start-tick 1000 --stop-tick 2000
horus record replay my_session --speed 0.5

# Compare two recording sessions
horus record diff session1 session2
horus record diff session1 session2 --limit 50

# Export to JSON or CSV
horus record export my_session --output data.json --format json
horus record export my_session --output data.csv --format csv

# Inject recorded nodes into a new run
horus record inject my_session --nodes camera_node,lidar_node
horus record inject my_session --all --loop

# Delete a recording session
horus record delete my_session
horus record delete my_session --force

Managing Recordings

// List all recording sessions
let sessions = Scheduler::list_recordings()?;

// Delete a recording session
Scheduler::delete_recording("old_session")?;

See Also