Skip to content

About

Portable task state across coding agents.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Agent Handoff

English | 简体中文

Portable task state across coding agents.

Agent Handoff aims to let an unfinished coding task move from one coding-agent harness to another without pretending that conversation history is the whole state of the task.

When a model quota runs out, a different agent is better suited to the next step, or a developer simply wants to switch tools, Agent Handoff captures the useful task context together with evidence from the real workspace. The receiving harness starts a normal native session, verifies the current repository, and continues from the unfinished work.

ZCode / Claude Code / Codex / other harnesses
                     ↓
               Agent Handoff
                     ↓
          portable handoff bundle
                     ↓
Claude Code / Codex / other harnesses

Why Agent Handoff?

Coding-agent sessions are usually tied to the harness that created them. Moving only the transcript loses important state, while copying a private session database couples the migration to undocumented internals.

Agent Handoff takes a different approach:

  • Conversation is portable. User intent, messages, tool events, decisions, and unresolved work can be represented in a harness-neutral format.
  • Workspace is authoritative. Files, Git state, and observed test results take precedence over what an earlier agent said it intended to do.
  • Harness is replaceable. The receiving tool creates and owns its native session; Agent Handoff does not forge private Claude Code, Codex, or ZCode records.

How it works

A handoff combines two kinds of evidence:

  1. Semantic context from the source session, such as the task, conversation, tool events, decisions, and outstanding questions.
  2. Workspace evidence captured from the repository, such as the current commit, branch, staged and unstaged changes, untracked files, conflicts, and observed command results.

The result is a versioned Handoff Bundle designed for progressive loading:

handoff bundle
├── manifest and compatibility metadata
├── concise task handoff
├── structured workspace state
├── transcript event stream
└── Git and file-state artifacts

Within an explicit context budget, the receiving integration first reads the concise handoff, checks the repository it is about to operate on, and then uses bounded search and pagination to load transcript or artifact details only when needed. Physical compression may optimize storage and transport, but is not treated as a substitute for controlling model context.

Intended workflow

The current command-line experience is:

# Discover logical-task roots (sub-agent children are summarized;
# --all lists them explicitly)
agent-handoff list zcode

# Inspect a session and its task tree without modifying it
agent-handoff inspect zcode:<session-id>

# Export a logical task (root plus sub-agent sessions) into the local store
agent-handoff export zcode:latest

# List bundles available in the local store
agent-handoff list bundles

# Run a bounded, resumable search over a bundle transcript
agent-handoff transcript search <handoff-id> "<keyword>"

# Verify a bundle for this workspace and compare it with the live state
agent-handoff resume

# List configured delivery targets
agent-handoff target list

# Deliver a finalized bundle to a target's remote store over ssh
agent-handoff send <handoff-id> --to <target>

# Guided setup: detect local sources/harnesses, scan explicitly selected
# hosts with a visible read-only probe, register targets, optionally
# install the harness integration (interactive in a TTY)
agent-handoff setup --host <ssh-alias|[user@]host[:port]> [--install|--uninstall]

# Manage the harness integrations shipped with this binary
agent-handoff skill status
agent-handoff skill install [--harness <name>]

Remote targets are configured in ~/.agent-handoff/config.yaml (a small, strictly validated YAML subset; never any credentials — authentication, host keys, and the SSH config all belong to the system ssh setup):

targets:
  linux-dev:
    harness: claude-code
    host: 203.0.113.10
    user: ben
    port: 22
    store_root: /home/ben/.agent-handoff/bundles

Product files live under ~/.agent-handoff/ on every supported platform: config.yaml, installs.json, and the local store bundles/. setup registers the same relative store path on a remote host unless --store-root is given.

Delivery goes through the system ssh client: the bundle is streamed into a staging directory on the remote store, verified against the local manifest byte-for-byte, and published with an atomic rename. Re-delivering the same bundle id with identical content is idempotent; the same id with different content is refused (store_conflict). Remote bundle directories are permission-restricted (0700/0600).

Safety model

Agent Handoff is designed around conservative boundaries:

  • source sessions are opened read-only;
  • unknown source schemas fail safely instead of being guessed;
  • target harness databases are never forged or rewritten;
  • handoff data is secret-scanned, permission-restricted, and loaded lazily;
  • repository identity is matched using multiple pieces of evidence rather than path names alone;
  • workspace evidence reports what was observed at capture time; a mismatch informs the receiving harness but does not impose a global stop policy;
  • bundles describe captured state but are not presented as workspace backups;
  • resuming a handoff does not automatically apply patches, switch branches, overwrite files, or replay commands.

Project status

Agent Handoff is under active development and not yet ready for day-to-day use. Phase 0 is complete: agent-handoff list zcode and agent-handoff inspect zcode:<session-id> (with --json) capture the source database and WAL through ordinary read-only file operations, inspect only a private snapshot, and report explicit not_installed, no_sessions, unsupported_schema, unavailable, and session_not_found states. Compatibility is currently validated only for the observed ZCode 0.16.3 schema, migration checksums, application version, and core JSON record shapes. Findings and the fully synthetic, reviewable test fixture are documented in the design document and the Phase 0 investigation report.

