Skip to content

feat: add memory.disable_global config option to skip global memory scope#7

Draft
Edison-A-N wants to merge 1 commit intojoshuadavidthomas:mainfrom
Edison-A-N:feat/disable-global-memory
Draft

feat: add memory.disable_global config option to skip global memory scope#7
Edison-A-N wants to merge 1 commit intojoshuadavidthomas:mainfrom
Edison-A-N:feat/disable-global-memory

Conversation

@Edison-A-N
Copy link
Copy Markdown

Summary

This PR adds a new configuration option memory.disable_global (boolean) that allows users to opt out of the global memory scope entirely. When enabled, only project-scoped memory blocks are active.

Motivation

I'm running OpenCode agents as headless background daemons (not interactive TUI sessions). In this setup, each agent instance operates in its own isolated working directory and should only maintain project-scoped memory. The global memory scope (~/.config/opencode/memory/) becomes problematic because:

  1. Cross-contamination: Multiple daemon agents sharing global human.md / persona.md is undesirable — each agent has a distinct role and context.
  2. No interactive editing: In daemon mode, no human is sitting in the TUI to curate global memory. Blocks seeded there go stale or accumulate noise.
  3. Isolation by design: Each agent should be a self-contained unit with its own project-scoped memory, independent of other agents and TUI sessions.

What Changed

4 source files, +71 / -16 lines — minimal and surgical.

src/journal.ts — Extended ConfigSchema with memory.disable_global boolean option.

src/memory.tscreateMemoryStore() now accepts an optional MemoryStoreOptions parameter:

  • ensureSeed() skips global seed blocks
  • listBlocks("all") excludes global scope (so system prompt injection only contains project blocks)
  • getBlock() / setBlock() / replaceInBlock() guard against global scope access

src/plugin.ts — Reads config.memory?.disable_global, passes { disableGlobal } to store and tool factories.

src/tools.ts — Tool schema enum values dynamically exclude "global" when disabled, so the LLM agent cannot even attempt to select it.

Configuration

In ~/.config/opencode/agent-memory.json:

{
  "memory": {
    "disable_global": true
  }
}

Default is falsefully backward compatible, no behavior change unless explicitly opted in.

Questions for Maintainer

I'd really appreciate your guidance on a few points:

  1. Is this the right approach? I went with a config-based opt-out rather than, say, removing global scope by directory detection or an environment variable. Would you prefer a different mechanism?

  2. Naming: I used memory.disable_global — would you prefer something like memory.global_enabled: false (inverted) or memory.scopes: ["project"] (allowlist)?

  3. Tool schema filtering: I chose to dynamically remove "global" from the tool enum values so the LLM can't even see the option. An alternative would be to keep the enum but return an error message. Which feels more aligned with your design intent?

  4. Is this something you'd want upstream? If this doesn't fit the project's direction, that's totally fine — I'm happy to maintain it as a fork. But if it does, I'd love to clean this up to your standards.

Thanks for building this plugin — it's been really useful for our daemon agent setup! Looking forward to your thoughts.

…cope

Add a new config option `memory.disable_global` (boolean) in
agent-memory.json that, when set to true:

- Skips seeding global memory blocks (human.md, persona.md)
- Filters global scope from listBlocks() results
- Guards getBlock/setBlock/replaceInBlock against global scope
- Removes 'global' from tool schema enums so the LLM agent
  cannot select it

This enables headless/daemon agent deployments where global
memory (shared across all sessions/projects) is undesirable
and only project-scoped memory should be active.
@joshuadavidthomas
Copy link
Copy Markdown
Owner

🎉 Thanks for the contribution!

It's been a bit since I initially wrote this so my motivation is a bit fuzzy, but it was probably a mix of copying how AGENTS.md/CLAUDE.md works and how Letta does its memory blocks. Not opposed to this though, I can see the usefulness of just having memory for the working directory.

I'm on my phone at the moment, but a quick glance at the patch it looks good. I'll leave a proper review later when I can get in front of my laptop.

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