Skip to content

fix(cli): dedup compact summaries on (source_id, content_hash), not source_id alone - #48

Merged
DottytheHomeless merged 1 commit into
mainfrom
fix/compact-summary-dedup
Oct 1, 2026
Merged

DottytheHomeless merged 1 commit into
mainfrom
fix/compact-summary-dedup

Conversation

@MXAntian

@MXAntian MXAntian commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

What

--store-compact-summary now dedups on (source_id, content_hash) instead of source_id alone.

Why

A compact summary is a running total of the session so far, so the first one is the narrowest. Keying dedup on source_id stored the first summary of a session and dropped every later, wider one ("already stored"). A SessionStart hook normally discards the CLI's stdout, so nothing surfaced the loss.

Measured over one hook-trace archive: 190 recorded compactions across 43 sessions; 30 sessions (69.8%) compacted more than once, so 147 summaries (77.4%) could never reach the table. One session compacted 55 times; 54 of those windows were never stored.

Change

Identical content still short-circuits, so a resume replaying the same summary stays a no-op. content_hash and its index already exist (migration 004); the hash is computed exactly as storeMemory computes it for content (SHA-256 of the same string, first 16 hex chars). Rows written before migration 004 have no hash, so an identical replay of one of those is stored once more — same as storeMemory's own dedup on legacy rows.

Testing

Through the CLI on a scratch DB, one session id: first summary → stored; same content again → already stored; wider summary → stored (was "already stored"); wider summary again → already stored. CI workflow steps run locally on Windows / Node 24 with temp DBs: 23/24 pass; the one failure is embedding-timeout, which passes 18/18 assertions then hits a libuv assertion on exit on Windows (identical on unmodified main).

🤖 Generated with Claude Code

…ource_id alone

A compact summary is a running total of the session so far, so the first
one is the narrowest. `--store-compact-summary` deduped on source_id alone:
the first summary of a session was stored, and every later, wider one hit
"already stored" and was dropped. A SessionStart hook normally discards the
CLI's stdout, so nothing surfaced the loss.

Scale, measured over one hook-trace archive: 190 recorded compactions
across 43 sessions. 30 sessions (69.8%) compacted more than once, so 147
summaries (77.4%) could never reach the table however clean the write path
was. One session compacted 55 times; 54 of those windows were never in
memory at all.

Dedup now keys on (source_id, content_hash). Identical content still
short-circuits, so a resume replaying the same summary stays a no-op.
content_hash and its index already exist (migration 004), and the hash is
computed the same way storeMemory computes it for `content`. Rows written
before migration 004 have no hash, so an identical replay of one of those
is stored once more -- the same thing storeMemory's own dedup does for
legacy rows.

Checked end to end through the CLI on a scratch DB, one session id:

  first summary             -> stored
  same content again        -> already stored   (dedup still works)
  wider summary             -> stored           (was "already stored")
  wider summary again       -> already stored

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: 千夏 <qianxia@clawgamers.com>
@MXAntian
MXAntian marked this pull request as ready for review October 1, 2026 07:51
@DottytheHomeless
DottytheHomeless merged commit df09ef5 into main Oct 1, 2026
2 checks passed
@DottytheHomeless
DottytheHomeless deleted the fix/compact-summary-dedup branch October 1, 2026 07:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants