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_mapping assigns 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:

BeforeAfter
OwnsTransactional DBs, vector stores, graph stores, caches, audit stateThe above, plus the memory lifecycle: formation, consolidation, reflection, promotion, recall mediation, decay, erasure
Must not ownWorkflow sequencing, UI logicThe 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.

TierQuestion it answersScopeLifetime
workingWhat is true right now, inside this run?run / sessionTTL-bound, never a source of truth
episodicWhat happened, and when?cross-sessionDurable, decays by policy
semanticWhat is true, independent of when it was learned?cross-sessionDurable
proceduralHow is this task done well?cross-sessionDurable, versioned
profileWho is this actor and what do they prefer?subject-scopedDurable, supersession-based
relationalWhat is the canonical business state?persistentDurable, transactional
graphWhat is connected to what, and what caused what?cross-sessionDurable, append-oriented
temporalHow has a measured quantity moved over time?persistentDurable, 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. Always derived_from at 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

TierWrite-authoritative storeProjections / indexes
workingRedisLangGraph checkpointer
episodicSupabase PG17Qdrant (semantic index)
semanticSupabase PG17Qdrant
proceduralSupabase PG17Qdrant
profileSupabase PG17Qdrant, Neo4j (subject node)
relationalSupabase PG17Neo4j (entity projection)
graphSupabase PG17 (lineage) / Neo4j (entities, via NAMS)Neo4j
temporalQuestDB—

Two invariants follow directly:

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

CollectionTier
mem_episodicepisodic
mem_semanticsemantic
mem_proceduralprocedural
mem_profileprofile

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 example ops_trd_regime_fingerprints). Never mem_*, and never a fabric tier or KB collection. Each belongs to one domain pack.
  • Point identity: a deterministic UUIDv5 where name is the UTF-8 string formed by tenant_id, then business_instance_id (empty string for tenant-level records), then each domain-key component, joined by the ASCII unit separator U+001F. It is never a memory_id, and tenant_id is part of the ID so two tenants cannot address each other’s points. Writes are idempotent upserts on that ID.
  • Tenant isolation: tenant_id is a required indexed payload field and a mandatory filter on every query and write. Where the source data is business-instance-owned, business_instance_id is also a required indexed payload field and a mandatory filter.
  • Authorization: collection-scoped Qdrant credentials (JWT r/rw per collection) are issued to the declared writer workflow and to readers. No agent holds a credential that spans an operational and a mem_* 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.

FieldTypeRequiredDescription
memory_idstring (UUID)YesGlobally unique record identifier. Stable across supersession.
tierstringYesOne of the eight tiers.
scopeobjectYesOwnership and visibility.
contentobjectYesThe memory payload. Shape is tier-specific.
content_hashstringYesHash of content, for dedup and tombstone verification.
provenanceobjectYesWhat produced this record.
derived_fromarray[string]Yesmemory_ids this record was consolidated or reflected from.
confidencenumber (0–1)YesExtraction or inference confidence.
validity_intervalobjectYes{ valid_from, valid_until } ISO 8601 UTC.
supersedesstring | nullYesThe memory_id this record replaces.
retention_classstringYesOne of the retention classes.
compliance_labelsarray[string]NoRegulatory tags (pii, pci, gdpr-subject).
versionstring (SemVer)YesRecord 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

StageWhat happensWho may triggerWho commitsEvent emitted
captureA source event carries content eligible to become memory.Any workflow or agent—(the source event)
formationContent becomes a raw memory record with a full envelope.Any agent (as a proposal)os-agt-010memory.record.formed
consolidationSeveral records merge into one derived record.os-agt-011 (recommends)os-agt-010memory.record.consolidated
reflectionA higher-order assertion is inferred — a profile trait, a distilled skill.os-agt-011 (recommends)os-agt-010memory.reflection.completed, memory.skill.distilled
promotionA record moves to a longer-lived tier.os-agt-011 or a workflowos-agt-010, gated by os-agt-012memory.record.promoted
recallA record is read into an agent’s context.Any agent, as a tool call— (read)memory.recall.requested / .served / .denied
decayvalidity_interval expires or a retention window closes.Scheduleros-agt-010memory.record.expired
demotionA record’s tier or visibility is reduced.os-agt-011os-agt-010memory.record.demoted
erasureContent is destroyed; a tombstone remains.Human or compliance workflowos-agt-010, approved by os-agt-002memory.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

StagePathRationale
capture, formation proposal, recallHot pathThe agent needs the result now; latency counts against its budget.
formation commit, consolidation, reflection, decay, demotionBackground, scheduledLLM-backed, latency-tolerant, must not block a reasoning step. Runs as WF-OS-MEMORY-CONSOLIDATE.
erasureOut of band, approval-gatedA 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.

