Skip to content

fix(session): stop leaving an empty messages.jsonl in every session - #4585

Draft
ZaynJarvis wants to merge 1 commit into
mainfrom
fix/no-empty-live-messages
Draft

fix(session): stop leaving an empty messages.jsonl in every session#4585
ZaynJarvis wants to merge 1 commit into
mainfrom
fix/no-empty-live-messages

Conversation

@ZaynJarvis

Copy link
Copy Markdown
Collaborator

Draft — the is_materialized() change touches the boundary #3820 deliberately drew, so I want that looked at before this merges.

Problem

Committing with keep_recent_count=0 moves every message into history/archive_NNN and then rewrites the live file as an empty string (session.py, _write_to_agfs_async). Every session directory therefore keeps a 0-byte messages.jsonl forever.

This is the single most complained-about piece of session-directory clutter — it has come up from more than one person internally and in the user group. A directory listing full of files containing nothing is hard to read and hard to explain.

Change

Remove the file rather than writing zero bytes. "No live messages" and "an empty list of live messages" are the same state, and VikingFS.rm is documented idempotent, so a session that never wrote a live file needs no separate guard.

The part that needs review

#3820 made messages.jsonl the materialization boundary: is_materialized() exists so a half-created session root is not used for session-aware recall (retrieve/context_assembler/pipeline.py:44 returns None when it is false).

Deleting the file naively would make every committed session look half-created and silently drop it out of context assembly. That would be a real regression, and it is the reason this is not a one-line change.

So is_materialized() now accepts either messages.jsonl or history/:

The boundary #3820 drew is preserved; it just has two halves now that the live file is no longer permanent.

Also guarded the commit path's strict live read: once the file can be absent, a second commit with nothing new must read as empty rather than raising.

Scope

This fixes it for all sessions, not only MCP ones. An earlier attempt (#4582, closed) went at the remember tool instead; that was the wrong layer — the empty file is written by the generic commit path, so every session had it.

Tests

tests/session/test_no_empty_live_messages.py, 5 cases: the empty write becomes a removal; a committed session (history only) is still materialized; a live session still is; a half-created root still is not — the #3820 regression case; and a storage failure is not swallowed as "not materialized".

tests/session, tests/service, tests/server, tests/retrieve show an identical failure set with and without the change — 177 failed / 790 errors before and after, 1182 → 1187 passed. Those pre-existing failures are this machine lacking a compiled ov binary and a server config, so I could not exercise a real commit end to end; the new tests use a fake filesystem. Worth a reviewer with a working environment confirming the archive path.

Committing with keep_recent_count=0 moves every message into
history/archive_NNN and then rewrote the live file as an empty string, so
each session directory kept a 0-byte messages.jsonl forever. Users see a
tree full of files that contain nothing.

Remove the file instead. "No live messages" and "an empty list of live
messages" are the same state, and VikingFS.rm is documented idempotent.

The catch is #3820, which made messages.jsonl the materialization
boundary so a half-created session root is not used for session-aware
recall (retrieve/context_assembler/pipeline.py:44). Deleting the file
naively would make every committed session look half-created and drop it
out of context assembly. So is_materialized() now also accepts history/:
a committed session has archives, a half-created root has neither. The
boundary #3820 drew is preserved, it just has two halves now.

Also guard the commit path's strict live read: once the file can be
absent, a second commit with nothing new must read as empty rather than
raising.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

1 participant