#20038: (fix): Compaction: preserve recent context and sync session memory post-compact
agents
size: L
experienced-contributor
Cluster:
Compaction Safeguards and Summaries
## Summary
- Problem: post-compaction sessions could drift because summaries were under-structured, recent turns were easy to lose, and session-memory indexing could stay stale after compaction.
- Why it matters: users see "forgotten context" right after compaction, especially when relying on memory search over session transcripts.
- What changed: added post-compaction transcript update + configurable index sync, safeguard summary structure/quality checks with retry, and preserved recent verbatim turns in safeguard compaction.
- What did NOT change (scope boundary): no model/provider changes, no messaging/channel routing changes, no non-compaction memory backend redesign.
## Change Type (select all)
- [x] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Docs
- [ ] Security hardening
- [ ] Chore/infra
## Scope (select all touched areas)
- [ ] Gateway / orchestration
- [x] Skills / tool execution
- [ ] Auth / tokens
- [x] Memory / storage
- [x] Integrations
- [x] API / contracts
- [ ] UI / DX
- [ ] CI/CD / infra
## Linked Issue/PR
- Closes #19207
- Related #
## User-visible / Behavior Changes
- New compaction settings:
- `agents.defaults.compaction.recentTurnsPreserve`
- `agents.defaults.compaction.postIndexSync` (`off|async|await`)
- `agents.defaults.compaction.qualityGuard.enabled`
- `agents.defaults.compaction.qualityGuard.maxRetries`
- New memory-search setting:
- `agents.defaults.memorySearch.sync.sessions.postCompactionForce`
- After successful compaction, session transcript updates are emitted and session-memory indexing can be synced immediately depending on config.
- Safeguard compaction now preserves recent turns, enforces structured summary sections, and retries once (configurable) when summary quality checks fail.
## Security Impact (required)
- New permissions/capabilities? (`No`)
- Secrets/tokens handling changed? (`No`)
- New/changed network calls? (`No`)
- Command/tool execution surface changed? (`No`)
- Data access scope changed? (`No`)
- If any `Yes`, explain risk + mitigation:
## Repro + Verification
### Environment
- OS: macOS
- Runtime/container: Node 22 + pnpm
- Model/provider: n/a (unit/integration tests)
- Integration/channel (if any): n/a
- Relevant config (redacted): default + compaction/memory overrides in tests
### Steps
1. Run typecheck: `pnpm tsgo`.
2. Run compaction/memory/reply targeted suites:
- `pnpm vitest run src/agents/compaction.retry.test.ts src/agents/compaction.identifier-preservation.test.ts src/agents/pi-embedded-runner/run.overflow-compaction.test.ts src/auto-reply/reply/post-compaction-context.test.ts src/auto-reply/reply/post-compaction-audit.test.ts src/memory/manager.async-search.test.ts src/memory/manager.watcher-config.test.ts src/memory/index.test.ts src/memory/manager.atomic-reindex.test.ts`
3. Run reply-runner suites:
- `pnpm vitest run src/auto-reply/reply/followup-runner.test.ts src/auto-reply/reply/agent-runner.runreplyagent.test.ts src/auto-reply/reply/commands.test.ts src/auto-reply/reply/agent-runner.misc.runreplyagent.test.ts`
### Expected
- Typecheck passes.
- All targeted compaction/memory/reply tests pass.
### Actual
- `pnpm tsgo` passed.
- First vitest batch: 9 files / 47 tests passed.
- Second vitest batch: 4 files / 110 tests passed.
## Evidence
Attach at least one:
- [x] Failing test/log before + passing after
- [x] Trace/log snippets
- [ ] Screenshot/recording
- [ ] Perf numbers (if relevant)
## Human Verification (required)
What you personally verified (not just CI), and how:
- Verified scenarios:
- Post-compaction transcript update is emitted and post-sync logic runs from compaction path.
- Safeguard compaction includes structured sections + preserved recent turns + quality audit retry path.
- Config/schema/type surfaces validate and compile.
- Edge cases checked:
- Post-compaction memory sync can be disabled (`off`) and supports async/await modes.
- Missing/unavailable memory manager is handled safely (best effort, warning only).
- What you did **not** verify:
- End-to-end live provider behavior under real long-running conversations.
- Full `pnpm test` matrix.
## Compatibility / Migration
- Backward compatible? (`Yes`)
- Config/env changes? (`No`)
- Migration needed? (`No`)
- If yes, exact upgrade steps:
## Failure Recovery (if this breaks)
- How to disable/revert this change quickly:
- Set `agents.defaults.compaction.postIndexSync: "off"` to disable post-compaction index sync.
- Set `agents.defaults.compaction.qualityGuard.enabled: false` to disable quality-guard retries.
- Set `agents.defaults.compaction.recentTurnsPreserve: 0` to disable preserved-tail behavior.
- Files/config to restore:
- Revert the compaction + memory config changes in `openclaw.json`.
- Known bad symptoms reviewers should watch for:
- Slower compaction in `await` mode due to blocking index sync.
- Unexpected summary verbosity if recent-turn preservation is set too high.
## Risks and Mitigations
- Risk: Post-compaction `await` mode may increase latency for replies right after compaction.
- Mitigation: default is `async`; `off` and `async` remain available.
- Risk: Quality-guard retries could increase compaction token/cost usage.
- Mitigation: default retry cap is low and configurable; guard can be disabled.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR hardens the compaction pipeline with three key improvements: (1) post-compaction transcript update emission and configurable session-memory index sync (`off`/`async`/`await`), (2) identifier-preservation instructions injected into both default and safeguard summarization paths, and (3) a quality-guard retry loop with structured summary section enforcement and recent-turn verbatim preservation.
- **Post-compaction sync** (`compact.ts`): After successful compaction, emits a transcript update event and optionally syncs the memory search index. The sync mode is configurable and defaults to `async` (fire-and-forget with warning on failure). Error handling is well-layered with try/catch at both initialization and async task levels.
- **Identifier preservation** (`compaction.ts`): `buildCompactionSummarizationInstructions` wraps custom instructions with explicit identifier preservation guidance, applied to every `generateSummary` call in chunk processing.
- **Safeguard compaction enhancements** (`compaction-safeguard.ts`): `splitPreservedRecentTurns` preserves the N most recent user/assistant messages verbatim (default 3, max 12). `auditSummaryQuality` checks for required section headings, identifier presence, and latest-ask overlap. On quality failure, the summary is regenerated with augmented instructions (up to configurable retries, default 1, max 3).
- **Config surface**: New settings are added with proper Zod validation, TypeScript types, schema help/labels, and runtime config resolution — consistent with existing patterns.
- Tests cover identifier extraction, quality audit, turn splitting, clamping/wiring, and config resolution.
<h3>Confidence Score: 4/5</h3>
- This PR is safe to merge — new features are additive, all settings default to backward-compatible values, and the changes are well-guarded with fallbacks.
- Score of 4 reflects solid implementation with proper config validation, error handling, and backward compatibility. No critical bugs found. Two minor style issues flagged (lowercase-only hex regex could cause unnecessary quality retries, and a redundant function call inside a loop). The changes are well-tested and all new config has sane defaults with disable toggles for quick rollback.
- `src/agents/pi-extensions/compaction-safeguard.ts` contains the bulk of the new logic (quality audit, identifier extraction, turn splitting) and deserves careful review. `src/agents/pi-embedded-runner/compact.ts` introduces a new async code path (memory sync) that could affect compaction latency in `await` mode.
<sub>Last reviewed commit: 12973de</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#14887: feat(compaction): configurable auto-compaction notifications with o...
by seilk · 2026-02-12
82.5%
#10711: fix: cancel compaction instead of truncating history when summariza...
by DukeDeSouth · 2026-02-06
82.2%
#10505: feat(compaction): add timeout, model override, and diagnostic logging
by thebtf · 2026-02-06
82.1%
#19923: feat: track held messages during compaction gate and split verifica...
by PrivacySmurf · 2026-02-18
82.0%
#8903: fix: improve compaction summary instructions to preserve active work
by joetomasone · 2026-02-04
81.4%
#11089: feat(compaction): support customInstructions and model override for...
by p697 · 2026-02-07
81.4%
#14021: feat(compaction): optional memory flush before manual /compact
by phenomenoner · 2026-02-11
81.2%
#18663: feat: progressive compaction escalation and mechanical flush fallback
by Adamya05 · 2026-02-16
80.8%
#14330: feat(compaction): structured summary template for safeguard mode
by vpesh · 2026-02-12
80.7%
#15322: feat: post-compaction target token trimming + fallback strategy
by echoVic · 2026-02-13
80.6%