Repository navigation
fix: preserve growth baseline when nothingToCompress - #207
Merged
Merged
Conversation
When growth threshold was met (nudgeAllowed) but all compressible ranges were filtered out (nothingToCompress), the old code reset lastPerMessageNudgeTokens = currentTokens. This ate accumulated growth every cycle, creating a feedback loop in short sessions (e.g., subagents) where the baseline chased the current context and the model never saw a nudge. Fix: remove the baseline reset; growth accumulates until there IS something to compress. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Removed 3 tautological tests from baseline-reset.test.ts (didn't call injectCompressNudges — violated AGENTS.md §5.6). Real regression coverage comes from updated inject.test.ts tests. Added E2E growth scenario to inject.test.ts that verifies: baseline preserved through nothingToCompress turns, growth accumulates, nudge fires when content exits protected zone. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
… test E2E test now uses 25+ messages in array (not just byRawId) with 200K-char bash outputs so compressible ranges pass the 100K floor. Turn 3 now asserts shouldInjectThisTurn=true (nudge fires when content exits protected zone) AND baseline=200K (growth accumulated from original). Also added baseline assertion to existing 'nudge suppressed when all content is protected' test. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This was referenced Jul 27, 2026
ranxianglei
added a commit
that referenced
this pull request
Jul 27, 2026
Bundle two PRs merged to master since v1.14.0: - PR #205 feat(log): add ACP version to daily logs and context logs (tsup define ACP_VERSION from package.json; logger.ts appends '| v={version}' to each daily log line and writes a one-shot _version file under each per-request context-log directory) - PR #207 fix: preserve growth baseline when nothingToCompress (remove lastPerMessageNudgeTokens=currentTokens reset that ate accumulated growth in short sessions / subagents, causing a baseline-chases-context feedback loop where nudges never fired) Release-only: no source changes. Source identical to master @ da590e1. Files: package.json (1.14.0 -> 1.14.1), README.md, README.zh-CN.md, devlog/2026-07-27_release-v1.14.1/{REQ,WORKLOG}.md.
ranxianglei
added a commit
that referenced
this pull request
Jul 27, 2026
Self-review caught two factual errors in the v1.14.1 changelog entry (propagated from PR #207's commit message without verification): 1. Claimed '3 tautological tests removed from tests/baseline-reset.test.ts'. That file does not exist on master. The actual PR #207 test diff in tests/inject.test.ts is 3 tests added + 2 removed (reworked baseline tests with assertions flipped advance->preserve, plus 1 new E2E growth scenario). Corrected to describe what actually changed. 2. Chinese changelog had typo 'taautological' (extra 'a'). Also dropped the editorial 'tautological' characterization since the actual change was legitimate assertion rework, not removal of trivial tests. No source code changes.
ranxianglei
added a commit
that referenced
this pull request
Jul 27, 2026
…e verification (#208) * docs: AGENTS.md §5.7 nudge/growth test requirements + Docker E2E nudge verification Added mandatory testing requirements after baseline-reset bug (PR #207) survived 900+ tests. §5.7 requires: multi-turn tests, side-effect assertions (lastPerMessageNudgeTokens), production config (preserveRecentMessages>0), Docker E2E nudge state verification. New E2E scenario 06-nudge-growth-compress + verify.ts nudgeBaselineSet/nudgeBaselineNotEquals fields. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix(review): address dual-agent review findings on PR #208 Removed scenario 06 (used scripted compress, violated §5.7.2 nudge-triggered requirement). Removed nudgeBaselineNotEquals (dead code, never used). Reworded §5.7.2: nudge-triggered compression noted as future work (fake-llm-server limitation). Removed shouldInjectThisTurn from §5.7.2 (can't verify post-hoc). Fixed 'three' → 'five' gaps. Added scenario 05 to README table. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * feat(e2e): real nudge→compress flow with detectNudge + nudge-compress step type Fake LLM server now detects ACP nudge injections in messages. When nudge detected, emits compress call (not scripted). Scenario 06 grows context past 20K threshold via repeated text turns, ACP auto-injects nudge, server detects it and compresses. Tests the real nudge→compress flow end-to-end. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix(e2e): detectNudge uses nudge-unique phrases + fake LLM reports real input tokens C1: detectNudge now scans only user-role messages for phrases that ONLY appear in actual nudge injections (efficiency nudge, Context limit reached, since last nudge) — not system prompt documentation markers that are always present. C2: computeInputTokens() calculates prompt_tokens from actual input message sizes so ACP sees realistic token counts for threshold evaluation. H1: §5.7.2 updated to describe detectNudge as implemented capability. H2: fake model config now includes limit.context=100000. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix(e2e): fix JSON brace structure + increase growth text to exceed growthFloor C1: opencode.json had broken brace nesting — models block indentation change caused agent/model/permission to be nested inside provider.fake instead of root. Fixed brace structure. C2: Growth text was ~1K tokens total, far below the 5000-token growthFloor. Increased to ~4K chars per turn (~1K tokens), 3 substantive turns = ~3K tokens growth. Combined with system prompt baseline this should approach the growthFloor threshold. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix(e2e): add limit.output to fake model config — all 6 scenarios pass opencode requires limit.output in model config. Without it, configuration validation fails: 'Missing key provider.fake.models.fake-model.limit.output'. Added output: 4096. All 6 E2E scenarios now pass: 01-basic-compress, 02-quality-reject, 03-quality-acknowledge, 04-batch-compress, 05-subagent-compress, 06-nudge-triggered. Verified: scenario 06 nudge fires on turn 2 (inputTok=17.6K, growth exceeds growthFloor). blockCount=1, nudgeBaselineSet=true. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> --------- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
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).
ranxianglei
pushed a commit
that referenced
this pull request
Aug 29, 2026
…ted .gitignore change Post-PR review of #351: - §5.7.1 required at least one test per PR using preserveRecentMessages > 0; all 17 original tests ran on the preserveRecentMessages: 0 default, which disables the protected-zone / nothingToCompress path (the #207 bug scenario). New 5-turn test: per-model floor suppression → fire → compress → new baseline → fire again, plus a fully-protected turn locking the #207 baseline-reset regression. Mutation-verified (reintroducing the #207 bug fails this test). - Reverted the node_modules/ → node_modules .gitignore edit bundled into e14193c (unsubstantiated 'symlink fix'; no tracked symlink exists). 1054/1054 green (1036 baseline + 18 new). Typecheck + build pass.
This was referenced Aug 29, 2026
ranxianglei
added a commit
to drexb-ops/opencode-acp
that referenced
this pull request
Sep 12, 2026
…DE candidates - lib/config.ts: CompressConfig.candidates (default false, 3-layer merge) - inject.ts: candidatesEnabled gates planning/candidateText/nothingToCompress/ actionHint/breakdown/maxLimit copy — off mode byte-exact master behavior, zero planning cost - prompts: master base restored; candidate guidance split into separate CANDIDATE_GUIDANCE constants, appended only when enabled - status.ts: scope:uncompressed falls back to ranges when disabled; config-neutral tool description - schema + config-validation + CONFIGURATION.md/.zh-CN docs - tests: switch test file (5 tests, §5.7 growth cycle, preserveRecentMessages=20, ranxianglei#207 baseline anti-regression); existing candidate tests opt in explicitly - 1261/1261 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.
Problem
When the growth threshold was met (
nudgeAllowed=true) but there was nothing to compress (nothingToCompress=true),inject.ts:368resetlastPerMessageNudgeTokens = currentTokens. This "ate" accumulated growth, creating a feedback loop in short sessions (e.g., subagent sessions):nudgeAllowed = truenothingToCompress = true(all ranges protected bypreserveRecentMessages: 20) →shouldInject = falseObserved in
ses_0604a0a1affebNnnFMo5KiM7GD: 31 API calls, context grew 719→142K, baseline ended at 132K (near peak).Fix
Remove
lastPerMessageNudgeTokens = currentTokensfrom thenothingToCompresspath. Only clearlastNudgeShownTokens. Growth baseline is preserved so it accumulates until there IS something to compress.The baseline is still correctly reset via the compress-detection path (
inject.ts:108-156) when the model actually compresses.Files
lib/messages/inject/inject.ts— 1 line removed from nothingToCompress blocktests/baseline-reset.test.ts— 3 regression teststests/inject.test.ts— 3 existing tests updated for new behaviordevlog/2026-07-27_fix-baseline-reset/— REQ.md + WORKLOG.mdTest Results