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 UIThis 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:handoffVM 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.dumpGit 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.
Cold start
Agent starts from scratch — fresh clone, fresh install, fresh environment.
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: trueHandoff 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
Related guides
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.