Skip to content

feat: experimental relevance compaction, off by default - #142

Closed
DevMortimer wants to merge 4 commits into
mainfrom
feat/relevance-compaction
Closed

DevMortimer wants to merge 4 commits into
mainfrom
feat/relevance-compaction

Conversation

@DevMortimer

Copy link
Copy Markdown
Owner

Experimental, off by default, and not recommended. It ships so anyone can try it or improve it.

What it does

When compaction.enabled is on (user config only), pi-warden replaces the summary Pi's model writes at compaction. User messages and assistant text are kept word for word, thinking is left out, and each tool call with its result is scored by the judge against the current task: kept word for word (long results as head and tail) or reduced to one line. Kept tool output is fenced as untrusted data, results flagged as possible prompt injection (when the security check is on) are never kept word for word, and any <summary tag in kept text is escaped so it cannot close Pi's wrapper. On any error, timeout, abort, oversize, or budget stop it returns nothing and Pi's own summary runs; it never cancels a compaction. It steps aside for providers that compact their own models (skipProviders, default ["claude-bridge"]).

It spends from the session request budget with limits: at most compaction.maxRequests (12) per compaction, and it sends nothing when fewer than 50 requests would remain for the guards.

Why not recommended

A replay of 48 recorded compactions against Pi's own summaries:

  • Size: median 12,371 tokens against Pi's 2,567.
  • Of 34 files the agent re-read after compaction, it kept 1 whole and 11 as head and tail; Pi's summary kept none but names every file.
  • The judge ranks well (22 of 32 re-read files scored above the keep threshold, a level only 20% of units reach); the size limits lose the content, not the ranking.
  • Cost: median 6 requests, 0.85 s per compaction.

Details and the replay script (scripts/relevance-replay.mjs) are in docs/guards.md.

Verification

  • npm run check: 1249 pass / 0 fail; typecheck and build clean.
  • An independent review found no blockers; its findings (wrapper escape, unredacted labels, deadline semantics, render/parse round trip, request budget) are fixed with tests.
  • Version bump to 0.78.0.

A new `compaction` config section (off by default) lets pi-warden write
the compaction summary. User messages and assistant text stay word for
word and thinking is left out. Jev scores each tool call with its result,
each extension message, and each part of the previous summary against the
current task. Kept units go in verbatim, with tool output fenced as
untrusted data; the rest become one line each. Results flagged as a
possible prompt injection are never kept verbatim, and results the
context saver compressed keep their excerpt.

Any failure, timeout, abort, missing consent, a provider in
`compaction.skipProviders`, or a summary over `compaction.maxSummaryTokens`
returns nothing, so Pi's own summary runs; the hook never cancels a
compaction. Each compaction leaves one trace entry, and /warden status
has one line for it.

scripts/relevance-replay.mjs replays recorded compactions with real
requests. First measurement (docs/guards.md, Calibration): the summary is
4.7 times larger than Pi's at the median and holds 1 of 34 re-fetched
reads whole and 11 as head and tail, so the feature stays off by default.
- Kept text can no longer open or close Pi's <summary> wrapper: a `<`
  that starts a summary tag is written `&lt;`, and the header says so.
- Extension message types and earlier-summary headings are redacted
  before they reach Jev, in the candidates and in the outline.
- Every rendered section is fenced with a fence longer than any backtick
  run in it, so the next compaction parses back the same units.
- compaction.timeoutMs bounds the whole compaction; each request is also
  bounded by the global timeoutMs, and the docs say exactly that.
- New compaction.maxRequests (default 12). A compaction sends nothing
  when its requests would leave fewer than 50 of the session budget, and
  stops before any request when fewer than 50 remain, read from the
  shared client. A budget stop no longer turns judgments off.
- compaction.enabled is user file only; a project tunes the other keys.
- Docs and changelog call the feature experimental, off by default, not
  recommended, with the replay result, and say that flagged results are
  recognised only when the security check is on.
@DevMortimer

Copy link
Copy Markdown
Owner Author

Superseded by 143: the same change plus the README update, ordered so the version bump stays the last commit.

@DevMortimer
DevMortimer deleted the feat/relevance-compaction branch September 29, 2026 02:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant