Status: Canonical · Date: October 2026 Implements: Core Principles Principle 5 (Shared context with scoped access) and Principle 7 (Explainability and audit by design) Authority for: Memory tiers, the memory record envelope, the memory lifecycle, the recall and promotion contracts, retention classes, decay and erasure, and the memory governance invariants Decided by: ADR-OS-002 — Memory Fabric Control Plane


Overview

Synedrix OS has always had a memory substrate. This document gives it a memory architecture.

Layer 7 owns the seven-store memory fabric — working memory (Redis), canonical memory (Supabase PG17), temporal memory (QuestDB), graph memory (Neo4j), semantic memory (Qdrant), LLM trace memory (Langfuse) and behavioural memory (PostHog). Those seven names answer one question: where does a byte live. This specification adds the two questions the OS has to govern but has never defined:

  • What kind of memory is this? — the tier axis (§3)
  • How does it come to exist, move, age and end? — the lifecycle axis (§5)

Open item. The canon does not agree on how many platforms Layer 7 owns. This document’s Overview, above, says “Layer 7 owns the seven-store memory fabric,” naming Redis, Supabase PG17, QuestDB, Neo4j, Qdrant, Langfuse and PostHog as the seven stores, and §2’s reconciliation table treats the Vocabulary “memory fabric” glossary entry — which lists the identical seven stores — as “authoritative for store names.” Against that, canonical/architecture.yaml’s platform_mapping — the machine-readable facts layer, the generator source of truth, and the same tie-breaker the Grafana LGTM Stack platform page already uses to settle a naming dispute — assigns only Redis, Supabase PG17, QuestDB, Neo4j and Qdrant to layers: [7], and assigns Langfuse ("LLM tracing and prompt engineering") and PostHog ("Behavioural analytics") to layers: [10]. Tech Stack’s Layered Truth Summary agrees with the facts layer: it lists five Layer 7 substrate rows (Supabase PG17, Neo4j, QuestDB, Qdrant, Redis) and a separate “LLM eval / observability” row for Langfuse whose “Memory tiers it backs” column reads “none — traces are not a system of record.” Layer Taxonomy Table’s Platform mapping table places the same five platforms at “7 (Memory)” and Langfuse and PostHog at “10 (Observability).” These are not two names for one fact. “Seven-store memory fabric” is a broader, defensible framing under which LLM traces and behavioural events are themselves a kind of memory — this document’s own §3.5 makes exactly that argument, that Langfuse and PostHog “remain in the seven-store fabric” as readable memory that is not a memory tier — while “Layer 7 owns” is the narrower, platform-mapping claim that a reader citing this Overview as a Layer 7 platform count would get wrong per the facts layer. This document keeps “seven-store memory fabric” here because that is its own established terminology, carried forward from ADR-OS-002 §1 and the Vocabulary entry this document elsewhere treats as authoritative for store names, and changing it would mean silently picking a winner between two legitimate but incompatible framings — what counts as memory, against what a layer’s platform-mapping row contains — without an explicit decision to do so. Reconciling the other documents requires an explicit decision and edits to those documents. It is not resolved here.

Together with the substrate axis, these three define the memory control plane: the part of Layer 7 that owns memory as a governed process rather than as a set of databases.

Three rules give the control plane its shape. Each generalises something the canon already asserted for exactly one case:

  1. No memory crosses a tier boundary without a governed promotion event (§7).
  2. Recall is a tool call, not ambient context (§6).
  3. Forgetting is an approved action that leaves a tombstone (§8).

Scope

In scopeOut of scope
Tier taxonomy and tier→substrate mappingWhich physical database is deployed where — Deployment Model Spec
The memory record envelope and its lineage fieldsThe event envelope — Event Taxonomy Standard
The lifecycle state machine and legal transitionsContext assembly for a specific agent run — Layer 4, LangGraph Runtime Implementation Guide
Recall, promotion and erasure contractsConcrete retention values and thresholds — Layer 12, business instance
Retention classes and tombstone semanticsDomain-specific memory content — Layer 11, domain packs
The memory governance invariantsThe runtime binding — Memory Runtime Integration Guide

What Layer 7 owns, before and after

BeforeAfter
OwnsTransactional DBs, vector stores, graph stores, caches, audit stateThe above, plus the memory lifecycle: formation, consolidation, reflection, promotion, recall mediation, decay and 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 layer count is unchanged. Memory cognition is a control plane over persistence, in the same relationship Governance (Layer 9) has to execution — not a peer layer beside it. See ADR-OS-002 §5.1.


