Agent Handoff and Seance in Gas Town: Managing Context Across Claude-Code Sessions
Agent Handoff transfers the current work state from a running Claude-Code agent to a fresh session using Dolt-backed git beads, while Seance enables non-destructive conversation with predecessor sessions by forking their full context without terminating the original process.
Gas Town is an agentic development environment where autonomous Claude-Code agents (Polecats, Witnesses, Deacons) operate inside tmux panes. When agent context windows fill or sessions require recovery, Agent Handoff and Seance provide deterministic state management and context preservation across agent lifecycles, as implemented in the gastownhall/gastown repository.
What is Agent Handoff in Gas Town?
Agent Handoff is a state migration primitive designed for context window exhaustion, patrol cycle completion, and crash recovery. According to the glossary entry in docs/glossary.md, Handoff creates a "handoff bead"—a Dolt-tracked git commit—that encapsulates the agent's environment variables, pending mail, and unsaved work states.
The mechanism triggers when:
- A Deacon completes its patrol cycle and squashes wisp work
- Claude's context window reaches capacity
- Crash recovery requires a clean slate
The Handoff Bead and Mail Injection
When gt handoff executes, it generates a handoff bead that stores deterministic git state. This bead includes a handoff mail injected into the next session's mailbox via internal/mail/router.go, ensuring the new agent receives explicit instructions about what to continue. The new session spawns in a fresh tmux pane with a pristine Claude instance, reads the handoff mail, and restores the environment as if uninterrupted.
What is Seance in Gas Town?
Seance provides context-preserving "conversation recall" between sessions without destroying the predecessor. Defined in docs/glossary.md and implemented in internal/cmd/seance.go, this primitive discovers past sessions from the ~/gt/.events.jsonl event log and executes claude --fork-session --resume <id> to query previous decision-making contexts.
Unlike Handoff, Seance does not terminate the original session. It creates a forked copy of the Claude context, allowing agents to ask questions like "Where did you leave this file?" or "Why did you abort?" while the predecessor continues running untouched.
Session Discovery and Filtering
The gt seance command reads session_start events from the event stream. Users filter discoverable sessions using:
--roleto specify agent types (polecat, deacon, witness)--rigto narrow by infrastructure rig--recent <n>to limit to the n most recent sessions
How Handoff Works Step-by-Step
The handoff flow documented in docs/design/dog-infrastructure.md follows this deterministic sequence:
- Patrol Cycle Completion – The Deacon squashes wisp work and writes a concise summary to the molecule state.
- Bead Creation –
gt handoffcreates a handoff bead (Dolt-backed git object) storing environment variables and pending state. - Mail Injection – The system generates handoff mail routed through
internal/mail/router.gointo the next session's mailbox. - Fresh Session Spawn – A new tmux pane launches via
gt-deacon, starting a new Claude instance that reads the handoff mail and resumes work.
This mechanism prevents context loss across agent restarts while maintaining deterministic git state, with internal/townlog/logger.go emitting handoff events (defined as TypeHandoff in internal/events/events.go) for audit trails.
How Seance Works Step-by-Step
The implementation in internal/cmd/seance.go handles session resurrection through four stages:
- Event Discovery – Without
--talk, the command parses~/gt/.events.jsonlto extractsession_startevents. - CLI Filtering – Flags like
--role polecator--recent 5narrow the session list. - Context Forking – With
--talk <session-id>, the command executesclaude --fork-session --resume <id>, checking theSupportsForkSessionflag ininternal/config/agents.goto ensure compatibility. - Query Execution – Optional
-p "<prompt>"enables one-shot queries, or omitting it opens an interactive REPL with the predecessor's full context.
The original session remains active; only a forked copy loads for interrogation.
Command Reference and Code Examples
Triggering a Handoff
At the end of a patrol cycle, Deacons invoke:
gt handoff -s "Routine cycle" -m "Patrol finished, handing off state"
This creates the handoff bead, writes handoff mail, and respawns the agent.
Discovering Past Sessions
List recent sessions with role filtering:
gt seance
gt seance --role polecat --recent 5
Querying Predecessor Sessions
One-shot question mode:
gt seance --talk abc123 -p "What file did you modify before the crash?"
Interactive mode:
gt seance --talk abc123
Programmatic Seance in Go
Spawn seances from Go code using:
cmd := exec.Command("gt", "seance", "--talk", sessionID, "-p", "What was the last error?")
out, _ := cmd.CombinedOutput()
fmt.Println(string(out))
Key Implementation Files
The complete architecture for these primitives spans these source files:
docs/glossary.md– Defines Handoff and Seance primitivesdocs/design/dog-infrastructure.md– Describes the Handoff Flow lifecycle and Deacon integrationinternal/cmd/seance.go– Implementsgt seanceCLI, session discovery, and fork logicinternal/templates/commands/provision.go– Registers thehandoffcommand for agent templatesinternal/mail/router.go– Handles handoff mail creation and injectioninternal/session/startup.go– Adds handoff-specific instructions to the startup beaconinternal/events/events.go– DefinesTypeHandoffevent constantsinternal/townlog/logger.go– Emits handoff events for debugginginternal/config/agents.go– StoresSupportsForkSessionconfiguration for seance compatibility
Summary
- Agent Handoff migrates work state to fresh Claude sessions via Dolt-backed git beads when contexts overflow or cycles complete.
- Seance enables non-destructive conversation with predecessor sessions using
claude --fork-sessionwithout terminating the original agent. - Handoff beads preserve environment variables and pending mail through
internal/mail/router.go, ensuring deterministic recovery. - Session discovery reads from
~/gt/.events.jsonl, with filtering support for roles, rigs, and recency. - Both primitives prevent context loss while maintaining audit trails through
internal/townlog/logger.go.
Frequently Asked Questions
When should I use Handoff versus Seance?
Use Handoff when the current agent session must end—such as when the Claude context window is full, a patrol cycle completes, or crash recovery requires a clean slate. Use Seance when you need to inspect or query a running or past session without interrupting it, such as debugging why a predecessor made a specific decision or locating files modified in previous steps.
How does Gas Town prevent data loss during agent restarts?
Gas Town prevents data loss through handoff beads—immutable Dolt-tracked git commits that encapsulate the agent's environment variables, pending work, and unsaved state. When gt handoff executes, it stores this bead in the git object database and injects handoff mail into the next session's mailbox, ensuring the new agent receives complete state information before resuming work.
What is a handoff bead in Gas Town?
A handoff bead is a specialized git commit object backed by Dolt that stores an agent's serialized state during the handoff process. It contains the agent's summary, pending mail queue, environment variables, and work-in-progress metadata. The bead serves as the canonical state artifact that new sessions read when spawning, as implemented in the handoff flow of docs/design/dog-infrastructure.md.
Can Seance modify previous session state?
No. Seance operates non-destructively by executing claude --fork-session --resume <id>, which creates a copy of the predecessor's context without affecting the original session. The source session continues running independently, and the forked conversation cannot write back to the predecessor's state. This design ensures audit integrity and prevents accidental corruption of active agent workflows.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →