Omniscio documentation
Browse all documentation
  1. Getting Started13
  2. Sessions & Agents115
  3. Inbox & Notifications59
  4. Projects & Tasks95
  5. Automation & Scheduling75
  6. Knowledge & Memory26
  7. AI Features60
  8. Integrations100
  9. Plugins & Marketplace33
  10. Cloud & Teams56
  11. Settings & Customization58
  12. Account & Billing28
  13. Troubleshooting84
  14. CLI & API Reference22
  15. Legal & Policies4
  16. Uncategorised22

Global memory

An agent-written memory library the agents can browse, search and add to — modelled on Omniscio's own docs system but live: a budget-aware tree a session can load at the size it wants, memories an agent writes from its own work, and comprehension search.

What it is

A progressive-disclosure, agent-written memory library built on the Context Dock native store — modeled on Omniscio's own docs system (CLAUDE.md → MEMORY.md → topic files), but live and agent-facing. Milestone 1 is the read path (browse a budget-aware tree + load any memory at the size you choose); Milestone 2 is the write path — agents remember from their own work; and Milestone 3 adds search — find memories by meaning + keyword. It is gated off by default (globalMemoryEnabled / the global-memory unreleased feature). The engine is agent-facing (CLI routes + first-message injection); a user-facing Memory panel under Agent Tools (desktop) is the one place to see and edit what the agents remember — see The Memory panel below.

The idea

  • A memory is just a Context Dock store doc — it already has three compression levels (full / medium / short = original / keyPoints / summary), a per-level token count, a one-line summary, and tags. Nothing new is stored.
  • Memories are organized into a tree: fixed top branches (About You / This Project / People) → tag-groups → memories. Every node shows how many memories it holds and what they'd cost to load at each level, so the agent only drills in when it's worth the tokens.
  • Groups are keyed on a standard set of 17 tags (merge, testing, git, cloud, bug-fix, …) rather than whatever tag the model happened to invent — see How the tree groups.
  • A tiny always-loaded root map is injected into each session's first message (when on), so the agent knows memory exists and how to reach it — capped (~6k tokens), and nothing at all when off.

Where to find it

The Memory panel (see + edit your memories)

When the system is on, a Memory item appears in the left sidebar under Agent Tools (desktop). It's the one place you can look at everything the agents have remembered and curate it:

  • A searchable list of your memories on the left; click one to read it at any level (full / key points / summary) on the right.
  • Edit a memory's tags or delete one you don't want kept — it reuses the ContextDock Library's detail pane, so it's familiar and consistent.
  • It shows ONLY the agent-written memories (rows minted with a mem_ id), never your imported course/curriculum docs — those stay in the ContextDock Library.

It reuses the ContextDock-native store under the hood (no new data, no new backend — just a widened access gate so the panel works with only Global Memory on), and it's desktop-only for now (the local store isn't wired to the mobile bridge yet). It's part of the same global-memory feature, so it stays hidden until you turn Global Memory on.

How it behaves

How the tree groups

Memories file under a standard tag, not the freeform one the model wrote. The distiller invents its own tags per session, so grouping on those directly shattered the library — on the real store (1,495 memories, 2,390 different tags) there were 713 top-level folders, and 522 of them held a single memory. A library where every memory is its own folder is one you can't browse.

So every tag is folded onto a closed list of 17 standard tags — merge, testing, git, cloud, bug-fix, infrastructure, build, automation, process, tech-debt, security, ui, docs, data, performance, i18n, preferences — plus a general catch-all. ready-to-merge, auto-lander, rebase and merge-conflict all land in merge; verification, typecheck and guard-lane all land in testing. On the same library that turns 713 folders into 18 — with no single-memory folders left at all — and 95% of memories land somewhere meaningful.

Two things worth knowing:

  • Nothing is rewritten. The fold happens when the tree is drawn, so your memories keep their specific tags for reading and searching — the standard tag is only the filing key. No migration, and the existing library regroups instantly.
  • Both levels fold. When a group gets too big it splits by a second tag — folding that one too is what stops the mess from just moving down a level (734 single-memory subfolders became 25).
  • A tag about two things files under the first one. cloud-testing is both cloud and testing; it files under cloud because the leading word is what it's mainly about.

The distiller is also shown the standard list so new memories arrive already using it, but that's a nicety: the fold happens on read either way, so a model that ignores the list still files correctly.

What an agent sees + does

Five routes on the local control server (http://127.0.0.1:19519, bearer $AMC_CLI_TOKEN):

  • GET /memory/map — the branch map: each branch with its memory count + short/medium/full token cost.
  • GET /memory/open?node=<node> — drill in. about-you lists that branch's tag-groups; about-you/auth lists the memories in a group (each with id, one-line summary, tags, cost).
  • GET /memory/load?id=<id>&level=short|medium|full — return one memory's body at the chosen level (falls back to an available level if the requested one wasn't generated; budget-capped via the Context Dock assembler).
  • POST /memory/remember (M2) — write a memory mid-work; it's scoped (About You / this project / People), deduped against what's already stored, and linked to the current session.
  • GET /memory/search?q=<query> (M3) — find memories by meaning AND keyword (hybrid); returns ranked hits with their ids to then load.

These were MCP tools until 2026-09-02 (memory_map, memory_open, memory_load, memory_remember, memory_search), served by a pure-Node subprocess spawned once per session. That subprocess is retired: the routes run in the main process, which already owns the database, so the whole per-session process disappeared and nothing about the behaviour changed. If you are hunting for a memory MCP tool, it no longer exists — call the route.

The root map is also injected as text at the top of the first message, so an agent that never calls a route still knows the library is there — and that injected text names the exact command.

How auto-write works (Milestone 2)

  • The agent that did the work writes the memory. At the end of its work, every session is asked — quietly, in its system prompt — whether anything about you is worth keeping. It asks exactly two things: did you reveal something about yourself, and did you correct it. It is explicitly forbidden from asking what the session accomplished, because in a fleet where agents finish tasks all day that question produces a changelog, not a memory. The default is to save nothing, and that is the normal outcome.
  • Why it moved off a separate summarizer. The old session-end distiller only ever saw a truncated transcript, so it could not tell whether a fact was already written down in the repo's own docs — and 75% of the library ended up as project notes duplicating git-tracked documentation. The agent that did the work can answer that, because it knows what it just wrote.
  • The bar it applies. Save what stops you having to correct or remind it again; nothing that will be stale in a week; facts, never instructions to itself ("you prefer short replies" ✓, "always reply briefly" ✗ — an instruction gets re-read as an order later); and knowledge about the codebase goes in the repository's own docs, never here.
  • Session-end distiller (legacy, still available). The original background pass that reads a finished session's transcript and extracts memories with a separate model. Set memoryDistillerModel to off to disable it, or to any model to run it alongside the capture above.
  • Configurable model (A/B testing). Which model the distiller runs on is a flippable setting, memoryDistillerModel — Haiku (default), Sonnet, Opus, DeepSeek V4 Flash, GPT-5.6 Luna, or off — set over the CLI (no UI toggle). The Claude tiers run on your API-key account; the DeepSeek/Luna tiers route through the app's bundled OpenRouter lane, so they need no extra key. It reuses the shared cross-provider utility path (llmProviderService.chat), so the daily cost cap covers every model.
  • A mid-work POST /memory/remember lets an agent record something the moment it matters, without waiting for session end.
  • Scope. Each memory is about-you (cross-project facts about the user), people, or project:<id>. A project memory only surfaces under that project; About You / People are global.
  • Dedup. A write matches an existing memory by content-hash or normalized title within the same scope and updates it instead of duplicating (meaning-based dedup arrives with M3's embeddings).
  • Safe by construction. The distiller is injection-fenced (the transcript is treated as pure data — instructions inside it are ignored — and the output is strict, validated JSON), so a memory can never smuggle a prompt-injection into future sessions. It is cost-capped (a per-account daily USD limit, default $1, memoryDistillerDailyCapUsd) and no-ops quietly when the feature is off, the chosen model's provider has no credential (the Claude tiers need your API-key account; the DeepSeek/Luna tiers use the bundled key so they need none), the cap is hit, or the session is too short.

Milestone 1 model (deliberately simple)

  • No persistent node table. The tree is a fixed scope scaffold (a code constant) + tag-derived groups computed on read. Deep, auto-splitting "index of indexes" arrives with the janitor (M4), which is the first thing that actually needs a stored node tree.
  • Migrated library = About You. Existing store docs (pre-M2) read as About You (the user's personal library); untagged docs fall under an Imported library group. New memories carry the scope the writer assigned.

Milestone 4 — janitor + nesting (built)

A daily background janitor tends the library, and it owns the persistent nested index (memory_index_nodes) — the "index of indexes" branches that auto-split when they grow. It stays gated off with the rest of the feature, and it NEVER deletes: everything it tidies away is archived (a distinct, fully recoverable state — deleting is a user-only action). An archived memory drops out of the agent's active browse and GET /memory/load (and reappears if restored), so the tidying is actually visible instead of silent.

Each run does four passes, cheapest-first:

  • NEST (pure, free): rebuild the nested tree — group by tag, split any group over ~20 memories or ~8k tokens into sub-tag subgroups (max three levels), stamp each memory's leaf. Deterministic, so the tree never churns between runs; it's a rebuildable projection, never a second source of truth (drop it and the on-read scaffold still shows every memory).
  • DEDUP (mechanical, free): collapse exact/title duplicates — keep the richest survivor, union its tags, keep the earliest provenance. A loser whose unique text isn't already on the survivor is co-filed (left live), never hidden.
  • PRUNE (mechanical, free): archive empty-body memories only.
  • AI lane (opt-in, ~$1/day cap): a cheap model (Haiku) does meaning-based near-duplicate matching (candidates from cosine neighbours over the M3 embeddings — read defensively, degrades to mechanical when they're absent) and stale judgement. Every prompt is injection-fenced (memory content = untrusted data) and every verdict is schema-validated (a bad one is dropped). Confirmed near-dups merge + archive their losers; stale memories archive — all recoverable.

The scheduler is a daily cron (hourly tick + a once-per-day file), single-flight, feature-gated so it costs nothing while off.

How search works (Milestone 3)

  • Hybrid. GET /memory/search runs two engines and merges them: meaning-based (an on-device embedding model, all-MiniLM-L6-v2, cosine similarity) and keyword (SQLite FTS5). A memory found by both ranks highest.
  • Free. Embeddings run locally — M3 makes no LLM/API call and needs no cost cap.
  • Always works. Keyword search is instant (a trigger-synced FTS index, no model). If the embedding model isn't ready, search degrades to keyword-only rather than failing.
  • Stays fresh. A background pass at session end embeds new or changed memories (detected by a content hash), so search keeps up as the library grows — harvested from the MemPalace engine.

Roadmap

  • All milestones (M1–M4) are built: read path (browse + load), auto-write (session-end distiller
    • POST /memory/remember), search/RAG (hybrid GET /memory/search + on-device embeddings), and the janitor
    • persistent nested index.

For agents

Where it lives

  • Types + scaffold: src/shared/memory-types.ts. Pure tree: src/main/services/memory/tree.ts.
  • Agent routes: src/main/services/cli/cli-server-memory-routes.ts. Root injector: src/main/services/memory/root-snapshot.ts.
  • Write path (M2): src/main/services/memory/store-write.ts, distiller.ts, memory-write-scheduler.ts, memory-distiller-cost.ts; distiller model picker src/shared/memory-distiller-model.ts (setting memoryDistillerModel).
  • Search (M3): src/main/services/memory/memory-retrieval.ts, src/main/db/queries-contextdock-embeddings.ts, memory-embedding-scheduler.ts.
  • Memory panel (UI): src/renderer/src/features/memory/ (MemoryView, memory-filter.ts), manifest src/shared/integrations/memory.ts, widened store gate src/main/services/feature-flag-gates.ts:requireContextDockStoreAccess.
  • Contract + invariants: global-memory-system-contract.md.

Related

Flashcards is the other local, agent-adjacent store in this library; the KMS vault is where your own hand-written notes live.

Last verified 2026-09-23