Jev Context Compaction — Score What to Keep

Replace summarization-based compaction with a relevance filter: score every completed tool result for whether it is still needed, then drop the rest below a threshold.

September 20, 2026
jevcontext-compactioncontext-managementagentstokenspatterns

Context Compaction with Jev

Long agent sessions fill their context with tool results that stopped mattering turns ago. The common fix is summarization: ask a model to rewrite the history shorter. That can lose detail and requires another generative pass.

Jev-based compaction replaces the summary with a relevance filter. Score every completed tool result for whether it is still needed for the current task, drop the ones that are not, and leave the rest untouched. It is a filter, not a rewrite.

The Three-Stage Design

The critical structural rule: Jev only scores. Code owns which results are candidates, what the threshold is, and what happens when a result is dropped.

  1. Code selects candidates. Walk the message list, find completed tool results, and build the state.
  2. Jev scores them. One Noul per result in a single batched call: "is this still needed for the current task?"
  3. Code prunes. Drop or truncate results below the threshold, with margin.
const results = completedToolResults(messages)

const { answers } = await client.systemOne({
  state: {
    current_task: taskDescription,
    recent_turns: recentTurns,
    results: results.map((r, i) => ({
      id: `r${i}`,
      tool: r.toolName,
      content: truncate(r.content, 2000),
    })),
  },
  questions: Object.fromEntries(
    results.map((_, i) => [
      `keep_${i}`,
      noul(`Is \`results[${i}]\` still needed to complete \`current_task\`?`),
    ]),
  ),
})

const toDrop = results.filter((_, i) => answers[`keep_${i}`].noul < 0.5)

Shadow mode first:

Ship this in log-only mode before it mutates anything. Score and record what it would drop, then inspect the results for a full session. A relevance filter that removes something the task still needed is worse than an oversized context.

One Noul Per Result

The shape matters. Do not ask a single question to rank the results, and do not ask for a Score of importance. One Noul per result lets each judgment stand alone, keeps the call parallel, and maps directly onto a per-item drop decision in code.

Long tool results should be truncated before they are sent — you are judging relevance, not re-reading the content, and the score call itself counts against your token budget.

Threshold with Margin

The keep/drop boundary follows the same rule as every other Jev threshold: never cut at a value the model actually returns. If results cluster around 0.48 and 0.52, a boundary at 0.5 sits in the gap. If you see values landing exactly on your boundary, move it.

Because this gate destroys information rather than routing it, bias the threshold toward keeping. A dropped result cannot be recovered without re-running the tool.

When to Prefer Compaction over Summarization

SummarizationJev scoring
OperationGenerate a shorter rewriteScore each item, drop the rest
LatencyAnother generative passOne decision call
FidelityLossy — the model paraphrasesVerbatim for what is kept
CostInput and output tokensInput tokens; output is currently free
Failure modeSubtle distortion of retained factsRemoving something still needed
Best whenContent must be fused into a narrativeMost results are independently disposable

In practice the two combine. Score first to drop the clearly irrelevant, then summarize only what remains if the task needs a fused narrative.

Do Not Skip the Safety Check

Tool output is untrusted data, and compaction sends it to a third party. Do not enable live pruning on a session whose tool output you have not classified as safe to send off-machine. Keep a kill switch so a single file or flag disables the whole hook.

Maintenance

  • Log what you drop. A compaction hook that logs its decisions can be audited after a bad session, the same way a routing log can.
  • Re-tune when the model is pinned forward. A threshold tuned against one version is not automatically valid for the next. Version the hook's config with the model ID.
  • Measure the drop. If the hook is not actually reducing tokens, it is just adding a call. Track before and after.