1. Terminology

This document uses the canonical forms fixed in Vocabulary and adds to them. The umbrella term remains memory fabric. The forbidden forms remain forbidden: never write memory layer, data layer, storage layer or database layer.

TermMeaning
memory fabricThe whole of Layer 7: the seven stores and the control plane over them.
memory control planeThe part of the fabric that owns the lifecycle — formation, consolidation, reflection, promotion, recall mediation, decay, erasure.
memory tierWhat kind of memory a record is (§3). Orthogonal to the store it lives in.
memory recordA single governed unit of memory, carrying the envelope in §4.
memory substrateThe store a tier is physically written to or projected into.
write-authoritativeThe one store that is right when two stores disagree. Every other copy is a projection.
promotionA governed transition of a record from one tier to a longer-lived tier.
consolidationMerging or summarising several records into one derived record of the same or higher tier.
reflectionDeriving a higher-order assertion (a profile trait, a distilled skill) from consolidated records.
decayScheduled reduction of a record’s availability — expiry of validity_interval, or demotion.
tombstoneThe durable marker left behind when a record’s content is erased.

2. Reconciliation of the existing taxonomies

Four memory tables exist across the canon. They are not contradictory so much as partial — all four describe the substrate axis, and none describes tier or lifecycle. This document is authoritative for the tier model; each prior table remains valid as a projection of it.

SourceWhat it enumeratesStatus after this document
Tech Stack § Layered Truth Summary — 6 truth classesSubstrate, by kind of truthRetained. A substrate view; each truth class maps to one or more tiers in §3.2.
Vocabulary § memory fabric — 7 storesSubstrate, by storeRetained and authoritative for store names. Tier names are additive, not replacements.
Taxonomy Spec §8 — 5 memory typesSubstrate + partial scopeSuperseded by §3 of this document. That table is replaced by the tier table when Taxonomy Spec is bumped.
Academy 02.8 — 5 kindsCognitive, non-normativeReconciled. The five kinds map onto tiers in §3.3; the chapter becomes teaching material for this specification.

Rule: where any other document’s memory table disagrees with §3 of this document, §3 wins. Where a document names a store, the Vocabulary’s canonical store names win.


3. Tier taxonomy

3.1 The eight tiers

TierQuestion it answersOwnerScopeLifetime
workingWhat is true right now, inside this run?OSrun / sessionTTL-bound, never a source of truth
episodicWhat happened, and when?OScross-sessionDurable, decays by policy
semanticWhat is true, independent of when it was learned?OScross-sessionDurable
proceduralHow is this task done well?OScross-sessionDurable, versioned
profileWho is this actor and what do they prefer?OSsubject-scopedDurable, supersession-based
relationalWhat is the canonical business state?OS / domainpersistentDurable, transactional
graphWhat is connected to what, and what caused what?OScross-sessionDurable, append-oriented
temporalHow has a measured quantity moved over time?OSpersistentDurable, retention-windowed

Tier definitions in full:

  • 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. Episodic records are the raw material every other durable tier is derived from, and they carry the strongest lineage obligation.
  • semantic — a durable assertion abstracted away from the episode that produced it (“this customer’s billing entity is X”). 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, so the profile at any past instant remains reconstructible.
  • relational — canonical business entities and their transactional state. The only tier a domain pack co-owns, and the tier with the strongest consistency requirements.
  • 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 the intelligence agents.

3.2 Tier → substrate mapping

Tier and substrate are orthogonal. One tier may be written to one store and projected into others; one store may serve several tiers. Neither may be inferred from the other.

TierWrite-authoritative storeProjections / indexesNotes
workingRedis (working memory)LangGraph checkpointerTTL-bound. The checkpointer is a projection of run state, not of business truth.
episodicSupabase PG17 (canonical memory)Qdrant (semantic memory)Content in Postgres, embedding + payload in Qdrant.
semanticSupabase PG17QdrantSame split. Qdrant is the retrieval index, never the record of truth.
proceduralSupabase PG17QdrantVersioned rows; the index points at the current version.
profileSupabase PG17Qdrant, Neo4j (subject node)Supersession chain lives in Postgres.
relationalSupabase PG17Neo4j (entity projection)The existing canonical-memory role, unchanged.
graphSupabase PG17 (lineage links) · Neo4j (entities and edges, via NAMS)Neo4jLineage remains Postgres-write-authoritative and synced to Neo4j, per the existing rule. Entity/relationship memory is NAMS-owned in Neo4j.
temporalQuestDB (temporal memory)—Unchanged.

