FunnyEnough

Engineering notes & expertise

Reading

Size
Theme
Motion
For long-form reading
Type
Width
Space
Aids

The four most expensive words in autonomous coding are “everything’s committed and ready”. My agent said them, I believed it, then I asked it to check again, properly. The second pass found a bug the first one had just written, in the single file I most needed to trust: the handoff.

If you run coding agents across more than one session, you’ve met the handoff. It goes by decisions.md, context-handoff.md, CLAUDE.md, handoff.json. You write it at the end of one run so the next run can carry on, because the next run remembers nothing. That amnesia is measured. The NoLiMa benchmark watched 11 of 13 models fall below half their baseline score by 32K tokens; Chroma saw all 18 models it tested degrade as context grew; a much-quoted 2026 figure blames roughly two-thirds of last year’s enterprise AI failures on context drift or lost memory. The handoff note is the industry’s duct tape over that hole.

Here’s the part the how-to-write-a-handoff posts skip. This file is written by the party with amnesia, for the party with amnesia. It’s a sticky note your goldfish leaves for your goldfish. We’ve built tooling that lints the instructions in these files (AgentLinter will scold a bloated CLAUDE.md all day) while nothing checks whether the facts in the handoff are still true. We spell-check the vibes and trust the diary.

A fact can be born stale

My handoff had a tidy table pinning each branch to its current commit. Writing the handoff committed a file. Committing a file moved the branch. So the hash was already wrong when I saved it, out of date before the ink dried.

| branch    | HEAD a1b2c3d |   <- already false; saving this file moved HEAD

No human catches that on a reread, because it looks exactly right. It’s a true-looking fact that was never true for a single second.

Split the file by shelf life

The fix is to stop treating the handoff as one document. It’s two, with wildly different shelf lives.

The volatile half is anything that changes when you breathe on the repo: branch heads, what’s dirty, which worktree holds what. Never type these. Generate them, so they’re correct by construction and refresh themselves:

# emit the live state INTO the handoff; don't describe it from memory
{
  echo '## Repo state (generated, do not hand-edit)'
  git worktree list
  echo '--- recent ---';      git log --oneline -6
  echo '--- uncommitted ---'; git status --porcelain
} >> HANDOFF.md

The durable half is the prose only judgement can produce: why you parked a task, what the next move is, the landmine waiting in some module. You write that by hand. Then you lint it.

The twelve-line handoff linter

It answers one question: does anything this file claims still exist?

# handoff-lint.sh - is the handoff still telling the truth?
f=${1:-HANDOFF.md}
grep -ohE '\b[0-9a-f]{7,40}\b' "$f" | sort -u | while read -r sha; do
  git cat-file -e "$sha^{commit}" 2>/dev/null || echo "stale ref: $sha (named here, not a commit)"
done
[ "$(wc -l < "$f")" -gt 100 ] && echo 'over 100 lines: nobody will read this'

I ran it on my own handoff while writing this paragraph. Clean: every hash a real commit, 44 lines. It only came back clean because the same instinct, re-derive from git instead of believing the prose, had caught the born-stale line the day before. The linter is that instinct written down, so I can stop relying on remembering to have it.

One honest limit: git cat-file proves a hash exists, not that it’s current. A commit you pinned as “HEAD” can be real, reachable, and thoroughly out of date. That’s the whole reason the volatile half gets generated and never typed. The linter only guards the leftovers.

The other handoff: you and the agent

There’s a second handoff running through every session, live, between you and the model. After a week of it, here’s which of my own moves actually steered the thing and which only felt productive.

Worked:

  • Hard limits, stated once. “Commit locally, never push.” “Don’t stage that file.” Give an agent a bright line it can check itself against and it holds it better than most of us hold a New Year’s resolution.
  • Asking for the recheck out loud. “Verify it again, properly” is five words, and it’s what caught the stale hash. The model is good at re-deriving the truth. It’s just too polite to do it uninvited.

Didn’t:

  • State I kept by hand drifted. A standing directive told the next session to resume task X. We’d spent the entire run on Y and Z, and I’d forgotten to update the note. A fresh boot would have marched confidently back into X, because nothing made it check the order against reality.
  • Vague asks bought confident nonsense. I once asked for a coat of paint and got a twenty-minute forensic audit of a correctness theory nobody had requested. Ambiguity doesn’t make an agent careful. It makes it inventive.

The shape underneath: an agent is dependable on bounded instructions and on re-deriving facts when told to, and undependable at holding your intent across a long run or noticing that the state you own has gone off. The handoff is where you pay down both debts in one place.

The cold-start test

Here’s the acceptance criterion I keep coming back to, and the one part of this I had to work out rather than look up. A handoff is good when a brand-new session can read only that file, run git status, and know exactly where to stand. Not “is it thorough”. Not “is it tidy”. Could a stranger holding your repo, with no memory of the work, take over from this alone? Mine failed that test on Monday and passed on Tuesday. Treat it like a runbook: if it can’t survive a cold start, it isn’t finished.

Takeaway

The handoff is the interface between agent runs, and the cheapest place to lose a day. Generate the facts that rot, hand-write only the judgement, lint what’s left, and make it pass a cold start before you close the tab. The fanciest agent-memory stack on the market still hands off, in the end, through a note somebody has to trust. Make it a note worth trusting.

Further reading: NoLiMa (LMU Munich / Adobe, ICML 2025) on long-context decay; Chroma’s “context rot” study across 18 models; mem0’s State of AI Agent Memory 2026; and AgentLinter, if you’d like your CLAUDE.md instructions linted too (different file, different problem).

Comments & Reactions

Got a thought, a war story, or a “well, actually”? Sign in with GitHub and jump in.

Loading comments…