Context Assembly at Run Time
You find out what is actually in front of the model at the moment it decides, and you take control of it. You learn the four sources that get assembled into every decision, which two of them you wrote and which two grow without asking, and what happens to the early instructions when a long run fills the space. By the end you have a context plan: a named budget saying what is pinned, what is fetched, what is summarised, and what you have decided to leave out.
WHAT THE MODEL SEES AT THE MOMENT IT DECIDES
┌──────────────────────────────────────────────────┐
│ 1 standing files AGENTS.md, workspace docs │
│ 2 the request the sentence you typed │
│ 3 fetched files it read, pages it pulled│
│ 4 the run so far its own steps and results │
└──────────────────────┬───────────────────────────┘
│ assembled fresh, every turn
▼
[ the decision ]
│
┌────────────────┴─────────────────┐
▼ ▼
┌─────────────┐ ┌────────────────────┐
│ you ✋ │ │ it chooses 3 │
│ write 1 │ and set the │ and produces 4, │
│ write 2 │ rules for 3 │ turn after turn │
└─────────────┘ └────────────────────┘You write two of the four sources. The other two grow on their own, and late in a long run they are most of what the model can see.
- Name the four sources that make up run-time context and say which of them you control directly.
- Read a transcript and list what entered the context, in order, with a rough size for each.
- Say why the same request behaves differently at turn three and turn forty.
- Decide, for a given piece of material, whether it should be pinned, fetched on demand, summarised, or left out.
- Say what compaction keeps and what it silently drops, and how you would notice.
- Remove a third of what enters a run and show that the output did not get worse.
stack/context-plan.md — a one-page budget for one real task, listing every item that enters the run, marked pinned, fetched, summarised or omitted, with a rough size and one line saying what it is there to make possible.
There is a habit of thinking about context as a setting, something with a size you were allocated and a switch somewhere in a menu. That framing hides the thing that matters. Context is a document. It gets built from scratch, in a specific order, immediately before every decision the model makes, and then thrown away and built again for the next one.
Nothing in that document is there because it is important. It is there because something put it there. Your standing brief is there because the harness prepends it. Your request is there because you typed it. The contents of four files are there because the agent decided to open them two minutes ago. Twelve tool results are there because twelve tool calls happened. The document is the union of all those decisions, and by the middle of a long run most of them were not yours.
Once you see it as a document, the useful questions change. Not "how big is my context window" but "what is in the document right now, in what order, and what is it crowding out". Not "does it remember" but "is that still in the document". A model that appears to have forgotten your instruction has usually not forgotten anything. The instruction is either still in the document and outweighed, or no longer in the document at all, and those two failures have different fixes.
This is also why the same request can work perfectly in the morning and behave strangely in the afternoon. The request did not change. The document it arrived inside did.
Key insight: the model does not have a memory that fades. It has a document that gets rebuilt, and things fall out of it for reasons you can trace.
Every run-time context comes from exactly four places, and separating them is the whole skill.
Standing files. Your project brain, plus whatever else your harness or workspace loads automatically. Constant across runs, entirely under your control, cheap to change and expensive to bloat. This is the source you audited in Module 03.
The request. What you asked for this time. The smallest of the four in almost every run, and the only one you compose fresh each time.
What it fetched. Files opened, pages read, records pulled from a connector, search results, database rows. This is the first source you do not write, and usually the largest. You do not choose these items directly; you choose the tools and the permissions that make them reachable, which is a slower and more powerful lever.
The run so far. Its own previous steps: what it decided, what it called, what came back, what it said about it. This one is different in kind from the other three, because it grows monotonically. Every turn adds to it and nothing removes it until something forces the issue.
The reason to hold these apart is that each has a different remedy. If the standing files are wrong, edit a file. If the request is vague, write a better one. If the fetched material is bloated, narrow the tools or the query. If the run so far has taken over, the fix is neither of those, and this is where people misdiagnose most often. They rewrite the prompt when the actual problem is that the prompt is now the fourth-oldest thing in a very long document.
Every piece of material you want available has two ways in, and picking wrongly is the most common cause of both bloat and blind spots.
Pinned means it is there every time, whether or not this run needs it. You pay for it on every run, and you pay nothing at the moment you need it, because it is already there. Pinning is right for small, stable, always-relevant things: the conventions, the prohibitions, the names, the commands. The test for pinning is not importance. It is importance times frequency. A critical fact needed in one run out of thirty is a bad pin and a good fetch.
Fetched means it arrives only when the agent goes and gets it. You pay nothing on the runs that do not need it, and you pay twice on the runs that do: once for the material, once for the step that decided to go and get it. Fetching is right for large or situational things, and it comes with a failure mode that pinning does not have. Fetched material can simply fail to arrive. The agent can decide it has enough, search badly, read the wrong file, or not think to look at all, and the run then proceeds confidently on a gap. A pinned fact is either there or visibly missing. A fetchable fact can be absent without anyone noticing.
So the honest way to choose is to ask what happens when the material is not present. If the answer is "the run is wrong in a way the output would not reveal", pin a short version of it even if the full version stays fetchable. One line saying which tab is authoritative costs almost nothing pinned, and prevents a class of silent error that no amount of retrieval quality will fix.
A short run is a clean document. A long run is a document where the most recent forty percent is the agent narrating itself.
The mechanism is simple and worth stating without hand-waving. Every step appends: the call, the arguments, the result, the reasoning about the result. Tool results are usually the heaviest part, because a file read or a page fetch arrives whole. After twenty or thirty steps, the run so far can dwarf everything you deliberately put in, and your standing brief is a small block at the top of a large document whose remaining bulk is all more recent, more specific, and more concrete than it is.
What you observe, from the outside, is drift. Early constraints get quieter. The formatting you specified at the start comes back approximately. A prohibition holds for fifteen steps and then does not. It is tempting to describe this as the model losing focus, and that description leads nowhere useful because it suggests the fix is emphasis. The fix is structure: shorter runs, fewer and smaller tool results, and restatement of the constraints that must hold at the moment they must hold.
The practical move is to stop treating run length as a free variable. A task that takes forty steps is usually two tasks that take twelve and fifteen, with a written handoff between them. That is not just cheaper. It gives you a document that stays legible, an intermediate result you can inspect, and a place to put a gate. Module 12 makes this into a technique; here it is enough to notice that "one long run" is a choice with a cost, and that the cost is paid in the instructions you thought were still holding.
Warning: the constraint most likely to fail in a long run is not the one you stated weakly. It is the one you stated earliest.
When a run outgrows its space, something has to give, and most harnesses handle it by summarising: the earlier part of the run is replaced with a compressed account of it, and the run continues. Workspaces do a version of the same thing to long threads.
This is a genuinely useful mechanism and it has a specific, predictable bias. Summaries keep narrative and lose specifics. What survives is the shape of what happened: the goal, the steps taken, the conclusions reached. What goes is the exact material — the literal contents of the file it read, the precise error string, the specific identifier, the exact wording you insisted on. It goes quietly, and the summary reads as though nothing is missing, because a good summary is supposed to read that way.
That is why the symptom of compaction is rarely confusion. It is confident approximation. The agent still knows it was updating the tracking sheet. It no longer has the row it read forty steps ago, so it reconstructs a plausible one. Nothing in its situation announces the difference between a value it is holding and a value it is recalling.
Two defences, both structural. First, write intermediate results to a file rather than leaving them in the run, so the material can be re-read rather than remembered. A path in the context is a durable pointer; the file contents in the context are a perishable copy. Second, restate the small set of constraints that must survive, at the point of the action they constrain, rather than trusting the version stated at the top. A short restatement immediately before a privileged step is worth more than a long specification an hour earlier.
There is a second, quieter effect that sits alongside compaction, and it is easy to overclaim about. Material at the start of a long context and material at the end are used more reliably than material buried in the middle. This shows up across models and it shows up in ordinary use: the thing you mentioned in the middle of a long brief is the thing that gets missed.
Do not treat that as a law with a coefficient. Treat it as a bias to design around, using three habits that cost nothing.
Put what must not be violated at the top, where the standing files already are, and keep that block short enough to still read as a block. Put what must be acted on now at the end, closest to the decision. And treat the middle as the place for reference material that the agent will notice it needs and can go back for, rather than for anything it has to apply without being reminded.
The same instinct explains why a fifteen-line brief outperforms a fifty-line one that contains it. In the short file, every line is near the top. In the long file, thirty-five lines are in the middle. You did not add information; you moved most of the existing information into the weakest position in the document.
Everything above turns into one artifact: a plan that says, for one real task, what enters the run and why.
The reason to write it down rather than hold it loosely is the same reason budgets exist anywhere. Every item looks defensible on its own. The whole set is what fails. A plan forces the items into one list where their combined weight is visible, and it makes the decision to include something an explicit act rather than a default.
Four verdicts per item is enough. Pinned: present every run, and small. Fetched: reachable, arrives only when needed, with a note on what happens if it does not arrive. Summarised: something large that enters as a short standing digest you wrote deliberately, rather than as a compaction the harness performed under pressure. Omitted: it does not enter, and the line says what you accept losing.
The omitted list is the one that makes this an artifact rather than an inventory. Deliberate omission is a skill, and it is the opposite of the instinct that says more context is safer. More context is not safer past the point where it pushes the important things into the middle of a long document. Writing "the full archive: omitted, because runs only ever touch the current quarter and the archive would triple the standing load" is a real engineering decision, recorded, reversible, and available for someone else to challenge.
An operator sets up a weekly summary that reads a shared project channel and a status document, then drafts an update. It works for a month. Then a long thread appears in the channel and the run gets longer than usual, the harness compacts the earlier part, and the compacted summary keeps the fact that a status document was read while dropping its contents. The agent, still knowing what it was doing and no longer holding what it read, writes a plausible status for each project based on the channel chatter. Two of the five are out of date and one is inverted. Nobody catches it, because the draft looks exactly like the four good ones before it, and the person approving it is checking the format they have learned to trust.
The gap was not judgement. The material left the document, the summary reported the activity rather than the content, and nothing in the output distinguished a value that was read from a value that was reconstructed. A plan that pinned the five status lines and left the channel history fetchable would have inverted which of the two was expendable.
Twenty minutes. You are measuring one real run, then cutting it. Use the task from your charter, not a fresh one.
- Every item in the plan has a source, a rough size, one of the four verdicts, and a reason line.
- Your omitted list is not empty, and each entry says what you accept losing.
- The largest three items are identified, and at least one of them is no longer entering the run whole.
- You reran after cutting and can say what changed, in a sentence, from a comparison rather than an impression.
- Anything marked fetched has a line saying what happens if it does not arrive.
Do not build a context plan for a task that takes three steps and reads one file. The whole exercise is about scarcity, and where there is no scarcity it is ceremony. The other case to skip it is a task that is still changing shape week to week: plan the context once the steps have settled, or you will be budgeting for a run that no longer exists. Until then, keep runs short and read the transcripts, which is where the plan comes from anyway.
Use this after a real run, with the transcript in front of you. It turns a wall of run history into a sorted inventory with verdicts, and its most useful output is usually the omission list, because that is the part you will not write unprompted. Paste as much of the transcript as you reasonably can; if it is too long, paste the first and last portions and say what is missing rather than silently trimming the middle.
<task> Turn the run below into a context inventory: everything that entered the model's context, sorted by weight, with a verdict on each. </task> <context> Run-time context comes from exactly four sources: 1. standing files loaded automatically on every run 2. the request I typed 3. material the agent fetched during the run 4. the run's own accumulated steps and results My standing files: [paste stack/AGENTS.md, plus the name of anything else that loads automatically] The task this run was doing: [one sentence] The run: [paste the transcript, or the first and last portions with a note marking what you left out] </context> <instructions> 1. List every distinct item that entered the context, grouped under its source. 2. Give each item an estimated relative weight. Rough is fine; say what your estimate is based on. 3. Sort within each source, largest first. 4. Give each item one verdict: pinned, fetched, summarised, or omit. 5. For anything you mark fetched, say what the run would produce if that material failed to arrive and nothing announced it. 6. Name the three items whose removal would free the most room, and say for each what would be lost. 7. Name anything that entered the context and was never used. </instructions> <output_format> ## Inventory [four sections, one per source; each item on one line: name — weight — verdict — what it makes possible] ## The three biggest cuts [for each: item, what is freed, what is lost] ## Entered but never used [bulleted, or "none"] ## Silent-absence risks [bulleted; for each fetched item, what a run looks like when it is missing] </output_format> <rules> - Do not estimate token counts or quote numbers you cannot derive from what I pasted. Relative weight only, and say what it is based on. - Do not suggest tools, products, or settings. - Do not recommend adding anything. This inventory only removes and re-sorts. - If a portion of the transcript is missing, say what you could not account for rather than inferring it. </rules>
Take your last long run and answer one question about it on paper: at the moment it made the decision that went wrong, what was in front of it. Write the four sources as four headings and fill them from the transcript. The item you cannot account for, or the one you are surprised to find taking up half the page, is your first cut.
Save the plan next to your project brain. The two are a pair: Module 03 decided what is always present, and this module decided what everything else costs. Keep the omission list where you will see it, because the temptation to add material back is strongest on the day something goes wrong for an unrelated reason.
Save as: stack/context-plan.md — read again in Module 14, where each line gets a cost against it.
Say these out loud. If you cannot, reread the section named after each.
- I can name the four sources of my run-time context and roughly how much of the budget each takes. (Four sources, and you wrote two of them)
- I cut something and can say, from a comparison, that the output did not get worse. (A context plan is a budget with names on it)
- I can say what a summary keeps and what it drops, and how a run behaves after it happens. (Compaction keeps the shape, not the details)
Module 05 takes the runs that worked and stops you re-explaining them. Three of your best become named moves the system knows by name, each tested against three genuinely different inputs.