Two invariants follow directly and are restated in §10:

  • Supabase PG17 is write-authoritative for every audit-bearing tier. Qdrant, Neo4j and the LangGraph store are projections. Wiping any projection and rebuilding it 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.

3.3 Mapping from the prior taxonomies

Academy 02.8 kindTech Stack truth classTaxonomy Spec typeTier(s) here
HotEphemeral / hot stateoperationalworking
TransactionalCanonical relationalrelationalrelational
SemanticSemantic / similaritysemanticepisodic, semantic, procedural, profile
GraphGraph / lineagegraphgraph
AuditCanonical relational—episodic (retention class audit, §8.1)
—Temporal—temporal
—LLM eval / observability—not a tier — see §3.5
——conversationworking (session-scoped, TTL-bound)

3.4 Where graph and audit memory finally live

Academy 02.8 observes that two of the five memory kinds it teaches have no framework primitive: neither LangChain nor LangGraph offers a home for graph memory or audit memory. This specification supplies both.

  • Graph memory is the graph tier, implemented on Neo4j through the NAMS client (see Memory Runtime Integration Guide §5). Its reasoning-to-entity edges give the OS a concrete representation of which agent step touched which entity — the missing link between an Outcome Envelope and the business state it moved.
  • Audit memory is not a separate tier. It is the episodic tier under retention class audit (§8.1), which makes it append-only, exempt from decay, and erasure-resistant except through the tombstone path in §8.4. Modelling audit as a retention class rather than a tier is deliberate: an audit record is an episode, and duplicating it into its own tier would create two records of the same fact with different retention.

3.5 What is not a tier

Observability stores are not memory tiers. Langfuse (LLM trace memory) and PostHog (behavioural memory) remain in the seven-store fabric and remain readable, but no memory record is write-authoritative in either. Traces are not a system of record: they are sampled, they expire on an observability schedule, and they are not transactionally consistent with business state. An agent that needs a durable fact must recall it from a tier, never reconstruct it from a trace.

3.6 Domain-owned operational stores

A domain pack may keep a Qdrant collection or a 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, so invariant 4 does not apply to them.

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 (§6), 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 (its Postgres domain schema, or its time-series data), or an external feed whose history the pack retains and names with the model version used to derive the records. A live external feed that the pack does not retain does not qualify, because losing the store would lose the history permanently. Wiping the store and rebuilding it from that source must produce identical behaviour. It is never the record of truth for anything, which is invariant 6 applied to a domain pack.
  3. Tenant-namespaced. Every collection, point payload, node and edge that holds tenant content carries tenant_id as the leading key or label, per invariant 12 and the Tenancy Spec. 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 (a lesson learned, a durable observation about a subject) is proposed through tool:memory-propose and committed by os-agt-010 as a new raw record with a memory.record.formed event, like any other formation (§5.2). The operational store is not a tier, so this is 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, whatever the domain pack calls it. It must be written through os-agt-010 into memory_records (Group G), with Qdrant and Neo4j as its projections, and the agent’s memory_profile must say so.

Qdrant remains the single semantic vector substrate (invariant 7): a domain-owned collection is another collection in that same Qdrant, not a second vector store. Its naming, point identity, authorization and rebuild rules differ from the tier collections and are set in the Memory Runtime Integration Guide §2.3 (operational collections).

A fact that is already OS-owned lineage is never an operational store, whatever the domain pack calls it. Agent-to-outcome causal and contribution edges are the graph tier: the domain workflow writes the Postgres source record (agent_lineage_links, Group F) and the system projector writes the Neo4j edge. A domain agent holds no Neo4j write for it.

An operational store’s source of truth is committed first, and the store never gates it. The workflow commits the domain-schema record, then projects to the operational store asynchronously with retry, so losing the store cannot suppress the canonical record. A domain pack that declares such a store must say so in its Data and Memory Usage section, name the write-authoritative source each collection or graph is rebuilt from, and use the term operational store in the agent’s required_memory_layers rather than semantic_memory or graph_memory, so the two are not confused. The Trading domain pack is the worked example.


4. The memory record envelope

Every governed memory record carries this envelope. It deliberately mirrors the structure of the common event envelope so memory lineage and event lineage compose without translation. The event envelope gained a required tenant_id at v1.0, which a memory record already carries as scope.tenant_id.

