Repository navigation
fix: split protected ranges + soften last-user-message protection - #210
Merged
Merged
Conversation
In autonomous agentic sessions (1 user message + many assistant messages), buildCompressibleRanges created one giant group because grouping only breaks on user messages — and tool results are assistant role in OpenCode. The giant group's endRef fell in the protected zone → excludeProtectedRanges removed the entire range → no recommendations → nudge suppressed → model could never compress. Two changes: 1. Group splitting: buildCompressibleRanges now accepts protectedZoneRefs and splits groups at the protected-zone boundary. The unprotected head survives as a recommended range; the protected tail is excluded. 2. Last-user-message softening: preserveLastUserMessage moved from hard-reject (checkProtectedRange throw) to soft-filter (filterLastUserMessage excludes from compress plan, like Bug 39 protected tools). The last user message survives in visible context; surrounding tool output compresses normally. Also added allInProtectedZone condition to nothingToCompress to cover the new case where all messages are in the protected zone (group splitting produces zero compressible ranges). 922 tests pass (920 existing + 2 new).
Review findings (both agents converged): 1. pipeline.ts checkProtectedRange error/JSDoc mentioned 'most recent user message' but that rule moved to filterLastUserMessage. Removed stale clause. 2. range.ts empty-plans error said 'protected tool outputs' exclusively but cause could also be last-user-message filtering. Updated message. 3. message.ts had weak guard (filteredPlans.length === 0 && skippedCount > 0) that missed the case where all plans soft-filtered with skippedCount=0. Now throws unconditionally when filteredPlans is empty, with accurate message branching on skippedCount. 4. Updated test assertion in protected-tool-exclusion.test.ts for new error string. 922/922 tests pass.
This was referenced Jul 27, 2026
ranxianglei
added a commit
that referenced
this pull request
Jul 27, 2026
E2E tests had severe gaps that made them ineffective: - ALL protection disabled (preserveRecentMessages:0) — the mechanism fixed 3 times (PR #210/#211/#212) was never exercised - CI ran only 4/6 scenarios (05 subagent, 06 nudge missing) - verify.ts only checked blockCount, not which messages were protected Changes: - run-e2e.sh: per-scenario config override via 'acpConfig' JSON field - verify.ts: compressedCount/min/max checks (byMessageId inspection) - scenario 07: protection-filtered (production config, compress succeeds via soft-filter, protected msgs excluded from compressed set) - scenario 08: nudge-with-protection (nudge→compress with protection enabled — tests exact bug from PR #207/#210/#212) - ci.yml: all 8 scenarios now in CI All 8 scenarios verified locally (8/8 pass).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a bug where autonomous agentic sessions (1 user message + many assistant/tool messages) could never successfully compress. Root cause:
buildCompressibleRangescreated one giant group (no user-message breaks since tool results areassistantrole), andexcludeProtectedRangesremoved the entire group because its endRef was in the protected zone — leaving zero recommendations and suppressing the nudge.Two changes:
Group splitting (
buildCompressibleRanges): now acceptsprotectedZoneRefsand splits groups at the protected-zone boundary. The unprotected head survives as a recommended range; the protected tail is excluded. This directly fixes the "can't compress in autonomous sessions" bug.Last-user-message softening (
preserveLastUserMessage): moved from hard-reject (checkProtectedRangethrow) to soft-filter (filterLastUserMessageexcludes from compress plan, following Bug 39'sfilterProtectedToolMessagespattern). The last user message survives in visible context; surrounding tool output compresses normally. No more hard rejection when the compress range happens to include the last user message.Also added
allInProtectedZonecondition tonothingToCompressto cover the new case where all messages are in the protected zone (group splitting produces zero compressible ranges — previously this would incorrectly fire the nudge with no recommendations).Test plan
computeProtectedRefsno longer includes last user message