All Guides

16 / 25

Handing Off Environments to Agents

Core Questions

  • How do you swap your running dev environment with an agent?
  • How does context transfer work?
  • What state does the agent need to pick up where you left off?

You've been working on a feature for an hour. The dev server is running, you've got a few files open, and you know exactly where you left off. Now you want to hand this to an agent to continue while you sleep or context-switch to something else. The handoff is surprisingly hard. Filesystem state transfers easily; mental context doesn't. Good handoff protocols bridge this gap.

The handoff problem

Humans carry context that doesn't exist in files. You know which approach you tried that didn't work. You know why you chose this library over that one. You know the test is failing because you haven't finished the implementation yet. None of this is written down.

What Transfers vs. What Doesn't

Transfers automatically

  • • Source code and file changes
  • • Git history and branch state
  • • Package dependencies
  • • Running processes (with snapshots)
  • • Environment variables
  • • Database state

Requires explicit handoff

  • • What you're trying to accomplish
  • • Approaches already tried
  • • Why certain decisions were made
  • • What's known to be broken
  • • Open questions and unknowns
  • • Implicit assumptions

A cold handoff gives the agent files and nothing else. A warm handoff gives them context. The difference in output quality is dramatic.

Context serialization

The goal is to externalize your mental state into something an agent can read. This doesn't need to be formal — a quick brain dump is better than nothing. But structure helps agents parse and act on the information.

Principle

Write the handoff note you'd want if you were picking this up in two weeks

Future-you has the same context blindness an agent does. If you can write a note that would get you back up to speed quickly, it'll work for an agent too.

# HANDOFF.md

## Current State
- Working on: User authentication flow
- Branch: feat/oauth-google
- Dev server: Running on localhost:3000 (npm run dev)
- Tests: 2 failing in auth.test.ts (expected, not implemented yet)

## What I've Done
- [x] Set up OAuth2 client configuration
- [x] Added Google provider to NextAuth
- [x] Created login button component
- [ ] Handle callback and session creation
- [ ] Add user to database on first login

## Approaches Tried
- Tried using the old googleapis package — deprecated, use google-auth-library
- Tried storing session in JWT — too large, switched to database sessions

## Known Issues
- The redirect URI in Google Console needs updating for production
- TypeScript types for NextAuth are wrong in v5 beta, using @ts-ignore

## Next Steps
1. Implement the callback handler in /api/auth/callback/google
2. Create or update user record in database
3. Fix the two failing tests

## Questions / Blockers
- Should we support multiple Google accounts per user?
- Need to decide on session expiry (currently 7 days)

## Relevant Files
- lib/auth.ts - Main auth configuration
- app/api/auth/[...nextauth]/route.ts - Auth routes
- components/login-button.tsx - Login UI

This handoff document is your interface contract with the agent. The more explicit you are, the less the agent has to guess. Every guess is a potential wrong turn.

Environment snapshots

Beyond context, there's runtime state. If you've been debugging a specific scenario, the agent needs to be able to reach that same state. Some platforms offer environment snapshots — freeze the current state and restore it later.

Snapshot Strategies

Docker commit

Snapshot a running container to a new image. Preserves filesystem state but not running processes. Quick and portable.

docker commit my-container my-snapshot:handoff

VM snapshots

Full VM state including memory. Preserves everything including running processes. Larger files, slower to transfer.

Database dumps

Export database to SQL or JSON. Essential if debugging involves specific data state. Script the dump and restore.

pg_dump -Fc mydb > handoff.dump

Git stash with metadata

For uncommitted work. Include a message describing the state. Better than losing work to a reset.

git stash push -m " handoff: auth flow incomplete"

Warm handoff vs cold start

There are two fundamentally different modes: warm handoff where the agent inherits your running environment, and cold start where the agent spins up fresh. Each has tradeoffs.

Handoff Modes

Warm handoff

Agent takes over your exact environment — same processes, same state, same open files.

Fast startupExact state preservedCan inherit your bugsPlatform dependent

Cold start

Agent starts from scratch — fresh clone, fresh install, fresh environment.

Clean slateReproducibleSlower startupLoses runtime state

For most handoffs, cold start with a good HANDOFF.md is the right choice. Warm handoffs make sense when you're debugging a specific runtime condition that's hard to reproduce from scratch.

Session handoff protocols

A handoff protocol is a checklist that ensures nothing gets lost. Run through it before passing work to an agent, and you'll avoid the "I don't know what state this is in" problem.

Pre-Handoff Checklist

Commit or stash all changes

Uncommitted changes are invisible to agents starting fresh. Either commit (even as WIP) or document what's in the working directory.

Write HANDOFF.md

Current state, what's done, what's next, what you've tried. Takes 5 minutes, saves hours of agent confusion.

Run tests, note failures

Which tests pass? Which fail? Are the failures expected or bugs? An agent seeing failures won't know if they're pre-existing.

Document environment state

Is the dev server running? What ports? Any special environment variables set? Database seeded with test data?

Define success criteria

How will the agent know they're done? A passing test? A working feature? Be specific about the acceptance criteria.

Set boundaries

What should the agent NOT do? Don't refactor unrelated code. Don't add new dependencies. Don't change the API contract.

Resumable workspaces

The best handoff is one you don't have to think about. Resumable workspaces — environments that persist state across sessions — make handoffs automatic. When you stop working, the workspace pauses. When an agent picks it up, it resumes where you left off.