FieldTypeRequiredDescription
memory_idstring (UUID)YesGlobally unique record identifier. Stable across supersession.
tierstringYesOne of the eight tiers in §3.1.
scopeobjectYesOwnership and visibility. See §4.1.
contentobjectYesThe memory payload. Shape is tier-specific and, for domain tiers, pack-defined.
content_hashstringYesHash of content, used for dedup and for tombstone verification after erasure.
provenanceobjectYesWhat produced this record. See §4.2.
derived_fromarray[string]Yesmemory_ids this record was consolidated or reflected from. Empty for a directly formed record.
confidencenumber (0–1)YesExtraction or inference confidence. Recall filters and promotion thresholds read this.
validity_intervalobjectYes{ valid_from, valid_until } (ISO 8601 UTC; valid_until nullable = open-ended). When the assertion is true, not when the row was written.
consolidation_statestringYesraw | consolidated | reflected | superseded | tombstoned. See §5.
supersedesstring | nullYesThe memory_id this record replaces, or null.
retention_classstringYesOne of the classes in §8.1. Determines decay and erasure behaviour.
compliance_labelsarray[string]NoRegulatory tags (e.g. pii, pci, gdpr-subject) inherited from the source event and honoured by erasure.
versionstring (SemVer)YesRecord schema version.

4.1 scope — tenant first, always

"scope": {
  "tenant_id":  "acme",
  "subject_id": "user-8842",
  "agent_id":   "com-agt-003",
  "session_id": "sess-1f9c",
  "visibility": "tenant"
}
Illustrative example, not a production implementation. Review and test before use.

tenant_id is mandatory and always first in every scope tuple and every store namespace. This is a fail-safe ordering, not a stylistic one: 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. Cross-tenant recall is not a scope setting; it is a promotion that requires policy approval (§7.3).

tenant_id is the tenant: the contracting organisation that owns one or more business instances (ADR-OS-008, Tenancy Spec). It is not a business instance, and the acme in these examples is a tenant. The reserved value platform marks shared reference data in other tables and is never a valid tenant_id for a memory record. visibility: tenant means visible across all of the tenant’s business instances. Whether memory needs a narrower business-instance visibility level is not decided here. The memory tables are tenant-owned, with composite same-tenant keys, as the Synedrix OS - Agent DB Schema defines.

4.2 provenance — every record traces to an event

"provenance": {
  "source_event_id": "evt-7b21...",
  "correlation_id":  "corr-9d4a...",
  "causation_id":    "evt-7b1f...",
  "formed_by":       "os-agt-010",
  "formation_method": "extraction"
}
Illustrative example, not a production implementation. Review and test before use.

formation_method is one of extraction (an LLM or rule derived it from content), declaration (an agent or human asserted it directly), consolidation (merged from derived_from), reflection (higher-order inference) or import (migrated from an external system, in which case source_event_id names the import event).

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.

4.3 Worked example

A consolidated semantic assertion derived from three episodes:

{
  "memory_id": "mem-4c8e1a72-...",
  "tier": "semantic",
  "scope": {
    "tenant_id": "acme",
    "subject_id": "user-8842",
    "agent_id": null,
    "session_id": null,
    "visibility": "tenant"
  },
  "content": {
    "assertion": "Primary billing entity is Acme Logistics BV (NL).",
    "entity_ref": "org-2231"
  },
  "content_hash": "sha256:9f2c...",
  "provenance": {
    "source_event_id": "evt-7b21c4d0-...",
    "correlation_id": "corr-9d4a83f1-...",
    "causation_id": "evt-7b1f0a92-...",
    "formed_by": "os-agt-010",
    "formation_method": "consolidation"
  },
  "derived_from": [
    "mem-11d0...","mem-2a7f...","mem-93be..."
  ],
  "confidence": 0.94,
  "validity_interval": { "valid_from": "2026-07-02T09:14:00Z", "valid_until": null },
  "consolidation_state": "consolidated",
  "supersedes": "mem-0aa4...",
  "retention_class": "durable",
  "compliance_labels": ["pii"],
  "version": "1.0.0"
}
Illustrative example, not a production implementation. Review and test before use.

4.4 Why derived_from and validity_interval are mandatory

These two fields are the direct answer to the strongest published failure mode. EverMemBench reports that current memory systems handle evolving decisions inadequately “without explicit versioning systems”, and score 26% on cross-speaker reasoning even when handed perfect information — the information was present and still unusable, because nothing recorded who asserted it, when it became true, or what it replaced.

derived_from makes a consolidated assertion traceable to the episodes that produced it, so a contested claim can be audited back to its speakers. validity_interval separates when a fact was true from when the row was written, so a superseded assertion remains correct for its own interval instead of becoming silently wrong. Neither is optional, because a record missing either one cannot participate in §9’s conflict resolution.


5. The memory lifecycle

5.1 State machine

flowchart TD
  S([source event]):::term -- capture --> P[proposed: any agent may reach here]:::agent
  P --> V{os-agt-012 validates scope}:::check
  V -- deny --> X[memory.recall.denied / proposal rejected]:::warn
  V -- allow, formation, os-agt-010 commits --> R[raw]:::agent
  R -- consolidation, os-agt-011 recommends, os-agt-010 commits --> C[consolidated]:::agent
  C -- reflection --> RF[reflected]:::agent
  RF -- supersession --> SU([superseded]):::term
  RF -- decay --> EXP([expired]):::term
  RF -- erasure --> T([tombstoned]):::warn
  PR[promotion, tier change may occur from raw / consolidated / reflected — see §7]:::check
  R -.-> PR
  C -.-> PR
  RF -.-> PR

5.2 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-012 (and os-agt-002 where §7.3 requires)memory.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 already uses to keep Policy Guard in front of side effects.

5.3 Hot path versus background

StagePathRationale
capture, formation proposal, recallHot path, inside the agent runThe agent needs the result now; latency counts against its budget.
formation commit, consolidation, reflection, decay, demotionBackground, scheduledLLM-backed, latency-tolerant, and must not block a reasoning step.
erasureOut of band, approval-gatedA compliance action with its own workflow and SLA.

Background stages run as a scheduled orchestration workflow (WF-OS-MEMORY-CONSOLIDATE) invoking os-agt-011, not as a side effect of an agent run. See Memory Runtime Integration Guide §4.


6. The recall contract

6.1 Recall is a 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 in Agent Runtime Policy Spec, traced to Langfuse, and rejectable with agent.tool.unauthorized like any other tool.

This is a deliberate divergence from both EverOS and NAMS, which return memory to the agent without an authorization boundary. It buys three things the OS cannot do without: recall appears in the audit trail, recall scope is enforceable per agent rather than per deployment, and recall becomes measurable — the existing retrieval quality and groundedness metric families apply to it unchanged.

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.

6.2 Request

{
  "correlation_id": "corr-9d4a83f1-...",
  "causation_id": "evt-7b1f0a92-...",
  "requesting_agent": "com-agt-003",
  "tiers": ["semantic", "profile"],
  "scope": { "tenant_id": "acme", "subject_id": "user-8842" },
  "query": "billing entity and invoicing preferences",
  "filters": {
    "min_confidence": 0.7,
    "valid_at": "2026-08-16T10:00:00Z",
    "compliance_labels_excluded": ["pci"]
  },
  "limit": 8
}
Illustrative example, not a production implementation. Review and test before use.

6.3 Resolution rules

  1. Scope is resolved before retrieval, never after. The broker intersects the requested scope with the agent’s memory_profile.recall_scope and pushes the result into the store query as a filter. Retrieving broadly and filtering in the agent is non-compliant — it means out-of-scope memory entered the process.
  2. Tier access is checked per tier. A request naming a tier the agent may not read is not silently dropped; the whole request is denied with memory.recall.denied and a reason.
  3. valid_at filters on validity_interval, not on write time. Absent valid_at, the broker defaults to now. Records whose interval does not contain valid_at are not returned.
  4. Superseded and tombstoned records are never returned by a normal recall. Reconstructing a past state is a separate, audit-scoped read available only to os-agt-008.
  5. Filters push down to the store. min_confidence, valid_at, scope and compliance exclusions are translated into Qdrant payload filters, Postgres predicates or Cypher constraints — not applied post-hoc.

Rule 5 is a retrieval-quality mechanism as much as a security one. Beyond the Needle’s Illusion shows that semantic interference, not context length, is the binding constraint on evidence access — systems that score well on needle-in-a-haystack “degrade sharply in evidence access under semantic interference”. Narrowing the candidate set before ranking is therefore the single highest-leverage retrieval decision, and it happens to be the same seam as authorization.

6.4 Response

{
  "correlation_id": "corr-9d4a83f1-...",
  "status": "served",
  "records": [ { "memory_id": "mem-4c8e...", "tier": "semantic", "content": { }, "confidence": 0.94,
                 "validity_interval": { }, "provenance": { } } ],
  "truncated": false,
  "scope_applied": { "tenant_id": "acme", "subject_id": "user-8842", "visibility": "tenant" },
  "tiers_denied": []
}
Illustrative example, not a production implementation. Review and test before use.

status is served, partial (some tiers denied, tiers_denied populated) or denied. Records are always returned with their provenance and validity interval attached — an agent that receives a memory without knowing where it came from or when it was true cannot ground its output, and groundedness is measured.


7. The promotion contract

7.1 The rule

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.

7.3 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. There is no cross-tenant visibility value, so this is by construction an exceptional, policy-gated act.
  • Any promotion of a record carrying a regulated compliance_labels value into a longer-retention class.
  • Any erasure (§8.4).

7.4 Thresholds are business-instance configuration

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.


8. Retention, decay and erasure

8.1 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 §8.4 tombstoneepisodic (audit records), graph (lineage)
regulatedRetention floor and ceiling set by complianceMandatory at ceilingany, driven by compliance_labels

8.2 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, how long a checkpoint is kept.

One cross-layer constraint is load-bearing and must be validated at instance configuration time:

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 — an approval that cannot be honoured.

8.3 Decay

Decay is scheduled, never opportunistic. Two mechanisms:

  • Interval expiry — validity_interval.valid_until passes. The record stops being returned by recall with a valid_at after that point, 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, so the shape of the history survives its detail.

Both emit memory.record.expired. Neither destroys lineage.

8.4 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.

The rule this protects: a deletion must never silently punch a hole in the audit trail. After erasure it remains provable that a record existed, what produced it, what was derived from it, and that it was destroyed under an approval — while the erased content itself is unrecoverable. 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, because a derived assertion may or may not itself be personal data — that is a judgement, not a mechanical consequence.


9. Conflict and contradiction

Two records may assert incompatible things. The fabric resolves by supersession, never by silent deletion.

SituationResolution
New assertion contradicts an existing one, same subject and scopeNew record sets supersedes; old record’s consolidation_state → superseded and its validity_interval.valid_until closes at the new record’s valid_from. Both remain readable for audit.
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 as above. declaration outranks extraction at equal confidence.
A record’s derived_from chain contains a superseded recordThe derived record is flagged for re-consolidation, not invalidated. Its own validity interval still stands.

The design commitment: the fabric never resolves a contradiction by destroying evidence. A superseded record is still true for its own interval, and the transition itself is a fact worth keeping.


10. 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 (§3.6). A store that fails any of these is governed memory and routes through os-agt-010.

11. 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 — the same rule the deployment model spec already applies to agent runtime policy, extended to the memory control plane.

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.


12. Adopted and rejected external systems

Recorded here for reference; decided in ADR-OS-002.

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.

13. Open items

  • Neo4j Community Edition vector-index support. Resolved. Vector indexes are available in Community Edition per the Operations Manual’s per-edition feature table, so NAMS’s 5.20+ requirement is met and the graph tier is deployable on Community in all three modes. Community’s actual limits for this tier are a single standard database, uniqueness-only constraints and offline-only backup — all absorbed by the control plane. See Memory Runtime Integration Guide §5.4.
  • 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.

Versioning


Decision and runtime binding

  • Synedrix OS ADR-OS-002 — Memory Fabric Control Plane — The decision this specification implements; the EverOS and NAMS evaluation.
  • Synedrix OS Memory Runtime Integration Guide — How Layer 4 binds to this specification: SynedrixMemoryStore, the NAMS client, the compliance checklist.

Architecture and principles

Agents and contracts

Platform reference

  • Supabase PG17 — Write-authoritative for every audit-bearing tier.
  • Qdrant — The single semantic vector substrate.
  • Neo4j — The graph tier and the NAMS binding.
  • Redis — The working tier.
  • QuestDB — The temporal tier.

Deployment

Teaching material

  • Synedrix OS Academy — Chapter 02.8 (context engineering and the memory taxonomy) and chapter 04.4 (short-term state versus canonical store) teach the reasoning behind §3, §6 and §10. Teaching material, not normative: where a chapter disagrees with this specification, this specification wins.


Synedrix OS · August 2026