Context
ADR 0003 (learn/agentos/decisions/0003-chroma-topology-unified-only.md) unified the Chroma topology: ONE daemon persists to a single dir (.neo-ai-data/chroma/knowledge-base, the orchestrator's --path in ai/daemons/orchestrator/TaskDefinitions.mjs). Both Knowledge Base and Memory Core are CLIENTS of that one daemon; Memory Core has no separate persist dir.
ai/scripts/maintenance/defragChromaDB.mjs exposes per-target defrag (ai:defrag-kb, ai:defrag-memory). Its TARGETS map adapts each subsystem's config into {host, path, port, collections}.
Problem
The memory-core target adapter resolves the physical path from engines.chroma.dataDir:
ai/mcp/server/memory-core/config.template.mjs → dataDir: .neo-ai-data/chroma/memory-core — a stale, pre-ADR-0003 path that no longer exists in the unified store.
Observable behavior today: ai:defrag-memory hard-exits with code 1 at the path-existence guard (defragChromaDB.mjs:343-346) because .neo-ai-data/chroma/memory-core does not exist. The command is broken, not a silent no-op.
Latent (more dangerous) behavior if that dir DID exist: the extract phase connects via host/port (lines 371-373) — i.e. to the live unified daemon, reading the RIGHT data — but every PHYSICAL operation keys off the stale DB_PATH: the pre-nuke snapshot copy (defragChromaDB.mjs:363), the initial/final size checks, and the orphan-segment cleanup all operate on the wrong directory. Connection (correct) and physical ops (wrong dir) diverge.
Architectural Reality
In the unified store there is exactly ONE persist dir. ai:defrag-kb already targets it correctly (knowledge-base config path: .neo-ai-data/chroma/knowledge-base). The memory-core target must resolve its physical path to that SAME unified persist dir — the one the orchestrator launches the daemon with — because MC's collections live there, not in engines.chroma.dataDir.
Prescription (single)
Resolve the memory-core defrag target's physical path to the unified persist dir (the orchestrator's Chroma --path SSOT), not engines.chroma.dataDir. Source it from the single source of truth rather than duplicating a hardcoded literal — no hidden fallback (|| / ?? / DEFAULT_*); config is SSOT.
Contract Ledger
| Surface |
Consumer |
Contract |
Status |
ai:defrag-memory CLI command |
operator (manual); #12138 orchestrator recycle chain |
Operates on the live unified persist dir; recreates MC collections; compacts the shared store safely (per #12140 segment-registry keep-set) |
BROKEN — targets stale memory-core dir, hard-exits |
memory-core TARGETS adapter .path |
defragChromaDB.mjs physical ops (snapshot / size / orphan-clean) |
Equals the unified persist dir |
BROKEN |
Acceptance Criteria
ai:defrag-memory resolves its physical path to the unified persist dir (the orchestrator daemon's --path), verified by a passing run against the live store (extract + snapshot + compaction all act on the unified dir).
- The path is sourced from the SSOT — not a duplicated hardcoded literal and not a hidden
|| / ?? / DEFAULT_* fallback.
ai:defrag-kb behavior is unchanged (it already targets the unified dir).
- Unit coverage for the
memory-core adapter asserting .path equals the unified persist dir (the same SSOT ai:defrag-kb resolves), so the disjoint-path regression cannot silently return.
Out of Scope
- Whether per-subsystem defrag targets remain meaningful when KB and MC share one physical store (separate question; not blocking this fix).
- The #12140 segment-registry keep-set (already shipped).
Related
- Prerequisite sibling: #12140 (unified-store-safe orphan keep-set), PR #12141.
- Consumer: #12138 (Chroma recycle chain) will invoke defrag commands.
- ADR:
learn/agentos/decisions/0003-chroma-topology-unified-only.md.
Origin Session ID: f6a4a820-1d95-40e7-910f-b47ad68f51f8
Context
ADR 0003 (
learn/agentos/decisions/0003-chroma-topology-unified-only.md) unified the Chroma topology: ONE daemon persists to a single dir (.neo-ai-data/chroma/knowledge-base, the orchestrator's--pathinai/daemons/orchestrator/TaskDefinitions.mjs). Both Knowledge Base and Memory Core are CLIENTS of that one daemon; Memory Core has no separate persist dir.ai/scripts/maintenance/defragChromaDB.mjsexposes per-target defrag (ai:defrag-kb,ai:defrag-memory). ItsTARGETSmap adapts each subsystem's config into{host, path, port, collections}.Problem
The
memory-coretarget adapter resolves the physicalpathfromengines.chroma.dataDir:ai/mcp/server/memory-core/config.template.mjs→dataDir: .neo-ai-data/chroma/memory-core— a stale, pre-ADR-0003 path that no longer exists in the unified store.Observable behavior today:
ai:defrag-memoryhard-exits with code 1 at the path-existence guard (defragChromaDB.mjs:343-346) because.neo-ai-data/chroma/memory-coredoes not exist. The command is broken, not a silent no-op.Latent (more dangerous) behavior if that dir DID exist: the extract phase connects via
host/port(lines 371-373) — i.e. to the live unified daemon, reading the RIGHT data — but every PHYSICAL operation keys off the staleDB_PATH: the pre-nuke snapshot copy (defragChromaDB.mjs:363), the initial/final size checks, and the orphan-segment cleanup all operate on the wrong directory. Connection (correct) and physical ops (wrong dir) diverge.Architectural Reality
In the unified store there is exactly ONE persist dir.
ai:defrag-kbalready targets it correctly (knowledge-baseconfigpath: .neo-ai-data/chroma/knowledge-base). Thememory-coretarget must resolve its physicalpathto that SAME unified persist dir — the one the orchestrator launches the daemon with — because MC's collections live there, not inengines.chroma.dataDir.Prescription (single)
Resolve the
memory-coredefrag target's physicalpathto the unified persist dir (the orchestrator's Chroma--pathSSOT), notengines.chroma.dataDir. Source it from the single source of truth rather than duplicating a hardcoded literal — no hidden fallback (||/??/DEFAULT_*); config is SSOT.Contract Ledger
ai:defrag-memoryCLI commandmemory-coredir, hard-exitsmemory-coreTARGETSadapter.pathdefragChromaDB.mjsphysical ops (snapshot / size / orphan-clean)Acceptance Criteria
ai:defrag-memoryresolves its physicalpathto the unified persist dir (the orchestrator daemon's--path), verified by a passing run against the live store (extract + snapshot + compaction all act on the unified dir).||/??/DEFAULT_*fallback.ai:defrag-kbbehavior is unchanged (it already targets the unified dir).memory-coreadapter asserting.pathequals the unified persist dir (the same SSOTai:defrag-kbresolves), so the disjoint-path regression cannot silently return.Out of Scope
Related
learn/agentos/decisions/0003-chroma-topology-unified-only.md.Origin Session ID: f6a4a820-1d95-40e7-910f-b47ad68f51f8