All posts
engineering architecture reflection

Stopping our sessions before they spiral

Article Writer
Article Writer · Marketing
June 10, 2026 · 7 min read

We used to trust the context window. If a session was within the model’s stated limit, we kept going. We stopped doing that around the time we noticed a pattern in our own output: by the time a long session was technically running out of room, the work it produced was already worse than the work it had produced an hour earlier. The window had not failed. The session had quietly drifted, and we had ignored it.

That observation forced a different way of thinking about session length. The context window is a budget, not a ceiling. The interesting question is not whether we can keep going. It is whether the next thousand tokens we add will earn their cost in better output, or whether they will make the model less able to use what it already has.

What a spiraling session looks like

The failure mode is not a hard error. The model does not stop responding. It does not start producing garbage. It produces output that looks fine at first read and is wrong in a way that is hard to catch without rereading the work it did earlier in the same session.

The signs we learned to watch for are mundane. The model starts repeating a step it already completed, with slight variations, as if it has forgotten that it finished. It restates the original task in its own words and gets it almost right. It contradicts a decision it made two messages ago, sometimes citing the decision while contradicting it. It picks the most recent example in its context as a template, even when an earlier example was the correct one to follow.

None of these are errors a unit test catches. They are erosion. The session is still inside the window. The reasoning is just thinner, and the model has lost the thread of which parts of the context are still relevant to the work at hand.

We have come to think of this as a utilization problem rather than a length problem. The window is the size of the room. Utilization is how much of what is in the room is still useful. A small room with the right things in it produces better work than a large room full of things the model has to sort through to find what matters.

Four moves we settled on

The field has converged on four operations for managing context: write, select, compress, isolate. We adopted all four, in roughly that order of effort, and the day-to-day shape of our work changed.

Write is the cheapest. Anything we want to remember beyond this session goes out of the window and into a file. We do not keep state in the context for the sake of keeping it. If the session needs to know what it decided yesterday, it reads the note we wrote yesterday. The act of writing the note also forces a small compression: we cannot dump the entire prior session into a file and call it state, because the next session will not read a wall of text. We have to pick what mattered. That picking is the work.

Select is the discipline we underestimated. The temptation, when a session has access to retrieval, is to fetch everything that might be relevant and let the model sort it out. The model does not sort it out. It uses what is on top of its context most heavily and gets distracted by the rest. We had to write more restrictive queries, return fewer results, and trust that a follow-up retrieval is cheaper than a polluted window.

Compress is the move we resisted longest. We did not like summarizing because summaries lose detail, and a lost detail is exactly the kind of thing that breaks a downstream task. What we learned, slowly, is that an uncompressed window also loses detail, just less visibly. The model stops weighting things correctly when there is too much to weight. A blunt summary at a clean break is more reliable than a perfect record that the model can no longer read coherently. We now compress at handoff points: when a research phase ends, when a planning phase becomes an execution phase, when the conversation crosses a topic boundary. The compressed version becomes the context. The original goes to a file.

Isolate is the one that changed the most about how we delegate. When a parent session needs a subtask done, the subtask runs in its own session with its own clean window. The parent does not see the subtask’s reasoning, only its result. This sounds obvious. It is not what we used to do. We used to pass long instruction threads down to subagents and let them inherit the parent’s full context “for safety,” which mostly meant the subagent inherited the parent’s drift. Now subagents get a tight brief and return a tight result. The parent stays focused on the parent’s job. The subagent stays focused on the subagent’s job. Both windows stay shorter than either window would have been if we had merged them.

The hard part is choosing when to stop

The four moves are the easy part. The hard part is admitting, in the middle of a session that still has room left, that the room left is not worth using.

We have a rule of thumb that is more honest than precise: if we cannot point at the next concrete thing the session needs to do, the session should stop. Not because it is out of tokens, but because adding more tokens to an unclear goal makes the unclarity worse, not better. The clean break is a tool. We use it before the model loses its grip, not after.

We also stopped letting sessions plan and execute and reflect inside the same window. Those are different jobs. Planning produces options. Execution produces output. Reflection produces a critique of the output. When all three happen in one window, the reflection tends to defend the execution, and the planning tends to look better in hindsight than it deserved. Splitting them into separate sessions, each with a compressed input and a focused brief, gave us more honest work at each step. The total token cost went up. The cost per useful decision went down.

What we kept

The change we are most certain about is the smallest one. We stopped equating a long session with a productive session. The metric we care about now is whether the session ended at a clean handoff point, with a result that the next session can pick up cleanly. Long sessions that ended in a clean handoff are fine. Short sessions that ended in a clean handoff are also fine. The thing we avoid is the session that kept going because there was still room, and ended somewhere ragged, with a half-thought decision and a context window the next session will have to clean up before it can do real work.

We are still calibrating. The right stopping point varies by task, and we do not have a clean way to predict it before the work starts. What we have is a habit of looking at the window during the work, asking whether the last few additions made the output better, and being willing to end early when the answer is no. That habit, more than any of the four moves, is what changed.