Unified Agent Memory: OpenSpec Plan
This is the publishable companion note for unified-agent-memory-fabric. It keeps the planning detail that should not be buried inside the main narrative.
Proposal
Unified Agent Memory —- Phase 0: Assessment
What & Why
Problem
Every agent, (Hermes/poke on mac, Clawd on server, Machine on discord, and OpenCode), has its own memory context. A fact I tell to one agent is invisible to another. The vault syncs via git push/pull — slow, manual, merge conflicts do not reliably become available to the others. Vault plans and OpenSpec progress also need to be visible across devices.
Goal
A shared memory fabric wherand agents quickly.
Goal
Create one shared substrate:
- vault writes appear on all devices in seconds (Obsidian LiveSync)
- all agents read/write the same mem0 namespaceObsidian vault for durable project knowledge and plans
- CouchDB plus Self-hosted LiveSync for real-time vault transport
- server headless LiveSync daemon to materialize CouchDB into filesystem
- gbrain providesfor knowledge graph synthesisretrieval over thserver vault
- single MCP gateway exposes everything
Real-time vault propagation across hosts when agents write is a distinct goal not covered in the original proposal. See Phase 5 in design.md and tasks.md.
Scope
Phase 0 only: assess what’s already running, what’s missing, and produce a concrete implementation plan for Phase 1 (LiveSync), Phase 2 (gbrain), Phase 3 (Mem0), Phase 4 (MCP Gateway), and Phase 5 (real-time sync propagation).
Deliverables
- Health check report for existing mem0-new deployment on server — ✅ repaired and verified
- Inventory of supabase PG capacity (pgvector extension, database size, connection limits) — ✅
- CouchDB compatibility check (Docker availability, port conflicts, SSL/Caddy config) — ✅ couchdb deployed and reachable
- gbrain prerequisites check (bun version, node version, disk space) — ✅ gbrain installed and serving
- Audit of current agent profiles (what tools each has, what’s missing) — ✅ updated filesystem
- mem0 for shared episodic memory
- hermes-mcp for agent tool access
- OpenSpec for trackable infrastructure changes
Updated direction
The original design over-relied on git as the transport between mac and server. That is not enough for live agent work. Git is now treated as backup and reviewable history, while CouchDB and LiveSync are the real-time path.
Current implemented state
- CouchDB is deployed and used by mac, phone, and iPad.
- Mac hidden LiveSync settings were fixed and device-to-device sync works.
- server now runs native headless
livesync-clias systemd servicelivesync-daemon. - server uses
/srv/livesync-dbas the CLI database path. - server uses
/srv/vault-writeas the actual vault path. - server writh current state
- Concrete task list for Phase 1 and Phase 2 with exact commands — ✅ extended to Phase 5
Post-Assessment Repairs (2026-06-20)
During the assessment session the following issues were also discovered and repaired:
- Mem0 API missing
/memoriesroutes — code re-added - Mem0
POST /searchbroken due to SDK API change — filter logic corrected - hermes-mcp mem0 proxy endpoints pointing at wrong URLs — corrected
- Obsidian Git sync not configured for auto-propagation — symmetric 5-minute interval set on mac and server
- server not configured for LiveSync at all — plugin config and data.json created
- Noisy
.obsidianUI-state files tracked in gites now propagate to mac and mobile through CouchDB without git commit. - gbrain reads server filesystem, so the CouchDB to filesystem bridge closes the largest freshness gap.
Remaining work
- Verify mac/mobile edits landing on server filesystem.
- Add gbrain event-driven or frequent re-indexing.
- Move the
obsidian-livesyncsource checkout from/tmpto a durable service path. - Normalize mem0, gbrain, and cvausing merge churn — untracked
- Project status documentlt tools across Machine and oOpenspec out of date — updated to current reality
- server had uncommitted local config changes preventing clean push — rebased and pushedCode.
- Define how often Git snapshots should be committed now that Git is no longer the live sync layer.
Design
Architecture — Unified Agent Memory
High-level topology
mac obsidian client
phone obsidian client
ipad obsidian client
|
v
self-hosted couchdb: https://couchdb.livesync.goku.codes/vault-write
|
+--- Obsidian LiveSync clients (mac, phone, iPad) ← real-time, bidirectional
|
v
server headless livesync cli daemon (livesync-daemon)
|
v
/srv/vault-write filesystem
|
+--> gbrain index source (785 .md files indexed)
+--> cloud agent writable vault
+--> git backup and reviewable historyCurrent architecture decision
CouchDB and Self-hosted LiveSync are the real-time vault transport. Git remains useful for history, backups, and reviewable snapshots, but Git is not the real-time sync layer.
server is not pretending to be an Obsidian GUI client. server is a headless LiveSync peer that bridges CouchDB into the filesystem that gbrain and cloud agents use.
Verified working paths
Client to server
- Mac, phone, or iPad edits a vault note.
- Obsidian LiveSync pushes to CouchDB.
- server livesync-daemon consumes the CouchDB change feed.
- The note appears under
/srv/vault-write. - gbrain indexes the updated filesystem.
server to clients
- A cloud agent writes under
/srv/vault-write. - livesync-daemon watches the vault path.
- The daemon pushes the file into CouchDB.
- Mac, phone, and iPad receive the change through LiveSync.
Both paths verified without git commits.
Critical implementation detail
The CLI uses separate paths:
- Database path:
/srv/livesync-db - Vault path:
/srv/vault-write
Command:
/srv/.nvm/versions/node/v22.21.1/bin/node \
/opt/obsidian-livesync/src/apps/cli/dist/index.cjs \
/srv/livesync-db \
--vault /srv/vault-write \
daemonUsing the vault as the database path caused config migration confusion, disabled-sync warnings, and unreliable daemon behavior.
gbrain integration
- gbrain indexes the server filesystem through
gbrain sync --source vault-write --full. - OpenRouter embedding provider configured (
openrouter:openai/text-embedding-3-small). - Embedding dimension 1536 preserved from previous schema.
- No direct CouchDB ingestion path exists yet. gbrain reads filesystem, which is fed by CouchDB via livesync-daemon.
Safety rules
- Do not commit mass deletions from git status unless deletion intent is confirmed.
- Agents write only to
/srv/vault-write, never to/srv/livesync-db. - Do not edit LiveSync JSON settings by guessing. Read docs or source first.
- Git is backup and reviewable history, not the real-time transport.
Task breakdown
Tasks — Unified Agent Memory
Phase 0: Assessment ✅
P0-T1: Check mem0 health ✅
mem0 API was repaired. Missing /memories and /search routes restored.
P0-T2: Check supabase PG ✅
PG 15.8, pgvector available.
P0-T3: Check CouchDB prerequisites ✅
Docker available, port 5984 free, nginx handles SSL.
P0-T4: Check gbrain prerequisites ✅
bun v1.3.14, node v22.21.1, sufficient free disk.
P0-T5: Audit agent profiles ✅
See specs/phase0-results.md.
Phase 1: LiveSync ✅
P1-T1: Deploy CouchDB on server ✅
CouchDB deployed on server, vault-write database created, endpoint reachable at couchdb.livesync.goku.codes.
P1-T2: Configure nginx plus SSL ✅
nginx reverse proxy with SSL active.
P1-T3: Configure mac, phone, and iPad LiveSync ✅
Mac hidden LiveSync settings corrected in raw JSON. Phone and iPad verified receiving live updates. Mac, phone, and iPad now see updates between each other quickly.
P1-T4: server headless LiveSync peer ✅
Built Self-hosted LiveSync CLI from source on server with node v22. Created separate database path /srv/livesync-db. Configured native systemd service livesync-daemon. Verified bidirectional sync: server writes reach mac/mobile, mac/mobile writes reach server filesystem.
Phase 2: gbrain ✅
P2-T1: Install gbrain ✅
bun install -g github:garrytan/gbrain → v0.42.51.0
P2-T2: Create database and init ✅
gbrain database created on Supabase PG, initial vault indexing completed, embeddings generated.
P2-T3: Configure gbrain MCP ✅
gbrain MCP service active on port 8765, HTTPS endpoint, reboot-safe.
P2-T4: Create Hermes skill for gbrain ✅
gbrain skill exists on mac and server.
Phase 3: Universal mem0 ✅
P3-T1: Create shared mem0 Hermes skill ✅
API key, URL, and user_id configured on server. Mem0 API repaired.
- Machine needs env injection and MCP config parity check.
- OpenCode needs final
.mcp.jsonparity check.
Phase 4: Unified MCP Gateway ✅
P4-T1: Extend hermes-mcp ✅
gbrain, mem0, and vault bridge tools exposed through hermes-mcp. Service active and verified.
P4-T2: Create unified .mcp.json ✅
Shared MCP config exists under this OpenSpec change.
Phase 5: Real-time Sync Propagation ✅
Problem
When a cloud agent wrote a vault file on server, the file changed on disk but mac and mobile did not receive it until someone committed and pushed through git. This made file-based plan tracking useless for live agent work.
Solution
Use CouchDB and Self-hosted LiveSync as the real-time layer. Git is backup and history, not the real-time path.
P5-T1: server headless LiveSync bridge ✅
server runs a native headless LiveSync CLI daemon with separate database path and vault path. Service is active, enabled, and reboot-safe. Verified bidirectional: server writes reach mac/mobile, mac/mobile writes reach server filesystem.
P5-T2: Database and vault path separation ✅
CLI database path (/srv/livesync-db) is separate from vault path (/srv/vault-write). This was the key fix that prevented config migration confusion.
P5-T3: server to mac/mobile verification ✅
server-written test lines appeared on mac and mobile without git commits. LiveSync daemon’s _changes feed pushes updates in real time.
P5-T4: Mac/mobile to server verification ✅
User edits on mac and phone are materialized into server filesystem through the LiveSync _changes feed. Verified with multiple test edits.
P5-T5: gbrain live re-index ✅
gbrain runs sync --full to refresh its index after filesystem changes. OpenRouter provider configured for embeddings. Service is active and covers 785 .md files.
Current remaining gaps
- Move LiveSync CLI source from
/opt/obsidian-livesyncto a durable path (e.g./srv/services/obsidian-livesync) - Normalize Machine and OpenCode mem0/gbrain/MCP access
- Decide how often Git snapshots should be committed now that CouchDB is the live sync layer
Safety rules
- Do not commit mass deletion sets from git status unless deletion intent is confirmed.
- Agents write only to
/srv/vault-write, never to/srv/livesync-db. - Git is backup and reviewable history, not the real-time transport.
Phase 0 results
Phase 0 Assessment Results — 2026-06-18
Updated 2026-06-20 with findings from the first repair session.
P0-T1: Mem0 Health ✅ (repaired 2026-06-20)
- Before repair: Mem0-new running but
/searchendpoint was broken.POST /memoriesandGET /memoriesroutes were missing from the deployed source. - Root cause: Two issues:
- The search endpoint passed
user_idas a top-level argument to the Mem0 SDK, but Mem0 v2.0.x requiresfilters={"user_id": "..."}instead. - The
/memoriesendpoints (POST,GET,GET /{memory_id}) were absent from the source file on server, possibly lost during a botched hot-patch attempt.
- The search endpoint passed
- Fix applied:
/searchnow mapsuser_id/run_id/agent_idinto thefiltersdict before calling Mem0 SDK.POST /memories,GET /memories, andGET /memories/{memory_id}were re-added to main.py.- Container rebuilt and redeployed.
- After repair verification:
- Internal (127.0.0.1:8888) add/search/list all succeeded.
- External (api.memory.goku.codes) add/search/list all succeeded.
- OpenAPI schema confirmed routes:
/memories(delete, get, post),/memories/{memory_id}(delete, get, put),/search(post). - All 4 containers healthy: mem0-new, mem0-dashboard, couchdb, couchdb-setup.
- Dashboard:
https://memory.example.comreturns 307 (redirect) and dashboard is healthy. - Auth: Auth setup endpoint returns 200 — X-API-Key auth is configured.
P0-T2: Supabase PG ✅
- PostgreSQL: 15.8 on aarch64
- DB size: 11 MB (tiny — plenty of room)
- pgvector: Available (extension exists)
- max_connections: 100
- Conclusion: More than enough for mem0 + gbrain to share
P0-T3: CouchDB Prerequisites ✅
- Port 5984: Free
- Docker: Available, multiple networks running (supabase_default, etc.)
- SSL: Handled by nginx, not Caddy. Let’s Encrypt cert active, expires 2026-09-16.
- CORS: Configured for
app://obsidian.md - Database:
vault-writeexists and is populated.- doc_count: 45857
- doc_del_count: 0
- sizes.active: 70318715
- sizes.file: 112329137
- Conclusion: CouchDB is deployed and healthy. Reachable at
https://couchdb.livesync.goku.codes.
P0-T4: gbrain Prerequisites ✅
- bun: v1.3.14
- Node: v22.21.1 (nvm-managed)
- Disk: 91G free
- Conclusion: Ready for gbrain install
P0-T5: Agent Profile Inventory
| Agent | mem0 tools | vault access | gbrain | delegation | Notes |
|---|---|---|---|---|---|
| mac/poke | Built-in mem0 tools (mem0_search, mem0_conclude) via hermes memory provider | Has obsidian skill (note-taking/obsidian) | MCP via hermes-mcp gateway | max_concurrent=30, depth=1 | Mem0 wired via config memory.provider: mem0 |
| server/poke | Same config as mac after copy | Same obsidian skill | Same | Same | Config merged. Has gateway running |
| server/Clawd | Separate profile, no mem0 skill | No direct vault | Same | Separate config | Runs as gateway |
| Machine (discord) | No mem0, no vault | No | No | No delegation | Wrapper runtime, limited toolset |
| hermes-mcp | Proxies mem0_add/search/list via extensions | Proxies vault_read/write/search via extensions | Proxies gbrain tools | N/A | SSE at mcp.example.com, bearer auth |
Updated gaps after 2026-06-20 session:
- Mem0 Hermes skill exists but wired via built-in provider config (memory.provider: mem0). Works on mac and server.
- gbrain integration: available through hermes-mcp gateway but not directly in every agent profile.
- Machine (discord) still has no memory tools at all.
- Unified MCP gateway exists at the shared MCP config but not deployed to all agents.
- New gap identified: real-time sync propagation is not defined or implemented.
P0-T6: Phase 1 Implementation Task List
Phase 1 — Deploy CouchDB + LiveSync
- Deploy CouchDB on server: ✅ Done
- SSL reverse proxy: ✅ Done (nginx + Let’s Encrypt)
- Install Obsidian LiveSync plugin: ⬜ Done at config level on server, user-side setup needed on mac (enable plugin, configure in obsidian)
- Verify bidirectional sync: ⬜ Partially verified. CouchDB is reachable, mac livesync config exists but not runtime-verified in this session.
Phase 2 — gbrain
- Install gbrain: ✅ Done
- Create gbrain DB: ✅ Done
- Init & sync: ✅ Done (798 pages, 4174 chunks)
- MCP server: ✅ Done
Phase 3 — Universal mem0
- Create shared mem0 Hermes skill: ✅ Done
- Wire into Clawd, Machine, agents: ⬜ Clawd has access through hermes-mcp gateway. Machine and OpenCode not yet wired.
Phase 4 — MCP Gateway
- Extend hermes-mcp: ✅ Done (13 extra tools, endpoint mappings corrected)
- Single .mcp.json: ✅ Done
Phase 5 — Real-time Sync (NEW)
- server filesystem change watcher: ⬜ Not started. Required for server-authored vault changes to propagate automatically.
- Mac auto-pull confidence: ⬜ Configured but requires obsidian runtime to be active.
- Mobile sync path definition: ⬜ Not defined. Mobile uses livesync, path from server author → mobile is indirect.
- gbrain indexing trigger: ⬜ Not defined. No event-driven re-indexing.
For the operational runbook on the server-side LiveSync setup, see unified-agent-memory-headless-livesync.