AI in Practice May 2026

The Session Is Not the Project

Surviving one reset is a session problem. Sustaining an AI project needs its own structure.

I wrote earlier about surviving the token limit. The argument was simple: stop treating one chat as the unit of work, keep the real memory in a few plain files, and a reset becomes a resumption instead of a reconstruction. A plan.md, a handoff.md, a log.md — that was enough.

It was enough to get started. It turns out it is not enough to keep going.

I found this out the hard way on a project that ran for weeks rather than days. The handoff file held up in the first few sessions. Then it started to bloat. The “decided” section grew until it was a paragraph of reasoning instead of a line of fact. The “next step” multiplied into five next steps. I was updating it faithfully, and it was getting harder to read, not easier. By the third week, opening the handoff file before a session felt less like consulting a compass and more like re-reading a transcript.

The problem wasn’t continuity. I had continuity. The problem was that I had treated the handoff as a journal when it needed to stay a signpost.

The files were right. The discipline was wrong.

Here is what I had not thought through in the original setup: different things in a project have different shelf lives, and collapsing them into the same document is what turns a clean handoff into noise.

A decision about architecture — “we deduplicate by email, not name” — is durable. It belongs somewhere permanent and should rarely change. A note about where you left off — “preview renders but errors aren’t highlighted” — is live for exactly one session and then it’s either done or it becomes a bug. The next task to pick up is a cursor, not a record. Mixing all of these into one file means every read costs you the whole history, even the parts that have already closed.

What actually helped was making the split deliberate.

Stable knowledge lives in one place. Active state lives in another.

The original three-file setup assumed the handoff carries everything. A larger project needs a cleaner separation.

Some things are durable and should be written once, then only touched when something structural changes: what we’re building, the constraints that are fixed, the decisions that are settled, the patterns we’ve agreed to follow. This is not a status update. It’s the project’s memory of itself — what it would tell a new collaborator if they asked “how does this work and what have we already figured out?” In the original framing, plan.md was closest to this, but it only held scope. In practice, it needs to also hold the stable technical decisions, the conventions, and the workflow patterns that the model would otherwise have to re-derive every session.

Other things are volatile: what you just did, what broke, what the one next thing is. This belongs in the handoff and should be aggressively trimmed. Once a task is done, it leaves. Once a decision is settled, it moves to the stable layer. The handoff should be short enough that you can read it in a minute, because if it isn’t, you will start skimming it, and skimming is where continuity quietly breaks.

The prompt is not the project, and the context is not the memory.

The second thing I had underestimated was how much re-explanation was still leaking into each session.

Even with a good handoff, I found myself writing the same framing twice: once in the handoff file and again in the opening message of the session, slightly differently, because the file didn’t quite fit the specific question I needed to ask. That repetition is a signal. When you find yourself re-narrating context that should already be captured, it means the captured context isn’t shaped right.

The fix is to think about what question each document answers, and to keep it answering only that question.

plan.md answers: what are we building and what’s fixed about it?
handoff.md answers: where did we stop and where do we pick up?
A stable conventions or decisions file answers: what have we already settled?
A log.md answers: what have we tried that didn’t work?

None of them answer all of these questions. When a document tries to answer more than one, it ends up answering none of them cleanly.

Skills are procedures, not personality.

The third thing that changed was how I thought about workflow steps that repeat.

On a short project, it is fine to explain how you want a review done, or how you want a triage pass structured, each time you ask for it. On a long project, that explanation is a fixed overhead you pay forever. And unlike most overheads, it doesn’t even compound into value — you are paying the same tokens to reinstruct the same behavior on every session, because the model has no memory of the previous ones.

The answer that emerged from practice is encoding stable workflows as short documents — not personality files, not giant system prompts, but focused procedure descriptions. “When I ask for a review, here is the structure: first look for broken contracts, then look for missing edge cases, then list anything that will make this hard to maintain. Output in this format.” Written once, referenced by name, not re-explained from scratch.

What is interesting is that writing these down improves the workflows themselves. The act of encoding a procedure surfaces the parts you haven’t thought through. A vague “do a thorough review” turns into a checklist you actually meant to run but had never formalized.

The session is the work unit. The project is the thing that persists.

