You ask the assistant to rename a hook, and it edits a file you deleted forty minutes ago. You point that out, it apologises, and in the next message it reintroduces the wrapper you removed at the start of the session because the wrapper "keeps the API consistent". That is the point where most developers decide to push harder: re-paste the current file, restate the constraint, maybe write it in capitals. It almost never works. The honest move is to start a new AI coding session, and the reason it feels expensive is a filing problem, not a loss of progress.

Three hours of back-and-forth feels like an asset. It mostly is not. The working code is on disk, the reasoning worth keeping can be written down in a couple of minutes, and everything else in that transcript is scaffolding you built to get here.

The mistake: treating the chat as where the work lives

A long session accumulates two things at once. One is real output: files changed, tests passing, a design you now understand. The other is conversational sediment, which includes every file version the model has seen, every wrong turn it took, every correction you issued, and every intermediate plan that got replaced. The model cannot tell which version of useSync.ts is current. It sees four of them, all equally present, and picks confidently.

So the cost of continuing is not "the model is tired". It is that the signal-to-noise ratio inside the context has degraded past the point where more instructions help. People call it context rot, and it is a straightforward consequence of how a context window fills up. Adding your fifth clarification makes it slightly worse, not better.

The sunk-cost feeling comes from believing the chat is the only record. Fix that belief and restarting becomes cheap.

Signs the session is already gone

You rarely get a clean break. These are the signals worth acting on:

  • It edits or references a file you deleted, moved, or rewrote during the session.
  • It re-proposes an approach you explicitly rejected earlier in the same conversation.
  • You have corrected the same misunderstanding twice and it comes back a third time.
  • It starts hedging: "you may want to check whether this file still exists".
  • You find yourself re-pasting current file contents to keep it honest. That is you manually repairing the context, which is the job a fresh session does for free.
  • Simple edits start producing collateral changes in files that have nothing to do with the request.

One of these is noise. Two in a row is a stale AI chat, and the useful response is to stop and capture, not to argue.

AI session length is a bad proxy on its own. A long session that stayed on one narrow task can be perfectly coherent at message ninety. A short one that wandered across four subsystems can be useless at message twenty.

The mistake: closing the chat without harvesting it

The opposite failure is restarting impulsively. You kill the session, open a new one, and realise you cannot reconstruct why you abandoned the queue-based approach, or which of the two migration orderings actually worked.

What survives a closed chat by default: the files, your git history, your terminal scrollback. What disappears: the reasoning. The three options you weighed, the constraint you discovered at minute fifty, the thing you tried that broke in a non-obvious way.

That reasoning is exactly what the next session needs and exactly what no amount of code reading will recover.

The fix: a two-minute harvest before you close

Before you restart an AI session, ask the current one to do the summarising while it still has the context. Something like: "Summarise what we changed, what we decided and why, what we tried and dropped, and what is still unfinished. Be specific about file paths."

Then put it somewhere durable. Plain Markdown is fine:

.prjcontext/
  memory/
    2026-10-04-sync-refactor.md
  sessions/
    sync-refactor-session-1.md

The memory entry is short and declarative:

### 2026-10-04 — Sync refactor, session 1
Decided: queue writes in the worker, not the hook.
Dropped: debounce in useSync (fired before the optimistic update landed).
Open: offline reconnect path untested.
Next: wire worker retry, then delete the old hook.

Keep the raw transcript too if the path mattered, not because you will reread it, but because the next session can. Guidance on which sessions are worth keeping applies here: a session you are abandoning because of context rot is often worth saving precisely because it contains the dead ends. Writing project memory an assistant actually uses is the other half of this habit, and it pays off well beyond restarts.

Loading the next session with exactly what it needs

A fresh session with a pointer to the memory entry starts better than the degraded one you just closed. Open it with the current state, not the history: the memory entry, the instruction file, the two or three files in play, and the next concrete task. No replaying of the previous conversation.

That is the point where a shared store beside the code earns its place. We built PrjLab so instructions, memory entries and kept sessions sit in the same versioned repository as the files, which means closing a stale chat costs nothing: prj push when you harvest, prj pull on the machine where you continue, and the next assistant (same tool or a different one) reads the same context. The same mechanism is what makes continuing on another machine uneventful. The getting-started guide walks through the first push.

A rule of thumb for when to start a new AI coding session

Restart when the context no longer matches reality: files have changed underneath it, or the same correction has not stuck. Harvest first, always.

Keep going when the session is still tracking the current state of the code and you are in the middle of one tight edit loop, even if it has been running for hours. Coherence beats brevity.

And restart on purpose at task boundaries, before anything degrades. Finishing the worker retry and then starting fresh for the offline path costs one memory entry and buys you a session that has never seen a wrong turn.