My CRM project, Crono, has a build plan with twelve phases, from identity and organizations through teams, billing and industry templates. The plan is too long for one AI conversation, and I do not want to compress a conversation and keep going until the details blur. So each phase gets its own fresh thread in T3 Code, and I use a small set of rules to bring each new thread up to speed.
This article describes that workflow, where it comes from, and what I measured when I tested it. I had Claude, the AI agent that works for me, run the measurements. It is not a replacement for anything. It is a way of working I settled on for large projects, and saving tokens turned out to be the smaller part of the benefit.
The rule: one task, one commit, one pack update
The workflow has three rules, applied in order:
- Commit only when a task is done. A task is one item on the phase's to-do list, with all of its subtasks finished. A commit therefore marks a task boundary, not a point in the middle of the work.
- Update the pack after the commit, looking forward. The pack records what is now finished, but its most important job is to say what happens next: the details of the next task and what comes after it. After every commit, a fresh thread or a fresh branch should be able to start from the pack alone.
- Start each phase in a new thread. The new thread reads the pack, the to-do list and the repository state, and carries on.
The pack is one Markdown file, docs/context-pack.md, kept under 10 KB. It holds what a newcomer needs: what is true now, decisions that change how people work, open questions, and above all the details of the next task and what follows it. Reasoning goes to the research notes, tasks go to todo.md, and finished history stays in Git. Four pieces keep it honest:
- A size cap. Over 10 KB, a commit prints a warning and the rules say to trim. Without a cap the file turns into the context it was meant to replace.
- A generated status section. A pre-commit hook rewrites the branch, the last five commits, the task count and the next open tasks. Code produces the facts that go stale fastest. If the hook fails, it only prints a warning, so it can never block a commit.
- A commit reminder. A Claude Code hook fires after any
git commitand asks the agent to update the hand-written sections. Because commits only happen at task boundaries, each reminder means a task has just finished. - An entry point.
AGENTS.mdtells a new thread to read the pack andtodo.md, then checkgit statusand the last few commits, and not to scan the rest. Where the pack and Git disagree, Git wins.
Phases in Crono have between 5 and 19 tasks, about 11 on average, so a phase typically sees about 11 pack updates.
Related approaches
I did not invent the idea of keeping project state in files for the next session. Others have shown the same need:
- Cline's Memory Bank keeps project memory in Markdown files in the repository. Its documentation describes a manual handoff: ask the agent to "update memory bank", start a new conversation, and have it follow its instructions to read the files.
- Anthropic's long-running agent harness, described in Effective harnesses for long-running agents, starts from the same problem: each session begins with no memory of the last. It hands state over with a progress file, a feature list and descriptive Git commits, and each new session starts by reading the progress file and the Git log.
- Session-handoff documents are a common idea in agent tooling. Some tools generate a handoff for each phase of a plan. I only read their listings, so I do not describe them in detail.
What is mine
What I did not find in those is the specific combination I settled on:
- a hard size cap on the briefing, with a rule for trimming it;
- a status section generated by a pre-commit hook, so the volatile facts are never written by hand;
- a rule that the pack is a snapshot, replaced and not appended, and that Git wins when sources disagree;
- the discipline of tying the update to a finished task, by committing only at task boundaries; and
- measurements of what it costs and saves, which follow.
None of those is a large idea alone. Together they are the workflow that works for me.
The first claim, and why I checked it
The chat I built this in estimated that gathering the same knowledge from the project's files would take about 18,000 tokens, against about 3,000 for the pack: a saving of 15,000 tokens per thread. That is a model's estimate, not a measurement.
The file sizes already adjusted it. The pack is about 9.4 KB, roughly 2,500 tokens, but the start-up flow also reads todo.md at about 3,700. A new thread really loads about 6,000 tokens before it does anything.
Test one: starting a phase
I had Claude run fresh, read-only sub-agents against the repository. Each was told it was a brand-new thread that must begin Phase 2, Phase 6 or Phase 10, three phases of very different size. Each produced a kickoff brief: the branch and exit test, the phase's tasks, earlier decisions that constrain it, open questions for me and anything that blocks starting. Every phase was run twice, once starting from the pack and once with the pack hidden.
| Phase | Tokens with pack | Tokens without | Difference | Time with / without |
|---|---|---|---|---|
| 2: Background work and reliability | 42,848 | 54,953 | −12,105 | 9.9 s / 23.1 s |
| 6: Teams and the Office template | 43,023 | 53,994 | −10,971 | 13.6 s / 24.5 s |
| 10: Guest pages and templates | 43,032 | 42,648 | +384 | 11.7 s / 25.5 s |
| Total | 128,903 | 151,595 | −22,692 | 35 s / 73 s |
Each figure includes a fixed overhead for the agent itself, so the difference is what counts. The pack saved about 7,500 tokens per phase start, 15% overall, halved the time and cut tool calls from 20 to 12. The saving was large for the two phases whose tasks touch many earlier decisions, and nothing for Phase 10.
The briefs were both correct, but they differed. Without the pack they were deeper: searching the repository turned up details the pack leaves out on purpose, such as reset emails sending inside the request in Phase 2. With the pack they were shorter, and every one noticed that Phase 1 was unmerged with 60 uncommitted files and said not to start the next phase. Two of them caught that the generated task list in the pack lagged behind todo.md. So the pack buys a cheaper, faster and consistent start, not depth. A thread pulls in that depth as the phase needs it.
I also tested six narrow lookups, such as "what are the superuser rules?". There the pack cost about 5% more tokens overall, because a targeted search opens two or three files while the pack and todo.md are always read in full. It is built for starting a phase, not for answering one-off questions.
Test two: what keeping it current costs
A saving at the start means little if the upkeep eats it, so I measured that too, first from my real Crono sessions, which Claude Code stores as transcripts with token usage. Across them there were 17 commit reminders, and in 13 the agent did nothing further because the pack had already gone into the commit. The text of a pack edit was a median of about 350 tokens.
Those figures only bound the cost, so I ran a controlled replay. I took real Crono commits, restored the pack to its state before each commit's update, and had Claude do what the reminder asks. I subtracted a no-op agent as the fixed overhead.
| Setup | Tokens per update |
|---|---|
| Cold: a fresh agent that knows nothing about the commit (6 commits, 8,753 to 12,359) | about 10,300 |
| Warm: the agent knows the commit but has not read the pack (4 commits, 4,574 to 6,309) | about 5,200 |
| Reading the pack once, with no edit | about 5,500 |
The warm figure is almost the same as the cost of reading the pack, so the edit itself is nearly free. In a thread that already holds the pack, as the start-up flow ensures, I estimate an update at about 1,000 tokens, within a range of 400 to 2,000. That figure is inferred from the gap between the measurements, not read directly.
What that means for the task-based rule
With about 11 tasks per phase, one update per task is about 11,000 tokens of upkeep per phase, within a range of roughly 4,000 to 22,000. The saving at the start of the phase is about 7,500. So on tokens alone the workflow is close to break-even, and probably a little negative, because Crono's phases are long. Earlier, while Crono's commits bundled several tasks, it needed fewer updates: 13 finished tasks went into 6 commits.
That does not make the rule wrong, since tokens were never the reason for it. The rule gives:
- A pack that is correct at every task boundary. If a thread ends early, the next one can resume from the last finished task, not from a guess.
- Faster, more consistent starts. Thread starts took about half the time, with 40% fewer tool calls, and every thread begins from the same agreed facts.
- A commit history that matches the plan. A commit means a task is done, so the log and
todo.mdtell the same story. - A safer start. Every pack agent flagged the unmerged previous phase.
If tokens matter more to you than the task-level guarantee, you can update at phase boundaries instead and keep a clear net saving. I do not, so I keep the task-level rule.
What T3 Code already gives this, and what is left
I run all of this in T3 Code, where one thread per phase is natural, and it needs very little from the tool. The agent reads AGENTS.md, AGENTS.md points to the pack, and the two hooks are ordinary Claude Code hooks. Nothing in the workflow depends on a T3 Code feature.
Other people are working on neighbouring problems, and it helps to say how mine differs:
- Handoff to a fresh thread. One discussion proposes handing a long thread over to a new one instead of compacting it, with a note kept from the start. An earlier proposal for a separate "Continue in new thread" action was closed as not a priority. Those notes are written by the agent at the moment of the handoff. Mine is a file in the repository that is kept current at every finished task, so it exists before any thread ends, survives a crashed or abandoned thread, and is read by every tool.
- Per-thread instructions and memory. Another proposal gives each thread its own role and facts. That is about who a thread is. A context pack is about where the project stands, and it follows the project from thread to thread.
If there is something to ask of the tool, it is small: show how many tokens a new thread spent before its first useful action, so people can compare ways of starting a thread with numbers, as I tried to do here. I would not ask for more than that without a clearer case.
Limits
This is one project, one model, three phase starts and one run per condition, so treat the numbers as an order of magnitude. The upkeep figures come from 13 real edits and ten replayed updates, and the replayed agents were separate, short-lived threads, not a long working session. Output tokens also cost more than input tokens, and most of the saving is input, so the two sides are not exactly like for like. I did not compare against compressing a long conversation and continuing, and I did not test whether a thread started this way builds better code. I only tested how well it begins.
Using it on another project
The idea suits any project with many phases or modules, where each gets its own thread and the background material is much larger than a thread can reread. The pieces carry over: a capped file, a rules file, a pre-commit script that rebuilds the status section, a post-commit reminder hook and a pointer in AGENTS.md. The one project-specific part is how the script reads your task list. Mine expects ## Phase headings and - [ ] checkboxes.
I have since turned that setup into one command in sk8r, a small open-source tool I am building. In a Git repository, sk8r pack init --dry-run shows the whole plan and changes nothing, and sk8r pack init carries it out after one confirmation:
- it creates
docs/context-pack.mdfrom a template that includes the rules and the 10 KB trimming guidance; - it finds your task list,
TODO.mdortodo.md, or creates a starter one in the expected format; - it records the task list, the pack and the branch the pack is refreshed on in a small settings file,
sk8r.toml; - it adds a start-here block to
AGENTS.mdand keeps everything already there; and - only if you ask, it adds the pre-commit refresh (
--hook), extending an existing hook instead of replacing it, and the Claude Code commit reminder (--remind claude), merged into your existing settings.
Every change is recorded, and sk8r undo reverses it. One deliberate difference from Crono's script: sk8r's generated section leaves out the list of recent commits by default, so the pack changes only when the plan's facts change, not with every commit. For agents without hooks, sk8r pack --check reports whether the pack is stale.
sk8r is early, at version 0.1, so I will update this section as it matures.
Comments
Tried this setup, hit a different result, or think something here is wrong? Say what you ran, what happened, and why. Agreement and disagreement are equally welcome; one-line reactions are not published. No account needed.