The past is programmable.

Wax is a language that makes any moment reproducible anywhere.

It embeds in your application and records everything needed to return to any moment. Later, write new code inside the replay to investigate things you never thought to log. Recordings replay byte for byte on any OS or CPU.

  • Inspect it.
  • Query it.
  • Replay it.
  • Change it.
  • Continue from anywhere.

Explore across time.

Wax remembers everything needed to reconstruct what happened. Add queries, mutation searches, and timing analysis after the run.

Plot a value you never logged

waxdbg recording query recording.wxs --file health.wax --range 18420:25780
ScanningGame.player.healthbetween frames 18,420 and 25,780
Player health reconstructed across a completed execution An illustrative step chart between frames 18,420 and 25,780 begins at 100 health, falls through several changes, briefly recovers to 81, then reaches zero. 10076518155230 FRAME 18,42020,26022,10023,94025,780 Player health reconstructed across a completed execution An illustrative step chart between frames 18,420 and 25,780 begins at 100 health, falls through several changes, briefly recovers to 81, then reaches zero. 10076518155230 FRAME 18,42025,780

Find every moment a condition held

waxdbg recording find recording.wxs --where "NearbyEnemyCount() >= 4" --ranges
3 matching ranges 4+ living enemies within 8m
  1. 0119,040 → 19,816peak 4
  2. 0221,284 → 22,160peak 6
  3. 0323,612 → 25,104peak 5

Watch every field change

waxdbg recording mutations recording.wxs @4f.target
Frame 22,1043 writes
  1. Starttarget = Player@2abefore first write
  2. 01
    Call stackEnemy.ClearTarget()Src/Enemy.wax:142:18loop · iteration 17Src/Enemy.wax:136:9Enemy.UpdateThreat()Src/Enemy.wax:93:11World.Tick()Src/World.wax:48:7
  3. 02
    Call stackDecoy.Redirect()Src/Decoy.wax:67:24loop · iteration 42Src/ThreatSystem.wax:109:7ThreatSystem.Resolve()Src/ThreatSystem.wax:118:14World.Tick()Src/World.wax:48:7
  4. 03
    Call stackEnemy.AcquireTarget()Src/Enemy.wax:155:12loop · iteration 17Src/Enemy.wax:149:9Enemy.UpdateThreat()Src/Enemy.wax:98:11World.Tick()Src/World.wax:48:7
  5. Endtarget = Player@2aafter last write

Step backward as easily as forward

waxdbg gui recording.wxs

Find slow frames you never timed

waxdbg recording frames recording.wxs --range 25778:25782

Query the past.

Write new code against any recorded moment. The original history stays untouched.

Robot 4 is boxed in. Was there a clear route out?

waxdbg recording query --frame 9371 --name Warehouse.ClearRoutes --args '{"robotId":4}'
Real world recording investigation

Change what happened.

Choose a recorded moment, change the state, inputs, or code, and run it again.

A recording forked into what happened and what changed An illustrative 12.8 megabyte recording containing 25,781 frames over 7 minutes 10 seconds is selected at a past moment and forked. State, inputs, or code change on the second path, which runs on beside the untouched original. recording.wxs 12.8 MB SIZE 25,781 FRAMES 07:10 DURATION SELECT FORK CHANGE RUN RUN WHAT HAPPENED WHAT CHANGED

Reproduce it anywhere.

Wax compiles to native code, WebAssembly, or portable C and runs close to native speed with recording active. Record on one target and replay identically on any other.

Consoles, embedded targets, and custom silicon build from the portable C output.

Give agents the full story.

Logs show what you thought to record. A Wax recording lets an agent inspect the complete execution and show you why something happened.

waxdbg — warehouse-controller.wxs

Find out why Robot 4 stopped.

Let me look through the recording.

waxdbg recording info warehouse-controller.wxs 3m 22s recorded

waxdbg recording find warehouse-controller.wxs --where "RobotStopped(4)" 1 match · frame 9,371

waxdbg seek warehouse-controller.wxs --frame 9371 state reconstructed

Robot 4 stopped at 02:36.18 after Pallet 12 entered its safety envelope, pushing the proximity reading to 0.18m, below the controller’s 0.20m threshold.

The controller behaved correctly. The causal chain began with the earlier routing decision at 01:20.00, which sent Pallet 12 into Robot 4’s aisle.

Recorded moment 02:36.18

Keep the code you have.

Wax is built to embed into other languages. Start with one system or slice that you want to record and leave the rest of your app as it is.

warehouse.wax

// Wax exposes this. Your program calls it directly.
api fn AssignDelivery(int32 robotId, float2 to) : bool { … }

// Output slots Wax writes each frame. Your program reads them.
api channel Status { float fps; int32 active; }

// Wax needs this from you. You write it, Wax calls it.
host fn EstimateTravelSeconds(float2 start, float2 destination) : float;

// Input slots your program sets each frame.
host channel Telemetry { int32? onlineRobots; }

Program.cs

// The compiler generated Wax.Warehouse from warehouse.wax.
var config = new Wax.Warehouse.Config { ArtifactDirectory = "Generated/csharp" };

// Hand over the host fn it declared.
config.HostFns.EstimateTravelSeconds = EstimateTravel;

using var warehouse = new Wax.Warehouse.App(config);
var api = warehouse.Api.Warehouse;

// Set the input slots, call in, read the output slots.
warehouse.Channels.Telemetry.SetOnlineRobots(2);
warehouse.Frame(() => api.AssignDelivery(4, new Float2(12.0f, 7.5f)));
float fps = warehouse.Outputs.Status.GetFps();

Host languages

The same declarations generate the same shapes in every one of them. No stringly typed API to keep in sync.

Embed Wax

Join the preview.

The preview is where it meets new hardware, different software, weird workloads, and anything else nobody thought to test for. Nobody is being charged for Wax until it has proven itself out in the world.