fix(compaction): let admission proceed when the breaker cancelled opportunistic compaction - #532
Conversation
…ortunistic compaction When the compaction circuit breaker trips (provider outage, persistent summarization failure), session_before_compact is cancelled with rejectionCause "circuit-breaker". Core converted that cancel into a hard RequiredCompactionError on every admission path, so any session over the soft threshold was bricked: every prompt rejected, and autonomous continuation drivers looped forever — observed live as a permanent "Compacting..." spinner with summarization retries at the 60s cooldown cadence. Opportunistic compaction (threshold/pre_prompt) is an optimization, so a breaker-cancelled compaction now degrades to proceeding without it: - _enforceCompactionBeforeProvider and _enforceFinalProviderAdmission proceed when the last rejection was circuit-breaker (final admission still fails closed when the payload is actually oversized) - _revalidateScheduledContinuationAdmission proceeds on cooldown - _handleRetryableError retries instead of returning "blocked" on cooldown Overflow-triggered admission is unchanged (fail-closed). If the context genuinely exceeds the window, the provider overflow error drives the existing one-shot overflow recovery. Regression: test/suite/regressions/531-compaction-cooldown-admission.test.ts (red before, green after; non-breaker cancel control stays fail-closed). Live CLI A/B driver: .agents/skills/senpi-qa/scripts/scenarios/compaction-retry-cycle-repro.mjs (unpatched: 8/8 prompts bricked; patched: 0/8, turns reach the provider). QA evidence: local-ignore/qa-evidence/20260730-issue-531-cooldown-admission/ closes code-yeongyu#531
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 34049272 | Triggered | Generic High Entropy Secret | 5e2781f | .agents/skills/senpi-qa/scripts/scenarios/compaction-retry-cycle-repro.mjs | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secret safely. Learn here the best practices.
- Revoke and rotate this secret.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
… driver GitGuardian flagged sk-ant-mock-7f3a as a Generic High Entropy Secret; replace it with the repo's existing committed mock credential (sk-mock-qa-7f3a from mock-loop-support.mjs API_PRESETS).
|
[sisyphus-bot] Thank you for the thorough investigation, regression test, and CLI repro. This fix was carried onto current |
What changed
When the compaction circuit breaker cancels an opportunistic (threshold / pre-prompt) compaction, admission now proceeds without compaction instead of throwing
RequiredCompactionError:_enforceCompactionBeforeProvider— pre-prompt threshold tail returns "not compacted" on cooldown instead of throwing_enforceFinalProviderAdmission— proceeds on cooldown only when the final payload is not actually oversized_revalidateScheduledContinuationAdmission— proceeds on cooldown_handleRetryableError— retries the turn instead of returning"blocked"on cooldownOverflow-triggered admission is untouched (fail-closed). If the context genuinely exceeds the window, the provider's overflow error drives the existing one-shot overflow recovery, so proceeding is safe.
Why
The breaker's job is to stop paying for doomed compaction during a provider outage. But core converted the breaker cancel (
rejectionCause: "circuit-breaker") into a hard admission failure on every path, so a tripped breaker bricked any session over the soft threshold: every prompt rejected withContext remains above the compaction threshold because compaction did not complete, forever. Any autonomous continuation driver (extensions that re-prompt onagent_end) loops without bound.Live forensics on a real stuck session (issue #531 has the full timeline): compaction spinner rendering ~13/s, summarization retries at the exact 60s breaker-cooldown cadence, and a final parked state burning >100% CPU with zero session writes.
Opportunistic compaction is an optimization; when the breaker declares compaction unavailable, the honest degradation is to let the turn try — the provider either accepts (soft threshold exceeded ≠ window exceeded) or returns a real overflow error.
Observed behavior (real CLI, mock provider, A/B)
Driver:
.agents/skills/senpi-qa/scripts/scenarios/compaction-retry-cycle-repro.mjs(included; turn 1 pins usage over the threshold, then all provider requests fail transiently, and the driver re-prompts like an autonomous continuation extension).agent_endafter prompt 2+compaction_startwithoutcompaction_endFull logs:
local-ignore/qa-evidence/20260730-issue-531-cooldown-admission/{unpatched,patched}.log.Tests
test/suite/regressions/531-compaction-cooldown-admission.test.ts: red before the fix (RequiredCompactionErrorat the exact admission site), green after; a non-breaker cancel control verifies admission still fails closed for generic refusals.npx vitest --run test/compaction/ test/compaction*.test.ts test/suite/ test/agent-session-auto-compaction-queue.test.ts test/interactive-mode-compaction*.test.ts: 364 files, 2466 passed, 1 skipped.npx biome checkclean; rootnpx tsgo --noEmitexit 0.Residual risk
closes #531
Summary by cubic
Let admission proceed without compaction when the circuit breaker cancels opportunistic compaction, so sessions over the soft threshold keep running during provider outages. Final oversized payloads and overflow-triggered paths still fail closed.
_enforceCompactionBeforeProvider,_revalidateScheduledContinuationAdmission: proceed on breaker cooldown instead of throwing._enforceFinalProviderAdmission: proceed on cooldown only if the final payload isn’t oversized._handleRetryableError: retry the turn instead of returning "blocked" when on cooldown.test/suite/regressions/531-compaction-cooldown-admission.test.tsand a CLI repro scriptcompaction-retry-cycle-repro.mjs; the repro uses the repo-standard mock keysk-mock-qa-7f3ato avoid secret scanner noise.Written for commit 3ff2c6f. Summary will update on new commits.