Skip to content

compaction-safeguard: oversized suffix evicts the structured summary body (summaries begin mid-string, all headings lost) #122618

Description

@BillVerhelle

Environment

  • OpenClaw 2026.7.2-beta.4, compaction.mode: "safeguard", Anthropic provider

Summary

In the compaction-safeguard extension, capCompactionSummaryPreservingSuffix() discards the structured summary body entirely whenever the assembled suffix alone exceeds MAX_COMPACTION_SUMMARY_CHARS (16000):

if (suffix.length >= maxChars) return sliceUtf16Safe(suffix, -maxChars);

The stored "summary" is then the tail 16,000 chars of the suffix — typically mid-word/mid-URL/raw tool JSON, with none of the structured sections (## Decisions, ## Open TODOs, exact identifiers) that the quality guard just spent an LLM round enforcing. On our instance, 5 of 8 compaction summaries in one day began mid-string with no headings; one opened with raw tool-schema JSON.

Why the suffix gets that big

assembleSuffix() concatenates splitTurnSection + preservedTurnsSection + toolFailureSection + fileOpsSummary + workspaceContext. The split-turn and preserved-turns sections carry verbatim message content; on tool-heavy turns they alone exceed 16K, and the branch above then evicts the body.

Secondary issue in the same function

Even below the eviction threshold, the body budget is maxChars - suffix.length with no floor — a 15K suffix squeezes the structured summary to 1K.

Suggested fix

Guarantee the structured body a floor share of the budget (e.g. half), and cap the suffix to the remainder — keeping the suffix's TAIL, since workspace critical rules and the post-compaction instructions are appended last:

if (summaryBody.length + suffix.length <= maxChars) return `${summaryBody}${suffix}`;
const bodyBudget = Math.min(summaryBody.length, Math.max(Math.floor(maxChars / 2), maxChars - suffix.length));
const suffixBudget = Math.max(0, maxChars - bodyBudget);
const cappedBody = capCompactionSummary(summaryBody, bodyBudget);
const cappedSuffix = suffix.length > suffixBudget ? sliceUtf16Safe(suffix, -suffixBudget) : suffix;
return `${cappedBody}${cappedSuffix}`;

We are running this as a local dist patch; happy to PR it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.no-staleExclude from stale automation

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions