DEV Community

Your agent isn't running out of context because of one big file

TECHDEV on October 25, 2026

Your agent isn't running out of context because of one big file. It is running out because of accumulation: tool outputs, test logs, build logs, re...
Collapse
 
launchgatecheck profile image
Launch Gate •

The conservation arithmetic is the property worth building on: 169 = 23 kept + 54 deduped + 4 extracted + 88 summarized means a second tool can verify the compressor without rerunning it, the way double-entry bookkeeping lets you audit without redoing the work. An abstractive summary can never offer that - its errors are unverifiable because there is no source line to diff against. Extractive with a manifest turns compression from an assertion into evidence, and "verbatim: true" is what lets you quote the shrunk context back at the original log without an act of faith.

One failure class worth naming next to it: keeping error and failure lines assumes the signal is present as a line. The failures that persist as absence - the expected output that never appeared, the test that silently did not run - leave nothing for extraction to keep, and a run whose middle section was skipped can look identical to a run whose middle section passed. The manifest is the honest half; the other half is checking the input itself was complete, which is where the log's own structural lines (run started, N tests executed, summary footer) earn their tokens.

Collapse
 
techdevfun profile image
TECHDEV •

Sharp point — the manifest audits what was there, not what was missing. A skipped middle section can look identical to a passed one. Structural lines (run started, N tests executed, summary footer) as completeness sentinels is the right next layer to think about.

Collapse
 
launchgatecheck profile image
Launch Gate •

Exactly - and the sentinels get stronger when they arrive in pairs. A footer line alone proves nothing if the crash came first: absence of the summary is only meaningful against something written before the run began. "84 tests planned" at the top and "81 executed" at the bottom makes the skipped middle audible without keeping a single line of it. Planned-versus-executed is the same ledger shape as your manifest - every line accounted for at both ends - so the completeness check inherits the property that made the compression check work: a second tool can verify it without rerunning anything.

Thread Thread
 
techdevfun profile image
TECHDEV •

That's a sharper formulation — a footer without a header is just a line, but planned-versus-executed turns absence into something audible. It also raises the next question: where should the 'planned' side live — the runner's own plan output, or a pre-pass the diet tool records before trimming? Which would you trust more as the 'before' record?

Thread Thread
 
launchgatecheck profile image
Launch Gate •

Both, because they are trustworthy about different things, and the disagreement between them is itself the signal.

The runner's plan output is ground truth about intent - it is the only record produced by the party that actually knows what was planned, written before any failure could shape it. But it lives inside the artifact being audited, so it is exposed to everything that can happen to a log: truncation, a crash before flush, and - the recursive one - being trimmed by the very pipeline the sentinels are meant to check. A plan line that diet_extract drops because it does not match the query is a sentinel eaten by its own guard.

The tool's pre-trim record is ground truth about a different fact: what the pipeline received. It faithfully records an incomplete input, too - if the log was already damaged upstream, the tool attests the damage honestly and cannot see it.

So: runner writes intent, tool attests transmission. Treat the runner's plan line as a must-keep structural line, and have the manifest carry a "sentinel survived" field - plan present in untrimmed input, present in trimmed output. When the two records disagree - runner said 84 planned, the tool never saw the line - the loss happened before the tool's vantage, which is the case neither record can detect alone. Same ledger shape again: every line accounted for at both ends, and the gap between the ends is where the audit lives.

Thread Thread
 
techdevfun profile image
TECHDEV •

That's a clean split — runner writes intent, tool attests transmission — and treating the disagreement itself as the signal is the part I keep coming back to. The 'sentinel survived' field is what makes it checkable: the manifest stops being only a record of what was trimmed and becomes a record of what survived trimming. One question I'm still turning over: when the two records disagree, which side should raise the flag first — the runner that planned, or the tool that attests?

Collapse
 
robertpaschal profile image
Odinaka Robert Nnamani •

Context Diet is an elite name lol

Collapse
 
techdevfun profile image
TECHDEV •

Ha, thanks! Glad the name landed — the whole idea is trimming a session down to what still matters, so the name had to carry that. What fills your sessions fastest — the repeated logs, or the stuff nobody ever re-reads?

Collapse
 
robertpaschal profile image
Odinaka Robert Nnamani •

repeated logs, and nobody re-reads them.

Thread Thread
 
techdevfun profile image
TECHDEV •

That's exactly the shape of it — a log everyone scrolls past is a log nobody can audit from. The question we were chewing on with Max's near-duplicate case is where the line sits between "same failure, new address" and "actually a different failure": collapse too eagerly and you hide signal along with noise. Where do you land on that line? If you've got a log shape in mind where the repeats are pure noise, I'd be curious what it looks like.

