# Agent Handoff and Seance in Gas Town: Managing Context Across Claude-Code Sessions

> Discover Agent Handoff and Seance in Gas Town. Seamlessly transfer Claude-Code agent context between sessions and engage non-destructively with past conversations.

- Repository: [Gas Town Hall/gastown](https://github.com/gastownhall/gastown)
- Tags: deep-dive
- Published: 2026-07-07

---

**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`](https://github.com/gastownhall/gastown/blob/main/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`](https://github.com/gastownhall/gastown/blob/main/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`](https://github.com/gastownhall/gastown/blob/main/docs/glossary.md) and implemented in [`internal/cmd/seance.go`](https://github.com/gastownhall/gastown/blob/main/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:
- `--role` to specify agent types (polecat, deacon, witness)
- `--rig` to 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`](https://github.com/gastownhall/gastown/blob/main/docs/design/dog-infrastructure.md) follows this deterministic sequence:

1. **Patrol Cycle Completion** – The Deacon squashes wisp work and writes a concise summary to the molecule state.
2. **Bead Creation** – `gt handoff` creates a handoff bead (Dolt-backed git object) storing environment variables and pending state.
3. **Mail Injection** – The system generates handoff mail routed through [`internal/mail/router.go`](https://github.com/gastownhall/gastown/blob/main/internal/mail/router.go) into the next session's mailbox.
4. **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`](https://github.com/gastownhall/gastown/blob/main/internal/townlog/logger.go) emitting `handoff` events (defined as `TypeHandoff` in [`internal/events/events.go`](https://github.com/gastownhall/gastown/blob/main/internal/events/events.go)) for audit trails.

## How Seance Works Step-by-Step

The implementation in [`internal/cmd/seance.go`](https://github.com/gastownhall/gastown/blob/main/internal/cmd/seance.go) handles session resurrection through four stages:

1. **Event Discovery** – Without `--talk`, the command parses `~/gt/.events.jsonl` to extract `session_start` events.
2. **CLI Filtering** – Flags like `--role polecat` or `--recent 5` narrow the session list.
3. **Context Forking** – With `--talk <session-id>`, the command executes `claude --fork-session --resume <id>`, checking the `SupportsForkSession` flag in [`internal/config/agents.go`](https://github.com/gastownhall/gastown/blob/main/internal/config/agents.go) to ensure compatibility.
4. **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:

```bash
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:

```bash
gt seance
gt seance --role polecat --recent 5

```

### Querying Predecessor Sessions

One-shot question mode:

```bash
gt seance --talk abc123 -p "What file did you modify before the crash?"

```

Interactive mode:

```bash
gt seance --talk abc123

```

### Programmatic Seance in Go

Spawn seances from Go code using:

```go
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`](https://github.com/gastownhall/gastown/blob/main/docs/glossary.md)** – Defines Handoff and Seance primitives
- **[`docs/design/dog-infrastructure.md`](https://github.com/gastownhall/gastown/blob/main/docs/design/dog-infrastructure.md)** – Describes the Handoff Flow lifecycle and Deacon integration
- **[`internal/cmd/seance.go`](https://github.com/gastownhall/gastown/blob/main/internal/cmd/seance.go)** – Implements `gt seance` CLI, session discovery, and fork logic
- **[`internal/templates/commands/provision.go`](https://github.com/gastownhall/gastown/blob/main/internal/templates/commands/provision.go)** – Registers the `handoff` command for agent templates
- **[`internal/mail/router.go`](https://github.com/gastownhall/gastown/blob/main/internal/mail/router.go)** – Handles handoff mail creation and injection
- **[`internal/session/startup.go`](https://github.com/gastownhall/gastown/blob/main/internal/session/startup.go)** – Adds handoff-specific instructions to the startup beacon
- **[`internal/events/events.go`](https://github.com/gastownhall/gastown/blob/main/internal/events/events.go)** – Defines `TypeHandoff` event constants
- **[`internal/townlog/logger.go`](https://github.com/gastownhall/gastown/blob/main/internal/townlog/logger.go)** – Emits handoff events for debugging
- **[`internal/config/agents.go`](https://github.com/gastownhall/gastown/blob/main/internal/config/agents.go)** – Stores `SupportsForkSession` configuration 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-session` without terminating the original agent.
- **Handoff beads** preserve environment variables and pending mail through [`internal/mail/router.go`](https://github.com/gastownhall/gastown/blob/main/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`](https://github.com/gastownhall/gastown/blob/main/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`](https://github.com/gastownhall/gastown/blob/main/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.