Memory Fabric
This page covers Layer 7’s memory architecture: the tier taxonomy, the memory record envelope, the full memory lifecycle, the recall and promotion contracts, retention and erasure semantics, and the three memory control-plane agents that execute it. It is the architectural companion to the Memory Fabric Spec and ADR-OS-002.
Note on terminology. The Memory Fabric Spec calls the fabric a “seven-store” set (Redis, Supabase PG17, QuestDB, Neo4j, Qdrant, Langfuse, PostHog). The facts layer’s
platform_mappingassigns only five platforms to Layer 7 and places Langfuse and PostHog at Layer 10 (Observability). Both framings are defensible — the seven-store naming is the spec’s established vocabulary for the broader concept of memory stores including traces and events, while the five-store assignment is the platform-mapping claim about what Layer 7 owns. No memory record is write-authoritative in Langfuse or PostHog, and no memory tier maps to them. The seven-store naming is preserved because changing it would silently pick a winner between two legitimate but incompatible framings without an explicit decision. This disagreement is recorded as an open item at the end of this page.
Where this sits in the architecture
Layer 7 owns the memory fabric — the substrate stores and the control plane over them. This ADR’s decision (Option A) extends Layer 7 to additionally own the memory lifecycle: formation, consolidation, reflection, promotion, recall, decay and erasure. Layer count stays twelve; memory cognition is a control plane over persistence, not a peer layer beside it, in the same relationship Governance (Layer 9) has to execution.
The layer boundary for Layer 7 after this document:
| Before | After | |
|---|---|---|
| Owns | Transactional DBs, vector stores, graph stores, caches, audit state | The above, plus the memory lifecycle: formation, consolidation, reflection, promotion, recall mediation, decay, erasure |
| Must not own | Workflow sequencing, UI logic | The above, plus retention policy (Layer 12 sets the values) and context assembly (Layer 4 decides what a given run needs to know) |
The eight memory tiers
The tier axis answers what kind of memory a record is. It is orthogonal to the substrate axis (which store it lives in). Neither may be inferred from the other.
| Tier | Question it answers | Scope | Lifetime |
|---|---|---|---|
working | What is true right now, inside this run? | run / session | TTL-bound, never a source of truth |
episodic | What happened, and when? | cross-session | Durable, decays by policy |
semantic | What is true, independent of when it was learned? | cross-session | Durable |
procedural | How is this task done well? | cross-session | Durable, versioned |
profile | Who is this actor and what do they prefer? | subject-scoped | Durable, supersession-based |
relational | What is the canonical business state? | persistent | Durable, transactional |
graph | What is connected to what, and what caused what? | cross-session | Durable, append-oriented |
temporal | How has a measured quantity moved over time? | persistent | Durable, retention-windowed |
Tier definitions:
working— hot state for an in-flight run: task graph position, iteration counters, dedup windows, idempotency keys, in-session conversation buffer. Explicitly not a source of truth. A run that cannot be reconstructed from durable tiers after working memory is lost is non-compliant.episodic— a record of something that occurred: an interaction, a decision, a tool call outcome, an approval. The raw material every other durable tier is derived from, and the tier that carries the strongest lineage obligation.semantic— a durable assertion abstracted away from the episode that produced it. Alwaysderived_fromat least one episodic record.procedural— a reusable method: a distilled skill, a task recipe, a validated tool sequence. Versioned rather than overwritten, so a run can be replayed against the procedure that was current at the time.profile— durable assertions about a subject (a user, an operator, a counterparty, an agent). Governed by supersession, never in-place mutation.relational— canonical business entities and their transactional state. The only tier a domain pack co-owns.- graph — relationships, entity links, and causal lineage: which agent influenced which outcome, which reasoning step touched which entity. This is the tier that Academy 02.8 identifies as having no framework home; §3.4 gives it one.
temporal— time-series measurements and their aggregations, consumed by intelligence agents.
Tier → substrate mapping
| Tier | Write-authoritative store | Projections / indexes |
|---|---|---|
working | Redis | LangGraph checkpointer |
episodic | Supabase PG17 | Qdrant (semantic index) |
semantic | Supabase PG17 | Qdrant |
procedural | Supabase PG17 | Qdrant |
profile | Supabase PG17 | Qdrant, Neo4j (subject node) |
relational | Supabase PG17 | Neo4j (entity projection) |
graph | Supabase PG17 (lineage) / Neo4j (entities, via NAMS) | Neo4j |
temporal | QuestDB | — |
Two invariants follow directly:
- Supabase PG17 is write-authoritative for every audit-bearing tier. Qdrant, Neo4j and the LangGraph store are projections. Wiping any projection and rebuilding from Supabase must produce identical behaviour.
- Qdrant is the single semantic vector substrate. No second vector store enters Layer 7. NAMS’s own vector index is scoped to entity resolution inside the graph tier and is not a general retrieval path.
Qdrant collection contract
The runtime integration guide v0.3 codifies the collection naming, payload fields and point-identity rules for fabric tiers, including the operational collections class.
Fabric tier collections — one collection per tier; scope lives in the payload, not the collection name:
| Collection | Tier |
|---|---|
mem_episodic | episodic |
mem_semantic | semantic |
mem_procedural | procedural |
mem_profile | profile |
KB / consumer collections are a separate class (example: synedrix_os_kb). Each consumer owns a dedicated collection and MUST NOT share a fabric tier collection. The same payload rules apply where the point represents a memory record.
Operational collections are a third class: the domain-owned operational stores of Memory Fabric Spec §3.6. They sit outside the eight tiers and the mem_* and KB rules above do not apply to them:
- Name:
ops_<domain-pack-id>_<store>(for exampleops_trd_regime_fingerprints). Nevermem_*, and never a fabric tier or KB collection. Each belongs to one domain pack. - Point identity: a deterministic UUIDv5 where
nameis the UTF-8 string formed bytenant_id, thenbusiness_instance_id(empty string for tenant-level records), then each domain-key component, joined by the ASCII unit separatorU+001F. It is never amemory_id, andtenant_idis part of the ID so two tenants cannot address each other’s points. Writes are idempotent upserts on that ID. - Tenant isolation:
tenant_idis a required indexed payload field and a mandatory filter on every query and write. Where the source data is business-instance-owned,business_instance_idis also a required indexed payload field and a mandatory filter. - Authorization: collection-scoped Qdrant credentials (JWT
r/rwper collection) are issued to the declared writer workflow and to readers. No agent holds a credential that spans an operational and amem_*collection. - Rebuild: from the source the domain pack declares for that collection, never from
memory_records. The embedding model, model version and dimension are part of the collection contract. - Not recalled as memory: read by a bound domain tool, never through the recall contract.
Point identity: for fabric projections, the Qdrant point id MUST be the memory_id UUID string from memory_records.
Required payload fields (indexed for filterable search): memory_id (string UUID, equals point id), tenant_id, tier, visibility, scope_type, scope_id, subject_id, agent_id, session_id, content_hash, confidence, valid_from, valid_until, consolidation_state, retention_class, compliance_labels, version.
Recall queries MUST push tenant_id and the applicable scope filter into Qdrant payload filters. Post-filtering a full tenant result set for scope is forbidden — out-of-scope memory that has already entered the process has already leaked.
The memory record envelope
Every governed memory record carries a structured envelope. It mirrors the 14-field common event envelope so memory lineage and event lineage compose without translation.
| Field | Type | Required | Description |
|---|---|---|---|
memory_id | string (UUID) | Yes | Globally unique record identifier. Stable across supersession. |
tier | string | Yes | One of the eight tiers. |
scope | object | Yes | Ownership and visibility. |
content | object | Yes | The memory payload. Shape is tier-specific. |
content_hash | string | Yes | Hash of content, for dedup and tombstone verification. |
provenance | object | Yes | What produced this record. |
derived_from | array[string] | Yes | memory_ids this record was consolidated or reflected from. |
confidence | number (0–1) | Yes | Extraction or inference confidence. |
validity_interval | object | Yes | { valid_from, valid_until } ISO 8601 UTC. |
supersedes | string | null | Yes | The memory_id this record replaces. |
retention_class | string | Yes | One of the retention classes. |
compliance_labels | array[string] | No | Regulatory tags (pii, pci, gdpr-subject). |
version | string (SemVer) | Yes | Record schema version. |
Scope
tenant_id is mandatory and always first in every scope tuple and every store namespace. A namespace assembled in the wrong order under-matches and returns nothing, rather than over-matching and returning another tenant’s memory. visibility is one of session, agent, subject, tenant — and there is no cross-tenant visibility value.
Provenance
formation_method is one of extraction, declaration, consolidation, reflection or import. A memory record with no provenance.source_event_id is non-compliant. There is no path by which memory enters the fabric without an event having caused it.
The memory lifecycle
The lifecycle state machine governs how records move through the fabric.
Stages and authority
| Stage | What happens | Who may trigger | Who commits | Event emitted |
|---|---|---|---|---|
| capture | A source event carries content eligible to become memory. | Any workflow or agent | — | (the source event) |
| formation | Content becomes a raw memory record with a full envelope. | Any agent (as a proposal) | os-agt-010 | memory.record.formed |
| consolidation | Several records merge into one derived record. | os-agt-011 (recommends) | os-agt-010 | memory.record.consolidated |
| reflection | A higher-order assertion is inferred — a profile trait, a distilled skill. | os-agt-011 (recommends) | os-agt-010 | memory.reflection.completed, memory.skill.distilled |
| promotion | A record moves to a longer-lived tier. | os-agt-011 or a workflow | os-agt-010, gated by os-agt-012 | memory.record.promoted |
| recall | A record is read into an agent’s context. | Any agent, as a tool call | — (read) | memory.recall.requested / .served / .denied |
| decay | validity_interval expires or a retention window closes. | Scheduler | os-agt-010 | memory.record.expired |
| demotion | A record’s tier or visibility is reduced. | os-agt-011 | os-agt-010 | memory.record.demoted |
| erasure | Content is destroyed; a tombstone remains. | Human or compliance workflow | os-agt-010, approved by os-agt-002 | memory.record.forgotten |
The separation of authority is the point. os-agt-011 recommends, os-agt-010 executes, os-agt-012 approves access. No agent both proposes and commits durable memory — the same shape the OS uses to keep Policy Guard in front of side effects.
Hot path versus background
| Stage | Path | Rationale |
|---|---|---|
| capture, formation proposal, recall | Hot path | The agent needs the result now; latency counts against its budget. |
| formation commit, consolidation, reflection, decay, demotion | Background, scheduled | LLM-backed, latency-tolerant, must not block a reasoning step. Runs as WF-OS-MEMORY-CONSOLIDATE. |
| erasure | Out of band, approval-gated | A compliance action with its own workflow and SLA. |
Recall as a governed tool call
Ambient memory injection is non-compliant. A memory read is a tool call bound in the agent’s active_tool_set, resolved through the three-layer tool authorization model, traced to Langfuse, and rejectable with agent.tool.unauthorized like any other tool.
The canonical tool identifiers are tool:memory-recall (read) and tool:memory-propose (write proposal). An agent with neither in its resolved active set has no memory access.
sequenceDiagram
participant Agent
participant Broker as os-agt-012<br/>(Memory Access Broker)
participant Policy as os-agt-002<br/>(Policy Guard)
participant Store as SynedrixMemoryStore
participant Lf as Langfuse
Agent->>Broker: tool:memory-recall<br/>(tiers, scope, query, filters)
Broker->>Broker: intersect request scope<br/>with memory_profile.recall_scope
alt scope denied or tier access denied
Broker-->>Agent: memory.recall.denied
Broker->>Lf: emit denial event
else scope granted
Broker->>Store: query with filter predicates<br/>(pushed down, not post-hoc)
Store-->>Broker: records with provenance + validity_interval
Broker-->>Agent: memory.recall.served + records
Broker->>Lf: emit served event + span
end
Resolution rules
Rule 5 is a retrieval-quality mechanism as much as a security one. Semantic interference, not context length, is the binding constraint on evidence access — narrowing the candidate set before ranking is the single highest-leverage retrieval decision, and it happens to be the same seam as authorization.
The promotion contract
No memory record crosses a tier boundary without a memory.record.promoted event carrying the record’s correlation_id and causation_id unchanged. This generalises the rule the OS already held for exactly one case — that conversation memory is never promoted to long-term semantic memory without an explicit handoff event — to every tier pair.
Legal promotions
| From | To | Typical trigger | Gate |
|---|---|---|---|
working | episodic | Session handoff, run completion | os-agt-012 scope check |
episodic | semantic | Consolidation over ≥ N corroborating episodes | Confidence threshold + os-agt-012 |
episodic | procedural | Skill distillation from repeated successful trajectories | Confidence threshold + os-agt-012 |
episodic | profile | Reflection over subject-scoped episodes | os-agt-012 + subject consent labels |
semantic | relational | An assertion becomes canonical business state | os-agt-002 policy approval |
| any | any, with widened visibility | Broadening from session → agent → subject → tenant | os-agt-012 per step |
Demotion is always legal and always logged (memory.record.demoted). Narrowing scope needs no approval; widening it does.
Promotions that require policy approval
approval_required.policy: true applies to:
- Any promotion into
relational— this writes canonical business state. - Any promotion that would widen
visibilitybeyondtenant. - Any promotion of a record carrying a regulated
compliance_labelsvalue into a longer-retention class. - Any erasure.
Thresholds
The mechanism — that a threshold is consulted before promotion — is OS-owned and specified here. The values (minimum corroborating episodes, minimum confidence, minimum successful trajectories before a skill is distilled) are business-instance configuration, per the rule of inclusion. A domain pack may declare defaults; only the instance may set them.
Retention, decay and erasure
Retention classes
| Class | Decay behaviour | Erasable | Typical tiers |
|---|---|---|---|
ephemeral | TTL, hard expiry | n/a — expires | working |
session | Expires at session close unless promoted | Yes | working |
operational | Windowed retention, then aggregation | Yes | temporal, episodic |
durable | No automatic expiry; decays only by supersession | Yes | semantic, procedural, profile |
audit | Never decays. Append-only. | Only via erasure tombstone | episodic (audit records), graph (lineage) |
regulated | Retention floor and ceiling set by compliance | Mandatory at ceiling | any, driven by compliance_labels |
The Layer 7 / Layer 12 boundary
Layer 7 owns the retention mechanism: what a retention class means, how decay executes, what a tombstone is. Layer 12 (business instance) owns the retention values: how long operational is, what the regulated floor and ceiling are for a given jurisdiction.
Checkpoint retention must exceed the longest approval timeout. A checkpoint that expires before its approval does leaves an approved action with no run to resume.
Decay
Decay is scheduled, never opportunistic. Two mechanisms:
- Interval expiry —
validity_interval.valid_untilpasses. The record stops being returned by recall but remains readable for audit and remains inderived_fromchains. - Retention window closure — the retention class’s window closes.
operationalrecords may be aggregated into atemporalsummary before removal.
Both emit memory.record.expired. Neither destroys lineage.
Erasure and the tombstone rule
Forgetting is an approved action that leaves a tombstone.
When a tenant exercises a right to erasure, or a regulated retention ceiling is reached:
- The request is approved by
os-agt-002and executed byos-agt-010. contentis destroyed in the write-authoritative store and in every projection — Qdrant points deleted, Neo4j property values cleared, checkpoints purged.- A tombstone is written in canonical memory retaining:
memory_id,tier,scope.tenant_id,content_hash,provenance,derived_from,validity_interval, the erasure approval reference, and the erasure timestamp.consolidation_statebecomestombstoned. - The lineage edges in graph memory survive — the shape of what happened remains, with the content gone.
memory.record.forgottenis emitted.
A deletion must never silently punch a hole in the audit trail. content_hash is retained so a later claim about what the record contained can be checked without the content being present. Records with derived_from pointing at a tombstoned record are not cascaded automatically; they are flagged for review by os-agt-011.
The three memory control-plane agents
Three OS-owned agents implement the memory control plane. They are registered in the Agent Registry.
os-agt-010 — Memory Curator Agent
- Family: Control · Layer: 7 · Canonical ID:
os-ctl-memory-curator-001 - Mission: Commit every durable memory record on behalf of the agents that propose them — forming, consolidating, promoting, expiring and erasing records under the memory lifecycle.
- Decision scope:
execute— the only agent permitted to commit durable memory records. - Authority boundary: The Memory Curator commits but never decides what should be remembered. Formation and consolidation proposals originate elsewhere, and the Curator’s role is to validate the envelope, enforce provenance, apply the write across the write-authoritative store and its projections, and emit the event. It has no authority to originate a memory record of its own. It may never destroy lineage: erasure removes content and leaves a tombstone.
- Approval required: broker (
os-agt-012) for every operation; policy (os-agt-002) for erasure, promotion intorelational, visibility widening beyondtenant, and promotion of records carrying regulatedcompliance_labels. - Risk tier:
critical— per ADR-OS-017,criticalagents require blocking policy compliance checks, a 1.0 compliance rate and strict observability. - Runtime engine:
n8n-aiagent— commits are deterministic. - Owner workflows:
WF-OS-MEMORY-CONSOLIDATE,WF-OS-MEMORY-ERASURE.
os-agt-011 — Consolidation & Reflection Agent
- Family: Intelligence · Layer: 7 · Canonical ID:
os-int-memory-consolidation-001 - Mission: Analyse accumulated memory records to propose consolidations, higher-order reflections, distilled procedural skills, tier promotions and conflict resolutions — producing recommendations only, never writes.
- Decision scope:
recommend— proposes consolidations, reflections, skills and promotions; commits nothing. - Authority boundary: Reads broadly and writes nothing. Reading broadly is precisely why it holds no write authority: an agent that can both survey the whole fabric and commit to it could rewrite memory to match its own inference without a second opinion. Every proposal it emits is a recommendation carrying its
derived_fromchain and rationale, and is only durable onceos-agt-012has scoped it andos-agt-010has committed it. - Approval required: none for proposals (it triggers no side effects).
- Runtime engine:
langgraph— consolidation isreflect-and-revise. - Owner workflows:
WF-OS-MEMORY-CONSOLIDATE.
os-agt-012 — Memory Access Broker Agent
- Family: Control · Layer: 9 · Canonical ID:
os-ctl-memory-broker-001 - Mission: Mediate every memory recall and every memory write proposal, resolving the requester’s declared scope against its
memory_profilebefore any store is queried, and emitting an allow, partial or deny decision. - Decision scope:
approve— validates and blocks memory access; performs no reads of memory content and no writes to memory records. - Authority boundary: The Memory Access Broker decides whether and at what scope memory may be read or written, and never sees the memory content itself. That separation is deliberate: the broker is on the path of every recall in the system, so granting it content access would make it the single most privileged reader in the OS. It resolves scope before the store is queried and returns filter predicates that are pushed down into the query — it never inspects and filters results after retrieval. A denial is terminal; the requesting agent escalates rather than reissuing a narrowed request automatically.
- Memory scope: Canonical memory: read (memory profile and registry tables only). No access to memory record content in any tier.
- Risk tier:
critical— per ADR-OS-017,criticalagents require blocking policy compliance checks, a 1.0 compliance rate and strict observability. - Runtime engine:
n8n-aiagent— deterministic scope intersection. - Owner workflows:
WF-OS-MEMORY-RECALL,WF-OS-MEMORY-CONSOLIDATE,WF-OS-MEMORY-ERASURE.
Control-plane interaction pattern
sequenceDiagram
participant A as Agent (any)
participant B as os-agt-012<br/>(Broker)
participant P as os-agt-002<br/>(Policy Guard)
participant C as os-agt-010<br/>(Curator)
participant CR as os-agt-011<br/>(Consolidation)
participant S as Supabase / Qdrant / Neo4j
Note over A,S: Recall path (hot path)
A->>B: tool:memory-recall (tiers, scope, query)
B->>B: intersect scope with memory_profile.recall_scope
B->>S: query with filter predicates (pushed down)
S-->>B: records with provenance + validity
B-->>A: served / denied + records
Note over A,S: Formation proposal path (hot + background)
A->>B: tool:memory-propose (content, tier)
B-->>A: proposal_id
Note over CR,P: Background: WF-OS-MEMORY-CONSOLIDATE
CR->>S: fetch uncommitted proposals + candidates
CR->>CR: reflect-and-revise (LangGraph)
CR->>B: propose consolidation / promotion
B->>S: scope-validate proposals
alt promotion requires policy approval
B->>P: policy gate
P-->>B: allow / block
end
B->>C: commit approved proposals
C->>S: write to write-authoritative store + projections
C->>S: emit memory.record.* events
Three things in this path are load-bearing. Scope resolution happens before the store is queried, not after results return. The proposal path is asynchronous by design, so an agent never waits on extraction. And the commit is separated from the recommendation, so the agent that surveys the whole fabric (os-agt-011) is not the agent that can rewrite it.
Conflict and contradiction
The fabric resolves contradictions by supersession, never by silent deletion.
| Situation | Resolution |
|---|---|
Two records overlap in validity_interval and disagree | memory.conflict.detected is emitted. Neither is returned as authoritative until os-agt-011 proposes a resolution. Recall returns both with their confidences, flagged. |
| Confidences are close and provenance differs | Higher confidence wins only if the margin exceeds the instance’s threshold; otherwise it escalates. declaration outranks extraction at equal confidence. |
The design commitment: the fabric never resolves a contradiction by destroying evidence.
Domain-owned operational stores
A domain pack may keep a Qdrant collection or Neo4j graph that is not memory. It is a domain-owned operational store: a derived, query-optimised index over data the domain pack already holds in its own write-authoritative schema, built so that a workflow can run a similarity match or a graph traversal at the latency the domain needs. It sits outside the eight tiers, and writes to it by a domain workflow are not memory commits — invariant 4 does not apply.
A store qualifies only if all four conditions hold:
- Not recalled as agent memory. It is read by a workflow step as a bound domain tool, such as
qdrant-queryorneo4j-query. It is never exposed through the recall contract, never injected as ambient context, and never offered to an agent as a way to retrieve what it or another agent “remembers”. - Rebuildable. Every record in it is derived from a source the store does not own: a retained, replayable source: the domain pack’s own write-authoritative store, or an external feed whose history the pack retains and names with the model version used to derive the records. Wiping the store and rebuilding it from that source must produce identical behaviour. It is never the record of truth for anything.
- Tenant-namespaced. Every collection, point payload, node and edge that holds tenant content carries
tenant_idas the leading key or label. Cross-tenant reads fail closed. - No silent formation. Nothing in it becomes a memory record by being read or copied. A fact that an agent wants the fabric to keep is proposed through
tool:memory-proposeand committed byos-agt-010as a newrawrecord — formation, not promotion:memory.record.promotedis reserved for the later transition of the resulting record between tiers.
A store that fails any condition is governed memory and must be written through os-agt-010 into memory_records with Qdrant and Neo4j as projections.
Qdrant remains the single semantic vector substrate: a domain-owned collection is another collection in that same Qdrant. Its naming, point identity and rebuild rules are set in the Memory Runtime Integration Guide: collections use the ops_<domain-pack-id>_<store> naming convention, point identity is a deterministic UUIDv5, and rebuild flows from the domain pack’s declared source rather than memory_records.
Governance invariants
These are enforced and must never be violated:
- No memory record crosses a tier boundary without a
memory.record.promotedevent carryingcorrelation_idandcausation_idunchanged. - Recall is a tool call. Memory reads are bound in
active_tool_setand pass the three-layer tool authorization model. Ambient memory injection is non-compliant. - Every memory record has
provenance.source_event_id. Memory never enters the fabric uncaused. - Only
os-agt-010commits durable memory. Every other agent proposes. Writes toepisodic,semantic,proceduralandprofilefrom any other agent are non-compliant. os-agt-012is on the path of every recall and every write proposal. Scope resolution happens before retrieval, never after.- Supabase PG17 is write-authoritative for every audit-bearing tier. Qdrant, Neo4j and the LangGraph store are projections; wiping and rebuilding a projection must not change behaviour.
- Qdrant is the single semantic vector substrate. No second vector store enters Layer 7.
- Erasure leaves a tombstone; lineage in graph memory survives erasure of content.
workingmemory is never a source of truth. A run that cannot be reconstructed from durable tiers after working memory is lost is non-compliant.- Contradictions are resolved by supersession, never by deletion.
os-agt-008(Audit & Lineage) remains read-only and must never appear in any agent’stools_allowedlist, including as a memory tool.tenant_idis first in every scope tuple and every store namespace, so a malformed scope fails closed.- A domain-owned operational store is never memory. It must be rebuildable from a retained source it does not own, tenant-namespaced, never recalled as agent memory, and never turned into a memory record except through
memory-propose(which forms it as a new record). A store that fails any of these is governed memory and routes throughos-agt-010.
Deployment modes
Every tier must be satisfiable in Mode 3 (air-gapped). Nothing in this specification requires an external service.
| Concern | Mode 1 (cloud-connected) | Mode 2 (self-hosted hybrid) | Mode 3 (air-gapped) |
|---|---|---|---|
| Stores | All self-hosted | All self-hosted | All self-hosted |
| Extraction / consolidation inference | Cloud model APIs permitted | Per-agent split, declared in runtime policy | Local only (Ollama / vLLM) |
| Embeddings for the Qdrant index | Cloud embedding APIs permitted | Per-agent split | Local only |
| NAMS | Self-hosted bolt against the OS Neo4j | Same | Same. MEMORY_LLM / MEMORY_EMBEDDING must resolve to local URIs |
| NAMS hosted service | Not permitted in any mode | — | — |
Air-gapped invariant. A business instance declared deployment_mode: air-gapped must not contain any memory control-plane configuration with a cloud model or embedding URI. This is a configuration validation error, not a warning.
Consolidation compute budget. In Mode 3, background consolidation and reflection compete with agent inference for the same local GPUs. The scheduling window and compute budget are business-instance configuration; the control plane must degrade by deferring background stages, never by skipping the governance path.
Adopted and rejected external systems
| System | Position | Reason |
|---|---|---|
NAMS (neo4j-labs/agent-memory, Apache 2.0) | Adopted as a library over the existing Neo4j | Runs on infrastructure the OS already operates; supplies the graph tier’s ontology and reasoning-to-entity edges. Not a platform row — the LangChain precedent. |
| NAMS hosted service | Rejected | Proprietary SaaS; breaks Principle 11 and Mode 3 — the LangSmith precedent. |
| EverOS model (episode → consolidation → profile/skill distillation) | Adopted as the canonical lifecycle | Implemented on the existing fabric in §5. |
| EverOS runtime (Markdown + SQLite + LanceDB) | Rejected from canon | LanceDB duplicates Qdrant; SQLite duplicates Supabase; Markdown-as-truth contests Supabase’s write-authoritative role. Evaluated under the governed lab lane as LAB-001 in the stack repository. |
LangGraph BaseStore | Interface adopted, implementation OS-owned | The compliance seam where authorization, lineage and retention are enforced. Stock implementations are not canonical. |
| EverMemBench / EverMemBench-S / LoCoMo / LongMemEval | Adopted as the memory evaluation harness | Hooked into the existing Agent Evaluation Spec rather than replaced by a bespoke suite. |
Open items
- NAMS project maturity. Experimental Neo4j Labs project, community-supported, no SLA. Version pinning and an exit path are required before production use.
- Licence verification. EverOS and NAMS both read Apache 2.0 from their repositories; re-verify at source per the platform-page convention before recording a licence position.
- Procedural memory evaluation. Whether a distilled skill improved outcomes is an evaluation question the Agent Evaluation Spec does not yet cover. Needs a promotion gate of its own.
- The “seven-store memory fabric” vs five-store Layer 7 assignment. The Memory Fabric Spec’s Overview and the facts layer’s
platform_mappingdisagree on whether Langfuse and PostHog are part of the Layer 7 fabric. No rule, tier, envelope field or invariant changes are required — reconciling requires an explicit decision to one framing in the other documents.
Related pages
- Overview — The 12 canonical layers, including Layer 7.
- Agent Runtime & Orchestration — Layer 3 (n8n) and Layer 4 (LangGraph) where the memory agents execute.
- Domain Packs Overview — How domain packs contribute memory content without owning the lifecycle.
- ADR-OS-002 — The decision that created this architecture.
- Memory Fabric Spec — The normative specification this page describes.
- Memory Runtime Integration Guide — The Layer 4 ↔ Layer 7 binding:
SynedrixMemoryStore, NAMS client, operational collections, compliance checklist. - Agent Registry — Full definitions of os-agt-010, os-agt-011, os-agt-012.
- Agent Spec —
memory_profileis the per-agent security boundary. - Agent Runtime Policy Spec — The three-layer tool authorization model recall passes through.
- Tech Stack — Layer 7 platform mapping and the twelve-platform non-overlap rule.