Skip to content

Branching conversation

When you want to try two versions of the same thought.

10 min

Linear chat is a tyranny that shipped because nobody had time to design an alternative. Every serious piece of work involves forking a thought, trying two versions, and deciding which one to keep. Linear chat pretends that doesn't happen. You get one thread, you live with what the model said, or you start over and lose the history.

Branching is the feature that turns a chat app into a writing room. It's also, not coincidentally, the feature that makes teams actually trust AI to do first drafts.

"Linear chat is a fiction that shipped first."
The pattern

Three verbs: fork, switch, merge.

Branching is not a sidebar of saved chats. It's an in-thread operation. The user hovers a turn, taps "fork from here," and a new branch spawns with that turn as its shared parent. Both branches continue from the same state. The UI makes it unambiguous which branch is active, and the model only reads from the active branch's history.

Switching between branches is one tap. Merging — keeping a winning branch and archiving the others — is a conscious step, not an automatic behavior. The user is the one who decides which draft is "the" draft.

Three branches of the same prompt
Pick one. Or keep all three. The tree is editable.
Branches
Active: B
Branch B · explanatory

Here's where the plan stands. Ship date is three weeks out — a date I chose because the audit-log dependency closes on day 18, leaving a week of buffer. The principal risk is platform hiring: two roles still open, both on the audit-log path. My proposed mitigation is a short-term contractor to unblock the dependency without waiting for the full-time backfill. I need a call on this by Friday.

Linear chat hides the forks. Branches make the argument visible.

The why

Drafts are how thinking works.

Writers know this already. Engineers know this already. Everyone who has written more than a paragraph they care about has a notebook full of discarded versions. Branching just makes that notebook visible inside the product.

Without it, users self-censor. They pick the one angle they want to try, the safest one, and settle for it. With it, they try three, because the cost is near zero and the archive is intact. The product feels like a room, not a corridor.

Three moves

The branch pattern I'd ship.

  • Fork is non-destructive by construction. A fork never modifies the original branch. Ever. This is the invariant the pattern stands on; break it and users won't trust fork.
  • Active branch is the visible truth. The chrome of the product should always make the active branch unambiguous — a color, a label, a small indent in the transcript. There should be no way to send a message to "a branch" that isn't the active one.
  • Merge is a human decision. Don't auto-merge. Don't offer a "quick merge" that picks the longer branch. The point of the pattern is that the human is in the loop on which version wins.

The trap

Stale branches poisoning memory.

If the model's memory extends across branches, branching breaks. An archived branch's facts start leaking into the active branch's responses. The user sees the model "remembering" things that belong to a version they discarded.

Memory must be branch-scoped. Facts learned in a branch only apply to that branch until the user explicitly promotes them.

Failure modes

What this pattern gets wrong when it gets wrong.

Stale memory
A persistent fact about the user that's out of date and silently poisoning answers.
Leaky context
Content from another source, session, or user surfacing in a place it shouldn't.
Ambiguous state
Running, done, errored, paused all look the same. The user has to infer from context.
Seen in the wild

Three shipping variants worth copying.

  • A vertical spine showing branches as indented threads
  • A 'fork this turn' button that appears on hover over any response
  • A merge affordance that keeps the winning branch and archives the others