Skip to content

Workspace memory: team decisions go to the engine memory hub instead of the workspace-mirrored block store, so other checkouts never see them #1332

Description

@anandgupta42

Summary

In a project linked to a workspace, a plain "remember this for the team" request is not persisted where other linked checkouts can read it. Two memory stores compete, and the one the model reaches for by default is the wrong one:

  1. Altimate Memory blocks (altimate_memory_write / altimate_memory_read): local Markdown blocks, mirrored to the workspace by memory-sync, loaded into every linked checkout's overlay with an origin label. This is the store the workspace feature is built on.
  2. The engine's memory hub (datamate_add_memories / datamate_search_memory, served by the datamate MCP server): a separate SaaS store with asynchronous extraction. Memories saved there did not show up in GET /datamates/memory/list minutes later, and datamate_search_memory in another checkout did not find them either.

The engine's always-active "Datamate MCP Workflow" instructions tell the model to "call add_memories to persist significant decisions", while the description of altimate_memory_write never says it is the team-shared, workspace-synced store. So on a natural prompt the model uses (2), and the decision is invisible to the rest of the team.

Reproduction (v0.12.0, ALTIMATE_WORKSPACE=1, engine 0.7.1, two repos bound to the same workspace)

Repo A, TUI:

Record this team decision: event tables use an append-only incremental strategy with a monthly full refresh, because source rows are never updated, only appended. Save it to memory so the whole team sees it.

Observed: the model calls datamate_add_memories only. No block appears under .altimate-code/memory/, nothing is added to altimate-workspace-memory-index.json, and the workspace memory list stays unchanged.

Repo B (different git remote, same workspace), TUI:

I'm about to build an incremental model for click events here. What strategy did the team decide on for event tables, why, and where does that decision come from?

Observed: the model searches thoroughly on its own (datamate_search_memory, altimate_memory_refresh, altimate_memory_read scope=all, grep, git log) and answers "I don't see a team-specific ADR or memory for event tables in this repo/workspace". It does see an older block from repo A that had been written with altimate_memory_write, which shows the mirror and the cross-project overlay work.

Control: the same flow with the prompt changed to name altimate_memory_write (scope project, id decisions/event-tables-incremental) works end to end: the block is mirrored (index gains the record), and repo B answers "append-only … Recorded by: workspace project orders-analytics, memory block decisions/event-tables-incremental". End users will not write that prompt.

Recordings and the exact tapes are in demos/workspace-pilot/ (e2-decisions-travel.tape) on the workspace_learning worktree.

Second, smaller defect in the same path

MemoryStore.write mirrors with void mirrorBlock(...) (packages/opencode/src/memory/store.ts:321), fire-and-forget. A session that saves a block and exits a few seconds later can lose the upload; /workspace → Sync is then required. For a bound workspace the mirror should either be awaited (it is one request) or flushed before the process exits.

Suggested fix

  • When the project is bound and workspace memory is enabled, tell the model which store is the team's: append a line to the workspace section of the system prompt (awareness.ts already renders ## Workspace), e.g. "Team memory: save decisions and conventions with altimate_memory_write; they sync to the workspace and to every linked checkout. The datamate_* memory tools are the engine's separate store." Alternatively make the altimate_memory_write description say this when bound.
  • Await or flush mirrorBlock when bound.
  • Consider whether the engine's memory hub should be hidden or de-prioritised when the workspace memory feature is on, since two stores with the same "remember" semantics will keep diverging.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions