How pi-compact-jev 0.5.1 works

September 20, 2026 · View on GitHub

This is the prune path that runs on Pi’s session_before_compact. It replaces Pi’s LLM summary of the dropped prefix. Kept text is verbatim. Landing page: README.md.

Order of operations

  1. Keep-windows on user/assistant text in the dropped region.
  2. Pin invoked skills, unresolved errors, git mutations, edit/write, images.
  3. Pair each toolCall with its toolResult. Unpaired calls are not scored.
  4. Ask Jev about unpinned pairs only.
  5. Apply useful → need-full.
  6. Render surviving messages as one markdown string. Flatten the previous compact under it (not Jev-scored).

Pi still cuts at firstKeptEntryId (about 20k live tokens). This package only rewrites the dropped prefix.

State (JSON, shared by every question batch)

Not the live transcript. Caps are characters.

FieldWhat
workspaceFolder name, depth-2 dirs (skips node_modules / .git / …), README ≤ 25,000
contextFixed paragraph: this is a compaction
firstFirst user + first assistant, pair ≤ 25,000
recentLast 5 user/assistant pairs, each ≤ 5,000
carriedPrevious compact, dumps stripped, ≤ 8,000. Mid-session commitments only. Not scored.

Tool dumps are not in state. fitState shrinks those caps until estimated tokens ≤ 28,000. One state for every batch. Whole POST (state + questions) ≤ 64,000 estimated tokens.

Questions (float noul, 0–1)

Two questions per unpinned call, same dump view on both (head / middle / tail, 2,500c each). Both go in one POST; the threshold is applied after.

useful_tN

Give confidence the following context useful to the current project and/or session context or the latest prompt(s)? [id, tool, args, dump windows]

full_tN

Do I need it in full? [same dump windows]

Criteria for full: after compact this dump is gone and will not be re-run. False means keep first 25% + last 25%, each capped at 2,500.

keepThreshold 0.5, inclusive.

usefulfullAction
< 0.5ignoredDrop call + result
≥ 0.5≥ 0.5Keep dump verbatim
≥ 0.5< 0.5Stub: 25% head + 25% tail, cap 2,500 each

Pinned calls skip Jev and stay.

Pins (Jev is not asked)

PinDump
Unresolved isError (last fail per tool+path/command with no later same-key success)Verbatim
Git mutations (commit/push/…, not status/diff/log)Cap 600c head
edit/writePath; edit old/new heads 300c; write body kept if ≤ 2,000c, else a length note
ImagesUntouched
Last invoked $skill loadFull body

A unique-command error (cat /tmp/old.log) never gets a same-key success, so it stays pinned even if the user later says ignore it. Unpinning on any later success would drop a real test fail after a following Read. That tradeoff is intentional.

What we tried that did not ship

  • now/later on full history — large, expensive, worse continuation.
  • Blind full (“would the stub drop info?” with no dump) — zero unpinned full-keeps; broker needle died in the middle.
  • 600c cap on unresolved errors — buried failures vanished.
  • Stripping every write body — HMAC in short Write args disappeared.

Restoring “Do I need it in full?” and putting dump windows on full is what made useful dumps stay whole (broker 0.89/0.68).

Known leftovers (not bugs to chase)

  • Tiny listings can score useful ~0.65 and stub instead of drop. Noise.
  • One-line facts may score full just under 0.5; if the dump is short, the stub keeps the whole line anyway.
  • Carried previous compact is shown in state, not re-scored. Re-pruning S1 with Jev stacks loss.