Skip to content

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

Description

@CHE10X

Summary

openclaw memory status (plain, without --index) can report dirty=false while a newly created usage-counted session transcript exists on disk with zero rows in both memory_index_sources and memory_index_chunks. This is a false-clean state: the operator sees no backlog, but memory search silently misses the unindexed transcript.

Reproduction

Reproduced 2026-06-29 on OpenClaw 2026.6.5 with agent archer:

  1. After normal gateway operation, plain openclaw memory status reported dirty=false.
  2. Indexed session files were 1762 while indexable session files on disk were 1763.
  3. The missing file was sessions/archer/1d5782de-a41a-4931-8519-fd4b15940947.jsonl — a normal live session transcript, not a checkpoint/trajectory artifact.
  4. The file had zero rows in both memory_index_sources and memory_index_chunks.
  5. Running openclaw memory status --agent archer --index --json repaired it immediately:
    • session indexed files: 1762 → 1763
    • total files: 1813 → 1814
    • session chunks: 6898 → 6905

Root Cause

The status-mode MemoryManager initialization path skips ensureSessionStartupCatchup():

  • When purpose === "status", the manager init does not call ensureSessionStartupCatchup().
  • status() reports persisted dirty flags only: dirty || sessionsDirty || indexIdentityDirty.
  • The CLI sync/index path calls markSessionStartupCatchupDirtyFiles() when reason === "cli" before sync.

This means any session transcript created after the last CLI sync that hasn't been caught by a non-transient manager cycle will be invisible to plain memory status.

PR #82341 (fixes #62625) added the startup catch-up scan for normal manager startup, but the status-purpose initialization path still bypasses it. The gap is specifically in the status code path, not the indexing code path.

Affected Source Areas

Based on compiled artifact inspection of 2026.6.5:

  • extensions/memory-core/src/memory/manager.ts — manager initialization branches on purpose
  • extensions/memory-core/src/memory/manager-sync-ops.tsensureSessionStartupCatchup() and markSessionStartupCatchupDirtyFiles()
  • extensions/memory-core/src/cli.runtime.ts — CLI status path initialization

Proposed Fix

Two design options:

Option A (preferred): Run the same lightweight ensureSessionStartupCatchup() detection in status mode, or a cheaper variant that surfaces effective dirtiness without performing a full sync. The status path would then report dirty=true when on-disk session files have no corresponding memory_index_sources rows, even if no in-process dirty flag is set.

Option B: Compute a session-surface drift signal explicitly in the status path — compare the canonical session file list against memory_index_sources rows for source sessions — and report effectiveDirty or similar without mutating state.

Either approach avoids making status heavy (no full reindex) while removing the false-clean reporting gap. The key requirement is that plain openclaw memory status must not claim dirty=false when unindexed usage-counted transcripts exist.

Why Current Status Is Misleading

  1. Operators rely on openclaw memory status as the primary health check for memory recall.
  2. A false-clean dirty=false signal means operators will not know session transcripts are unindexed.
  3. This can hide recall gaps for indefinite periods — only --index or --force triggers the catch-up path.
  4. During incident triage on 2026-06-28, this false-clean state compounded confusion because the fleet appeared healthier than it was.

Environment

  • OpenClaw version: 2026.6.5
  • OS: macOS 15.5 (x64)
  • Confirmed still present based on code inspection of 2026.6.10 and 2026.6.11-beta.1 compiled artifacts (status-purpose path still skips catch-up init)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:data-lossCan lose, corrupt, or silently drop user/session/config data.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.maturity:stableIssue affects a taxonomy feature currently scored M4/M5.no-staleExclude from stale automation

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions