151 lines
4.7 KiB
Markdown
151 lines
4.7 KiB
Markdown
# Pre-Compaction Flush Implementation Analysis
|
|
|
|
**Date:** 2026-02-15
|
|
**Spec Reference:** Signet SPEC.md Section 6.4
|
|
|
|
## Spec Requirements (Section 6.4)
|
|
|
|
### 6.4.1 Trigger
|
|
- MUST trigger flush when token usage reaches compaction threshold - safety margin
|
|
- RECOMMENDED margin: 4,000 tokens
|
|
|
|
### 6.4.2 Protocol
|
|
1. Send system instruction: "Pre-compaction memory flush. Store durable memories now."
|
|
2. Agent writes accumulated context to database
|
|
3. Agent responds with acknowledgment (e.g., "NO_REPLY")
|
|
4. Implementation proceeds with compaction
|
|
5. Flush MUST be invisible to user
|
|
|
|
### 6.4.3 Content
|
|
- Decisions made during session
|
|
- New facts learned about user
|
|
- Project progress and blockers
|
|
- Action items and todos
|
|
|
|
---
|
|
|
|
## Harness Implementation Status
|
|
|
|
### OpenClaw ✓ FULL COMPLIANCE
|
|
|
|
**Location:** `/usr/lib/node_modules/openclaw/dist/auto-reply/reply/memory-flush.js`
|
|
|
|
**Key Constants:**
|
|
```javascript
|
|
DEFAULT_MEMORY_FLUSH_SOFT_TOKENS = 4000 // safety margin
|
|
DEFAULT_MEMORY_FLUSH_PROMPT = "Pre-compaction memory flush. Store durable memories now..."
|
|
DEFAULT_MEMORY_FLUSH_SYSTEM_PROMPT = "Pre-compaction memory flush turn. The session is near auto-compaction..."
|
|
```
|
|
|
|
**Implementation Details:**
|
|
- `resolveMemoryFlushSettings(cfg)` - reads config, returns settings or null if disabled
|
|
- `resolveMemoryFlushContextWindowTokens(params)` - calculates context window for model
|
|
- `shouldRunMemoryFlush(params)` - determines if flush is needed based on token count
|
|
- `runMemoryFlushIfNeeded(params)` - executes the flush turn
|
|
|
|
**Trigger Logic:**
|
|
```javascript
|
|
threshold = contextWindow - reserveTokens - softThreshold
|
|
if (totalTokens >= threshold && !alreadyFlushedAtThisCompactionCount) {
|
|
// trigger flush
|
|
}
|
|
```
|
|
|
|
**State Tracking:**
|
|
- `memoryFlushAt` - timestamp of last flush
|
|
- `memoryFlushCompactionCount` - prevents re-triggering at same compaction count
|
|
|
|
**Config Options:**
|
|
- `agents.defaults.compaction.memoryFlush.enabled` (default: true)
|
|
- `agents.defaults.compaction.memoryFlush.softThresholdTokens` (default: 4000)
|
|
- `agents.defaults.compaction.memoryFlush.prompt` (customizable)
|
|
- `agents.defaults.compaction.memoryFlush.systemPrompt` (customizable)
|
|
- `agents.defaults.compaction.reserveTokensFloor`
|
|
|
|
---
|
|
|
|
### OpenCode ⚠️ PARTIAL IMPLEMENTATION
|
|
|
|
**Location:** `~/.config/opencode/memory.mjs`
|
|
|
|
**Available Hook:** `experimental.session.compacting`
|
|
|
|
**Current Implementation:**
|
|
```javascript
|
|
"experimental.session.compacting": async (input, output) => {
|
|
output.context.push('[memory active: /remember to save, /recall to query]')
|
|
}
|
|
```
|
|
|
|
**Limitations:**
|
|
- Only adds context reminder during compaction
|
|
- Does NOT trigger a full agent turn for memory saving
|
|
- Cannot execute memory save operations before compaction
|
|
|
|
**Available Hooks (OpenCode Plugin API):**
|
|
- `experimental.chat.messages.transform` - transform chat messages
|
|
- `experimental.chat.system.transform` - transform system prompt
|
|
- `experimental.session.compacting` - hook during compaction (limited)
|
|
- `experimental.text.complete` - text completion hook
|
|
|
|
**What's Missing:**
|
|
1. Token monitoring before compaction threshold
|
|
2. Ability to inject a memory flush turn before compaction
|
|
3. State tracking for flush operations
|
|
|
|
**Possible Enhancement:**
|
|
The plugin API would need a new hook like `experimental.session.preCompaction` that:
|
|
- Receives current token count
|
|
- Can inject a system message
|
|
- Can pause compaction until agent responds
|
|
- Can execute tool calls (like memory save)
|
|
|
|
---
|
|
|
|
### Claude Code ⚠️ INTERNAL MECHANISMS
|
|
|
|
Claude Code uses its own internal memory mechanisms. No external plugin API
|
|
for pre-compaction flush.
|
|
|
|
**Notes:**
|
|
- May have internal memory management
|
|
- Not configurable via user-facing hooks
|
|
- Would need Claude/Anthropic to implement spec compliance
|
|
|
|
---
|
|
|
|
## Recommendations
|
|
|
|
### For OpenCode
|
|
1. Request new hook: `experimental.session.preCompaction`
|
|
2. This hook should receive token count and allow injecting messages
|
|
3. Alternative: Document that pre-compaction flush requires harness-level changes
|
|
|
|
### For Claude Code
|
|
1. Document that flush is handled internally (if it is)
|
|
2. Or note as "implementation pending"
|
|
|
|
### For Signet Spec
|
|
1. Document that pre-compaction flush is a HARNESS-LEVEL feature
|
|
2. Provide reference implementation based on OpenClaw
|
|
3. Define minimum hook requirements for plugin-based harnesses
|
|
|
|
---
|
|
|
|
## Test Verification
|
|
|
|
To verify pre-compaction flush is working:
|
|
1. Start a long session that approaches context limit
|
|
2. Check if memory save operations occur before compaction
|
|
3. Verify saved memories contain session decisions, facts, progress, todos
|
|
4. Confirm NO_REPLY is stripped from user output
|
|
|
|
**OpenClaw Test:**
|
|
```bash
|
|
# Check config
|
|
openclaw config get agents.defaults.compaction.memoryFlush
|
|
|
|
# Monitor session for flush events
|
|
# Look for "Pre-compaction memory flush" in logs
|
|
```
|