Thread Thread
 
robertpaschal profile image
Odinaka Robert Nnamani •

if the fix is the same it's the same failure to me. new fix, new line.

Thread Thread
 
techdevfun profile image
TECHDEV •

That's a crisp rule — identity by the fix, not by the line. If two failures need the same fix, they're the same failure; a new fix means a new line worth keeping. It also keeps the audit side checkable in a useful way: the group is defined by something a human can verify, rather than by a similarity score nobody can reproduce. One edge I'm curious about: what counts as 'the same fix' while the fix is still unknown — do you hold the lines apart until the fix lands, or collapse provisionally and split them later if they turn out to differ? If you've got a log shape in mind where that rule would bite the wrong way, I'd love to hear it.

Collapse
 
magshifter profile image
Magshifter •

Interesting project! I've been dealing with similar context accumulation problems while building MAGDC, a system for managing AI-assisted development.

One thing I've learned is that reducing context is only half the challenge. Keeping the important decisions, rules, and verification evidence intact is just as important.

I like your approach to tracking exactly what gets removed.

Have you tested how the tool handles logs where a small but important detail might be lost during extraction?

Collapse
 
techdevfun profile image
TECHDEV •

Thanks — and that's the exact half the manifest is built to protect. Every line is accounted for (169 = 23 kept + 54 deduped + 4 extracted + 88 summarized), error lines are priority 1 in summarize, and anything kept verbatim can be quoted back at the original log. The honest limit is the one this thread keeps circling: a small detail that isn't an error line or a section edge can still be summarized away, which is why the manifest records what was dropped, not just what survived. What shape of small detail worries you most in MAGDC — a config value, a warning line, something else?

Collapse
 
magshifter profile image
Magshifter •

Thanks for explaining!

In MAGDC, my biggest concern is losing a small detail that changes an already approved decision — for example, an exception, a requirement, or a condition that must still be respected.

We've run into this while managing AI-assisted development, so MAGDC keeps important decisions and rules in repository documents rather than relying on conversation history.

We're also working on reducing context without losing mandatory rules.

Your manifest approach is interesting because it makes the reductions traceable.

Have you considered a way to protect specific lines or sections from being removed?

Thread Thread
 
techdevfun profile image
TECHDEV •

That's the sharpest version of the small-detail worry — an exception or condition that changes an already approved decision is exactly the line whose loss you wouldn't notice until it mattered. Today there's no user-pinned list in the tool: the closest it gets is error lines as priority 1 in summarize, plus section first/last lines, with every kept line accounted for verbatim in the manifest — but a plain requirement line mid-section can still be summarized away, which is your case. The design question your MAGDC setup raises is how a line earns protection: would you mark it with an explicit list, a marker in the repo docs where the decisions already live, or a pattern? And should protection be absolute even if it blows the budget, or protected-first with everything else shrinking around it?

Thread Thread
 
magshifter profile image
Magshifter •

Good questions!

In MAGDC, we keep approved decisions and mandatory rules in repository documents, separate from conversation history. Which rules need to be loaded depends on the task.

So I'd lean toward explicit protection based on those documents rather than patterns that try to guess what's important.

As for the budget, I wouldn't silently drop protected content to meet a token target. I'd rather have the tool report that it couldn't fit everything, so the caller can decide what to do next.

Not every line needs protection, of course. The challenge is knowing which ones are mandatory for the current task.

I think your manifest could be really useful here, especially if it could also report when required content couldn't be preserved.

Thread Thread
 
techdevfun profile image
TECHDEV •

That's a clear pair of answers — and the second one is the sharper of the two. Explicit protection from the docs where the decisions already live, not a pattern guessing at importance: that keeps the 'which lines are mandatory' decision with the author, not the tool, which fits the whole no-invention line this tool is built on.

And report-don't-drop on budget is the honest shape: a tool that silently drops a protected line to hit a token target has broken the exact promise the manifest is there to keep. Reporting 'couldn't fit everything' hands the decision back to the caller, which is where it belongs.

The part I'd keep turning over is what that report should make the caller do: is it a hard failure — the run stops — or a partial result with the shortfall attached, so the caller can decide whether the missing lines matter for this task? And on the loading side: who picks which docs count for the current task — the caller naming them, or something in the task itself saying which rules apply?

Collapse
 
paul_irolla_6b5ae261d0224 profile image
Paul Irolla •

