Branch Your Thinking

Git-like forking for AI sessions

The Frame

AI conversations run in a straight line — but thinking doesn't

A session with an AI runs turn after turn, each one building on the context before it. Real thinking branches. Session forking lets you branch a conversation at any turn instead of losing the thread.

And it isn't a sketch — it's shipped code. →

It's real, and it's tested

fork_session lives in microsoft/amplifier-foundation, in amplifier_foundation/session/fork.py — a working feature, not a proposal.

So why fork at all? Consider the cost of staying linear. →

Verified present & tested
492
lines in fork.py
63
passing tests in test_session.py

A “what if” shouldn't cost you the whole thread

Twenty turns into a good conversation, you want to explore a tangent. Without forking, you either abandon the thread you built or re-explain all of its context from scratch.

Forking removes the choice — here's the core move. →

A fork slices the transcript up to your chosen turn

fork_session() loads the parent's transcript, slices it to a chosen turn, and writes it to the new session — so the branch inherits every prior message. The forked session is independently resumable and addressable.

But what exactly is “a turn”? →

A “turn” is a precise, 1-indexed unit

A turn is a user message plus all subsequent non-user messages until the next user message — and turns are 1-indexed for user-facing operations. That precise definition is what makes forking at an exact point meaningful.

And the branching itself? It was already in the kernel. →

# messages.py — boundaries at each user message get_turn_boundaries(messages) # indices where role == "user" count_turns = len(boundaries) # turns are 1-indexed

Forking is a thin policy layer — zero core changes

The kernel, amplifier-core, already carried the branching primitive: AmplifierSession accepts parent_id and emits a session:fork event. The fork utilities are policy built on that — “zero changes required to amplifier-core.”

Which means forks compose — and that's the payoff. →

# amplifier-core kernel AmplifierSession(parent_id="…") # emits event: session:fork # parent_id flows into all events # foundation adds the fork policy # on top — no kernel edits

Forks nest into a queryable lineage tree

Fork a fork a fork. A test confirms it: parent → fork1 → fork2 yields a lineage of depth 2 with 2 ancestors. Every branch still knows its parent and its full ancestry — an auditable tree of thought, not one lost thread.

So what does that change about how you work? →

parent   └─ fork1 (depth 1)      └─ fork2 (depth 2, ancestors: 2)
Takeaway

Branch your conversations like you branch your code

Stop treating an AI conversation as one throwaway line. Fork it at any turn, keep every path, and let your thinking be as non-linear as it really is.

Conversations as branchable, versioned artifacts.

Sources

Sources & Research Methodology

Data as of: 2026-04-09 (HEAD 0965a34, branch fix/session-naming-timeout-configurable).

Feature status: Verified present and tested in microsoft/amplifier-foundation; built as a policy layer on the amplifier-core kernel's parent_id / session:fork mechanism.

Research performed (commands run):

Gaps: No dedicated end-user fork CLI subcommand exists (session CLI exposes diag, repair, rewind, info, find only). The amplifier-core copy read here is the ramparte/amplifier-core fork; upstream assumed equivalent but not directly inspected.

Primary contributors: Brian Krabach (author of the fork utilities, introducing commit 2ba2a2c, and most subsequent fork.py/session commits); Salil Das (partial-orphan transcript fix, commit 0188499, 2026-03-21).

More Amplifier Stories