Branch a session

Fork at any prior turn so dead ends stay reachable, alternative paths run side by side, and a misdirected steering message no longer means losing the work it sat on top of.

/undo deletes, /branch rewinds

Cantrip stores the conversation as a tree, not a flat list. Every assistant turn carries the id of the turn it replied to, and the active session is just “which leaf is currently live.”

/undo walks back by removing rows: the messages disappear from history and the working tree restores from the snapshot before that turn. Use it when the last turn was wrong and you want the alternate reality where it never happened.

/branch walks back without removing anything: the session pointer moves to a prior turn, but every turn that hung off the old leaf is still in the SQLite store and stays reachable. Use it when the last turn might have been wrong or might be salvageable, and you want both options available later.

Quick reference

CommandWhat it does
/branch Fork before the most recent user turn. The typical recovery from a bad steering message.
/branch <turn-id> Move the active head to a specific turn. The turn id comes from /tree.
/tree Render every turn in the session as an indented tree, with an asterisk on the active branch. In the TUI this is an interactive picker; in the CLI it prints to chat.
cantrip export-transcript <charm> --branch <turn-id> Export the conversation path leading to a specific leaf, even if that leaf is no longer the active branch.

Recover from a bad steering message

You typed “use Path B for this Flask workload” and the agent dutifully started scaffolding a Path B charm even though you meant Path A. Three turns later you realise the mistake.

cantrip> /branch
Forked before turn 14 (your last user message).
Active branch: turn 13 — “Looks good, go ahead.”

The Path B work didn't disappear — it's still on the old branch. Your next user message extends the active branch from turn 13. If you ever want to inspect the abandoned Path B exploration, /tree will show it.

Explore alternatives in parallel

For a charm where the substrate or relation graph has more than one defensible answer, branching lets you walk both paths and compare them rather than picking blind.

  1. Drive the agent down option A as a normal session.
  2. Inspect the result, then /branch <id> back to the design-decision turn.
  3. Steer the agent down option B from the same starting point.
  4. Use /tree to see both branches.
  5. Pick one as the active branch; export the other for reference if it had useful artefacts.
cantrip> /tree
Session 4f8a… (charm: my-flask)
* turn 18 — “Run acceptance tests” (Path B branch)
  turn 25 — “Add ingress integration” (Path A branch)

Press Enter on a row in the TUI picker to dispatch /branch <id> for that turn. Escape leaves the active branch alone.

Export an off-branch path

Branching changes which turns are live, not which turns exist. Every leaf is exportable by id even after the head moves elsewhere:

$ cantrip export-transcript ./my-flask --branch t-25 --format html
Wrote transcript_t-25.html (Path A exploration, 18 turns).

Without --branch, exports follow the currently active branch, so a forked session exports only the active path by default.

Snapshots, undo, and branches together

Every user turn takes a working-tree snapshot before it executes (unless --no-snapshots / CANTRIP_SNAPSHOTS=false turns it off). Those snapshots back both /undo and /branch:

The snapshot repo lives at $XDG_STATE_HOME/cantrip/snapshots/<hash>/, outside the charm tree, so git clean -fdx on the charm cannot wipe out your branch history.

Caveats