Skip to content

feat(agent): embed the original task verbatim in the compaction checkpoint - #303

Open
raymondginger2018-sudo wants to merge 1 commit into
HKUDS:mainfrom
raymondginger2018-sudo:pr/compaction-task-embed
Open

raymondginger2018-sudo wants to merge 1 commit into
HKUDS:mainfrom
raymondginger2018-sudo:pr/compaction-task-embed

Conversation

@raymondginger2018-sudo

@raymondginger2018-sudo raymondginger2018-sudo commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Compaction replaces the dropped history with a lossy summary — after the first compaction the session's original task is gone from the context, and every later turn is planned against a paraphrase instead of the actual request. The task is the one piece of ground truth that should survive every round of compaction.

This PR embeds the original task verbatim in the checkpoint, in a labeled block (ORIGINAL TASK (preserved verbatim):) appended after the summary. The summary stays exactly as it is; the task rides along beside it.

Changes

  • core/agent_runtime/compaction.py (+42/−1): TASK_BLOCK_LABEL / _TASK_BLOCK_MARK constants; _original_task() recovery (first user message without a compaction marker; for a first-user checkpoint, rfind the label block — a re-summarized checkpoint may echo it — and legacy pre-block checkpoints yield ""); the checkpoint content becomes summary + task block.
  • tests/test_session_compaction.py (+67/−5): three new tests — byte-for-byte embedding, the keep-cap with explicit truncation marker, and a re-compaction round-trip that keeps the block — plus updated checkpoint-shape assertions in two existing tests (MSG0 survives as the embedded task; MSG1 is now the oldest turn that is genuinely gone).

Design constraints honored:

  • SUMMARY_PREFIX keeps offset 0 — the block is appended after the summary, never before, so the content[:200] anchor window of compact_governance is untouched.
  • Legacy checkpoints degrade to current behavior — a first-user checkpoint that predates the block yields "", and re-compaction then behaves exactly as it did before this change.
  • Capped with an explicit marker — the block is cut at COMPACT_KEEP_USER_CHARS (60k, pre-existing constant) with a trailing [original task truncated] line, so nothing silently disappears.
  • Deduplicated on re-compaction — skipped when the retained tail already ends with the task; the checkpoint never accumulates task blocks.
  • No new dependencies — string operations on the existing checkpoint path only.

Tests

  • Local (Windows lane): tests/test_session_compaction.py → 10 passed (7 existing + 3 new), ruff clean.
  • Local CI preflight (Windows lane, pr-ready, head ff993b0a): FAIL (new=3 | known=2) — every new red is evidence-chained as pre-existing, none is a regression. Verdict line: PREFLIGHT: FAIL | jobs=10 | rc0=25 | new=3 | known=2 | skipped=apt,upload | notrun=web-browser | warn=none | tree=0->0 | sanitize=clean | tree_head=ff993b0a | audit=SKIPPED | parallel=off | elapsed=3897s. The 7 new-red nodes (6 xdist suite-load flakes + 1 deterministic env red) each pass isolated single-process reruns as designed: the flakes are GREEN 3/3 without xdist load, and test_default_entrypoints.py::test_cancelled_mcp_waiter_detaches_without_cancelling_the_task is RED on base aa6ed161 too (2/2, identical :145: assert False signature) — a pre-existing Windows-env red, not introduced here. Zero intersection with this PR's diff files (core/agent_runtime/compaction.py, tests/test_session_compaction.py). Evidence chain: append-only verification.md (2026-11-08 record) + isolated-rerun and base-differential logs. Local Windows lane is advisory; the upstream check-run is the gate.
  • Upstream check-runs (the real gate) on head ff993b0a, all completed 2026-11-08T23:03–23:11Z: 12/12 completed — 10 success, 2 skipped, 0 failed — test (3.12), test (3.13), test (3.14), lint-and-format, Pull request dependency review, Secret history scan, package, browser, Desktop quality gates, Windows lifecycle locks and platform isolation all green; Bundle + Dependency and license audit skipped.

Dependency note

A single 2-file PR with one intent: keep the original task across compaction. It touches neither runner.py nor the fog marker — the post-compaction fog ledger (#301, split from the closed #300) is an independent, read-only observation lane; this PR does not measure, record, or gate anything. The tool-call volume accounting (message_chars) in other local branches is also deliberately not included.

Out of scope (follow-up): the stale compact_governance._is_compaction_summary anchor constants (they predate this change and neither this PR nor #301 alters the prefix bytes they anchor on).

…point

The compaction summary is lossy by design; the session's original task is
the one piece of ground truth that must survive every round of compaction.
Append a labeled block (ORIGINAL TASK (preserved verbatim):) AFTER the
summary — never before — so SUMMARY_PREFIX keeps offset 0 and the
content[:200] anchor window of compact_governance is untouched. The task
is recovered from the first user message without a compaction marker; a
checkpoint carries the block at its tail (rfind, because a re-summarized
checkpoint may echo the label) and pre-block checkpoints yield "" so
re-compaction behaves exactly as it did before the block existed. The
block is capped at COMPACT_KEEP_USER_CHARS with an explicit truncation
marker and skipped when the retained tail already ends with the task.

Tests cover byte-for-byte embedding, the keep-cap, and re-compaction
round-trips; existing checkpoint-shape assertions are updated for the
appended block (MSG0 survives as the task; MSG1 is the oldest turn gone).

This branch has not been deployed

No deployments
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