Phase 1 (local handoff) is implemented: a ZCode session is normalized into the versioned Agent IR, local workspace evidence (Git status, staged and unstaged patches, untracked manifest, repository identity) is captured read-only, and a complete handoff bundle (manifest.json, bounded handoff.md, state.json, transcript.jsonl, artifacts/) is published atomically into a permission-restricted local store with idempotent re-delivery. Bundles are secret-scanned with typed placeholders, every file is hashed and token-estimated, handoff.md respects explicit soft/hard token budgets with deterministic degradation, and transcript search returns at most 50 events and 8,000 estimated tokens per query with a stable cursor. A missing or non-Git workspace degrades the export to an explicitly reported partial capture instead of failing.

This Phase 1 baseline originally exported one native ZCode session at a time. Phase 2 closed that gap: ZCode's parent/child relationship records were validated against a real multi-agent sample (Phase 2 investigation report), and a logical task is now represented as a session tree — discovery lists root tasks (sub-agent children summarized, --all to list them), inspection exposes the tree with roles, status, depth, and linkage evidence, and export includes related child sessions with every event tagged by its source session. Incomplete relations, deeper-than-validated nesting, diverging child directories, and still-active sessions produce traceable warnings or partial captures instead of silent repairs.

Phase 2 also adds the receiving side of the protocol: agent-handoff resume verifies a bundle for the current workspace (manifest integrity, capture status), matches it by repository evidence (worktree, history, remotes) with a HEAD relation report, and prints a bounded projection with pointers for on-demand transcript search. Thin, installable integrations for Claude Code and Codex live under skills/; they call the CLI and follow the same protocol without parsing any source-harness data. Since Phase 4.5 every target exposes the same entry — agent-handoff, invoked as /agent-handoff where the harness has a / menu — installed as ~/.claude/skills/agent-handoff/SKILL.md and ~/.codex/skills/agent-handoff/SKILL.md. The local ZCode-to-Claude-Code resume path has been verified; the local Codex path is postponed, and the cross-machine path is still open.

Workspace evidence is an observation, not a synchronization mechanism or a mandatory gate. A receiving harness may already be operating on the same remote workspace even when the source UI ran locally. Target integrations compare their live workspace with the capture, explain matches, differences, or uncertainty, and then decide how to proceed through their own policy and permission model; Agent Handoff does not automatically fetch, apply patches, switch branches, or overwrite files.

Remote delivery is implemented for the Phase 3 location-transparency scope: agent-handoff send <handoff-id> --to <target> publishes a finalized local bundle to a configured target's remote store, and agent-handoff target list shows the configured targets. The combined handoff [source] --to <target> convenience command is not implemented yet. The recommended cross-machine topology (validated against ZCode Remote Workspace in the Phase 3 investigation report) is to run the CLI on the machine where the session data lives; SSH delivery covers the local-session-to-remote-target path.

Phase 4 adds the setup and integration manager: agent-handoff setup detects local sources and harnesses, offers host candidates read from ~/.ssh/config (never written to), and accepts either an alias or a direct [user@]host[:port] destination — the explicit selection is the authorization. Selected hosts are scanned with one fixed read-only probe whose command line is shown in full before anything runs; supported hosts get a target appended to config.yaml (comments preserved, duplicate names refused), and --install writes the harness integration to the remote host after confirming the harness is configured there. agent-handoff skill status|install|update|remove manages the same integrations locally: they are embedded in the binary, and compatibility is decided byte-for-byte against the embedded content and the install records in ~/.agent-handoff/installs.json — a file that matches neither is reported as modified and never overwritten without --force. Implementation notes are in the Phase 4 report. Phase 4.5 then put every target on the shared agent-handoff entry (skills/agent-handoff/SKILL.md for both harnesses; see the Phase 4.5 report). The local ZCode-to-Claude-Code complementary test is done; the local Codex path is postponed, and the cross-machine path is still open. Phase 5 is more sources.

The initial implementation focuses on safely reading ZCode sessions and handing work to Claude Code or Codex. Additional source harnesses, remote backends, and execution environments will be added only after their storage and integration behavior has been validated.

Platform and installation status

The current reference implementation is validated on macOS arm64 (ZCode 0.16.3; the Phase 0–2 verification environments) and, for the Phase 3 scope, on a real Linux machine (Ubuntu 24.04): the local pipeline (SQLite snapshot, workspace Git evidence, bundle build, permission-restricted atomic store publish, resume) and the SSH delivery path (idempotent atomic publish, cross-clone same-history matching) both passed end-to-end. Windows is not currently supported and is deferred until the core protocol and Unix-like platform behavior are stable or concrete demand justifies the additional platform work.

Compiling the Go source on another operating system does not imply that its data locations, permissions, atomic file operations, Git subprocess behavior, or SQLite snapshot behavior have been validated there. Agent Handoff does not yet provide release binaries, an installer, package-manager formulas, code signing, or automatic updates; build-from-source is the only supported development workflow.

Build from source

Prerequisites:

  • Go 1.25 or later;
  • Node.js and npm for documentation formatting and linting only.
npm ci
make check
make build
./build/agent-handoff --help

Common development commands:

make format        # format Go code and project documentation
make format-check  # verify formatting without changing files
make lint          # run go vet and markdownlint
make test          # run Go tests
make build         # build build/agent-handoff
make check         # run format checks, lint, and tests

The Go module currently uses the local development path agent-handoff. It will be replaced with the canonical repository path before a public Go module is published.

Documentation

The design document describes the architecture, intermediate representation, bundle format, source-read safety, workspace matching, security model, implementation stages, and acceptance criteria.

About

Portable task state across coding agents.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages