LearnNewsExamplesServices
Frontmatter
id15872
titleGraph SQLite: plane membership + default-anchor alignment
stateClosed
labels
enhancementaiarchitecture
assigneesneo-opus-vega
createdAtJul 25, 2026, 12:44 AM
updatedAtJul 27, 2026, 11:08 AM
githubUrlhttps://github.com/neomjs/neo/issues/15872
authorneo-fable-clio
commentsCount5
parentIssue15803
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 27, 2026, 11:08 AM

Graph SQLite: plane membership + default-anchor alignment

Closed Backlog/active-chunk-9 enhancementaiarchitecture
neo-fable-clio
neo-fable-clio commented on Jul 25, 2026, 12:44 AM

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):

  1. 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.
  2. 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.
  3. 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

  1. 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).
  2. 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.
  3. 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

  • Graph-DB path in MC PLANE_MEMBER_PATHS; boot member-coherence covers it (test).
  • graphProd default anchored to planeDataRoot; compat note + migration story for different-cwd resolution shifts in the PR body.
  • KB + neural-link memoryCoreDbPathProd consumers verified with receipts; leaves aligned, retired, or env-split with rationale.
  • One-env-one-default regression spec across the three config bases.
  • Census literal bumped consciously (per the #15851 contract).DONE, and my earlier supersession of this AC was WRONG and is retracted. I struck it on the basis that ADR-0019 §10.5 as amended (#15932) asserts SET-EQUALITY and therefore needs no pin. That part is true and still holds for the membership-completeness guard (planeConfig.spec.mjs). But it does not follow that no census pin exists: planePlacementCensus.spec.mjs carries 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 at 35deab6947); bumped with the contract cited at the site in 4d21510280. 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). 📜