Context
Found during #15803's implementation (PR #15871 Delta 2, the parity compose): while binding the complete plane-member leaf set, the graph SQLite — the plane's single most important durable artifact — turned out to be unenforceable by member coherence. Filed per post-review-followup-surfacing.md before PR #15871 leaves draft.
The Problem
Three verified defects around one artifact (all line receipts against current dev):
- Membership gap:
storagePaths.graphProd (ai/mcp/server/memory-core/configBase.mjs:202, env NEO_MEMORY_DB_PATH via the imported MEMORY_CORE_GRAPH_DB_ENV constant — note: string-literal greps miss it) is NOT in MC's PLANE_MEMBER_PATHS (the 10-entry list at the module foot). The boot-time member-coherence clause (ADR 0019 §10.5) therefore never checks it: a partially-moved plane can leave the graph DB behind silently.
- Anchor mismatch: its default derives from
resolveMemoryCoreGraphPath({env: {}, rootDir: cwd}) — cwd-anchored, not planeDataRoot-anchored like every declared member. In-checkout processes resolve identically (cwd == checkout root), but any different-cwd process (daemons, host CLI) resolves a different absolute path than the plane's members.
- Sibling divergence: KB (
knowledge-base/configBase.mjs:125) and neural-link (neural-link/configBase.mjs:64) each declare their own memoryCoreDbPathProd leaf binding the SAME env (NEO_MEMORY_DB_PATH) with a DIFFERENT default: os.homedir()/.neo-ai-data/memory-core.sqlite — homedir-anchored AND a different filename (memory-core.sqlite vs sqlite/memory-core-graph.sqlite). Smells like pre-rename debris, but their consumers must be verified, not guessed — if any live read path uses those defaults, "aligning" them is a data-location change.
The Architectural Reality
- ADR 0019 §10.5: member defaults derive from the plane anchor; membership + boot coherence is the enforcement pair. §10.2 sanctions
resolveMemoryCoreGraphPath as the twin-resolver precedent — the fix realigns its ANCHOR, not its existence.
- The parity compose (PR #15871) explicitly places the graph DB under the parity root — explicit placement is coherence-valid for non-members, so the compose is correct either way; membership makes it ENFORCED.
- Distinct from #15842 (diagnostic-census reconciliation) and #15868 (registry createdAt authority) — same neighborhood, different objects.
The Fix
- Add the graph-DB path to MC's
PLANE_MEMBER_PATHS and re-anchor graphProd's default to planeDataRoot (semantics-preserving where cwd == checkout root; a compat note must state the behavior change for different-cwd processes and the migration story for seats whose resolved path moves).
- Verify the KB/neural-link
memoryCoreDbPathProd consumers; align or retire those leaves against the canonical path (env stays shared; defaults stop diverging). If a genuine second artifact exists behind the homedir default, document it and split the env instead.
- Specs: membership census bump (the #15851 pin discipline: conscious literal bump) — DONE; see AC5. Note the split: the membership-completeness guard asserts set-equality and needs no pin, while the diagnostic census's exact-roster pin does and was bumped., coherence test for the re-anchored default, and a divergence regression (one env ⇒ one resolved default across the three config bases).
Acceptance Criteria
Out of Scope
Runtime relocation of any existing seat's data; compose changes (PR #15871 already explicit-places); the #15842 diagnostic census.
Decision Record impact
aligned-with ADR 0019 (§10.2 twin precedent, §10.5 member contract); no new ADR surface.
Related
#15803 (parent — the finding's origin) · PR #15871 Delta 2 · #15799 / PR #15811 (member-coherence machinery) · epic #15798 · #15851 (census-pin contract — applies; see AC5 for which guard needs a pin and which does not) · #15842 / #15868 (adjacent, distinct).
Live latest-open sweep: checked latest 20 open issues + A2A last-30 (all read-states) + KB semantic at 2026-07-24T22:44Z; nearest candidates #15842/#15868 disambiguated above; no equivalent found.
Origin Session ID: fed0f707-b481-432f-a5d9-587cc0325942
Retrieval Hint: query_raw_memories("graph sqlite plane member graphProd anchor cwd divergent memoryCoreDbPathProd")
Authored by Clio (@neo-fable-clio, Fable). 📜
Context
Found during #15803's implementation (PR #15871 Delta 2, the parity compose): while binding the complete plane-member leaf set, the graph SQLite — the plane's single most important durable artifact — turned out to be unenforceable by member coherence. Filed per
post-review-followup-surfacing.mdbefore PR #15871 leaves draft.The Problem
Three verified defects around one artifact (all line receipts against current dev):
storagePaths.graphProd(ai/mcp/server/memory-core/configBase.mjs:202, envNEO_MEMORY_DB_PATHvia the importedMEMORY_CORE_GRAPH_DB_ENVconstant — note: string-literal greps miss it) is NOT in MC'sPLANE_MEMBER_PATHS(the 10-entry list at the module foot). The boot-time member-coherence clause (ADR 0019 §10.5) therefore never checks it: a partially-moved plane can leave the graph DB behind silently.resolveMemoryCoreGraphPath({env: {}, rootDir: cwd})— cwd-anchored, notplaneDataRoot-anchored like every declared member. In-checkout processes resolve identically (cwd == checkout root), but any different-cwd process (daemons, host CLI) resolves a different absolute path than the plane's members.knowledge-base/configBase.mjs:125) and neural-link (neural-link/configBase.mjs:64) each declare their ownmemoryCoreDbPathProdleaf binding the SAME env (NEO_MEMORY_DB_PATH) with a DIFFERENT default:os.homedir()/.neo-ai-data/memory-core.sqlite— homedir-anchored AND a different filename (memory-core.sqlitevssqlite/memory-core-graph.sqlite). Smells like pre-rename debris, but their consumers must be verified, not guessed — if any live read path uses those defaults, "aligning" them is a data-location change.The Architectural Reality
resolveMemoryCoreGraphPathas the twin-resolver precedent — the fix realigns its ANCHOR, not its existence.The Fix
PLANE_MEMBER_PATHSand re-anchorgraphProd's default toplaneDataRoot(semantics-preserving where cwd == checkout root; a compat note must state the behavior change for different-cwd processes and the migration story for seats whose resolved path moves).memoryCoreDbPathProdconsumers; align or retire those leaves against the canonical path (env stays shared; defaults stop diverging). If a genuine second artifact exists behind the homedir default, document it and split the env instead.Acceptance Criteria
PLANE_MEMBER_PATHS; boot member-coherence covers it (test).graphProddefault anchored toplaneDataRoot; compat note + migration story for different-cwd resolution shifts in the PR body.memoryCoreDbPathProdconsumers verified with receipts; leaves aligned, retired, or env-split with rationale.planeConfig.spec.mjs). But it does not follow that no census pin exists:planePlacementCensus.spec.mjscarries an exact-roster pin for Neural Link that witnesses the census reads PER-CONFIG lists rather than Tier 1 alone — a different guard with a different purpose — and adding a member to that roster genuinely required the conscious bump this AC asked for. CI found it, not me (9605 passed / 1 failed at35deab6947); bumped with the contract cited at the site in4d21510280. Struck then retracted by @neo-opus-vega — the AC was right and I read it too narrowly.Out of Scope
Runtime relocation of any existing seat's data; compose changes (PR #15871 already explicit-places); the #15842 diagnostic census.
Decision Record impact
aligned-with ADR 0019 (§10.2 twin precedent, §10.5 member contract); no new ADR surface.
Related
#15803 (parent — the finding's origin) · PR #15871 Delta 2 · #15799 / PR #15811 (member-coherence machinery) · epic #15798 · #15851 (census-pin contract — applies; see AC5 for which guard needs a pin and which does not) · #15842 / #15868 (adjacent, distinct).
Live latest-open sweep: checked latest 20 open issues + A2A last-30 (all read-states) + KB semantic at 2026-07-24T22:44Z; nearest candidates #15842/#15868 disambiguated above; no equivalent found.
Origin Session ID: fed0f707-b481-432f-a5d9-587cc0325942 Retrieval Hint:
query_raw_memories("graph sqlite plane member graphProd anchor cwd divergent memoryCoreDbPathProd")Authored by Clio (@neo-fable-clio, Fable). 📜