Skip to content

fix(memory): detect session drift in status mode to avoid false-clean dirty flag#98072

Closed
ly-wang19 wants to merge 1 commit into
openclaw:mainfrom
ly-wang19:fix/memory-status-session-drift-97814
Closed

fix(memory): detect session drift in status mode to avoid false-clean dirty flag#98072
ly-wang19 wants to merge 1 commit into
openclaw:mainfrom
ly-wang19:fix/memory-status-session-drift-97814

Conversation

@ly-wang19

Copy link
Copy Markdown
Contributor

What Problem This Solves

Fixes #97814.

openclaw memory status (plain, no --index) can report dirty=false while a usage-counted session transcript exists on disk with zero rows in memory_index_sources / memory_index_chunks. The operator sees no backlog but memory search silently misses the unindexed transcript. During a recent incident this false-clean state compounded triage confusion because the fleet appeared healthier than it was.

Root cause: status-purpose manager init skips ensureSessionStartupCatchup(), so on-disk session drift is never surfaced through the dirty flag in the plain status path.

Why This Change Was Made

Status mode intentionally avoids the full catch-up sync to stay light, but the previous implementation also skipped drift detection, which made the dirty flag unreliable. This PR threads detection (without sync) through the status path so status() reflects reality, then waits for that detection to settle before the CLI reads status.

Design choice: detection-only, no sync in the status path. The status-purpose manager now records a promise that resolves with the list of unindexed session files (using the existing markSessionStartupCatchupDirtyFiles() helper). status() already honors the dirty flag set by detection. The CLI status path calls a new refreshSessionStartupDirtyDetection() method to await detection before reading status, so the response is accurate even when the manager was constructed milliseconds ago.

User Impact

  • openclaw memory status no longer claims dirty=false when unindexed session transcripts exist; operators can trust the dirty flag as a health signal.
  • No behavioral change for --index / --force / --deep paths — they already triggered catch-up.
  • No performance regression: status mode still does not perform a full sync; it only runs the existing lightweight on-disk-vs-DB file comparison.

Evidence

The new method is thread-local to the builtin MemoryIndexManager; the CLI uses type narrowing with a runtime typeof === "function" guard so other backend implementations are unaffected.

… dirty flag

Plain `openclaw memory status` skipped `ensureSessionStartupCatchup()` because
status mode is transient, so unindexed on-disk session transcripts never set
`sessionsDirty`. Operators saw `dirty=false` while memory search silently missed
recent transcripts.

Status mode now runs the detection half (no sync) in the constructor and exposes
`refreshSessionStartupDirtyDetection()` so the CLI status path can await it before
reading `status()`.

Fixes openclaw#97814
@clawsweeper

clawsweeper Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Close as superseded: this PR targets the same memory-status false-clean bug as #97857, and that open clean branch is the stronger landing path because it awaits the existing session drift helper during status-purpose manager creation before any status caller reads the dirty flag.

Root-cause cluster
Relationship: superseded
Canonical: #97857
Summary: This PR, the canonical open PR, and sibling candidates target the same memory-status false-clean issue; the canonical PR is the proof-positive clean landing path because it fixes the manager acquisition boundary rather than one CLI caller.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Canonical path: Use #97857 as the canonical landing path for the memory-status false-clean fix, then close sibling candidate branches once that path is resolved.

So I’m closing this here and keeping the remaining discussion on #97857.

Review details

Best possible solution:

Use #97857 as the canonical landing path for the memory-status false-clean fix, then close sibling candidate branches once that path is resolved.

Do we have a high-confidence way to reproduce the issue?

Yes, at source level. Current main constructs purpose-status managers as transient, skips ensureSessionStartupCatchup(), and status() reports dirty from manager flags rather than comparing usage-counted session files with indexed sessions rows.

Is this the best way to solve the issue?

No for this branch as the landing path. The safer solution is the open canonical PR because it awaits the existing dirty-file scan during status-purpose manager creation, so all status callers observe the refreshed dirty flag.

Security review:

Security review cleared: The diff only touches memory-core runtime and test code, with no dependency, CI, package metadata, secret, permission, or supply-chain surface changes.

AGENTS.md: found and applied where relevant.

What I checked:

Likely related people:

  • masatohoshino: Current blame for the status-purpose manager branch, catch-up helper lines, CLI status path, and shared status scan adapter points to the merged status-drift work in commit 888f399 / fix(status): surface should-run plugin drift #97878. (role: recent adjacent contributor; confidence: high; commits: 888f399499c4, 74ad546d24b2; files: extensions/memory-core/src/memory/manager.ts, extensions/memory-core/src/memory/manager-sync-ops.ts, extensions/memory-core/src/cli.runtime.ts)
  • giodl73-repo: Authored the merged startup and CLI session catch-up PR that introduced the helper and behavior this PR family extends. (role: adjacent fix contributor; confidence: high; commits: 8af2af24a53c, 8102434a234a, 5e02e33cb438; files: extensions/memory-core/src/memory/manager.ts, extensions/memory-core/src/memory/manager-sync-ops.ts, extensions/memory-core/src/memory/manager-session-sync-state.ts)
  • steipete: Git history shows Peter Steinberger authored the shared status scan helper refactor that owns the sibling openclaw status surface affected by the manager-level fix boundary. (role: adjacent status-scan refactor contributor; confidence: medium; commits: 143530407dd1; files: src/commands/status.scan.shared.ts)

Codex review notes: model internal, reasoning high; reviewed against 56c2d637d940.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. labels Jun 30, 2026
@clawsweeper

clawsweeper Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper applied the proposed close for this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extensions: memory-core Extension: memory-core P2 Normal backlog priority with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: memory status reports dirty=false for unindexed usage-counted session transcripts (false-clean status path)

1 participant