Decision Desk forking
Eli wants to explore another direction while keeping the original conversation available.
A fork is useful for that. It separates conversation identity and future journal ownership. It does not isolate workspace changes.
Milestone: Fork the current conversation
Need. Keep the original Lantern Board discussion while creating another conversational starting point.
Obstacle. The word “fork” can suggest a Git branch, a file snapshot, or a previous-message picker. The supplied /fork does none of those things.
Use the complete Decision Desk recipe and its state ledger.
Create a new disposable lab for this story. Preserve the previous receipt separately if you still need it.
Terminal shell — Decision Desk preparation, from extracted examples/:
bun return-desk/lab.ts '{"version":1,"op":"discover"}'
RECEIPT=$(mktemp -t continuity-decision-receipt)
bun return-desk/lab.ts '{"version":1,"op":"act","action":"create"}' | tee "$RECEIPT"
Stop on ok: false. Then retain its paths and the intended executable:
Terminal shell — read the successful Decision Desk receipt:
LAB=$(jq -r '.root' "$RECEIPT")
SOURCE=$(jq -r '.yesterday' "$RECEIPT")
SESSIONS=$(jq -r '.sessions' "$RECEIPT")
PROJECT=$(jq -r '.cwd' "$RECEIPT")
OMP_BIN=$(command -v omp)
The same prerequisites and stop rules from Return Desk lab setup apply.
Record the parent and workspace before opening OMP:
Terminal shell — read-only baseline:
shasum -a 256 "$SOURCE"
jq -s 'map(select(.type == "session") | {id,parentSession,cwd,title})' "$SOURCE"
cat "$PROJECT/today.txt"
jq -r '.commands.resumeExplicitPath' "$RECEIPT"
Run the complete printed resume command. Stop if it requires model/auth setup. Do not submit a prompt.
Inside the idle fictional conversation:
Human OMP slash command — create the conversational fork:
/fork
Then inspect the child:
Human OMP slash commands — inside the fork, one at a time:
/session info
/dirs
Keep the child active for the reset sequence in the next chapter.
The fork ledger
A successful interactive fork has these source-backed effects:
| Field | Expected result |
|---|---|
| Persistent identity | A new journal ID. |
| Transcript path | A new JSONL path. |
| Parent metadata | parentSession records the previous persistent ID. |
| Title and cwd | Retained from the current session. |
| Live conversation | Retained. |
| Ordinary steering/follow-up queues | Retained by this fork path. |
| Journal entries | All existing non-header entries are carried into the new journal—not only the currently visible messages. |
| Workspace files | Still the same files in the same workspace. |
| Session artifacts | Copied recursively where available, best-effort. |
For this public source, the child’s parent ID should be:
11111111-1111-4111-8111-111111111111
The current registry description mentions a fork “from a previous message.” The implementation route is more specific: handleForkCommand calls AgentSession.fork() immediately. This is a current-state fork, not a previous-message picker.
A copied journal can retain older branches and pre-clear entries that are not in current model context. Forking is therefore not a way to reduce the disclosure content of a later export.
Artifacts are not a verified backup
copySessionArtifacts derives the artifact directory by removing .jsonl from the transcript filename.
- Missing sources are ignored.
- Other copy errors are logged rather than thrown from that helper.
- The fork can therefore exist without every expected artifact having copied.
That copy does not cover arbitrary workspace files, remote copies, previously generated exports elsewhere, or a guaranteed complete backup of every dependency.
Recorded checks. The real SDK/registry/controller fork check created a new identity with parent metadata, retained messages and ordinary queues, preserved parent bytes around the fork call, and copied one ordinary artifact.
The same test then wrote a fictional file in the shared workspace and confirmed that the parent manager saw the changed file at the same cwd. The write was a test action, not something /fork performed.
A separate real copySessionArtifacts check encountered a regular file blocking the destination directory. It returned without throwing and did not copy the artifact. That supports the best-effort warning; it is not broad filesystem coverage.
Failure and recovery. Interactive /fork refuses while streaming. An in-memory session cannot fork through this path. A before-switch hook can veto it. After any refusal or error, inspect the actual file and identity before proceeding.
Self-check. If Eli later changes a workspace file while working in the fork, will resuming the parent undo that file change?
Answer: No. The conversation identities differ; the workspace is shared.
Interactive and startup forks differ
This is a source-backed comparison, not another executed scenario:
| Boundary | Interactive /fork | Startup --fork |
|---|---|---|
| Source | Current session | Explicit path or resolved native identity |
| Cwd | Existing active cwd | Launch cwd supplied to startup |
| Conversation | Retains current live messages | Rebuilds from copied journal history |
| Parent-process queues | Ordinary queues remain on the active fork path | No parent-process steering/follow-up queues are cloned |
| Journal | New identity; original retained | New identity; source retained |
| Artifacts | Best-effort copy | Best-effort copy by default |
| Workspace isolation | None | None |
Full forks may inherit a provider prompt-cache identity. That is separate from journal identity and from provider request identity. Changing the startup model, thinking, prompt, or tool shape can suppress automatic inheritance; explicit provider/cache overrides are separate controls.
You do not need to tune those controls for this workbook. The important conclusion is simpler: a new journal is not proof of a cold provider cache, and a fork is not /fresh.
Source anchors: packages/coding-agent/src/slash-commands/builtin-session.ts — fork entry; packages/coding-agent/src/modes/controllers/command-controller.ts — handleForkCommand; packages/coding-agent/src/session/agent-session.ts — fork; packages/coding-agent/src/session/session-manager.ts — fork, forkFrom, copySessionArtifacts; packages/coding-agent/src/main.ts — createSessionManager, buildSessionOptions.
Sessions, resets, and reviewable history · Source chapter: continuity/decision-desk-forking. Original evidence remains scoped to its recorded snapshot.