Replay
The ledger is the source of truth. Entity snapshots, projection tables, and query results are all derived — they can be rebuilt or inspected by re-processing history. Because rules are deterministic, the same event sequence always produces the same outcome.
Use this page when a workflow failed halfway and you need to inspect → fork → replay → repair without guessing from logs.
Live timeline / replay tooling requires Causet Cloud (Early access) today. See What runs today?.
Failed workflow walkthrough
Example: access request notification failed after approval.
request submitted ✓ access_requested
approval succeeded ✓ access_approved
notification failed ✗ notification_failed
projection stale status still pending_notification1. Inspect the timeline
causet inspect timeline --stream access_request_stream --entity ar_123Or open Decision Timeline in the control plane. Confirm which events committed and which side effect failed. See Timeline.
2. Understand event history
| Cursor | Event | Meaning |
|---|---|---|
| 1 | access_requested | Intent accepted |
| 2 | approval_required | Waiting on approver |
| 3 | access_approved | Approval succeeded |
| 4 | notification_failed | Email/Slack step failed |
Entity state may show approved while your app DB / projection still shows pending_notification.
3. Simulate a failure
On a fork (not main):
- Branch from the cursor after
access_approved - Force or re-run the notification path with a bad provider / mock failure
- Confirm
notification_failedappears and the projection lags
This teaches the team what the timeline looks like before a production incident.
4. Fork from a known point
From Decision Timeline → Branch from cursor, or create a sandbox fork. Explore repairs without touching production.
5. Replay with corrected input
- Fix the notification template / provider config
- Re-submit a guarded notification intent on the fork (idempotent)
- Or rebuild the entity snapshot / projection after deploying corrected handlers
Gate side effects with is_replay or idempotency keys so you do not double-email on main.
6. Repair downstream projection state
If the read model is stale:
- Deploy corrected projection IR if the bug was in
derive/ handlers - Rebuild the projection from the ledger (UPSERTs are idempotent)
- Optionally update your existing app DB from the repaired events (webhook/consumer bridge)
Do not treat a one-off SQL UPDATE as the long-term fix — the ledger should remain the source of truth.
What replay means in Causet
| Kind | What it does | Where |
|---|---|---|
| Point-in-time inspect | View entity state as it was at a specific cursor | Entity Inspector replay scrubber |
| Snapshot rebuild | Re-apply ledger history to fix a corrupted entity snapshot | Entity Inspector → Rebuild, or platform API |
| Projection rebuild | Re-consume the event stream to refresh read-model tables | Projection worker (ops) — see Schema Versioning |
| Decision replay | Re-run or compare execution from a cursor for forensics | Decision Timeline → Replay |
| Fork from cursor | Branch timeline exploration without affecting production | Decision Timeline → Branch |
The source of truth
Everything downstream of commit is derived:
- Entity snapshots — materialized state per stream/entity/fork
- Projection tables — read models for named queries
- Vector memory — re-ingested from source events
If derived state is wrong or missing, replay from the ledger. The ledger itself cannot be reconstructed from snapshots or projections — protect it accordingly.
Entity Inspector: live vs replay mode
The Deep Entity Viewer supports two modes:
| Mode | Behavior |
|---|---|
| Live | Current snapshot — what the runtime would load for the next intent |
| Replay | State at cursor — scrub the timeline to see entity fields at any point in history |
In replay mode, the scrubber loads state at cursor from the ledger (not the live snapshot). Use this to answer: what did this entity look like when intent X committed?
You can also compare two cursors (state diff) to see exactly which fields changed between commits.
Rebuilding an entity snapshot
When a snapshot is stale or corrupted, rebuild it from the ledger for one entity:
- Open the entity in Entities or the Deep Entity Viewer.
- Run Rebuild — the runtime re-applies ledger commits in order and writes a fresh snapshot.
Rebuild is scoped to a single (stream, entity, fork). It does not re-run side effects or re-emit Kafka events for projections — it fixes entity materialized state.
When to use:
- Snapshot drift after an incident
- After fixing a rules bug (deploy fixed IR first, then rebuild affected entities)
- Verifying ledger vs snapshot during an investigation
Decision Timeline replay and branch
From Decision Timeline (per entity), you can:
| Action | Purpose |
|---|---|
| Replay from cursor | Forensics — re-execute or compare rule evaluation from a cursor onward and report divergences |
| Branch from cursor | Create a new fork whose history starts at that cursor — safe what-if exploration |
| Repair plan | Generate a suggested repair intent for a problematic decision step |
Replay and branch here are investigation tools tied to timeline. They complement the Entity Inspector scrubber: decisions show how rules ran; replay mode shows what state was.
For the same jobs from the terminal (sandbox), use causet forensics: replay-check for snapshot drift, and repair-plan / repair-apply for an inverse patch on one timeline step.
Projection rebuild
Projection tables are filled asynchronously from the event stream. To rebuild read models:
- Deploy IR with corrected projection handlers or schema.
- Reset the projection worker consumer to replay events from the needed offset (or from the beginning for a full backfill).
- The worker re-applies handlers — UPSERTs are idempotent, so re-processing is safe.
When to use:
- New projection added — backfill from history
derive:expression or handler bug fixed- Column type change after schema migration
Projection rebuild does not re-run intent rules or side effects — only projection handlers. No risk of duplicate emails or charges from projection replay alone.
Determinism
Core rules are deterministic: no wall clock, no randomness, no external I/O in preflight or core. Replaying the same events with the same ruleset version yields the same state.
Same events + same rules = same result. That is why rebuild and scrubber replay are trustworthy after incidents.
Side effects and replay
Warning: Snapshot rebuild and decision replay paths that re-execute rules can re-fire side effects (emails, webhooks,
submit, AI calls) if your rules are not guarded.
| Replay type | Side-effect risk |
|---|---|
| Entity Inspector scrubber (state at cursor) | None — read-only |
| Projection rebuild | None — handlers only UPSERT tables |
| Snapshot rebuild (full rule re-apply) | Yes — if implementation re-runs side_effects |
| Decision Timeline replay | Yes — designed for forensics; use non-production forks |
Patterns:
- Pass
is_replay: truein intent payload and gateside_effectsrules. - Use idempotency keys for external calls.
- Run risky replays on a branch fork, not
main.
Choosing the right tool
| Symptom | Tool |
|---|---|
| ”What was state at cursor 42?” | Entity Inspector → replay scrubber |
| ”Snapshot doesn’t match ledger” | Entity Inspector → Rebuild, or forensics replay-check |
| ”Which branch did rules take?” | Decision Timeline |
| ”Undo one bad timeline step” | forensics repair-plan → repair-apply |
| ”Read model rows are wrong” | Projection rebuild |
| ”Try a fix without touching prod” | Branch from cursor / sandbox fork |
See also
- Forensics CLI —
causet forensicsdrift check and per-decision repair - Entity Inspector — browse, scrub, diff, rebuild
- Timeline — step-by-step rule trace
- Ledger Events — commits and intent status
- Idempotency — safe retries and replays
- Schema Versioning — when projection rebuild is required