Time-travel debugger
Record the app's ChangeEvent timeline and scrub a table's rows back and forward through it — read-only point-in-time replay, env-gated + redacted, surfaced in the DevTools / cloud Time-travel panel.
The time-travel debugger records the app's ChangeEvent stream into a bounded, redacted ring and lets you scrub any table's rows back and forward through it — replaying what the data looked like at any recorded point. Read-only: replay reconstructs a row-set by reversing the recorded changes over the live rows; it never writes.
Turn it on
Recording is env-gated and off by default in production (volume + PII are
the real cost — use OTLP for prod forensics). Set VOLTRO_TIMELINE:
| value | records |
|---|---|
off (also 0 / false) |
nothing |
interesting (also on / 1 / true) |
user tables only (skips _voltro_* framework noise) |
all |
every table (except the timeline's own writes) |
The default is interesting outside production, off in production — the same
environment-aware default the durable trace persistence uses.
Sensitive-looking columns (password / secret / token / api_key /
authorization / cookie / ssn / credit_card / cvv / …) are redacted
before a row enters the ring — PII never sits in the debug buffer.
Scrub it
Open the Time-travel panel in the DevTools dashboard (or the cloud dashboard, for a deployed app): pick a table, drag the scrubber across the recorded sequence, and the panel reconstructs that table's rows as of the selected point. The event log shows every recorded change; click one to scrub to just before it. "Jump to now" returns to live.
The endpoint
The panel reads two read-only inspect endpoints:
GET /_voltro/inspect/timeline— the recorded events (?table=&tenantId=&from=&to=&limit=) plus the current sequence (currentSeq).GET /_voltro/inspect/timeline/replay?table=<t>&seq=<n>—<t>'s row-set as of sequence<n>.
# Gated by the same inspect auth as every /_voltro/inspect/* endpoint.
curl "http://localhost:4000/_voltro/inspect/timeline?table=todos&limit=50"
curl "http://localhost:4000/_voltro/inspect/timeline/replay?table=todos&seq=42"Limits
- Read-only. Time-travel never writes — restoring a past value is the universal-undo primitive's job (and only for safe inverses).
- In-memory ring (bounded, per-process) in v1 — it is for scrubbing recent history, not durable forensics: it resets on restart, and a replay is correct only as long as the events after your target sequence are still in the ring.
- The inspect surface is a
voltro dev/ DevTools concern; out-of-band DB writes (not in the app's ChangeEvent stream) aren't recorded, and production should use OTLP for forensics.