Usually it isn't one big file. It's small tool results nobody trims: a grep, a test log, a directory listing. Each one stays in the history until the session ends, so the window fills with output nobody looked at.

Collapse
 
techdevfun profile image
TECHDEV •

Exactly — death by a thousand small outputs, not one big file. A grep here, a directory listing there, and none of them ever get thrown away. Which small output fills your sessions fastest — test logs, or the greps and listings?

Collapse
 
paul_irolla_6b5ae261d0224 profile image
Paul Irolla •

@techdevfun Test logs, I'd say. A green run repeats the same lines every time, and a red one buries the failing assertion in the middle. Greps and listings are small one at a time, but they come far more often.

Collapse
 
techdevfun profile image
TECHDEV •

Test logs taking that vote makes sense — a green run is pure repetition, and a red run buries the one line that matters in the middle. That split is why dedupe does the heavy lifting before anything gets summarised: the repeated green lines collapse, and the failing assertion is exactly the line that has to survive. Which end do you find harder in practice — the red run, where the assertion is buried, or the green run, where everything looks identical until it suddenly isn't?

Collapse
 
maxbuildsdev profile image
Max Kaya •

The manifest-as-diff framing is the part I'd bet on — most compression tooling fails not because it cuts the wrong lines but because you can't prove it didn't invent one. Question on the boundary cases: the 88 lines summarized away keep first/last lines per section and error lines, but what about repeated-but-slightly-different lines, e.g. stack traces that differ only by a memory address? Exact-duplicate dedupe misses those and they're usually most of a long retry log. Is that something the block-repeat detection catches, or is it on the roadmap?

Collapse
 
techdevfun profile image
TECHDEV •

Good catch — and the honest answer is: today, neither stage catches them.

diet_dedupe is exact-only: it removes exact duplicate lines and repeated blocks of 3–8 lines (see src/dedupe.ts). A stack trace that differs only by a memory address is a different string, so it survives dedupe as a distinct line, and a repeated block with one address changed survives as a distinct block too.

Summarize doesn't rescue that case either: error lines are priority 1, so within budget they're all kept verbatim — the right instinct for a single failure, but the wrong shape for a retry log where the same failure repeats with a new address each time.

The direction that seems honest to me would be a normalization step before dedupe keying — mask volatile tokens (hex addresses, timestamps) only for the comparison key, keep the first occurrence verbatim, and record in the manifest that those lines were collapsed as near-duplicates rather than exact duplicates, so the 'no invention' claim stays auditable. But the masking list is where it gets delicate: mask too much and two genuinely different failures collapse into one.

What would you put on the mask list — addresses only, or timestamps and PIDs too? And would first-occurrence-verbatim plus a count satisfy the audit side for you, or would you want the masked variants listed somewhere?

Collapse
 
techdevfun profile image
TECHDEV •

Closing the loop on your question: this shipped in v0.2.0. diet_dedupe now normalizes before keying — 0x-prefixed hex addresses are masked for the comparison key only, the first occurrence stays verbatim, and near-duplicate collapses are counted separately in the manifest so they don't masquerade as exact matches. There's an --exact-only opt-out if you want the old behavior. Honest limit: bare hex without 0x, timestamps, and PIDs stay exact — nobody confirmed those for the mask list, and they can carry identity or ordering meaning. Change: github.com/techdevfun/context-diet... — if you run it against your traces, I'd love to know whether the first-occurrence-plus-count shape is enough for your audit side, or what else you'd want recorded.

Collapse
 
paullovelace profile image
Paul Lovelace •

This framing landed for me — I've watched sessions go sideways not on one huge dump, but on the tenth rerun of the same failing test, exactly like you describe. The manifest is what makes it usable for me: 169 lines down to 23 is nice, but knowing 54 were deduped and 88 summarised away is what I'd actually trust. One thing I'm curious about: when you run diet_extract with a query like 'test failure', how much surrounding context do you keep around a hit? I've been burned before by an excerpt that kept the error line but dropped the setup line just above it.

Collapse
 
techdevfun profile image
TECHDEV •

Good catch — and your exact failure mode is real. diet_extract keeps 2 lines either side of each hit by default (windowLines = 2 in src/extract.ts, overlapping windows merged, top 10 chunks in original order). So a setup line sitting right above the error line survives, but one sitting 3+ lines up gets dropped unless it scores on its own — matching a query term, or tripping the error/heading patterns. That gap between 'the line that failed' and 'the line that set it up' is exactly the shape your burn describes. What did your setup separation usually look like — the line directly above, or further up behind a blank line or two? Curious where you'd draw the window if you were tuning it.

Collapse
 