The original insight — stop treating the chat as the unit of work — was correct. The refinement is that the project needs its own architecture, and that architecture is not the same as the files that survive a session.

What I mean is this: a project that runs for weeks across dozens of sessions has a shape. It has layers — things that were decided early and haven’t moved, things that are in active flux, things that got tried and failed and should be remembered so they don’t get tried again. That shape needs to be reflected in the files you keep, or every session starts with a minor archaeology project — sorting through what’s current, what’s settled, and what’s already been discarded.

Building that structure is not a prompting problem. It is closer to information architecture. You are deciding, deliberately, what survives, in what form, at what granularity. The model benefits from it, but so does anyone else working on the project, including you three weeks from now.

What it looks like on disk

If you are a developer and want something concrete to copy, here is the structure that emerged from practice. It fits in a .claude/ directory at the project root, which Claude Code picks up automatically.

.claude/
  STATUS.md          ← the entrypoint; read this first, every session
  HANDOFF.md         ← volatile; where we stopped, what's next
  DECISIONS.md       ← durable; settled architectural choices
  HANDOFF-ARCHIVE.md ← sealed history; indexed, never loaded by default
  skills/
    review.md        ← how to run a code review
    triage.md        ← how to triage a bug or failing test

STATUS.md is the only file that gets read unconditionally at the start of every session. It is intentionally small — thirty lines maximum — and its job is to orient, not to explain.

# STATUS — contacts import module

Last commit: a3f92c1 — wire rollback on partial failure
Phase: build (not yet in review)
Tests: 47 passing, 2 skipped (rollback path)

## Read next
- HANDOFF.md for active state
- DECISIONS.md §3 for the dedup strategy

## Open
- [ ] highlightErrors() not yet hooked into preview table
- [ ] 50k row sample test still failing on malformed headers

DECISIONS.md is where a decision goes once it stops being live. The entry is short: what was decided, why, and what was ruled out. Nothing else.

## §3 — Deduplication strategy (settled 22 May)

Deduplicate by email, not name.
Name collisions were too common to trust as a unique key.
Considered composite key (name + company); ruled out — company field is optional.

Once something lands in DECISIONS.md, it does not go back into HANDOFF.md. If you find yourself re-explaining a decision in the opening message of a session, it either belongs in DECISIONS.md and isn’t there yet, or it’s there but not being loaded.

skills/review.md is a short procedure file, not a personality prompt. The model reads it when you say “run a review using the standard process.” It should fit on one screen.

# Skill — code review

1. Check contracts first: do the types and interfaces match what callers expect?
2. Look for missing edge cases: empty input, max size, partial failure.
3. Flag anything that makes this hard to maintain six months from now.

Output format:
- Contracts: [list or "none found"]
- Edge cases: [list or "none found"]
- Maintenance: [list or "none found"]
- Verdict: ready / needs work / blocked

The total cold-start context for a session — STATUS.md plus HANDOFF.md — should stay under two hundred lines. If it grows past that, something that belongs in DECISIONS.md or the archive is still sitting in the live files.

The trigger for updating HANDOFF.md is not the model running low. It is you: when a real chunk of work just finished, when you are about to paste a large file into the context, or when you catch yourself re-explaining something for the second time. Those are the moments to checkpoint and decide whether to keep going in the current session or start clean from STATUS.md and the updated handoff.

Token savings are a side effect, not the goal.

The best practices that emerged from this — status files, live/archive splits, skills as procedures, memory files trimmed to signal rather than history — will also reduce the tokens you spend per session. That is real and worth having.

But I keep noticing that the projects where these habits actually stick are not the ones where someone sat down to optimize costs. They are the ones where someone got frustrated that context kept breaking, that decisions kept getting re-litigated, that the model kept wandering back to approaches that had already been ruled out. Token efficiency was the side effect of solving a different problem: keeping the work coherent across time.

The framing that has stayed with me is this. A session is a workspace. The project is what persists between workspaces. For a long time I was designing good workspaces and hoping the project would take care of itself. It doesn’t. The project needs its own structure — not elaborate, not bureaucratic, but deliberate. A few files with clear responsibilities, updated on human triggers rather than when the model complains, light enough to be read before every session without becoming a burden.

Do that, and the limit becomes what it always was: an ordinary boundary at the edge of a workspace, not the edge of the project itself.