FromToTypical triggerGate
workingepisodicSession handoff, run completionos-agt-012 scope check
episodicsemanticConsolidation over ≥ N corroborating episodesConfidence threshold + os-agt-012
episodicproceduralSkill distillation from repeated successful trajectoriesConfidence threshold + os-agt-012
episodicprofileReflection over subject-scoped episodesos-agt-012 + subject consent labels
semanticrelationalAn assertion becomes canonical business stateos-agt-002 policy approval
anyany, with widened visibilityBroadening from session → agent → subject → tenantos-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 visibility beyond tenant.
  • Any promotion of a record carrying a regulated compliance_labels value 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

ClassDecay behaviourErasableTypical tiers
ephemeralTTL, hard expiryn/a — expiresworking
sessionExpires at session close unless promotedYesworking
operationalWindowed retention, then aggregationYestemporal, episodic
durableNo automatic expiry; decays only by supersessionYessemantic, procedural, profile
auditNever decays. Append-only.Only via erasure tombstoneepisodic (audit records), graph (lineage)
regulatedRetention floor and ceiling set by complianceMandatory at ceilingany, 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_until passes. The record stops being returned by recall but remains readable for audit and remains in derived_from chains.
  • Retention window closure — the retention class’s window closes. operational records may be aggregated into a temporal summary 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:

  1. The request is approved by os-agt-002 and executed by os-agt-010.
  2. content is destroyed in the write-authoritative store and in every projection — Qdrant points deleted, Neo4j property values cleared, checkpoints purged.
  3. 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_state becomes tombstoned.
  4. The lineage edges in graph memory survive — the shape of what happened remains, with the content gone.
  5. memory.record.forgotten is 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 into relational, visibility widening beyond tenant, and promotion of records carrying regulated compliance_labels.
  • Risk tier: critical — per ADR-OS-017, critical agents 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_from chain and rationale, and is only durable once os-agt-012 has scoped it and os-agt-010 has committed it.
  • Approval required: none for proposals (it triggers no side effects).
  • Runtime engine: langgraph — consolidation is reflect-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_profile before 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, critical agents 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.

SituationResolution
Two records overlap in validity_interval and disagreememory.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 differsHigher 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:

  1. Not recalled as agent memory. It is read by a workflow step as a bound domain tool, such as qdrant-query or neo4j-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”.
  2. 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.
  3. Tenant-namespaced. Every collection, point payload, node and edge that holds tenant content carries tenant_id as the leading key or label. Cross-tenant reads fail closed.
  4. 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-propose and committed by os-agt-010 as a new raw record — formation, not promotion: memory.record.promoted is 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:

  1. No memory record crosses a tier boundary without a memory.record.promoted event carrying correlation_id and causation_id unchanged.
  2. Recall is a tool call. Memory reads are bound in active_tool_set and pass the three-layer tool authorization model. Ambient memory injection is non-compliant.
  3. Every memory record has provenance.source_event_id. Memory never enters the fabric uncaused.
  4. Only os-agt-010 commits durable memory. Every other agent proposes. Writes to episodic, semantic, procedural and profile from any other agent are non-compliant.
  5. os-agt-012 is on the path of every recall and every write proposal. Scope resolution happens before retrieval, never after.
  6. 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.
  7. Qdrant is the single semantic vector substrate. No second vector store enters Layer 7.
  8. Erasure leaves a tombstone; lineage in graph memory survives erasure of content.
  9. working memory is never a source of truth. A run that cannot be reconstructed from durable tiers after working memory is lost is non-compliant.
  10. Contradictions are resolved by supersession, never by deletion.
  11. os-agt-008 (Audit & Lineage) remains read-only and must never appear in any agent’s tools_allowed list, including as a memory tool.
  12. tenant_id is first in every scope tuple and every store namespace, so a malformed scope fails closed.
  13. 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 through os-agt-010.

Deployment modes

Every tier must be satisfiable in Mode 3 (air-gapped). Nothing in this specification requires an external service.

ConcernMode 1 (cloud-connected)Mode 2 (self-hosted hybrid)Mode 3 (air-gapped)
StoresAll self-hostedAll self-hostedAll self-hosted
Extraction / consolidation inferenceCloud model APIs permittedPer-agent split, declared in runtime policyLocal only (Ollama / vLLM)
Embeddings for the Qdrant indexCloud embedding APIs permittedPer-agent splitLocal only
NAMSSelf-hosted bolt against the OS Neo4jSameSame. MEMORY_LLM / MEMORY_EMBEDDING must resolve to local URIs
NAMS hosted serviceNot 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

SystemPositionReason
NAMS (neo4j-labs/agent-memory, Apache 2.0)Adopted as a library over the existing Neo4jRuns 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 serviceRejectedProprietary SaaS; breaks Principle 11 and Mode 3 — the LangSmith precedent.
EverOS model (episode → consolidation → profile/skill distillation)Adopted as the canonical lifecycleImplemented on the existing fabric in §5.
EverOS runtime (Markdown + SQLite + LanceDB)Rejected from canonLanceDB 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 BaseStoreInterface adopted, implementation OS-ownedThe compliance seam where authorization, lineage and retention are enforced. Stock implementations are not canonical.
EverMemBench / EverMemBench-S / LoCoMo / LongMemEvalAdopted as the memory evaluation harnessHooked 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_mapping disagree 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.
  • 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_profile is 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.