@mikefreno/pi-fold0.1.0
Fold-once context compaction for pi — each span is summarised exactly once, and every folded block restores in full.
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
pi-fold
Fold-once context compaction for pi. Each span of a session is summarised exactly once, and every folded span stays restorable in full.
Why
Pi's compaction summarises the span since the previous kept boundary together with the previous summary:
compaction 1: summary(span 1)
compaction 2: summary(summary(span 1) + span 2)
compaction 3: summary(summary(summary(span 1) + span 2) + span 3)
So the oldest content in a long session is re-abstracted once per compaction, and detail decays geometrically. One opaque blob also means you cannot ask "what did the user say about the auth flow 300 turns back" and get anything back.
This extension keeps a ledger of blocks instead:
b1 · auth refactor ← written once at compaction 1, never rewritten
b2 · migration plan ← written once at compaction 2
b3 · test failures ← written once at compaction 3
raw: last ~20K tokens
Each fold summarises only the span it replaces. A decision made four compactions ago stays exactly one abstraction deep. Because pi's session file is append-only, the raw span behind each block is still on disk, so fold_restore writes it to a file and the model reads it with its ordinary read tool.
What it does
| Piece | Mechanism |
|---|---|
| Owns compaction | session_before_compact returns a compaction whose summary is the rendered digest of all blocks and whose details.piFold carries the block ledger. previousSummary is deliberately ignored. |
| Restores a span | fold_restore(block) slices [fromId, toId) out of sessionManager.getBranch(), renders it as markdown into $TMPDIR/pi-fold/<session>/<block>.md, and returns the path. |
| Tells the model | Two prompt guidelines via before_agent_start: the digest is a gist and fold_restore reads the original; state decisions explicitly so they survive a fold. |
| Shows the ledger | /fold lists blocks, topics and entry spans. |
No proxy, no provider rewrite, no background process, no network calls beyond the summarisation itself, which uses the session's own model.
Install
The directory is a submodule of ~/.pi, so it is already loaded: pi loads any subdirectory of ~/.pi/agent/extensions containing an index.ts.
npm test # 13 tests, node:test through jiti
npm run typecheck # tsc against the global pi install
Verify it is working
After a session has compacted under this extension, /fold lists blocks. The compaction summary in the transcript reads as a folded-history digest with ## b1 · <topic> sections rather than one prose blob.
What it does not do
- No tier-2 folding. Blocks are flat. Re-folding blocks into blocks is what makes the paper's month-long single sessions possible; the same paper reports tier-2 touching only 60 of 1,711 production blocks, so it is not the part worth building first.
- No growth gate. Pi still decides when to compact, at
contextWindow − reserveTokens. Folding at ~0.45 of the window instead is the paper's operating point and a plausible next change. - No cache savings beyond pi's own. A compaction invalidates the prefix in both designs; blocks only shrink what churns on that event.
- Falls back to pi's compaction on failure, including a failed summarisation. That path also resets the ledger — a degraded fold is worse than stock behaviour, not better.
Provenance
The design comes from Model-Driven Incremental Hierarchical Compression (Ran, preprint v0.2) and its billion-context implementation, specifically the parts its own pilot supports: increment-only folding with restorable blocks, and the reasoning doctrine. The paper's own controlled results are worth knowing before expecting more than that — its doctrine-plus-tags control cut re-fetches 62% against a 63% headline with zero compressions executed, its threshold baseline arm never fired, and no controlled round exercised multi-generational tiering.
MIT.