Skip to content

Compaction: carry plugin text verbatim; the summariser reads the retained tail - #14

Merged
TheFabFab merged 2 commits into
documentor-pgfrom
documentor-compaction-carry
Oct 22, 2026
Merged

TheFabFab merged 2 commits into
documentor-pgfrom
documentor-compaction-carry

Conversation

@TheFabFab

@TheFabFab TheFabFab commented Oct 22, 2026 •

Copy link
Copy Markdown
Owner

Two changes to compaction, both from production bug reports of 2026-10-22 (21:09) where a compacted mentor chat lost its project files and got a summary that contradicted the messages after it.

1. Carry. experimental.session.compacting now receives messages — the messages created before the retained tail starts, i.e. those leaving the model's view, in model order — and may return carry: string[]. Once the summary succeeds, each carried text is stored as a synthetic text part (metadata.compaction_carry) on the compaction's user message. The model reads it before the summary from the auto-continue turn on, and completedCompactions already hides that message from every later summariser, so it is never paraphrased. A tail can reach back past an earlier compaction message, which then stays in view; it is not handed to the hook, so nothing is carried twice. DocuMentor's plugin (TheFabFab/KPG) carries its PROJECT.md, MEMORY.md, knowledge-base index and WORKSPACE.md blocks.

2. The summariser reads the retained tail. It was shown only the head, so two helper results and a retried action that landed in the tail left the summary saying "two background tasks running, archive move failed". buildPrompt takes retained; the prompt shows the tail in <retained> after the conversation, with the instruction not to summarise it and to write Work State and Next Move as the state after it.

Tests

  • documentor: carries plugin text verbatim … (compaction.test.ts): stored, seen by the model before the summary, absent from the second summariser's input, handed to the second compaction's hook. Fails without the change.
  • Upstream's tail tests now assert the tail stays out of <conversation> and appears in <retained>.
  • End to end, compiled binary over ACP with DocuMentor's plugin and a fake OpenAI-compatible provider recording every request, three forced compactions: the auto-continue request after each holds each project file exactly once (before its summary where the carrier is the new compaction message), later summarisers never see them, and the first summariser reads the kept turn in <retained>, not in <conversation>. The same run against a binary without this change fails the six carry checks.
  • FORK.md rows added.

🤖 Generated with Claude Code

https://claude.ai/code/session_0148RPMT9kUkZ6BL4TtebZJe

experimental.session.compacting now receives the messages a compaction
takes out of the model's view and may return `carry` texts. Once the
summary succeeds, each is stored as a synthetic text part on the
compaction's user message: the model reads it before the summary from the
auto-continue turn on, and no later summariser is shown it.

DocuMentor uses this to keep its project files (PROJECT.md, MEMORY.md,
the knowledge-base index, WORKSPACE.md), injected once per chat, verbatim
across compactions instead of paraphrased by the summary.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148RPMT9kUkZ6BL4TtebZJe
@github-actions

Copy link
Copy Markdown

Hey! Your PR title Compaction carries plugin text verbatim on the compaction message doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@github-actions

Copy link
Copy Markdown

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 72 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

…stays in view

The summariser was shown only the head, so anything that happened in the
retained tail - a background task finishing, an action retried - left the
summary stating the older state, contradicting the messages that follow
it. It now also reads the tail, in <retained>, with the instruction not to
summarise it and to write Work State and Next Move as the state after it.

The compacting hook's `messages` are now the messages created before the
tail starts. A tail can reach back past an earlier compaction message,
which then stays in view; handing it to the hook carried its text twice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148RPMT9kUkZ6BL4TtebZJe
@TheFabFab TheFabFab changed the title Compaction carries plugin text verbatim on the compaction message Compaction: carry plugin text verbatim; the summariser reads the retained tail Oct 22, 2026
@TheFabFab
TheFabFab merged commit be7e919 into documentor-pg Oct 22, 2026
7 of 11 checks passed
@TheFabFab
TheFabFab deleted the documentor-compaction-carry branch October 22, 2026 22:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant