---
title: "Handoffs and carry: keeping continuity across agent sessions"
description: "I kept losing open items in prose session handoffs, so carry blocks now hold each one until it's done, dropped with a reason, or promoted to the backlog."
url: "https://michael.zazon.us/notes/handoffs-and-carry-keeping-continuity-across-500-plus-sessions"
published: "2026-09-25T12:00:00-04:00"
kind: "build-log"
subject: "ai-agents"
tags: ["agents"]
---
Good ideas show up in the middle of building something, but chasing them wrecks the session's context and flow. So I log them as carry blocks, and they feed the backlog where I can prioritize them properly.

Before I started using carry blocks, I used to pass open items as prose in my session handoffs, instructing each session to copy the list into the next handoff. I didn't verify that they did. I should have checked instead of trusting the instruction. At one boundary, a backlog that had accumulated over months got squeezed down to 4 lines, losing 3 HIGH importance items.

The carry block is the check. I have one note per project in [my Obsidian vault](https://michael.zazon.us/notes/my-obsidian-setup-and-how-i-use-it) and read/write it through [Memento](https://michael.zazon.us/notes/memento-agent-memory-i-can-read-edit-and-prune), which already handles handoffs. Open tasks only.. facts stay in Claude Code's [memory files](https://docs.anthropic.com/en/docs/claude-code/memory). An item leaves the Open list only 3 ways: done, dropped with a reason, or promoted to the backlog. Anything else, the validator rejects the commit removing it.. a silent drop becomes an error.

I considered putting a `TODO.md` in each repo, but that broke two of my rules: tasks live in the vault, and public repos can't hold infrastructure details. Plus, any project without a repo wouldn't have anywhere for it. I also considered limiting each block to 15 items (I've since removed that limit) and breaking them into sections by workstream, but having every agent see everything is more valuable than saving a few tokens.

[Diagram: Carry item leaves only as done, dropped with a reason, or promoted; silent drop refused](https://michael.zazon.us/notes/handoffs-and-carry-keeping-continuity-across-500-plus-sessions)

[Image: A carry block note in Obsidian with its Open items and active Decisions](https://michael.zazon.us/notes/handoffs-and-carry-keeping-continuity-across-500-plus-sessions)

The first block for each project was seeded from the full session history. home-infra (my homelab project) alone turned up 62 open items from March-July that were documented nowhere. It exposed prose handoffs leaking for months, well before the one known bad boundary.

The day after I shipped the blocks, I ran a session in one of my projects to see what a fresh session would get. Claude Code only passes the output of a [hook](https://docs.anthropic.com/en/docs/claude-code/hooks) inline up to 10,000 characters.. beyond that, the model only sees a short preview. Four of my eight blocks exceeded that limit, so they arrived at the model with zero open items. (My earlier check that supposedly confirmed all items were arriving was testing a simulated session start, and I'd believed it.)

Re-imposing a cap would have satisfied the limit, but home-infra would have had to drop ~100 of its 126 items. I settled on a summary plus the 10 newest items per session, with the full file readable on demand. A live check after the fix showed the session searching the file for an item outside the window.. exactly the behavior the summary was supposed to enable.

Checking the hook's output isn't the same as checking what the model saw. The rule now is to verify from the session's own transcript. It was the best fix, since the limit was there whether I liked it or not.

This needs to work when I have multiple sessions open in the same project, as described in [Running six to nine Claude Code sessions at once](https://michael.zazon.us/notes/running-six-to-nine-claude-code-sessions-at-once). If one session tries to create a commit based on a stale read of a block, it gets rejected.. one session can't overwrite another's changes.

The 60+ recovered items showed how much was getting lost before. Keep feeding the backlog from carry and doing a weekly prioritization pass. Using carry blocks to prioritize and keep me honest about follow ups and check-after dates while I let something soak for a while or need to step away from a project for a few weeks.

This opens up future for parallel workflows and side sessions during the main thread, using [worktrees](https://git-scm.com/docs/git-worktree) or similar.