Origin Story

WTF is going on in this program?

Wax began with a question I kept asking throughout my career: Why is it so hard to reproduce what happened on someone else's machine?

The hardest bugs are almost never the convenient ones.

I've been building game engines and other software professionally and as a hobby since 2012, shipping across Windows, Linux, macOS, iOS, Android, and game consoles. The most infuriating bugs appeared on hardware I did not own, on a user's machine, in some headless CI build I couldn't inspect directly, or under some combination of inputs, timing, locale, save data, hardware, and game state that nobody could reproduce.

Sometimes just getting to the point where I could investigate was expensive. I needed the right version of the game, the matching source revision, the correct assets and build configuration, and ideally the same hardware. On large projects, compiling that build could take 45 minutes or more.

That was 45 minutes before I could even try a fix. And then maybe the bug would reproduce. Maybe it wouldn't. Bug reports rarely came with much to work with. If you were lucky, there was a screenshot. If you were really lucky, a video. Usually there was neither. So you tried to reconstruct what happened from whatever scraps you had.

There are tools for this. Logs, stack traces, core dumps, and debuggers are all wonderful technologies. Nowadays LLMs can help reason about the evidence you managed to collect. But the evidence is usually the problem.

Logs preserve whatever we predicted would matter. In a real-time system they are not free, so you choose what to record. Then a bug appears six months later and the one value you need is the one thing you did not log.

You're out of luck.

A core dump captures a moment. It can tell you a lot about the state of the program when it crashed, but almost nothing about how it got there. If the real cause happened five minutes earlier and only surfaced later, that history is gone.

And many of the worst bugs do not crash at all. The software just does something wrong. An interaction feels strange. A system arrives at an impossible state. Something works 99.9% of the time and then, under some weird sequence of events, it doesn't. Nothing fails loudly enough to leave behind an explanation.

Logs preserve predictions. Core dumps preserve one moment. Neither lets you move through what happened or investigate why. So debugging becomes an attempt to reconstruct a world that no longer exists: the exact program, assets, hardware, inputs, timing, and surrounding state. Even after assembling all of that, there is no guarantee the behavior will happen again.

That was the part I could never stop thinking about. When a program runs, an enormous amount of information passes through it. Then the program exits and almost all of it disappears. We keep a few breadcrumbs and try to infer the rest.

I kept wondering why execution itself had to be so ephemeral. Why couldn't I take what happened on somebody else's machine and bring it home? Why couldn't I inspect it later and ask questions I had never thought to prepare for? Wax grew from the belief that a program's execution should be a tangible thing you can bring home and poke at, not an event that happens once and disappears.

More, more, give me more

The obvious answer was to record more. More logs. More telemetry. Maybe a video of every session.

But a video only records the surface. It can show me that a character walked through a door or that a button did something strange. It cannot tell me which objects existed, how their state changed, what inputs the program observed, or which decision five minutes earlier led to what I was seeing now.

I did not want a video of the execution. I wanted the execution.

I wanted to move to any point in its history and have the program's world there in front of me. I wanted to inspect an object, follow it across time, visualize its data, and ask questions that did not exist when the program originally ran.

Then came the next question: if I could record an execution, why couldn't I change it too?

Why couldn't I return to an earlier moment, change an input or a piece of code, and follow what happened next? The original history should remain intact, but it should not remain inert. It should be a path I could explore, poke at, and branch away from.

That became the idea at the center of Wax. A completed execution should not be a dead artifact. It should be something programmable.

Unravelling the sweater

Once I started pulling on that thread, it reached into everything.

You cannot reliably replay a program if the same inputs produce different results on another CPU or operating system. You cannot reconstruct its state if some of that state lives in memory the runtime does not understand. You cannot reproduce what the outside world told it unless every crossing into that world is explicit. You cannot ask new typed questions later if the recording no longer knows what its data meant.

This was not going to be a recorder bolted onto C++.

The language, compiler, runtime, memory model, host boundary, recording format, replay engine, and Inspector all had to be designed as parts of the same system. Each decision closed another place where information could disappear or behavior could drift between machines.

That is why Wax is a language, not only an Inspector. The language is what makes the promise possible.

A Wax recording preserves the program's retained state and the outside values it observed. The Inspector can reconstruct completed frames, inspect historical objects, and compile new queries against the source bundled into the recording. The question no longer has to exist before the program runs. You can write it after the fact.

Logs ask you to predict the future question. Wax is built so you can ask it later.

Give the machine a time machine

As AI became capable of reading and writing serious amounts of code, another gap became obvious to me.

AI is very good at producing plausible explanations. Give it a bug report, a screenshot, a stack trace, and a codebase, and it can tell you what might have happened. Sometimes it will be right. But it is still reconstructing a missing execution from clues, just like the rest of us.

The problem is not always a lack of intelligence. Often it is a lack of access. No amount of reasoning can recover a fact that was never captured, and a sufficiently clever guess is still a guess.

What if AI did have the right data? What if it could work with that data directly, through code and structured tools, instead of operating a GUI built for a human?

What if it had control over time?

It could independently rewind the execution that actually happened, replay it, inspect the state at any retained frame, insert a new query, visualize the data, test a hypothesis, and compare the result. It could investigate the weird behavior itself instead of asking a developer to reproduce it or add another log statement.

Debugging could become a loop the AI drives for itself: form a hypothesis, write a query, test it against the actual history, inspect the result, and refine the next question.

Then it could reason from what actually happened, not only guess about what might have happened.

There is another part of this that matters to me: trust.

AI can give an explanation that sounds completely convincing and still be wrong. I do not want to trust an answer because it is written confidently. If an AI says an object changed on frame 4,218, it should be able to point to that object, that frame, and the writes that changed it. If it says a piece of code caused the problem, I should be able to run the same query and check.

I do not want an AI that is better at convincing me it found the answer. I want one that can show me what it found.

That idea changed what I thought developer tooling could become. A recording could be more than evidence for a human looking backward. It could be an environment in which people, tools, and AI actively investigate the past.

Passion and obsession

Wax has been a solo project for more than three years. From the first day, it has been equal parts passion and obsession.

I kept building because I could not let go of the original question. One answer required another: the language needed a compiler, the compiler needed a runtime, the runtime needed deterministic boundaries, recordings needed replay, and replay needed tools capable of doing something useful with it.

What began as frustration with bugs I could not reproduce grew into the language, compiler, runtime, recording system, replay engine, and Inspector I wished I had throughout my career.

Why it is called Wax

The technology came from that obsession. The name comes from somewhere more personal.

Wax was my dad's childhood nickname. It has nothing to do with candles or wax as a material.

He has been my mentor, my role model, my friend, and my biggest fan for my entire life.

He was diagnosed with pancreatic cancer more than four years ago and has since undergone more than sixty rounds of chemotherapy. The resilience he continues to show throughout this ordeal is extraordinary.

Keep fighting, Dad. This is my tribute to you, your strength, and everything you mean to me.

With love.

-- Matt