plank โ€บ User guide โ€บ Sessions

6. Sessions

A session is the whole conversation: every message, the tasks, and โ€” where the engine supports it โ€” a snapshot of the model's internal KV state so returning to it does not mean re-reading it from scratch.

Sessions live under ~/.plank/kvcache/ as <name>.kv, with a fingerprinted <name>.kv_raw sidecar holding the engine state and a small <name>.json describing it. A session id is a memorable adjective-celebrity name (deadly-einstein), and titles derive from your first prompt, so /list is readable rather than a wall of hashes. The name is minted when the session starts, not when it is first saved, and the TUI floats it at the right end of the rule above the prompt โ€” so the name a transcript will be saved under is visible from the first frame.

Saving, listing, switching

Sessions save automatically; /save forces it.

/list               # most recent first
/switch <id>        # load another session
/tag reindex bug    # label this one
/rename apollo      # name this one something you will recognize
/del <id>           # delete

/rename <name> changes the name later saves use and leaves what is already on disk alone, so a session saved before the rename stays resumable under its old name and the next save is a copy rather than a move. Names are validated rather than quietly rewritten: ASCII letters, digits and - only, and nothing starting with sysprompt, which is reserved for cache files. _ and . used to be accepted, but a session so named never showed up in /sessions, so they are now refused up front. A name already taken on disk is confirmed with you before it is reused.

/strip <id> drops a session's KV payload to reclaim disk. The transcript survives untouched, so the session still loads; it just re-prefills the conversation the next time you open it, and /list shows it as stripped.

The KV cache

/kvcache shows what is actually on disk, as the tree it really is. A system-prompt snapshot sits at the root, the project-context snapshots that extend it hang below, and each session's payload hangs below the project it belongs to. Every row carries its size, how many times it has been reused, when it was last touched, and whether it is about to expire.

system  a19f4c21  412 MB  ๐Ÿ“Œ pinned
โ”‚  max ยท 12 global MCP tools
โ”œโ”€ project  7c02be90  88 MB  hits 41  2h ago
โ”‚  โ”‚  ~/Code/plank ยท AGENTS.md ยท 2 local MCP
โ”‚  โ”œโ”€ session cheeky-bell   1.2 GB  hits 3   2h ago
โ”‚  โ””โ”€ session bouncy-dali   0.9 GB  hits 1   6d ago  โณ ttl 8d
โ””โ”€ project  4d81a7f3  61 MB  hits 2   9d ago
   โ””โ”€ (no sessions)

total 2.6 GB ยท 0 B reclaimable

Move with โ†‘โ†“, fold a subtree with โ†โ†’, and act on the selected row: p pins it so no sweep will ever take it, d deletes it after a confirmation, g runs the sweep immediately. Esc closes. Piped into a non-interactive shell the same tree prints as plain text, and /kvcache pin|unpin|rm|gc do the same jobs by fingerprint prefix.

Pinning is the thing worth knowing about. Snapshots expire on age (see Configuration), and the largest ones are the most expensive to rebuild, so if you have a setup you return to every few weeks it is cheaper to pin it than to let it lapse and pay the re-prefill. A pinned entry is also exempt from the size ceiling.

Nothing here can lose a conversation. Deleting a cache entry deletes a snapshot, never a transcript; the worst case is that plank re-reads the conversation once.

Resuming

/resume             # inside plank: the most recent, or a picker
/resume dead        # by name prefix or list number
plank /resume       # straight from the shell

A resumed session replays through the same renderer as a live one, so history comes back as rendered markdown with thinking dimmed, not flat text. The KV sidecar is restored alongside the transcript โ€” which is the difference between resuming instantly and waiting for the whole conversation to be re-read. If the sidecar does not match the current model, system prompt, and transcript, it is rebuilt rather than trusted.

Checkpoints and rollback

A checkpoint is a named return point inside a session:

/checkpoint before-refactor
โ€ฆ let the model work โ€ฆ
/rollback before-refactor

Rolling back restores the transcript verbatim and hands the engine its KV bytes back, so the next turn resumes with almost no re-reading. The tail you discarded is not lost: it is saved as a checkpoint named pre-rollback, so a rollback is itself reversible.

Two properties worth knowing:

Branching

A session is stored as a straight line, but a conversation is really a tree: from any earlier prompt you can try a different approach without losing what you already explored.

/tree            # show the tree; fork points are numbered
/fork 3          # rewind to just before the 3rd prompt and go a different way
/clone           # freeze this branch and continue on a copy

/tree collapses linear runs into one line each, so what you see is the fork structure rather than every turn; * marks the active branch, and a trailing section numbers the fork points /fork accepts.

Fork points are your real prompts โ€” tool results do not count, so /fork 2 means "the second thing I actually asked", which is how you think about it.

Branching costs nothing to keep: the off-path branches are written into the session file as extra records, and a session that never branched is byte-identical to one written before branching existed. Older session files load as single-branch trees.

There is worked-through advice on when to fork versus checkpoint versus start fresh in Advanced workflows.

Exporting

/export                      # markdown, auto-named in the working directory
/export html                 # standalone HTML
/export md notes/review.md   # explicit path

HTML output is self-contained โ€” inline CSS, no external assets โ€” and every byte of model and tool content is escaped, since transcripts routinely carry arbitrary code.

Reproducing a bug

/repro

writes ~/.plank/repro/repro-<timestamp>.md: the exact rendered prompt the engine would see, plus the model, backend, context size, sampling settings, think mode, and engine tuning. Hand that to a maintainer and the state that triggered your bug is reproducible without your live session. It is a read-only snapshot; nothing about the running session changes.

Insights

/insights          # full report
/insights fast     # statistics only, no model-written prose

Reads every saved session and writes ~/.plank/usage-data/report.html. Every number is computed deterministically in code; the model is used only for narrative prose. The two halves never mix, so a failed model call costs you the narrative and never the statistics.


Next: Context โ†’