Resumable Workspace Platforms

GitHub Codespaces

Auto-suspends after idle timeout, resumes on reconnect. State persists including running processes (with limitations). Good integration with VS Code and GitHub Actions.

Gitpod

Workspace snapshots preserve full state. Can share workspaces via URL. Prebuilds make cold starts fast by pre-running setup.

Custom persistent volumes

Mount a persistent volume into ephemeral containers. State survives container destruction. Requires careful management of what persists vs. what resets.

# .gitpod.yml with prebuilds
tasks:
  - name: Setup
    init: |
      npm ci
      npm run db:migrate
      npm run db:seed
    command: npm run dev

# Persist state across sessions
workspaceLocation: /workspace/project
vscode:
  extensions:
    - dbaeumer.vscode-eslint
    - esbenp.prettier-vscode

# Prebuild on push to main
github:
  prebuilds:
    master: true
    branches: true
    pullRequests: true
    addBadge: true

Handoff tooling patterns

Automate what you can. A script that captures state is more reliable than a human remembering to document everything.

#!/bin/bash
# scripts/handoff.sh - Generate handoff documentation

echo "# Handoff State - $(date)" > HANDOFF.md
echo "" >> HANDOFF.md

# Git state
echo "## Git State" >> HANDOFF.md
echo "```" >> HANDOFF.md
echo "Branch: $(git branch --show-current)" >> HANDOFF.md
echo "Last commit: $(git log -1 --oneline)" >> HANDOFF.md
echo "Uncommitted changes: $(git status --porcelain | wc -l) files" >> HANDOFF.md
echo "```" >> HANDOFF.md
echo "" >> HANDOFF.md

# Uncommitted files
if [ -n "$(git status --porcelain)" ]; then
  echo "### Modified Files" >> HANDOFF.md
  echo "```" >> HANDOFF.md
  git status --porcelain >> HANDOFF.md
  echo "```" >> HANDOFF.md
  echo "" >> HANDOFF.md
fi

# Test state
echo "## Test State" >> HANDOFF.md
echo "```" >> HANDOFF.md
npm test 2>&1 | tail -20 >> HANDOFF.md
echo "```" >> HANDOFF.md
echo "" >> HANDOFF.md

# Running processes
echo "## Running Processes" >> HANDOFF.md
echo "```" >> HANDOFF.md
lsof -i -P -n | grep LISTEN | grep -E "(node|npm|next)" >> HANDOFF.md || echo "No dev servers running"
echo "```" >> HANDOFF.md
echo "" >> HANDOFF.md

# Prompt for context
echo "## Context (fill in manually)" >> HANDOFF.md
echo "- What I'm working on: " >> HANDOFF.md
echo "- What's done: " >> HANDOFF.md
echo "- What's next: " >> HANDOFF.md
echo "- Blockers: " >> HANDOFF.md

echo "Handoff document created. Edit HANDOFF.md to add context."

Run this before stepping away. It captures the mechanical state automatically; you just need to fill in the context sections.

Agent-to-human handoff

Handoffs go both directions. When an agent finishes a task (or gets stuck), you need to pick up where they left off. Good agents document their work; great systems require it.

Agent Handoff Requirements

Summary of changes

What files were modified? What functionality was added or changed? A diff isn't enough — explain the intent.

Decisions made

Why did the agent choose approach A over approach B? What tradeoffs were considered? This context helps humans review meaningfully.

Test results

All tests passing? Any new tests added? Any tests that were skipped or disabled? The test state is the primary quality signal.

Known limitations

What edge cases aren't handled? What assumptions were made? What would the agent do differently with more time?

Reproduction steps

How can a human verify the work? Step-by-step instructions to see the feature working. Screenshots or recordings if relevant.

What goes wrong

Agent ignores handoff context

You write a detailed HANDOFF.md explaining what you've tried. The agent immediately tries the same approach, wastes tokens, hits the same wall.

Fix: Put handoff context in the system prompt or first message, not just a file. Reference it explicitly:" Read HANDOFF.md before proceeding. Do not retry approaches marked as failed."

State drift during handoff

You document the state, hand off to an agent, but by the time the agent starts, something has changed (another PR merged, dependencies updated).

Fix: Pin the exact commit in the handoff. Lock the branch from other merges during agent work. Use lockfiles and version pinning to prevent dependency drift.

No handoff documentation at all

Developers hand off work without any context. Agent has to reverse-engineer intent from code, often guessing wrong.

Fix: Make handoff documentation a required artifact. Block agent task assignment until HANDOFF.md exists. It's a small friction that prevents large waste.

Agent doesn't document its work

Agent makes changes but doesn't explain them. Human picks up a diff with no context, has to spend time understanding what was done and why.

Fix: Require structured output. The agent must produce a COMPLETION.md with summary, decisions, test results, and verification steps before the task is considered complete.

Summary

  • Handoffs fail when context is lost — mental state doesn't transfer automatically, only files do
  • Write HANDOFF.md before stepping away: current state, what's done, what's next, what you've tried, and acceptance criteria
  • Cold starts with good documentation beat warm handoffs with poor documentation
  • Automate state capture with scripts — humans forget, scripts don't
  • Require agents to document their work too — handoffs go both directions

Stay updated

Get notified when we publish new guides or make major updates.
(We won't email you for little stuff like typos — only for new content or significant changes.)

Found this useful? Share it with your team.