DebuggingForensics CLI

Forensics CLI

When entity state looks wrong, you need to know whether the snapshot drifted from the ledger and, if one timeline step caused the damage, how to reverse just that step without rewriting history by hand.

causet forensics is the sandbox CLI for those two jobs:

CommandPurpose
replay-checkRe-apply recorded ledger patches and report fields that diverge from the stored snapshot
repair-planBuild an inverse __SYSTEM_APPLY_PATCH__ intent from a timeline step’s captured previousValues
repair-applySubmit that repair intent through the normal pipeline (explicit — never auto-applied from plan)

Full flag reference: causet forensics.

⚠️

Forensics commands are sandbox-only. Prefer cloning into a fork, validating there, then promoting a release — not patching production entities in place.


Why use it

SituationWhy forensics helps
Snapshot looks wrong vs historyreplay-check tells you if storage/replication drifted — without re-running today’s product rules
One bad intent corrupted fieldsrepair-plan / repair-apply restore fields using values recorded on that step
You need an audit trailRepairs are new intents tagged repair_source=generate_repair_plan, not silent DB edits
You’re not sure which step to undoPair with inspect timeline to pick the decision ID

Do not use forensics when:

  • Many entities need the same product fix → use bulk recovery repair with a compensating action
  • Ops weren’t invertible (no previousValue) → define a compensating action in your .causet app
  • You want “re-run today’s rules on old intents” → that is a different product concern (fork + new release + compensating intents)

Mental model

ConceptMeaning
Timeline / cursorPer-entity ordered history. Cursor N means “through decision N” for that entity
Decision IDUUID primary key of one decision_routes row — the same id shown on a timeline step
RepairA new intent that corrects state (inverse system patch). It does not delete the bad step
Replay-checkRe-apply recorded patches and compare to the snapshot. Does not re-evaluate product rules

Repairs always go through the normal intent pipeline. System patches use __SYSTEM_APPLY_PATCH__ and require a repair_source tag — you cannot submit them as ordinary public intents.


Prerequisites

causet login
causet context show
causet context use fork sandbox   # recommended

Sandbox-gated: causet forensics … refuses to run outside the sandbox environment.


Interactive usage

With no subcommand (or missing flags) in a terminal, the CLI prompts:

causet forensics
# → menu: replay-check / repair-plan / repair-apply
SubcommandPrompts for
replay-checkStream (picker), entity, from-cursor
repair-planDecision / timeline step ID
repair-applyDecision ID or plan file path; confirms before apply when generating from a decision

Non-interactive / --json / CI still require flags.


Detect storage drift (replay-check)

causet forensics replay-check \
  --stream order_stream \
  --entity order-123 \
  --from-cursor 5

Re-applies ledger patches from --from-cursor and compares the recomputed state to the stored snapshot at head.

ResultMeaning
No diverged fieldsSnapshot matches ledger patches
Diverged fields listedStorage/replication drift — not “rules would produce a different result today”

Undo one timeline step (repair-planrepair-apply)

1. Find the decision ID

causet inspect timeline --entity order-123 --stream order_stream

Copy the step’s id (UUID). That is the decision ID — the primary key of the decision_routes row forensics loads.

2. Generate a plan (does not apply)

causet forensics repair-plan --decision <decision-uuid>
# Optional: save for review
causet forensics repair-plan --decision <decision-uuid> --json > plan.json

Builds a __SYSTEM_APPLY_PATCH__ intent that restores fields using captured previous values. Review strategy, affected fields, and intent JSON before applying.

If generation fails (success=false), the strategy usually means a non-invertible op (no previousValue). Fall back to a product compensating action + bulk repair.

3. Apply explicitly

causet forensics repair-apply --decision <decision-uuid>
# or
causet forensics repair-apply --plan-file plan.json

Plans are never auto-applied from repair-plan. Interactive apply from a decision asks for confirmation first.


Suggested workflow

  1. causet fork create or fork branch from main into sandbox
  2. causet inspect timeline --entity … — pick the bad decision ID
  3. causet forensics replay-check if you suspect snapshot drift
  4. causet forensics repair-plan → review
  5. causet forensics repair-apply on the sandbox fork
  6. Validate with inspect / queries / fork diff
  7. Correct production via a product fix + compensating action (or promote a release) — not a silent patch on main

Choosing the right tool

SymptomTool
Snapshot ≠ ledger patchesforensics replay-check
Undo one invertible stepforensics repair-planrepair-apply
Many entities / non-invertible opsrecovery repair with app compensating action
Recompute stream from patchesrecovery replay (sandbox)
What-if rewind without mutating current forkfork branch … --entity stream:id@cursor
Missing projection rows after poison eventsprojection dlq list / dlq replay

See also