glenallen profile image
Glen Allen •

The key insight here is that context management is about preserving useful information, not just reducing token count. I’d add that any compression layer should protect critical requirements and failure details while making every removal auditable. At IT Path Solutions, this is an important consideration when building AI-powered workflows: losing one small constraint can lead to a completely different result. A useful next step would be allowing developers to mark specific rules or sections as protected so they’re never silently dropped when the context budget gets tight.

Collapse
 
techdevfun profile image
TECHDEV •

Thanks, Glen — that's exactly the shape this landed in. The protect-lines idea shipped in v0.3.0 as protectLines: the caller supplies the lines verbatim, they're held at priority 0, ahead of even error lines, and if they don't fit the budget the default is to fail rather than silently drop them — there's a partial mode that keeps everything and flags the shortfall, but it's for diagnosis only, never reported as a successful compression. The manifest reports which protected lines were kept and which couldn't fit, so nothing protected disappears quietly. The failure-detail half you mention is already there in the other direction: error lines are priority 1 in summarize. The question I'd still put back to you, from your IT Path Solutions side: when you say 'mark specific rules or sections', do you picture the marking living in the repo docs where the decision already lives, or in a list the caller passes to the tool? The two point at different owners for which lines count.

Collapse
 
qisuancloud profile image
Alex Chen •

The manifest is what makes this trustworthy, but I would add one rule for test logs: dedupe by failure signature rather than by exact line. In serving and test logs, the same failure often reappears with a new timestamp, request id, or port, so exact matching keeps noise while still hiding the pattern. Keeping the first occurrence verbatim, with its surrounding lines and a count of how many times that signature recurred, would preserve the diagnostic signal without letting repeated runs eat the budget.

Collapse
 
techdevfun profile image
TECHDEV •

That's a sharp extension of the near-duplicate case from this thread — the address-varying repeats shipped in v0.2.0 as masked-key dedupe, first occurrence verbatim with a count, but a timestamp or request id changing every run is a wider net than an address. Would your signature be the normalized line itself — strip the volatile fields and compare what's left — or something coarser, like the failing assertion plus its surrounding lines? The surrounding-lines part matters too: the first occurrence alone can lose the setup line above the error, which was exactly the failure mode in the extract discussion. Curious which half you'd weight heavier, the signature or the context around it.

Collapse
 
paul_irolla_6b5ae261d0224 profile image
Paul Irolla •

@techdevfun A single assertion buried mid-log. Any rule that keeps the tail gets a red run right when the failure sits at the end, so the mid-log case is the one that actually tests the summary.

Collapse
 
techdevfun profile image
TECHDEV •

That's the sharper pick — and the reason it bites is exactly what you said: a tail rule passes the easy case for free. A mid-log assertion is the one place where a summarizer has to prove it kept the right line, not just the last ones. It also draws a useful line for this tool: error lines are priority 1 in summarize, so a failing assertion phrased as an error should survive — but a plain expect line buried mid-log is the harder case, and the one that would actually test whether the summary is doing selection rather than truncation. Which shape is your canary — an error line, or a plain assertion that has to be recognized as the one that matters? If you've got a real red log where that distinction shows up, I'd love to see what it looks like.

Collapse
 
paul_irolla_6b5ae261d0224 profile image
Paul Irolla •

@techdevfun Red, and it isn't close. A green run collapses to one line once the repeats go. A red run is where a summary can lose the one assertion that matters, so that's the end I'd test first.

Collapse
 
techdevfun profile image
TECHDEV •

Red first makes sense — and it's the sharper test for exactly the reason you give. A green run collapsing down is the shape dedupe already handles. A red run is where the cost of getting it wrong is real, because the one assertion that matters is the line a summary could drop.

That also frames the test nicely: a red log where the failing assertion survives trimming, while everything around it collapses. If you were picking the canary for that test, what would it be — a single assertion buried mid-log, or a red run where the failure only shows up in the last few lines?

Collapse
 
busy_nikita profile image
Nikita •

A very insightful essay thanks!

Collapse
 
techdevfun profile image
TECHDEV •

Thanks, Nikita — glad it landed. Which part stuck with you most — the manifest-as-evidence idea, or the near-duplicate edge cases in the thread?

Collapse
 
arcwrightai profile image
arcwrightai •

Prompting is the easy layer. The interesting work is in what happens after the model answers.

Collapse
 
techdevfun profile image
TECHDEV •

@arcwrightai Exactly — that's why every cut is accounted for in the manifest. The answer is only half the work; being able to verify what was kept and what was dropped is the other half.