Skip to content

fix(mcp): reuse one resident session for remember - #4582

Closed
ZaynJarvis wants to merge 1 commit into
mainfrom
fix/remember-reuse-session
Closed

fix(mcp): reuse one resident session for remember#4582
ZaynJarvis wants to merge 1 commit into
mainfrom
fix/remember-reuse-session

Conversation

@ZaynJarvis

Copy link
Copy Markdown
Collaborator

Draft — the behaviour question in "Open question" below should be settled before this merges.

Problem

Every remember call minted a fresh mcp-store-<uuid> session (mcp_endpoint.py:715-733).

A session directory survives its own commit. remember commits without keep_recent_count, so it takes the default 0: every message moves into history/archive_001/, and session.py:5279-5287 then rewrites the live messages.jsonl as an empty string. The directory stays, along with .meta.json, .abstract.md and .overview.md.

Net effect: one permanently near-empty directory per remembered fact. That is the reported "lots of empty directories, hard to read, and we bill per file" experience.

Change

Use one resident session id per user. Sessions are already scoped to viking://user/<user_id>/sessions/, so a fixed id is per-user without any extra keying — no account, peer, or agent component needed.

The diff is one constant and one assignment.

Relationship to #4029

#4029 proposes an opt-in retention/GC sweep for session directories and commit archives. This PR does not replace it — archives still accumulate inside the resident session and still need a retention policy.

What it does is remove the largest class of garbage at the source, so the GC is no longer the only thing standing between a busy deployment and unbounded directory count. Cleaning up files that never needed to exist is the wrong place to spend a background scanner.

Open question

remember still commits on every call, so a busy user accumulates history/archive_NNN inside the one resident session. Committing less eagerly would cut that too, but it changes when extraction runs and therefore when a memory becomes searchable. I have deliberately not touched that — it is a latency contract, not a cleanup detail. Worth deciding whether it belongs here or in #4029's retention work.

Also worth a look: concurrent remember calls now share a session, so one call's commit can sweep in another's just-added messages. That is harmless for extraction (all of it is material to extract, and it produces fewer archives), but it is a real behaviour change from the isolated-session-per-call model and should be a conscious choice rather than a side effect.

Tests

tests/server/test_mcp_remember_session_reuse.py, 4 cases: two calls reuse one session, the id is stable rather than random, the commit targets the session that was written to, and content still reaches the session with empty messages skipped.

They stub the service and the identity contextvar directly, so unlike the rest of tests/server/test_mcp_endpoint.py they run without a server configuration file.

Verified they fail without the fix (3 of 4 fail when the uuid id is restored). tests/server, tests/session and tests/service show an identical failure set with and without the change — 177 failed / 790 errors before and after, 1124 → 1128 passed. Those pre-existing failures are this machine lacking a compiled ov binary and a server config.

Every remember call minted a fresh mcp-store-<uuid> session. A session
directory survives its own commit -- the live messages.jsonl is rewritten
empty and the content moves to history/archive_NNN -- so each remembered
fact left a permanently near-empty directory behind, holding an empty
messages.jsonl plus .meta.json, .abstract.md, .overview.md and
archive_001/.

Use one resident session id per user. Sessions are already scoped to
viking://user/<user_id>/sessions/, so a fixed id is per-user without any
additional keying, and the archives now accumulate inside one directory
instead of one directory per fact.

This is the source of the largest class of session-directory clutter that
issue #4029 proposes to sweep with a background GC. It does not replace
that GC: archives still accumulate and still need a retention policy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ZaynJarvis

Copy link
Copy Markdown
Collaborator Author

Closing. The directory-per-fact effect is real, but session directories do not enter the vector store and their .abstract.md / .overview.md are written deterministically by Session._generate_abstract / _generate_overview rather than by the semantic pipeline, so collapsing them saves neither billing nor LLM work — only clutter.

The cost that does exist is one archive per commit, each with an LLM-generated Working Memory document (prompts/templates/compression/ov_wm_v2.yaml). This PR does not touch that, because remember still commits on every call. Anything worth doing here has to address commit cadence, which trades against how soon a memory becomes searchable — a separate discussion, not this two-line change.

@ZaynJarvis ZaynJarvis closed this Sep 2, 2026
@ZaynJarvis
ZaynJarvis deleted the fix/remember-reuse-session branch September 2, 2026 03:15
@github-project-automation github-project-automation Bot moved this from Backlog to Done in OpenViking project Sep 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant