fix(reply): gate preflight compaction fast-path on token threshold (#63892)#64384
Conversation
Greptile SummaryThis PR fixes a bug where proactive preflight compaction stops firing after the first compaction checkpoint. Once Confidence Score: 5/5Safe to merge — targeted one-line logic fix with correct tests and no surface-area changes outside the preflight gate. The fix is logically sound: the guard is coherent with shouldUseTranscriptFallback (when totalTokensFresh !== false and tokens are valid, freshPersistedTokens is guaranteed to be a positive number, so the new predicate behaves correctly in all reachable states). Both directions of the condition are covered by regression tests. No config, schema, or public SDK surface was touched. No remaining P0/P1 findings. No files require special attention. Reviews (1): Last reviewed commit: "fix(reply): gate preflight compaction fa..." | Re-trigger Greptile |
|
Related work from PRtags group Title: Preflight compaction skips fresh token totals
|
|
Thanks for the context here. I did a careful shell check against current Close this stale, conflicting PR because its central useful fix, letting fresh persisted token totals reach the preflight threshold check instead of returning early forever, is already present on current main and shipped in v2026.5.22. The remaining branch value is obsolete changelog/test churn, while the distinct next-input projection refinement is tracked separately. So I’m closing this older PR as already covered on Review detailsBest possible solution: Keep the shipped current implementation and close this stale branch; continue any distinct fresh-token next-input projection work in #91488. Do we have a high-confidence way to reproduce the issue? Yes. The linked issue discussion and earlier source review define the old failure path: a non-heartbeat, non-CLI run with fresh persisted tokens over threshold returned before the threshold helper; current released code no longer has that return. Is this the best way to solve the issue? No for this PR as a landing branch. The fix direction was sound, but the central behavior shipped in v2026.5.22, the branch is now conflicting, and the remaining changelog entry is release-owned rather than useful to merge. Security review: Security review cleared: No concrete security or supply-chain issue was found; the PR only changes runtime compaction logic, adjacent tests, and a changelog line. AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against c78f9376d929; fix evidence: release v2026.5.22, commit b8e9ab9385c0. |
|
ClawSweeper PR egg 🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat. Where did the egg go?
|
|
This pull request has been automatically marked as stale due to inactivity. |
|
ClawSweeper applied the proposed close for this PR.
|
Summary
Fixes #63892. After the first compaction, `entry.totalTokensFresh` is set to `true` by `incrementRunCompactionCount`. On subsequent runs, `runPreflightCompactionIfNeeded` unconditionally short-circuits at `src/auto-reply/reply/agent-runner-memory.ts:379` because `shouldUseTranscriptFallback` is `false`. The stale-tokens path below (which is what runs the actual threshold check) is never reached, so proactive compaction never re-fires. Overflow-retry recovery still worked because it runs through a separate path in `src/auto-reply/reply/pi-embedded-runner/run.ts` that catches `isLikelyContextOverflowError` directly, bypassing the preflight gate entirely.
Change Type
Scope
Verification
I also verified the equivalent gate on the compiled dist of v2026.4.9 on a long-running gateway against GLM-5.1:cloud (`contextWindowTokens` ≈ 200k, `reserveTokensFloor` 40k, `softThresholdTokens` 25k). Before the patch: zero proactive checkpoints after the first, overflow-retry checkpoints only. After the patch: proactive checkpoints fire on every subsequent cycle as expected.
Credit
The root cause analysis, exact file/line pointers, and the fix direction are all @martingarramon's from the issue thread. My earlier hypothesis about `compactionCount` latching was wrong — thanks for the correction. @mjamiv independently confirmed the repro on v2026.4.9, which is what motivated digging past the first hypothesis.
AI-assisted disclosure
This PR was written with AI assistance (Claude). I (the submitter) read and understand the change, verified the fix against the live compiled runtime before writing the source patch, and wrote the regression tests to directly exercise the `totalTokensFresh === true` re-fire case.
Fixes #63892