Run memory flush before preflight compaction#84792
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 6, 2026, 4:06 AM ET / 08:06 UTC. Summary PR surface: Source +14, Tests +81. Total +95 across 3 files. Reproducibility: yes. Source inspection of current main and Review metrics: none identified. Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Land the narrow ordering change if maintainers accept memory flush as the canonical pre-compaction maintenance step, keeping the adjacent in-turn catch-up and other memoryFlush failure modes on their separate tracks. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection of current main and Is this the best way to solve the issue? Yes. Moving the existing memory-flush call ahead of the existing preflight-compaction call is the narrow owner-boundary fix for this direct ordering bug, and the PR keeps adjacent in-turn catch-up work separate. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against f1f8c1ed1682. Label changesLabel justifications:
Evidence reviewedPR surface: Source +14, Tests +81. Total +95 across 3 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (1 earlier review cycle)
|
|
ClawSweeper PR egg ✨ Hatched: 🌱 uncommon Moonlit Clawlet Hatch commandComment Hatchability rules:
Rarity: 🌱 uncommon. What is this egg doing here?
|
|
Real behavior proof for #84695 / this PR: I reran the targeted maintenance-order regression locally on the PR branch and verified the memory-flush phase runs before preflight compaction. Command: /opt/homebrew/opt/node@22/bin/node scripts/run-vitest.mjs src/auto-reply/reply/agent-runner-direct-runtime-config.test.ts src/auto-reply/reply/agent-runner-memory.test.ts src/auto-reply/reply/reply-state.test.tsObserved terminal result: Specific behavior proved by the new regression: expect(runMemoryFlushIfNeededMock.mock.invocationCallOrder[0]).toBeLessThan(
runPreflightCompactionIfNeededMock.mock.invocationCallOrder[0] ?? Number.POSITIVE_INFINITY,
);That exercises
This is the behavior the bug needs: the flush gate sees the pre-compaction session state, instead of seeing the lower post-compaction token count after preflight compaction has already run. Additional validation: @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Heads up: this PR needs to be updated against current |
023afa3 to
01e356a
Compare
01e356a to
f472d0e
Compare
cb17b53 to
26caf5e
Compare
|
Rebased onto current The proof is now in Local verification on this head: @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Added the live Gateway proof ClawSweeper asked for. Current head: This is no longer only e2e/test-harness evidence. I started an isolated foreground Gateway on loopback with diagnostics enabled, sent a real Redacted timeline excerpt: {"type":"span.start","timestamp":"2026-07-01T07:04:45.661Z","name":"gateway.chat_send.dispatch_inbound","phase":"agent-turn","attributes":{"runId":"pr84792-live-gateway-proof","sessionKey":"agent:main:main","provider":"proof-local","model":"proof-model"}}
{"type":"span.start","timestamp":"2026-07-01T07:04:46.038Z","name":"reply.memory_flush","phase":"agent-turn"}
{"type":"span.end","timestamp":"2026-07-01T07:04:46.038Z","name":"reply.memory_flush","phase":"agent-turn","durationMs":0.374}
{"type":"span.start","timestamp":"2026-07-01T07:04:46.038Z","name":"reply.preflight_compaction","phase":"agent-turn"}
{"type":"span.end","timestamp":"2026-07-01T07:04:46.041Z","name":"reply.preflight_compaction","phase":"agent-turn","durationMs":2.642}
{"type":"span.start","timestamp":"2026-07-01T07:04:46.043Z","name":"reply.run_agent_turn","phase":"agent-turn"}The run then reached provider transport and failed against the intentionally unreachable local endpoint ( @clawsweeper re-review |
|
PR body now has a literal @clawsweeper re-review |
|
Land-ready after maintainer rewrite.
Codex contract check: native pre-turn and mid-turn compaction remain owned by Known proof gap: no live long-context provider conversation was forced; source-level ordering, 98 focused tests, the full remote suite, and exact-head hosted CI cover the changed decision surface. Thanks @TurboTheTurtle. |
|
Merged via squash.
|
Fixes #84695.
Summary
runReplyAgent.What Problem This Solves
runReplyAgentmust run the memory-flush phase before preflight compaction so durable memory has a chance to run before aggressive transcript reduction. Before this PR, preflight compaction could run first and reduce transcript context before the automatic memory flush path had a chance to preserve it.Evidence
Real Gateway Proof
/private/tmp/openclaw-pr84792-proof-rebase-20260630./private/tmp/openclaw-pr84792-live-gateway/home/.openclaw/openclaw.jsonwith loopback-only gateway auth disabled, channels skipped, and a dummy local OpenAI-compatible provider at127.0.0.1:9.origin/mainb63e06f68aa, PR head26caf5e60ec2.OPENCLAW_HOME=/private/tmp/openclaw-pr84792-live-gateway/home \ OPENCLAW_CONFIG_PATH=/private/tmp/openclaw-pr84792-live-gateway/home/.openclaw/openclaw.json \ node scripts/run-node.mjs gateway call chat.send \ --url ws://127.0.0.1:48792 \ --token proof-token \ --json \ --timeout 60000 \ --params '{"sessionKey":"main","message":"PR 84792 live gateway proof: respond with NO_REPLY after diagnostics","idempotencyKey":"pr84792-live-gateway-proof"}'{ "runId": "pr84792-live-gateway-proof", "status": "started" }/private/tmp/openclaw-pr84792-live-gateway/timeline.jsonl:{"type":"span.start","timestamp":"2026-07-01T07:04:45.661Z","name":"gateway.chat_send.dispatch_inbound","phase":"agent-turn","attributes":{"runId":"pr84792-live-gateway-proof","sessionKey":"agent:main:main","provider":"proof-local","model":"proof-model"}} {"type":"span.start","timestamp":"2026-07-01T07:04:46.038Z","name":"reply.memory_flush","phase":"agent-turn","attributes":{"provider":"proof-local","hasSessionKey":true,"isHeartbeat":false,"queueMode":"steer"}} {"type":"span.end","timestamp":"2026-07-01T07:04:46.038Z","name":"reply.memory_flush","phase":"agent-turn","durationMs":0.374} {"type":"span.start","timestamp":"2026-07-01T07:04:46.038Z","name":"reply.preflight_compaction","phase":"agent-turn","attributes":{"provider":"proof-local","hasSessionKey":true,"isHeartbeat":false,"queueMode":"steer"}} {"type":"span.end","timestamp":"2026-07-01T07:04:46.041Z","name":"reply.preflight_compaction","phase":"agent-turn","durationMs":2.642} {"type":"span.start","timestamp":"2026-07-01T07:04:46.043Z","name":"reply.run_agent_turn","phase":"agent-turn"}Observed result after fix: the real Gateway
chat.sendpath startsreply.memory_flushbeforereply.preflight_compaction, then entersreply.run_agent_turnand reaches the provider transport. The provider failure is expected because the isolated proof config intentionally points at an unreachable local endpoint after the pre-run ordering has been proven.Verification