Merged
Size
S
Change Breakdown
Bug Fix70%
Testing15%
Docs15%
#61674fix(memory-core): isolate dreaming narrative sessions per workspace

Dreaming narrative sessions now isolated per workspace

A bug in the memory system's dreaming narrative generation could cause workspace sessions to collide when multiple workspaces ran the same phase at the same millisecond — now each workspace gets its own isolated session key.

In multi-workspace environments, the memory system's dreaming feature generates transient subagent sessions to build narrative summaries. A bug in session key construction meant these keys were derived from only the phase and timestamp — two workspaces hitting the same dreaming phase at the same millisecond would derive identical session keys and could interfere with each other's message reads or session cleanup.

The fix makes session keys workspace-aware by including a stable SHA1 hash of the workspace directory path. Session keys now follow the format dreaming-narrative-{phase}-{workspaceHash}-{timestamp}, ensuring each workspace maintains completely isolated transient sessions even when processing identical phases simultaneously.

This fix lives in the memory-core module and specifically targets the dreaming narrative generation path. No changes were made to dreaming ranking, promotion thresholds, diary file formats, or DREAMS.md write behavior — the scope is intentionally narrow to prevent unintended side effects.

View Original GitHub DescriptionFact Check

Summary

Describe the problem and fix in 2–5 bullets:

  • Problem: dreaming narrative generation derived its transient subagent sessionKey from only the phase and timestamp.
  • Why it matters: in multi-workspace setups, two workspaces hitting the same phase in the same millisecond could reuse the same subagent session and race on message reads or cleanup.
  • What changed: make the dreaming narrative session key workspace-aware by including a stable hash of workspaceDir, and add regression coverage for same-phase same-timestamp multi-workspace runs.
  • What did NOT change (scope boundary): this does not change dreaming ranking, promotion thresholds, diary file format, or DREAMS.md write behavior.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #
  • Related #
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: the temporary dreaming narrative subagent session key was not scoped by workspace, even though dreaming state and outputs are workspace-local.
  • Missing detection / guardrail: there was no test covering multiple workspaces entering the same dreaming phase at the same timestamp.
  • Contributing context (if known): dreaming now runs per workspace inside a shared sweep path, which makes key collisions possible when the session key omits workspace identity.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: extensions/memory-core/src/dreaming-narrative.test.ts
  • Scenario the test should lock in: two different workspaces running the same phase at the same timestamp must use different subagent session keys and clean up their own sessions.
  • Why this is the smallest reliable guardrail: the bug is local to narrative session-key construction and does not require a full dreaming sweep to reproduce.
  • Existing test that already covers this (if any): None.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

None.

Diagram (if applicable)

Before:
[workspace A light phase @ t]
[workspace B light phase @ t]
        -> same sessionKey
        -> shared subagent session / cleanup race

After:
[workspace A light phase @ t] -> sessionKey(workspace A)
[workspace B light phase @ t] -> sessionKey(workspace B)
        -> isolated transient sessions

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) No
  • New/changed network calls? (Yes/No) No
  • Command/tool execution surface changed? (Yes/No) No
  • Data access scope changed? (Yes/No) No
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: local Node + pnpm
  • Model/provider: N/A
  • Integration/channel (if any): N/A
  • Relevant config (redacted): N/A

Steps

  1. Run generateAndAppendDreamNarrative() twice with the same phase and timestamp.
  2. Pass different workspaceDir values to each call.
  3. Inspect the sessionKey used for subagent.run() and subagent.deleteSession().

Expected

  • Each workspace gets its own transient narrative session key.

Actual

  • Before this change, both calls could derive the same session key when phase and timestamp matched.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: ran pnpm test extensions/memory-core/src/dreaming-narrative.test.ts and confirmed the new same-phase same-timestamp multi-workspace test passes.
  • Edge cases checked: same phase, same timestamp, different workspaces; cleanup still uses the matching per-workspace session key.
  • What you did not verify: I did not run a full end-to-end dreaming sweep across multiple real workspaces.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes/No) Yes
  • Config/env changes? (Yes/No) No
  • Migration needed? (Yes/No) No
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk: session keys now include a workspace-derived hash, so any debugging flow that expected the old exact key format would see different transient names.
    • Mitigation: the session is internal and short-lived; the new format remains deterministic, phase-scoped, and easy to recognize in logs.
© 2026 · via Gitpulse