# A well-designed tool still fails if the window around it is unmanaged. Source: https://customlabs.io/context-engineering/ Updated: 2026-09-20 Context Engineering # A well-designed tool still fails if the window around it is unmanaged. Six surfaces, 24 practices tagged by when in a run they apply and what actually implements them, an eight-symptom table that resolves straight to a fix, and a window ledger at three run horizons. Updated September 20, 2026 · First published August 16, 2026 · 37 min read · Key takeaways - → A delegated subtask can act on information the parent already learned was wrong. - → Prompt caching can stop paying off partway through a long run, for no visible reason. - → A document written in plain language can quietly change what the model does next. - → The same failed action retried with no new information is a named failure signature. - → State kept outside the window is named as a separate surface from history and compaction. - → A per-run budget protects the goal and open commitments first when [compaction](https://customlabs.io/glossary/compaction/) cuts in. Every tool definition, every retrieved passage, and every prior turn compete for the same fixed context window, whether the run is one call or a fleet of delegated agents working a single task for hours. Nothing about a bigger window changes that competition; it only moves where the ceiling sits. This page is about deciding, on purpose, what occupies that window at each step, what gets summarized or dropped as a run grows, what moves to durable storage outside it entirely, and how a clean boundary gets drawn when one unit of work hands off to another. Three other pages sit on adjacent ground, and it's worth naming the split once rather than leaving a reader to guess it. [The Agent Tool Interface](https://customlabs.io/tool-design/) covers designing one tool's interface well, and already carries four practices on this exact ground under its own [context surface](https://customlabs.io/tool-design/#surface-context), and this page links to [stable-prefix-first](https://customlabs.io/tool-design/#stable-prefix-first), [budget-the-window](https://customlabs.io/tool-design/#budget-the-window), [compact-on-a-rule](https://customlabs.io/tool-design/#compact-on-a-rule) and [keep-data-separable-from-instructions](https://customlabs.io/tool-design/#keep-data-separable-from-instructions) by anchor rather than restate them. [MCP in Production](https://customlabs.io/mcp/) covers running an integration layer across an organisation: identity, the catalog, supply chain. [The Agentic Delivery Playbook](https://customlabs.io/agentic-delivery/) covers operating a fleet of coding agents: tasks, gates, spend. This page is what occupies the window at every step of a long run, however many tools, integrations or delegated agents that run happens to involve. The six surfaces ## Where a long-running window actually breaks. Each surface fails a different way. Most failures trace back to something never getting a budget in the first place. Three of context engineering's six surfaces act within a single turn. Two act across a run, and one acts across many runs. 01 ### Budget & allocation **Covers:** The window as a fixed resource split across instructions, tool definitions, retrieved content, running history and the task itself, and who is accountable for what each slice actually costs. **Breaks when:** The task is assembled last, after everything else has already claimed its share, so it's the first thing cut the moment the window runs out. **Watch:** Whether every slice in a run has a named owner and a written share, rather than a shared pool nobody is actually rationing. 02 ### Selection **Covers:** What actually gets pulled into a given step: preloaded at session start versus fetched just-in-time, a relevance floor for anything retrieved, and the discipline that stops a wider retrieval set from making an answer worse. **Breaks when:** A bigger retrieval set reads as more thorough and instead buries the one passage that mattered under nine that were merely on-topic. **Watch:** The share of retrieved tokens a response actually cites or acts on, against the share it silently carried and ignored. 03 ### History & compaction **Covers:** What a long-running conversation or agent loop keeps, drops or summarizes as it grows past what fits, and whether that happens on a stated rule or as a scramble once the window is already full. **Breaks when:** Compaction runs for the first time under pressure, and whatever is oldest or least structured gets cut first, which is usually the goal and the constraints a long-running task most needed to keep. **Watch:** Whether the original goal, active constraints and open commitments are still recoverable after the fifth compaction pass, the same way they were after the first. 04 ### State outside the window **Covers:** Durable state that lives outside any single [context window](https://customlabs.io/glossary/context-window/) entirely — files, working notes, a task registry — and what belongs there instead of being carried in-window turn after turn. **Breaks when:** Everything worth remembering is kept in-window by default, so it either falls out the moment the window turns over or gets re-explained at real token cost every step. **Watch:** Whether a fact written once to durable storage is actually read back in on the step that needs it, rather than re-derived or asked for again. 05 ### Isolation & delegation **Covers:** A clean context window handed to one unit of work at a time, the handoff contract between units, and what's actually allowed to cross that boundary versus what has to be re-derived on the other side. **Breaks when:** A subtask inherits the entire parent window instead of a scoped handoff, so it reasons over context nobody actually curated for its job. **Watch:** How much of a delegated unit's starting window is context it actually referenced, against context it simply inherited by default. 06 ### Integrity & measurement **Covers:** Instructions kept structurally apart from data at scale, the provenance of everything sitting in the window, ordering that survives a compaction pass, and what gets logged per turn so a context problem is diagnosable after the fact. **Breaks when:** Retrieved content and a real instruction sit in the same undifferentiated stream, with nothing in the format telling the model which is which. **Watch:** Whether a context-related incident produces a specific per-turn span to inspect, or just a shrug and an account of the model getting worse. The practice bank ## 24 practices, six surfaces. Filter by when in a run a practice applies, or by what actually implements it, then copy the visible list as a Markdown checklist. Horizon Per turn Per run Across runs Lever Prompt Retrieval Orchestration Instrumentation Showing all 24 practices Copy as Markdown ### 01 Budget & allocation A context window isn't elastic just because a provider raised the advertised limit. Every token spent on a tool definition, a paragraph of retrieved text or last turn's transcript is a token unavailable to the instructions that matter or the task itself, and a bigger window doesn't change that arithmetic, it just moves where the ceiling sits. /tool-design/ already covers writing down a per-slice token budget and alarming when one crosses it (see stable-prefix-first and budget-the-window). This surface is the layer above that: deciding who owns the allocation decision across an entire run, and reserving room for the model's own output before the rest of the window quietly claims it. A window with no output reserve produces a response cut off mid-sentence, which reads to a user like the system stalled rather than like the budget it actually was. #### Reserve a fixed share of the window for the model's own output before anything else claims it Per turn Prompt **What it is** An explicit, protected token allowance for the response itself, set before instructions, tool definitions, retrieved content or history are assembled, rather than whatever happens to be left over. **How to build it** Compute the output reserve first, subtract it from the total window, and only then allocate the remaining space across every other slice. **Produces** A response that finishes instead of one truncated mid-sentence because the rest of the window filled up first. **Tradeoff** A generous output reserve shrinks how much instruction, retrieval or history the same window can carry, which matters on a genuinely input-heavy step. **Prove it** A step run at every other slice's full allowance still completes its response without truncation, checked directly rather than assumed from headroom. #### Give every context slice a named owner and a written share Per run Orchestration **What it is** A per-slice owner (instructions, tool defs, retrieved content, history, task) accountable for what that slice actually costs, in place of one shared pool everyone assumes someone else is rationing. **How to build it** Assign the owner at design time alongside a numeric or proportional share, and revisit the assignment whenever a new slice type joins the run. **Produces** A run where a slice that starts growing has a specific owner to flag it, instead of a shared budget nobody is actually watching. **Tradeoff** Named ownership adds a real coordination step whenever a new context source joins the run, friction worth having against a budget nobody owns. **Prove it** Every slice in the current run maps to a named owner in the design record, checked against the actual assembled context rather than assumed. [The Agent Tool Interface: Budget the window](https://customlabs.io/tool-design/#budget-the-window) #### Treat the window as a fixed, competed-for resource, not a bucket that expands to fit whatever gets assembled Per run Prompt **What it is** A standing design assumption that every context source competes for the same finite space, so adding one is understood as shrinking the room left for the others. **How to build it** Model context assembly as an allocation decision with a fixed total, the same discipline a budget review applies to headcount, rather than appending sources until something breaks. **Produces** A design conversation that asks what a new context source displaces, instead of only whether the new source is useful on its own. **Tradeoff** Treating the window as fixed means saying no to a genuinely useful addition until something else is cut to make room for it. **Prove it** The last context source added to a live run has a recorded answer for what it displaced, alongside what it added. #### Alarm the moment any slice crosses its written budget, not once the whole window overflows Per turn Instrumentation **What it is** A per-slice measurement on a live run that fires the instant one slice exceeds its stated share, rather than a single check for total window overflow. **How to build it** Instrument token counts per slice at assembly time, compare each against its written allocation, and raise the alarm on the specific slice that broke budget, not the aggregate. **Produces** A fix that targets the actual slice that grew (a retrieval set, an unbounded history), instead of a blanket truncation applied wherever the window happens to run out. **Tradeoff** Per-slice instrumentation costs real engineering time to build and keep current as new slice types join a run. **Prove it** A deliberately oversized test input on one slice trips that slice's specific alarm, checked directly rather than assumed from the aggregate limit. ### 02 Selection Retrieval quality gets measured constantly on this site; how much of what's retrieved actually belongs in the window at all gets measured far less. A wider retrieval set looks like due diligence and is often the opposite: a model reasoning over ten passages, nine of them merely topical, finds the genuinely relevant one harder to weigh, not easier. Selection is the discipline of deciding what a given step actually needs before it's fetched, not what it might conceivably use, and setting a real relevance floor rather than a fixed count that pads itself out on a thin result set. The failure this surface exists to catch is quiet: a retrieval set that grew because growing it felt safer, never checked against whether the growth helped. #### Default to fetching content just-in-time, not preloading everything a task might need Per turn Retrieval **What it is** A retrieval design that fetches content at the step that actually needs it, rather than loading everything a task could conceivably touch into the window up front. **How to build it** Scope retrieval calls to the current step's actual question, and reach for a broader preload only when a specific, named latency or availability constraint requires it. **Produces** A window where the content present at any given step is content that step is likely to use, instead of a standing library carried the whole run on the chance it helps. **Tradeoff** Just-in-time fetching adds a real retrieval call, and the latency it costs, at the exact moment the answer is needed. **Prove it** A sampled step's context is checked against what that step actually referenced, and the share of unused preloaded content is measured directly. #### Set a relevance floor for what gets included, not a fixed top-K Per turn Retrieval **What it is** A minimum relevance score a retrieved item must clear before it enters the window, checked in addition to any fixed count like top-5 or top-10. **How to build it** Score every retrieved candidate, drop anything under a stated floor regardless of rank, and let the count actually included vary step to step instead of fixing it at a round number. **Produces** A window that never pads itself with a merely-topical eighth result just to fill a fixed slot count, because a floor, not a count, decides what enters. **Tradeoff** A strict floor sometimes returns fewer results than a fixed top-K would have, and a genuinely thin result set has to show as thin rather than be padded out. **Prove it** A retrieval run against a query with few genuinely relevant matches returns fewer than the nominal top-K, rather than padding out to it. #### Measure whether a wider retrieval set is actually helping before assuming it is Across runs Instrumentation **What it is** A standing check that a larger retrieved set correlates with a better answer on the eval set, rather than an assumption that more context is strictly safer. **How to build it** Run the same eval cases at two or three retrieval widths and compare pass rate directly, instead of widening the set on intuition whenever an answer looks incomplete. **Produces** Evidence for the width that actually helps a given task, which is very often narrower than the width that felt safer to configure. **Tradeoff** Running the comparison costs real eval time against every retrieval-width change, instead of trusting a single plausible-looking setting. **Prove it** The current retrieval width has a recorded eval comparison against at least one narrower setting, checked, not assumed from why wider felt safer. [Failure mode: Similarity is not relevance](https://customlabs.io/failure-modes/similarity-is-not-relevance/) #### Carry the source alongside every retrieved item, alongside its text Per turn Retrieval **What it is** A structural provenance field on every retrieved chunk (which document, which system, how current) that travels with the content into the window, alongside the passage itself. **How to build it** Attach source metadata at retrieval time and preserve it through to whatever renders the context, so the model and a human reviewer can both tell where a claim actually came from. **Produces** An answer traceable back to a specific source instead of one where retrieved text and the model's own reasoning are indistinguishable after the fact. **Tradeoff** Provenance metadata is itself tokens in the window, a real cost against the budget surface above for a benefit that only pays off when something needs checking. **Prove it** A claim in a sampled answer is traced back to the specific source record it came from, using only the metadata carried in context. ### 03 History & compaction History is the slice that grows the most predictably and gets managed the least deliberately, because a run that's going fine never seems like the moment to build the compaction path. The fix is treating compaction as a scheduled routine exercised while the window still has headroom, not an emergency response improvised the day it fills. What a compaction pass is allowed to drop matters as much as when it runs: a summarizer with no explicit instruction to preserve the goal, the active constraints and any open commitment will compress those along with everything else, and an agent that's forgotten what it was asked to do is a harder failure to spot than one that's simply run out of room. #### Compact history on a rule written down in advance, never as an emergency response Per run Orchestration **What it is** A stated compaction trigger (turns older than N, or a slice crossing a named share) defined before the run starts, in place of an improvised summarization the moment the window is already full. **How to build it** Publish the specific trigger condition alongside the run's design, and execute compaction on that schedule even while the window still has headroom, so the mechanism is exercised before it's ever load-bearing. **Produces** A compaction pass that runs under normal conditions, with time to check what it kept, rather than one improvised under pressure with whatever's oldest cut first. **Tradeoff** Compacting on a fixed schedule sometimes runs before it's strictly needed, spending the summarization cost earlier than a just-in-time trigger would. **Prove it** A run forced past its compaction trigger executes the pass on schedule, checked against the published rule rather than against whether the window happened to be full. [The Agent Tool Interface: Compact on a rule](https://customlabs.io/tool-design/#compact-on-a-rule) #### Name the three things a compaction pass must never drop: the goal, active constraints, and open commitments Across runs Orchestration **What it is** A fixed, explicit checklist a summarization step is required to preserve, regardless of how aggressively it compresses everything else in a long run's history. **How to build it** Write the checklist into the compaction routine itself, and validate its presence in the compacted output before accepting it, rather than trusting a general-purpose summarizer to keep what matters. **Produces** An agent that still knows what it was asked to do and what it already promised after the tenth compaction pass, the same as after the first. **Tradeoff** A protected checklist gives the summarizer less room to compress the sections it's actually free to shrink, so overall compaction is less aggressive. **Prove it** A long run forced through several compaction cycles is quizzed on its original goal and any open commitment, and answers correctly from the compacted state alone. #### Summarize history that no longer fits, and reach for truncation only as a last resort Per run Orchestration **What it is** A preference for lossy-but-structured summarization over blind truncation when history has to shrink, reserving a hard cutoff for the case where summarization itself has no time or budget left to run. **How to build it** Build the summarization path first and treat truncation as a documented fallback with its own trigger, not the default mechanism reached for whenever the window fills. **Produces** A history that degrades to a shorter, still-coherent account of what happened, instead of one that stops mid-turn with no signal anything was cut. **Tradeoff** Summarization costs a model call and real latency that a blind truncation, being nearly free, doesn't. **Prove it** A run that hits its history limit produces a coherent summary of the dropped turns, checked against the fallback truncation path never having triggered instead. [Failure mode: Context overflow drops the task](https://customlabs.io/failure-modes/context-overflow-drops-the-task/) #### Detect a repeated failed approach sitting in history before it gets read as fresh information Per run Orchestration **What it is** A check that flags when the last several turns show the same failed action retried with no new information, distinct from genuine progress that happens to look similar. **How to build it** Compare a candidate next action against recent history for a near-repeat of an action that already failed, and surface that comparison to whatever decides the next step, rather than trusting the model to notice the pattern in its own transcript. **Produces** A loop that gets interrupted and redirected instead of one that reads its own failed attempt as informative context and tries the same thing again. **Tradeoff** A repeat detector can misfire on a legitimate retry with a genuinely new parameter, so it needs a real similarity threshold, not an exact match. **Prove it** A test run seeded with a repeated failing action gets flagged and redirected before a stated retry ceiling, checked directly against a live loop. [Failure mode: Unbounded agent loop](https://customlabs.io/failure-modes/unbounded-agent-loop/) ### 04 State outside the window Not every fact worth keeping belongs in the window at all. A file, a working note or a task-registry entry can hold state far longer and far more cheaply than a context window can, and the discipline this surface is built around is deciding, at the point something is produced, whether it needs to survive past the current step and, if so, writing it out immediately rather than carrying it forward in every turn's history. The re-entry side is just as real a cost as the write side: a durable record that's expensive to read back in has just moved the overflow problem from now to whenever it's needed again, so pricing that re-entry cost belongs in the same decision as writing the record in the first place. #### Write durable facts to storage outside the window, then read them back in on demand Across runs Orchestration **What it is** A discipline where anything worth keeping past the current step is written to a file, a note, or a registry entry, and pulled back into context only on the step that needs it, in place of being carried forward through every subsequent turn's history. **How to build it** Identify what genuinely needs to survive past this step at the point it's produced, write it out immediately, and treat the in-window copy as disposable once it's been persisted. **Produces** A window that isn't paying the ongoing cost of restating something already safely stored, and a fact that survives a compaction pass that would otherwise have dropped it. **Tradeoff** Writing state out costs a real step, and reading it back in costs a real retrieval, both against a task that could have kept the fact in the window a little longer instead. **Prove it** A fact written to durable storage early in a run is still correctly recalled several steps later, after the in-window copy has been compacted away. #### Separate a disposable scratchpad from a durable note, and mark which is which Across runs Orchestration **What it is** Two distinct classes of outside-window storage — a scratchpad expected to be discarded at the end of the run, and a durable note expected to outlive it — with the distinction stated explicitly rather than implied by which folder it happens to sit in. **How to build it** Name the class at the point of writing, scratch versus durable, and give each its own retention rule and its own reader, so a downstream step never has to guess which kind of note it just found. **Produces** A durable note that survives a routine cleanup pass, and a scratchpad that doesn't quietly become load-bearing because nobody remembered it was meant to be temporary. **Tradeoff** Maintaining two classes with different retention rules is more moving parts than a single undifferentiated notes folder. **Prove it** A cleanup pass run against a completed task's storage removes every scratchpad entry and leaves every durable note intact, checked against the stated class on each. #### Price the token cost of reading a piece of outside-window state back in before deciding to persist it Across runs Instrumentation **What it is** An explicit check, at the point something is written to durable storage, for how expensive it will be to read back into context later, since a large persisted record just moves the budget problem from now to whenever it's re-entered. **How to build it** Estimate the re-entry token cost when the record is created, and prefer a compact, structured format over a full transcript dump for anything expected to be read back frequently. **Produces** Durable state that's cheap to re-enter on the step that needs it, instead of a record so large that reading it back in recreates the exact overflow problem it was written out to avoid. **Tradeoff** A compact persisted format loses some of the original detail a full dump would have kept, a real cost if that detail turns out to matter later. **Prove it** The token cost of reading the largest durable record actually in use back into a fresh window is measured, not assumed to be negligible because it lives outside the window. #### Keep durable state in a shared, queryable registry, not a private file only one run knows to check Across runs Orchestration **What it is** A standing, shared location for state meant to outlive a single run — a task registry, a shared notes store — queryable by any run that needs it, rather than a file path only the run that wrote it remembers. **How to build it** Route anything meant to persist across runs through the shared registry rather than a working directory scoped to one session, and make the registry itself the thing a new run checks first. **Produces** State that a second, unrelated run can actually find and use, instead of a fact trapped in the first run's own private storage. **Tradeoff** A shared registry needs real access and naming conventions to stay usable as more runs write to it, discipline a private per-run file never had to enforce. **Prove it** A fact written by one run is found and correctly used by an unrelated second run querying the shared registry, not by inheriting the first run's own files. [CodeHerder](https://customlabs.io/products/codeherder/) ### 05 Isolation & delegation This is where the studio's own delivery model earns its place on the page: a fleet of coding agents run through CodeHerder gets one clean context per stage, and a handoff comment is the contract between them, not a forwarded transcript. That shape generalises past coding agents. A subtask that starts from the parent's full window carries every tool definition, every piece of retrieved content and every prior turn the parent accumulated, whether or not any of it is relevant to the narrower job it was actually delegated. A scoped handoff, built from a stated contract rather than a raw dump, is what keeps a delegated unit's window small enough to reason over cleanly, and keeps a parent's context from ballooning with every subtask's needs at once. #### Start each unit of delegated work from a clean window scoped to its own job Per run Orchestration **What it is** A fresh context window for a subtask or subagent, populated only with what that specific unit of work needs, rather than the full parent window inherited wholesale. **How to build it** Define the minimum context a delegated unit actually requires before it starts, assemble only that, and resist the shortcut of forwarding the parent's entire window because it's already there. **Produces** A subtask that reasons over context actually curated for its job, and a parent window that isn't bloated by carrying every subtask's needs at once. **Tradeoff** Scoping a clean window per unit of work costs a real design step at every delegation point, instead of the zero-effort default of passing everything along. **Prove it** A delegated unit's starting context is audited against what it actually referenced during its run, and the share of unused inherited context is measured. [The Agentic Delivery Playbook](https://customlabs.io/agentic-delivery/) #### Define a handoff contract between units of work, not a raw transcript dump Per run Orchestration **What it is** A structured handoff — what was asked, what was decided, what's still open — passed between one unit of work and the next, in place of the entire raw conversation transcript that produced it. **How to build it** Specify the fields a handoff must carry before the boundary is built, and require the sending unit to fill them explicitly, rather than letting the receiving unit page back through a full transcript to reconstruct what it needs. **Produces** A receiving unit that starts with exactly what it needs stated plainly, instead of re-deriving it from a transcript that was never written for that purpose. **Tradeoff** A structured handoff can drop nuance that only lived in the raw transcript's phrasing, a real loss if the receiving unit needed that nuance. **Prove it** A receiving unit given only the structured handoff, with the raw transcript withheld, completes its job correctly, checked directly rather than assumed from how thorough the handoff looks. [The Delivery Record](https://customlabs.io/delivery-record/) #### Decide explicitly what's allowed to cross a delegation boundary, and block the rest Per run Orchestration **What it is** An enforced allowlist for what a parent unit's context can pass to a delegated one, and what a delegated unit's result can pass back, rather than an open channel that lets anything cross by default. **How to build it** Name the specific fields permitted to cross each boundary at design time, and reject or strip anything else at the boundary itself instead of trusting each side to only send what's appropriate. **Produces** A delegation boundary that can't leak an unrelated credential, an unrelated user's data, or simply more tokens than the receiving unit's own budget allows. **Tradeoff** An enforced allowlist means a genuinely new field a delegated unit needs requires a deliberate boundary update, rather than being added to whatever gets passed along. **Prove it** A field deliberately excluded from the boundary's allowlist is confirmed absent on the receiving side, tested directly rather than assumed from the design document. #### Require a delegated unit to re-derive anything it needs to trust, rather than assume the parent's state still holds Per run Orchestration **What it is** A rule that a delegated unit re-checks any fact it depends on for a correctness- or safety-relevant decision, instead of trusting a value the parent handed off as still current. **How to build it** Mark handoff fields safe to trust as-is separately from ones that must be re-verified — a file's current state, a permission grant, a price — and re-derive the latter inside the delegated unit's own boundary before acting on it. **Produces** A delegated unit that doesn't act on a stale assumption inherited from a parent whose own state may have moved on since the handoff was written. **Tradeoff** Re-deriving anything genuinely re-checkable costs a real call the delegated unit could have skipped by trusting the handoff outright. **Prove it** A test where the parent's state changes after handoff but before the delegated unit acts shows the delegated unit catching the change, not acting on the stale value. ### 06 Integrity & measurement A model reads one stream of tokens with no privileged channel marking an instruction apart from a retrieved passage or a tool's return value — /tool-design/'s trust-boundary and context surfaces cover why that matters for a single call. At the scale of a whole run, the same fact compounds: content that entered the window three compaction passes ago, retrieved by a call nobody can trace, sitting next to instructions that survived unchanged, is a window nobody can actually audit. Provenance carried with the content, ordering that survives a rewrite instead of resetting it, and a per-turn log of what was actually assembled are what turn a context problem from a vague complaint into a specific span someone can open and inspect. #### Mark retrieved content and tool output as data in the format itself, not by convention alone Per turn Prompt **What it is** A structural distinction — a dedicated field, a wrapping delimiter the system prompt names explicitly as untrusted — between an instruction and anything retrieved or returned, rather than relying on everyone remembering to phrase retrieved text carefully. **How to build it** Wrap retrieved content and tool output in a format the assembly code enforces, not one a prompt author has to remember to apply by hand on every call site. **Produces** A model that has an actual structural signal to weigh against an embedded instruction hiding inside retrieved text, instead of one undifferentiated stream of tokens. **Tradeoff** Structural marking adds real assembly-code discipline at every place context gets built, a cost worth paying once rather than skipped per call site. **Prove it** A labelled injection attempt planted inside retrieved content is run through the full path and the structural marking is confirmed present around it, and around the system instructions alike. [The Agent Tool Interface: Keep data separable from instructions](https://customlabs.io/tool-design/#keep-data-separable-from-instructions) #### Stamp provenance on every piece of content that enters the window, including the parts a reviewer is unlikely to check Per turn Instrumentation **What it is** A recorded source for every context item — which retrieval call, which tool response, which prior turn — carried alongside it rather than only in a system log a reviewer would have to separately correlate. **How to build it** Attach the provenance stamp at the point content enters context, and keep it attached through any compaction or summarization step rather than letting it drop out the first time the content is rewritten. **Produces** A context problem that's diagnosable from the window's own contents, not one that requires reconstructing which source contributed what after the fact. **Tradeoff** Carried provenance is itself tokens against the budget surface above, a cost that only pays off when something actually needs checking. **Prove it** A claim in a sampled response is traced to its provenance stamp alone, with no need to consult a separate system log to confirm the source. #### Keep a stable assembly order through every compaction and retrieval change, through the last call as much as the first Per run Prompt **What it is** The same discipline /tool-design/'s stable-prefix-first rule applies to a single call, held constant across an entire run: static content first, volatile content last, and that order preserved through every compaction pass rather than reset by it. **How to build it** Apply the ordering rule inside the compaction and retrieval-refresh routines themselves, in addition to the initial assembly code, so a mid-run rewrite doesn't quietly reorder what a later call depends on for caching. **Produces** A cache-read share that holds steady across a long run instead of resetting every time history gets rewritten. **Tradeoff** Enforcing stable ordering through a compaction pass constrains how that pass can restructure content, a real limit on how freely it can rewrite. **Prove it** Cache-read share is measured immediately before and after a compaction pass on the same run, and the two numbers are close rather than the pass resetting the hit rate. [The Agent Tool Interface: Stable prefix first](https://customlabs.io/tool-design/#stable-prefix-first) #### Log the shape of the assembled context on every turn, alongside the final response Per turn Instrumentation **What it is** A per-turn record of what actually went into the window — which slices, roughly how large each, which sources — captured alongside the ordinary request and response logging a system already keeps. **How to build it** Instrument context assembly to emit its own shape as a structured log line per turn, and retain it for at least as long as the corresponding response is retained. **Produces** A specific, inspectable record of what the model was actually looking at when something went wrong, instead of reconstructing it after the fact from an incomplete transcript. **Tradeoff** Per-turn context logging adds real storage volume over a long-running system, and needs the same redaction discipline any other request log needs for sensitive content. **Prove it** A context-related incident picked at random has its per-turn shape log recoverable, and that log alone is enough to identify which slice caused the problem. No practices match that combination. Clear a filter to see more. Failure signatures ## Start from the symptom, not the taxonomy. Each row is something a real run does that looks like a model problem and isn't. It resolves to the surface that owns the fix and the specific practice that is the fix. ### The response is cut off mid-sentence, right when it should be finishing. **What's actually happening:** Nothing reserved room for the output. Instructions, tool defs, retrieved content and history claimed the window first, and the answer ran out of space on the way out. Budget & allocation [The fix: Reserve a fixed share of the window for the model's own output before anything else claims it →](https://customlabs.io/context-engineering/#reserve-the-output-slice) ### A crowded retrieval set comes back confidently, and the one document that actually answers the question isn't reflected in the response. **What's actually happening:** A fixed top-K padded the set with merely-topical passages instead of applying a relevance floor, so the genuinely relevant one competed with nine that weren't. Selection [The fix: Set a relevance floor for what gets included, not a fixed top-K →](https://customlabs.io/context-engineering/#relevance-floor-not-top-k) ### A long-running agent loses track of what it was actually asked to do partway through the task. **What's actually happening:** A compaction pass summarized the goal along with everything else, because nothing told it that the goal, active constraints and open commitments were the one thing it couldn't compress away. History & compaction [The fix: Name the three things a compaction pass must never drop: the goal, active constraints, and open commitments →](https://customlabs.io/context-engineering/#preserve-goal-constraints-commitments) ### The same failed action gets retried over and over, with no new information between attempts. **What's actually happening:** The failed attempt sits in history looking exactly like fresh information to reason from, and nothing is checking recent history for a near-repeat before the next action runs. History & compaction [The fix: Detect a repeated failed approach sitting in history before it gets read as fresh information →](https://customlabs.io/context-engineering/#detect-the-stalled-repeat) ### A fact established early in a session has to be re-explained on every turn after. **What's actually happening:** The fact was only ever kept in-window, so it falls out of history the moment the window turns over or gets compacted, instead of being written once to durable storage and read back on demand. State outside the window [The fix: Write durable facts to storage outside the window, then read them back in on demand →](https://customlabs.io/context-engineering/#write-then-read-not-carry-forward) ### A delegated subtask acts on information the parent had already learned was wrong. **What's actually happening:** The subtask trusted a value from its handoff as still current instead of re-deriving anything correctness-relevant inside its own boundary before acting on it. Isolation & delegation [The fix: Require a delegated unit to re-derive anything it needs to trust, rather than assume the parent's state still holds →](https://customlabs.io/context-engineering/#re-derive-dont-assume-shared-state) ### Prompt caching stops paying off partway through a long run, for no visible reason. **What's actually happening:** A compaction or retrieval-refresh pass rewrote content without preserving the stable-prefix ordering, quietly resetting the cache hit rate the run had been relying on. Integrity & measurement [The fix: Keep a stable assembly order through every compaction and retrieval change, through the last call as much as the first →](https://customlabs.io/context-engineering/#stable-ordering-survives-compaction) ### A document written in plain, unremarkable language quietly changes what the model does next. **What's actually happening:** Retrieved content sat in the same undifferentiated stream as real instructions, with no structural marking telling the model one was data and the other wasn't. Integrity & measurement [The fix: Mark retrieved content and tool output as data in the format itself, not by convention alone →](https://customlabs.io/context-engineering/#mark-data-structurally-not-by-convention) The window ledger ## What occupies the window, at three run horizons. No token counts or vendor window sizes here on purpose. The shape holds regardless of which model or context size a run happens to use. ### Per turn **What occupies it** Everything assembled for this exact request: the system instructions, the tool catalog, whatever's been retrieved for this question, and the running history handed in so far. **Typical failure** The task itself, added last, is the first thing truncated once the rest of the window has already claimed its space. **The discipline that holds** A protected output reserve and a per-slice budget, checked before anything is added rather than after the window overflows. ### Per run **What occupies it** The accumulated state of one continuous task across many turns: everything the earlier turns established, plus whatever's been delegated out to subtasks and handed back. **Typical failure** History grows past what fits and gets compacted under pressure, cutting whatever is oldest rather than whatever is least important. **The discipline that holds** Compaction on a published schedule that protects the goal, the active constraints and any open commitments before anything else. ### Across runs **What occupies it** Whatever is meant to outlive the run that produced it: a durable note, a registry entry, a file a later run is expected to find and read. **Typical failure** A fact worth keeping was never written outside the window at all, so it vanishes the moment the run that produced it ends. **The discipline that holds** A write-then-read discipline through a shared registry, with the token cost of reading a record back in priced before it is persisted. What this is built from ## Grounded in mechanics, not a vendor's benchmark. No percentages, no token counts, no vendor context-window sizes, no third-party prevalence statistics. The arithmetic of a fixed, competed-for window is stable; those numbers rot in weeks. - /tool-design/ covers designing one tool's interface and already carries four practices on this exact ground under its context surface. This page is the layer above a single call: what occupies the window across an entire run, well past what one tool definition or one response costs it. [The Agent Tool Interface](https://customlabs.io/tool-design/#surface-context) - The Agentic Delivery Playbook is the isolation surface's first-party case: a fleet of coding agents run through CodeHerder, one clean context per stage, a handoff comment as the contract instead of a forwarded transcript. [The Agentic Delivery Playbook](https://customlabs.io/agentic-delivery/) - The Delivery Record is where that handoff discipline gets checked against what actually shipped, not argued in the abstract — a real defect the review stage caught, and the build-time check that now fails if it recurs. [The Delivery Record](https://customlabs.io/delivery-record/) - CodeHerder is the registry the memory surface argues for: a shared, queryable place for state meant to outlive one run, rather than a fact trapped in whichever session produced it. [CodeHerder](https://customlabs.io/products/codeherder/) - Context overflow drops the task, the unbounded agent loop, and injection via retrieved content are named failure modes on this site, not hypotheticals — each is the reason a specific practice above exists. [Failure mode: Context overflow drops the task](https://customlabs.io/failure-modes/context-overflow-drops-the-task/) ### Sources - [arXiv - Lost in the Middle: How Language Models Use Long Contexts](https://arxiv.org/abs/2307.03172) The paper measuring how a fact's position in a context window affects recall. Retrieved 2026-08-24. - [arXiv - Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks](https://arxiv.org/abs/2005.11401) The paper that named retrieval-augmented generation as a technique. Retrieved 2026-08-24. Designing a long-running agent A Ship Audit checks the window ledger above against the specific run you're building, before the budget, compaction and isolation calls get made by default instead of on purpose. [Book a Ship Audit →](https://customlabs.io/diagnostic/ship-audit/) [See the tool interface guide →](https://customlabs.io/tool-design/) Questions ## Before the window fills up. What teams ask us once a run stops fitting comfortably in a single context window. 01 Isn't this just prompt engineering with a longer name? + Prompt engineering is one input to it, not the whole discipline. This page covers what occupies the window across an entire run — retrieved content, tool catalogs, history, state that lives outside the window entirely — and in what order, which is a design and orchestration problem as much as a wording one. 02 How is this different from /tool-design/? + /tool-design/ is about designing one tool's interface well and already owns four practices on this ground under its own context surface. This page starts where a single call stops mattering: what occupies the window across a whole run, whether that run is one agent or a fleet of delegated ones. 03 We just bought a model with a much bigger context window. Does this still matter? + Yes. A bigger window changes where the ceiling sits, not whether one exists, and it doesn't fix a retrieval set that buries the relevant passage or a compaction pass that drops the goal. Budgeting and selection discipline get more forgiving at a larger size, not unnecessary. 04 What's the single most common mistake on this page? + Treating compaction as an emergency response instead of a scheduled routine. A summarizer improvised the day the window fills has no instruction to protect the goal or open commitments, and cuts whatever's oldest, not whatever matters least. 05 Do we need all 24 practices before our first agent ships? + No. Scope to what the run actually does: a single-turn assistant with no delegation needs the budget and selection surfaces far more than isolation. The failure-signature table above is the fast way to find which surface a symptom you're already seeing actually maps to. 06 Where does the memory surface stop and a vector database start? + They solve different problems. Retrieval (chunk, embed, retrieve) is how a system answers from a large corpus; the memory surface here is about small, specific, durable facts a run produces itself and needs back later — a decision, a constraint, a handoff note — not a search problem over a document collection. Pick the shape that fits The same failed action retried with no new information is one of eight symptoms this page traces back to a cause. The architecture picker matches your own system to a shape like grounded answering, instead of a generic pipeline. [Use the architecture picker →](https://customlabs.io/tools/architecture-picker/) [See grounded answering →](https://customlabs.io/architectures/grounded-answering/)