pi-fold Agent-Governed Lossless Context Folding
A session folds its own transcript instead of losing it. The originals stay on disk, verified by hash, one tool call away.
Scroll to explore
The Problem
Compaction does not continue a session, it starts a new one
An agent session is a transcript that only grows. Every tool result, every file read, every plan revision stays in the window because the next turn might need it. Eventually the window fills, and the standard remedy is compaction: summarize the transcript, discard the originals, start again from the summary. Pi's native compaction does exactly this, and the word continuation is carrying a great deal of unearned weight: when compaction fires the session ends, a new session begins holding the summary, and the agent genuinely starts over. The controlled run behind the numbers on this page makes that literal rather than rhetorical. Native compaction fired three times, and the request immediately after each one carried a prompt of exactly zero tokens: 369.0k to 0k, then 364.6k to 0k, then 363.0k to 0k. A continuation does not restart at zero.
The cost is not only the pause. A summary is a decision about what mattered, made before anyone knows what will matter. The continuation key an agent was carrying, the exact error string from a build, the line number it planned to return to: these are the details a summarizer drops because they read as bookkeeping, and they are the details that become unrecoverable once the originals are gone. The agent has no way to tell that they are gone. It sees a coherent summary and proceeds as if nothing were missing.
The handoff is also written before the end, which means the freshest material is precisely what is missing from it. A summary can describe what the session did. It cannot describe what the session was in the middle of, because that was still happening when the summarizer ran. In this run the third compaction summary said so itself: under its own "Blocked" heading it recorded that "Stage 55's delivered tool result is truncated in the transcript, so its NEXT_KEY must be recovered from repository-tool state after the file review". The new session then called the stage tool with a fabricated all-zero continuation key, having lost the real one. It recovered, and then ended its turn at stage 56 of 64 while holding a valid key. That is one observed incident with a clear mechanism, not a rate. It happened once, in one run, and nothing here replicates it.
Agents have become good at picking up the pieces, and that competence is what hides the bill. The new session has to read its handoff, and then it has to read back everything the old session already had open, because those files are now described rather than present. The work is measurable. Native made 117 agent-initiated file reads pulling 0.93 MB from disk; the folding arm made 27, pulling 0.06 MB. Same task, same seed, both counted up to the stage 56 record where native stopped: 4.3 times the reads and 15 times the bytes, spent recovering ground that had already been covered.
The quieter problem is that nobody is controlling the size of the window. Between compaction events it drifts across the entire allotment the model permits, a span that reaches a million tokens on the largest windows served today, and behavior is not constant across that range. Attention thins, instructions early in the window lose their grip, and retrieval from the middle turns unreliable. You are not running one system at two sizes; you are running a different system at 40k than at 400k. Native's operating band across all 117 message requests in its ledger was 0k to 369.0k, a swing of 369.0k around a mean of 140.9k, and 12 of those requests were served above 300k.
Folding does not aim at a smaller window. It aims at a narrower one. When occupancy crosses a threshold the runtime folds pieces in place and the session keeps its turn, so the window stays inside a band instead of sweeping the whole allotment. Across 82 requests the folding arm ran between 1.1k and 236.9k, a swing of 235.8k around a mean of 138.8k: essentially the same average window as native, held inside a range that never touched zero, never passed 236.9k, and never once entered the zone above 300k. Its six fold events cut the window from 237k, 230k, 210k, 212k, 215k and 182k down to 71k, 58k, 77k, 77k, 86k and 98k. Nothing restarted, and nothing had to be read back.
Where the window actually sat, request by request
Prompt size on every message request in the full ledger of both arms of the same seed. Native compaction climbs to 369.0 thousand tokens and collapses to zero three times, at requests 29, 61 and 98, because each compaction ends the session and a new one starts from nothing. pi-fold stays between 1.1 and 236.9 thousand tokens across 82 requests, folding in place six times without ever resetting. Native served 12 of its 117 requests above 300 thousand tokens; pi-fold served none of its 82 there.
Prompt size on every message request of both arms, same seed and same plan hash. Native climbs to 369.0k and falls to nothing three times, once per compaction, and the line returns from zero because a new session is building a new window from scratch. pi-fold folds in place six times and never leaves its band. The shaded region is everything above 300,000 tokens, where the model is a meaningfully different system: native served 12 of its 117 requests inside it, pi-fold none of its 82. The two arms hold almost the same mean window, 140.9k against 138.8k; what differs is the range. Both lines are their arm's whole ledger, so native's 117 message requests include the six it made after the stage-56 cut that the cost comparison further down is drawn at. Its three compaction summarization calls are billed too, and they are counted in that cost rather than plotted here. Hover, tap or arrow key any request to read both arms at once. Measured from the sealed run artifacts.
The Mechanism
A summary with the original still attached
A fold takes a contiguous span of session entries and replaces them, in the window only, with a short brief. The entries themselves are written to a fold store, byte for byte, addressed by their SHA-256 hash. The brief carries a handle, the handle resolves to the original, and expansion restores the exact bytes after verifying the hash. A fold is therefore a claim the runtime can check, not a claim the reader has to trust.
Because nothing is destroyed, the window behaves like a conveyor belt rather than a bucket that gets emptied. New entries arrive at the tail. Older spans fold down into briefs. Occupancy stays roughly flat while the session keeps running and the agent keeps its turn. There is no restart, no handoff, and no moment where a fresh session has to reconstruct what the old one knew.
The tradeoff is that a brief is genuinely less useful than the original. That is the point: a brief costs a fraction of the tokens, and the original is one tool call away for the cases where the brief turns out not to be enough.
One session, folding as it goes
One agent session drawn as a chat transcript that keeps running. User messages sit on the right in cream, assistant replies on the left in green, tool results a quieter shade of the same green, each sized by how much of the context window it occupies. Some tool calls are the agent marking spans: a mark outlines the span it names and moves nothing, and the next fold event commits every standing mark in one rewrite, so two marked spans can collapse to two briefs at once while the unmarked stale end is left for the ladder. A protected fresh tail covers the newest turns: a marked span still inside it is held at the fold event and commits only after it ages out, so recent work is never folded out from under the turn using it. As the window fills, finished units of work fold into single briefs: at the stale end, in the middle of the index with older messages still open above them, and finally into folds that hold other folds. The session never restarts, and every folded message stays recoverable byte for byte.
One session, drawn as the transcript it is: your messages on the right, the agent's replies and tool results on the left, each sized by how much of the window it costs. Colour follows the speaker: you in cream, the agent in green, tool results one shade quieter in the same green. Watch the tool rows that call pi_fold_context mark: the agent is naming spans it has finished with, each mark outlines the span it claims and moves nothing, and the next fold event commits every standing mark in one rewrite, two outlined spans collapsing to two briefs at once. The dotted rule riding over the newest turns is the protected fresh tail: a mark that lands inside it is held at the fold event, so nothing folds out from under the turn still using it, and it commits a few turns later once it has aged out. When occupancy crosses the budget the runtime folds a finished unit of work into a single brief and the session keeps its turn. Folds land where the work finished rather than only at the stale end: watch one form in the middle of the index with older messages still open above it, and watch the ladder take the unmarked stale end on its own. Neighbouring folds then consolidate into a fold that holds folds, and the exact messages stay on disk, addressed and verified by SHA-256. Nothing restarts. Click any fold to open it: the messages it holds come back from disk, each row in its speaker's colour dimmed a step to read as folded material, and the window does not change. Hover, tab to, or tap any message to read it in full; the session holds still while you do. Illustrative visualization.
Curation
The agent holds the verbs, so the cuts follow the work
The folding tools are in-band. The session agent, the one actually doing the assignment, can mark any span it judges finished: a file it has already extracted what it needed from, a search whose results it has acted on, a plan revision three revisions stale. It can mark as it works, because it is the only party that knows when a span stopped being load bearing. Boundaries then follow the shape of the work rather than position in the transcript. That is the defining feature of this runtime, and it is also the one thing on this page with no measurement behind it yet.
There is an automatic ladder underneath, and it is the fallback rather than the primary. A session that never calls the tool still folds: the runtime collapses aging spans on its own and consolidates them as they age further, which degrades into lossless hierarchical compaction. Both modes ship and both are real. The claim is not that the agent must curate, only that it can. In the one run measured on this page the agent never called the tool at all, so every number here was produced by the floor and nothing above it. That is the open problem at the end of this page, not a footnote to it.
Boundaries by position, boundaries by the work
Two tracks over the same illustrative transcript of one hundred messages. The positional ladder folds from the oldest end as material ages, and four of its five boundaries land inside a unit of work rather than on the edge of one. The agent curated track folds only whole units, messages 12 to 22, 31 to 46, 72 to 78 and 83 to 92, and the material in the gaps between them is still live in the window. Marks accumulate without moving a byte and then land together, so four folds arrive in two commits against the ladder's five rewrites.
The same hundred messages under both modes. Above: the automatic ladder folds from the oldest end as material ages, so its boundaries track position and cut a unit of work in half four times out of five. Below: the agent marks a span the moment it stops being load bearing, so every boundary lands on the edge of a unit and the gaps between the folds are live material the session is still using. Under epoch scheduling marking moves no bytes and leaves the projection byte-identical, so the cached prefix survives; every accumulated mark then lands in a single rewrite when the runtime commits, which is why four folds here cost two rewrites and the ladder's five folds cost five. Both modes ship, and a session that never calls the tool degrades into the ladder. The loop runs on its own; drag the scrub to stop on any message, and hover a span to see the same messages on the other track. Illustrative visualization.
Cost Discipline
Marking is free, folding is rare and batched
A mark costs nothing. It records the judgment that a span has gone stale, it lives in durable session state, and the projection stays byte-identical: no byte moves, and the cached prefix survives intact. A commit is the one moment the projection gets rewritten, and it earns that rewrite because every accumulated decision lands in it at once, so the cost of moving bytes is paid once for many folds instead of once per fold. Marking is continuous; folding happens in rare bulk events. Free marks and batched commits are epoch scheduling, the mode the run measured here used; the shipped default is the simpler one, where a fold applies the moment it is made and pays for its own rewrite.
The wire trace of the 64-stage run shows exactly that shape, though the marks in it were the automatic ladder's rather than the agent's: 76 prefix appends, 6 rewrites, 0 unattributed rewrites. Every rewrite is attributed to a commit, and the six of them landed batches of 12, 14, 9, 11, 9 and 7 folds, which sum to the run's 62. The stream carries 12 commit events behind those 6 rewrites, because a commit that frees nothing still records itself and two can land in the same rewrite. Nothing happened in between, because every other turn was a pure append at the tail. The zero is the number worth reading twice: an unattributed rewrite is a byte that moved for a reason the runtime cannot name, and every one of those is a cache miss nobody chose.
Eighty-two requests on the wire
Projection size across the 82 provider requests of pi-fold rep23. The line climbs on pure appends toward the 255,616 token fold budget and drops sharply at each of six rewrites, which occur at requests 19, 33, 44, 57, 68 and 76 and commit 12, 14, 9, 11, 9 and 7 folds respectively. 76 of the 82 requests moved no existing byte.
pi-fold rep23, the complete 64-stage run: 76 pure appends at the tail and 6 rewrites, none of them unattributed. Every rewrite is attributed to a commit, each landing a batch of folds at once, 12, 14, 9, 11, 9 and 7 of them, which is why the projection sawtooths against the budget instead of creeping past it. Hover, tap or arrow key any request to read its projection size, its share of the fold budget, and at a rewrite the batch of folds that landed there. Measured from the sealed run artifacts.
Structure
Folds nest, and peek reaches any depth
The fold structure is a DAG, not a list. Leaves are the exact session entries. Every fold record keeps ordered references down to those leaves, so the path from any brief to its original bytes is explicit. Folds nest rather than partially overlap: consolidation takes two or more adjacent folds and makes a deeper one, which means the structure is hierarchical and can be many levels deep. Expansion at any depth restores the originals after SHA-256 verification.
There are two verbs, and the difference between them is the interesting part. peek returns one fold's exact verified source as a tool result, at any depth, with the ancestors still collapsed and the projection untouched. The agent can reach into a deeply nested fold and pull just that content into its window without digging down through everything above it, and without committing to keep it. expand is the commitment: it restores the source in place until it is refolded, and it works outside-in, level by level, so expanding a parent reveals its children's briefs, each expandable in turn.
Looking is not the same as taking. Most of the time an agent needs to check one detail, not reopen an hour of work, and peek is the verb for that.
Folds inside folds, and reaching into one without opening it
An agent's context window as a single column, oldest entry at the top: the standing request, five chapters of work that have each collapsed into one fold brief, and a live tail of exact entries. A fold boundary sits at every chapter shift. The oldest chapters carry three levels of folds inside folds, the newest carry one. Hovering or focusing a brief only previews it: a tooltip says what its peek would return and the window is left untouched. Pressing that brief's PEEK button is the commit, appending the fold's own verified source at the tail, from any depth, with its ancestors still collapsed and nothing already in the window moved. Expand restores a brief in place, outside in, one level at a time, and rewrites the window from that point down. Each level opens onto a mix of exact entries and deeper folds, and the deepest levels are exact entries alone.
This is the window, and the seat is yours. One session runs top to bottom in a single column: the request, five chapters of work, the live tail. A fold boundary sits at each chapter shift, which is why the pivots stayed raw and the exploration around them folded. Older chapters have been consolidated more than once, so the rail on the left counts the levels stacked over them: three, three, two, one, one. Click a brief and it expands in place, one level per click, and the window is rewritten from that point down; click it again to refold it, which rewrites it back. What an expand returns is conversation rather than more briefs: exact user messages, replies and tool results, mixed with sub-folds where a run of work had already collapsed, until the deepest level is nothing but exact entries. Hover or tab to a brief instead and you get a preview and nothing else: a tooltip at the cursor says what its peek would return, and hovering it a hundred times leaves the window byte for byte where it was. Press that brief's PEEK button and the exact source travels to the tail, from any depth, with every fold above it still collapsed and nothing already in the window moved. The folds nested underneath carry their own PEEK, so you can raise one buried thing without restoring the rest. Watch the rewrite counter: expands move it, peeks never do, however deep you reach. Illustrative visualization: rep23 produced a single flat layer of 62 folds, so the nesting drawn here is the mechanism, not that run. A peek card previews the source it returned rather than printing all of it, and carries no digest, because an illustration has no source bytes to hash.
The Trap
A prefix cache is positional, so a fold can cost more than it saves
A provider prefix cache replays the longest byte-identical prefix of the prompt. That is the whole rule, and its consequence is unforgiving: one changed byte at offset K discards everything cached after K. The cost of a mutation has no relation to its size. Deleting a single character in the middle of a large window and rewriting a hundred thousand tokens near the end of it bill the same way, because both invalidate the same suffix.
Folding is a mutation. A fold that removes a stale span from the middle of the window forces a re-send of everything positioned after it. The saving is real, but it accrues over future turns, and the bill arrives on this one. Fold too eagerly, or fold in the wrong place, and a mechanism designed to reduce token spend increases it.
This is why folding has to be rare and batched, and why the first instinct, fold as soon as something goes stale, is exactly wrong. It is also why the invariant further down is stated in terms of bytes and positions rather than in terms of what the code intended.
Why a twelve byte edit can cost a million tokens
A projected prompt of 1,000,000 tokens as one long bar with a draggable edit point. Every token after the edit point is invalidated regardless of how small the edit is: the same edit costs up to 1,000,000 re-sent tokens at the head of the window and zero at the tail. A ledger below stacks several unbatched edits against the same edits landed as one commit. Illustrative at a 1,000,000 token window; the measured runs ran at 272,000.
A provider prefix cache is positional: it replays the longest byte-identical prefix, so one changed byte at offset K discards every cached token after K. Drag the edit point. The edit is the same twelve bytes wherever you put it; only its position changes the bill, and at the tail it costs nothing. That is why the runtime may move a byte only at a moment it is already rewriting the window, and why everything else is a pure append that is never later altered. Illustrative visualization at a hypothetical 1,000,000 token window, chosen to show the extreme; the measured runs ran at a 272,000 token context window. The annotated peek reclamation cost of about 100,000 fresh input tokens is measured.
Scheduling
The simple design spent 5.4x the fresh input, so a fold request became a mark
The obvious design is to fold in place the moment the agent asks for it: a tool call, applied immediately. That is simpler, and it is what was built first. It turned out to be expensive, because every fold event is a reindexing of the context window, and reindexing forces a complete re-cache. The purpose of the work is to do more with less, so a simplicity that makes the provider read 5.4 times more fresh input is not a good trade.
The compromise that shipped: the agent's fold requests become marks. A mark records where a fold should happen and what its brief will say. Marks are stored outside the context window, so recording one moves no bytes in the window and the cached prefix survives intact. Nothing is applied when the mark is made. When a fold event does trigger, every accumulated mark is applied together, in one batch. The agent still manages its own context; the mutation events are simply consolidated into one.
Two runs from the campaign, both on gpt-5.6-luna, put a number on it. This pair is the second of the two experiments behind this page: pi-fold against itself rather than against native. Same plan, same seed, same model, identical configuration, with exactly one variable changed: fold scheduling. Applying folds immediately spent 19,623,502 fresh input tokens across 105 requests at a pooled cache share of 0.119. Recording marks and landing them together at the next fold event spent 3,603,440 across 99 requests at 0.756. That is a 5.4x reduction in the tokens the provider had to read for the first time, with observed mutations falling from 83 to 19, and it carried the total down from 22,316,589 tokens to 14,818,833: about a third less for the same work.
Three things keep that honest. Epoch was slower in wall clock on this pairing, 33.5 minutes against 26.7, so the trade bought tokens and not time. These are two runs, one per arm, a single pair rather than a rate or a general law. And the mutation figure is an older instrument: it counted provider-side cache misses and real projection rewrites together, so 83 against 19 is a valid comparison between these two runs and nothing else. The six rewrites reported earlier on this page come from a later per-message digest that separates a rewrite the runtime actually made from a miss it did not cause, and chaining 83 to 19 to 6 would change instruments partway through the series.
One variable changed: when a fold applies
Five paired bars comparing two runs of the same plan and the same seed with only fold scheduling changed. Applying a fold when the agent asks for it: 83 observed mutations, 19.62 million fresh input tokens, pooled cache share 0.119, 22.32 million total tokens, 26.7 minutes. Recording a mark and landing every mark together at the next fold event: 19 observed mutations, 3.60 million fresh input tokens, pooled cache share 0.756, 14.82 million total tokens, 33.5 minutes. Batching spent 5.4 times less fresh input and a third fewer tokens in total, and took 1.25 times as long in wall clock.
pi-fold against itself on gpt-5.6-luna, same plan and same seed, with fold scheduling as the only variable. Applying a fold the moment it is asked for reindexes the window every time, so the cache rarely survives; accumulating the requests as marks and landing them together at a fold event collapses fresh input 5.4x and inverts the cache share. Epoch was slower here, 33.5 minutes against 26.7, and this is one run per arm rather than a rate. Observed mutations is an older conflated counter, comparable between these two runs and not to the six rewrites reported above. Each row scales to its own larger value, except pooled cache share, which runs the full 0 to 1. Measured from the sealed run artifacts.
What Went Wrong
Three mechanisms, three confident comments, one bug
Three separate features shipped that each rewrote the window mid-prefix: the surfacing slate, peek reclamation, and the receipt block. Each carried a code comment asserting the edit was tail-local and therefore safe. In all three cases the comment was the marker of the bug, and it was also the reason the bug survived review: the reasoning looked done, so nobody redid it.
Peek reclamation was the costliest. It removes duplicate bytes from the window after a peek, on the argument that the fold store already holds them losslessly, and it defers the removal until a later assistant message exists so the edit lands behind the tail. That deferral is what makes it look tail-local and what guarantees it is not: waiting for a later message is precisely the condition under which the window has already grown over the site of the edit. Two reclamations cost about 100,000 fresh input tokens to reclaim bytes that were never at risk.
An edit is tail-local at the moment it is conceived and has stopped being tail-local by the time it runs, and the gap between those two moments is where the confidence lives.
Surfacing
Cut for the delivery, not for the idea
Of those three, the surfacing slate deserves its own account, because the idea was not the problem. The mechanism scored the fold set against the live window and surfaced potentially relevant folds to the agent: a short slate of what might be worth peeking at, or worth expanding, given what the session was doing right then. It worked, in the sense that the selection was useful.
What failed was the delivery. The slate arrived as an ephemeral message at the tail of the window, shown on one pass and withdrawn on the next so a recomputed slate could take its place. That is a show-then-retract. The slate's bytes occupy prefix positions in one request, different bytes occupy those positions in the next, and the cached prefix dies at the first position that changed. An ephemeral message at the tail sounds tail-local, and that is the same trap as the other two: by the time the next request goes out, the window has grown past the slate, and the retraction is an edit in the middle of the prefix. On the Codex transport this happened on essentially every pass.
So the feature was cut for its delivery mechanism, not because suggesting was wrong. Any future version has to put a suggestion in front of the agent without the window changing underneath it; the shape that survives the invariant is the open problem this page ends on.
The Simplification
Move a byte only at a moment you are already moving bytes
The fix was not a better heuristic for deciding when an edit is safe. It was removing the question. The runtime may move a byte in the window only at a moment it is already rewriting the window, which is to say during a commit or a fold. Everything else is a pure append at the tail, and an appended byte is never later altered, shortened, removed, or repositioned.
Stated plainly: never mutate the window, and never show something and then take it back. The second half is the one that costs features. Anything that displays state and then updates it in place is out, however useful the display was, because updating in place is a mid-prefix write with better manners.
Several mechanisms were deleted rather than repaired under this rule. That is the trade the numbers below reflect: a smaller, duller runtime that spends its rewrites deliberately, instead of a richer one that leaked them.
Experiment Design
One task, two runtimes, everything else held
There were two experiments, and they answer different questions. The first sets folding against Pi's native compaction on the same assignment: three runs, all gpt-5.6-sol, giving the two pairings reported below. The second set pi-fold against itself with one variable changed, when a fold applies, per tool call or marked and landed in a batch; that pair ran earlier, both arms gpt-5.6-luna, and its result is the reason the runtime measured here folds the way it does. The second experiment is reported in the Scheduling section above. Everything from here down is the first.
The workload is a 64-stage staged assignment over the curl C repository: one Pi session per run, one user message, and the agent calls a repo_stage tool 64 times inside a single agentic turn. Model gpt-5.6-sol at xhigh effort, provider openai-codex. The folding runtime measured itself against a fold budget of 255,616 tokens, which is the per-request input descriptor this model advertises, 272,000 tokens, less a 16,384 token reservation for output. That descriptor is the transport's number, not the model's: gpt-5.6 advertises a 1,050,000 token context window, and the Codex catalog caps it at 372,000, which is where the native arm actually lived, climbing to 369.0k before each compaction. The runtime falls back to the descriptor whenever a deployment hands it no total-window fact, which is the honest default for an unlisted model. So this run folded against roughly two thirds of the window the transport actually served, and the sawtooth above is the fold cadence at that budget rather than at the true ceiling. One arm runs the folding runtime. The other runs Pi's native compaction. The shape of the task is the hard part: one long turn with no natural handoff point, over a repository large enough that both runtimes have to shed context well before stage 64.
The caveats are load bearing, so they go first. There is one run per arm. Native did not finish: it ended its turn at stage 56 of 64. That leaves two comparisons, and both are reported here. The complete-vs-complete pairing puts a finished folding run against a finished native run, but those two runs sit on different days, so provider conditions differ, and on that pairing native was faster in wall clock, 32.4 minutes against 34.2. The stage-56 pairing holds seed and plan hash constant and cuts both arms at the stage where native died, which controls the comparison at the price of never exercising the last eight stages.
The Result
The same material, at two thirds of the tokens
On the controlled pairing, same seed, same plan hash, both arms cut at the ledger record that delivered stage 56: folding spent 9,598,126 total tokens against native's 16,011,169, a ratio of 0.60x, across 69 requests against 111. Tokens and dollars are summed over exactly those records for both arms, native's three billed compaction calls included, so the usage and the bill describe the same rows. Fresh input barely separates the runtimes: 1,249,415 for folding against 1,322,539 for native, a ratio of 0.95x, and on the complete pairing it runs the other way at 1.06x, so neither one consistently reads less new material. The 6.4 million token gap is re-sends of accumulated context rather than a difference in how much material was consumed: 6.29 million of it is cache read alone.
The work done off the wire moved the same way. Folding made 27 agent-initiated reads totaling 0.06 MB from disk; native made 117 reads totaling 0.93 MB, which is 4.3x the reads and 15x the bytes. That is the shape of an agent re-reading files it had already read and lost. Wall clock on this pairing was 25.2 minutes against 42.7, a ratio of 0.59x.
One number runs backwards, and it is the most useful finding here. Native's pooled cache share is higher, 0.917 against 0.869, while native spends 67 percent more tokens and bills 82 percent more dollars, $21.00 against $11.57 in Pi's own session ledgers. Cache share measures how cheap each prompt was, not how much prompt was needed, so a runtime that re-sends an enormous window every turn scores beautifully on it. This campaign spent several iterations optimizing against that number before the inversion was obvious. The correction is to read total tokens as the headline and cache share as a diagnostic underneath it.
The complete-vs-complete pairing points the same direction with weaker control: 11,435,313 total tokens against 16,970,754, a ratio of 0.67x, over a folding run that made 62 folds. On that pairing native finished in 32.4 minutes against 34.2, so native was faster, and the two runs sit on different days, so provider conditions differ.
The arm that wins the popular metric loses the bill
On the same seed cut at the record that delivered stage 56, native reached a pooled cache share of 0.917 against pi-fold's 0.869 while spending 16.01 million tokens against pi-fold's 9.60 million and billing $21.00 against pi-fold's $11.57. Both arms are summed over the same billed records, native's three compaction calls included. Fresh input was 1.25 million for pi-fold and 1.32 million for native, so the gap is re-sent context rather than material consumed. On the completed pairing pi-fold spent 11.44 million tokens over 82 requests against native's 16.97 million over 105, and native finished in 32.4 minutes against pi-fold's 34.2.
The popular metric and the bill point in opposite directions. Native holds the higher pooled cache share and still pays more to do the same work, because cache share measures how cheap a prompt is, not how much prompt was needed. Both arms are cut at the ledger record that delivered stage 56, and tokens and dollars are summed over exactly those records, native's three billed compaction calls included. Fresh input barely separates them, 1,249,415 against 1,322,539, so the 6.4 million token gap is re-sent context rather than extra material consumed. Cost is what Pi itself billed, and the cost gap is wider than the token gap: pi-fold spent 0.599x the tokens and 0.551x the dollars, $11.57 against $21.00. Three mechanisms open that extra distance. The largest is a pricing tier: Pi doubles input and cache read and adds half again to output on any request whose context passes the 272,000 token window, and native crossed that line on 17 of its 111 requests while climbing toward each compaction, $4.50 of its bill; at flat base rates it would have paid $16.51, cutting pi-fold's 44.9 percent cost saving to 29.9. Native also spent 86,390 output tokens against pi-fold's 38,951, more than double, re-orienting after each restart, and output is the dearest category at $30 per million. And native's three compaction summarizations are themselves billed calls, $0.58 that pi-fold never pays. Switch pairings to see the complete runs as well, where native finished faster, 32.4 minutes against pi-fold's 34.2. Measured from the sealed run artifacts.
Prior Work
The lossless DAG is shared ground; who decides is not
Lossless hierarchical compaction is not new here. LCM (arXiv:2605.04050, with an interactive walkthrough at losslesscontext.ai) builds a summary DAG over older messages with lossless pointers back to every original. That is the same structure, and it is what this runtime falls back to when the agent stays silent, so the lossless DAG is shared prior art rather than a contribution of this project. What differs is who decides and where the boundaries fall. In LCM the system alone decides when to compact, and folds accrete sequentially from the beginning of the conversation as it ages, so the cuts track position. Here the verbs are in-band, so the cuts can track relevance instead. LCM-style compaction is the floor; letting the agent curate its own context is what this adds on top of it.
Self-GC (arXiv:2607.00692) is the closest on governance: it treats context as indexed, recoverable objects with fold, mask and prune actions, though those actions are proposed by a side-channel planner under harness enforcement rather than by the session agent itself. Context-Folding (arXiv:2510.11967, ByteDance Seed) has the agent branch into a sub-trajectory and fold it on completion, with the behavior shaped by reinforcement learning, and that fold keeps a summary of the outcome rather than a lossless path back to it. MemGPT and its successor Letta are the canonical agent-held memory-verb systems, and two things separate this from them. First, what is governed: Letta manages traffic between the window and outside storage, and when its message queue overflows the in-window record becomes a lossy recursive summary, where folding restructures the transcript in place. Second, recovery: theirs is retrieval, a search that re-ingests whatever comes back as new tokens; this is expansion, which restores the exact folded entries after SHA-256 verification.
The honest placement is narrow. The distinguishing claim is agent curation, and the run measured on this page never exercised it, so every number above belongs to the fallback: lossless hierarchical compaction driven by an automatic ladder, which is the part that is not new. The part that is new is stated here and not yet measured.
What Is Next
The agent never touched the surface at all
All 62 folds in that run were the automatic ladder's, and every commit in the event stream records zero agent marks against seven to fourteen ladder marks: no marks, no peeks, no expands, across the entire 64-stage turn. So the 0.60x above is the floor's number. The compression worked without the agent's help, and the retrieval, which is the entire justification for the compression being lossless, went unused: the session carried a verified, addressable copy of everything it had folded away and never opened it.
This is not a capability gap. Earlier iterations did get the agent to engage with peek and expand, but only through persistent in-window guidance: a block that lived in the window and was rewritten as the fold set changed. That is a mid-prefix mutation, exactly what the invariant forbids, and it was deleted along with the other three. Engagement went with it. The honest reading is that the runtime bought part of its token numbers by removing the mechanism that made the lossless half worth having.
So the open problem states precisely: give the agent a reason to reach for peek and expand without moving a byte it has already been shown. The next experiment is surfacing. Score folds against the current task, and deliver the resulting suggestions at a moment when the window is already being rewritten, since a commit is the one point where a rewrite is already paid for. Marks can live outside the window and land at a fold event, so the same batching that makes folding cheap can carry the invitation.
pi-fold is published on npm as pi-fold under the MIT license. One repository carries the runtime, the gate suite that is its contract, and the experiment harness that produced every measured number on this page. Source is linked below.
Citations
The source, the package, and the work this stands on
pi-fold. The runtime, its gate suite, and the experiment harness behind every measured number above: github.com/shaneconner/pi-fold. Published on npm as pi-fold, MIT licensed.
LCM: Lossless Context Management. Clint Ehrlich and Theodore Blackman, February 2026. arXiv:2605.04050, with an interactive walkthrough at losslesscontext.ai. The lossless summary DAG over aging messages, which is what this runtime's automatic ladder amounts to.
Self-GC: Self-Governing Context for Long-Horizon LLM Agents. Xubin Hao, Hongjin Meng, Xin Yin, Jiawei Zhu and Chenpeng Cao, July 2026. arXiv:2607.00692. Context as indexed, recoverable objects under fold, mask and prune actions, proposed by a side-channel planner under harness enforcement.
Scaling Long-Horizon LLM Agent via Context-Folding. Weiwei Sun and colleagues, ByteDance Seed, October 2025. arXiv:2510.11967. The agent branches into a sub-trajectory and folds it on completion, keeping a summary of the outcome, with the behavior shaped by reinforcement learning.
Letta, formerly MemGPT. github.com/letta-ai/letta. The canonical agent-held memory verbs, governing traffic between the window and outside storage.