CORE DIRECTORY // SYSTEM.USER.DIANA_ISMAIL

Labs by Diana — Experiments that ship.

Side projects that got out of hand. AI tools built for problems I kept tripping over — now live, now yours.

ResearchActive

Your Agent's Memory Is a Contract, Not a Database

ARTICLE_027

THE_UNBUILT_LAYERS // 1_OF_1

PUBLISHED

2026.06.25

READ

~13 MIN

The agentic stack has named layers - model, tools, memory - and unnamed layers: contract, authorisation, audit, kill switch, attribution. The unnamed ones are where production breaks. This article takes the memory layer and asks a prior question that most builders skip: what is your agent actually entitled to expect when it looks something up? The answer requires specifying four things - what the agent expects to find, what shape it arrives in, how old it is allowed to be, and what happens when it finds nothing. Until those four things are written down, you do not have a memory system. You have an implicit contract nobody signed.

The_Contract_Problem

Here is what actually happened when my agent produced wrong output: the model did not hallucinate. The model wrote prose on top of what memory returned, and what memory returned was stale. The agent had retrieved a model tiering rule - accurately, from the right file - but the rule described a configuration that had changed three weeks earlier. The agent saw a result, assumed it was current, and acted. There was no error. There was no flag. There was an output that looked completely reasonable and was completely wrong.

This is not a retrieval failure. The query worked. The file existed. The content was returned. It is a contract failure: the agent had an implicit assumption about the freshness of what it would find, and nobody had written that assumption down.

The agentic stack has named layers - model, tools, memory - and unnamed layers: contract, authorisation, audit, kill switch, attribution. The unnamed ones are where production breaks. Memory gets a lot of architecture attention - which vector store, which embedding model, RAG versus GraphRAG versus PageIndex. Anthropic's acquisition of Stainless in May 2026, ~$300M for SDK and MCP infrastructure, signals that the memory and tooling layer is becoming infrastructure-grade. What that acquisition cannot do is write your retrieval contracts for you. That part is still hand-rolled, per fleet, every time.

The framework I am about to describe is not theoretical. I built the operational version of it - under live production pressure, after incidents, with real cost - before I had a name for any of it. The article's job is to name what I built and make it portable.

What_(Retrieval_Shape)

A retrieval contract specifies four things, per memory source. Not globally - per source, because each source has a different staleness rate, a different data shape, and a different blast radius when the retrieval fails.

The first dimension is the explicit specification of what the agent expects to find, and how it will look for it. Not what is stored in memory - what the agent will search for, with what trigger, against what structure.

The failure mode when this is missing: the agent queries with an implicit assumption, returns either a stale match or nothing, and defaults to its training weights - which may be months out of date.

The fix I implemented was structural rather than instructional. The per-CWD MEMORY.md index in my fleet is not a flat list. It is an index organised by retrieval intent. There is a Pre-action Gates section - entries that must fire before a specific class of action. A Lookup Pointers section - entries that redirect to canonical sources rather than containing facts themselves. An Identity section - anchors that must be correct in every session regardless of context.

The section heading is the retrieval shape specification. An agent loading MEMORY.md does not scan for relevance; it knows which section answers which class of query.

Shape_(Data_Shape_Returned)

The second dimension is the structural format of what memory returns: which fields are mandatory, which are optional, how the body is structured, and which fields the agent should act on versus which provide context.

The failure mode when this is missing: the agent receives content in an inconsistent format and has to infer structure. Inferred structure means inconsistent extraction, which means the rule gets applied partially - or not at all.

Every memory file in my fleet follows a mandatory schema: a frontmatter block with name, description, and metadata.type fields, followed by a body structured as rule, then Why:, then How to apply:. Each field is load-bearing. The description field is not documentation - it is the field the agent scans to decide whether to load the full file at all. The type field determines which reasoning framework applies: feedback entries are corrective rules, project entries are decaying state, reference entries are stable pointers.

The feedback_data_mutation_protocol.md file is the clearest illustration of this. Its body is a structured 5-step gate with named standing rules, a Why: section that names a specific incident - the Sanity createOrReplace operation in 2026 that destroyed heroImage fields across eight project documents, some images permanently lost - and a How to apply: section specifying the exact decision point.

Freshness_(Maximum_Acceptable_Staleness,_Per_Source)

The third dimension is the explicit, per-source specification of how old a memory entry can be before it must be re-verified before acting on it. Not a global TTL. Per source, because operational rules tied to tool behaviour go stale faster than architectural decisions.

The failure mode when this is missing: the agent acts on content that was accurate when written and is no longer accurate now. Because there is no freshness contract, the agent has no mechanism for detecting the drift. The failure is silent.

My fleet implements two distinct freshness mechanisms. The last_verified convention handles external facts - tool behaviour, platform constraints, agent capabilities. The Memory Hygiene section of my ~/.claude/CLAUDE.md specifies: memory files describing facts that can go stale should carry a last_verified: YYYY-MM-DD line in their frontmatter. When last_verified is more than 90 days old, the entry is a re-verification candidate before acting on it.

The two-tier lifecycle model handles structural facts. Tier 1, at Claude/ root: stable references - decisions.md, voice-system.md, schedulers.md, project-index.md. These are citable by path because their staleness rate is low enough to warrant direct reference. Tier 2, in proj-plan/: work-shaped artefacts - briefs, audit memos, drafts. These are volatile; they are not cited by path in agent prompts.

The graduation pattern between tiers is itself a freshness signal. When a proj-plan/ artefact stops changing and begins being cited by path, it graduates to Tier 1.

Behaviour-When-Missing_(Explicit_Degradation_Strategy)

This is the most commonly skipped dimension. When a memory entry cannot be found, returns empty, or is present but too stale to act on - what does the agent do? Fail silently is not a degradation strategy. It is the absence of one, and it is where the real cost lives.

I run three distinct degradation strategies across my fleet, and the choice between them is not arbitrary.

Fail closed applies to irreversible or high-cost actions. The feedback_model_tiering_applied.md entry documents the model tiering rule: always pass the model parameter explicitly in every Agent tool call. Omitting it means the subagent inherits the parent's model - Opus - and the rule was written after 114 subagent sessions ran on Opus because the parameter was not specified: 11.2 million output tokens, 96.6% of all Opus spend, because silence was treated as a valid default.

Fail open applies only when failing closed adds no safety. My Memory Hygiene section notes that Redis failures in the chat engine cause fail-open behaviour for OTP: when Redis is unavailable, the OTP flow cannot function regardless of the degradation strategy.

Surface to owner is the third strategy: when memory cannot determine the safe action without current state, the agent retrieves that current state before proceeding. A bulk Notion status update regressed six Published posts to Scheduled in 2026 because the agent did not check current state before mutating.

The three strategies are not interchangeable. The choice is determined by blast radius, by the usefulness of the fallback, and by whether current state can resolve the ambiguity.

The_Four-Tier_Architecture_as_Worked_Example

The framework above is abstract until it has an implementation behind it. Here is the one I am actually running.

Tier 1 - Stable references (Claude/ root). Contract: What = cross-project decisions, voice system, fleet conventions. Shape = standalone .md with explicit ownership. Freshness = infrequent change, citable by path in agent prompts. Behaviour-when-missing = consult the canonical source; never substitute from training weights.

Tier 2 - Work-shaped artefacts (proj-plan/). Contract: What = in-flight planning work. Shape = brief + deliverable markdown with frontmatter. Freshness = volatile; briefs older than 48 hours on an active repo require cited paths to be verified before commission. Behaviour-when-missing = retrieve from proj-plan/{project}/briefs/ or flag to owner.

Tier 3 - Per-CWD MEMORY.md index. Contract: What = pre-action gates, identity anchors, and lookup pointers scoped to this working directory. Shape = structured index with named sections and one-line trigger-condition hooks. Freshness = last_verified on external-fact entries; 90-day re-verification threshold. Behaviour-when-missing = do not load from a different CWD's MEMORY.md; treat as no relevant gate and flag the gap.

Tier 4 - Individual memory files. Contract: What = specific rule, gate, or pointer triggered by the index entry. Shape = frontmatter (name, description, type) + body (rule + Why: + How to apply:). Freshness = tied to the incident that generated it; last_verified for tool-behaviour facts. Behaviour-when-missing = binary: if a file is not indexed in MEMORY.md, it is in archive/. There is no middle state.

Define the contract before choosing the store.

What_This_Changes_for_Builders

If you are reaching for a RAG store, or evaluating GraphRAG versus PageIndex, or wondering whether your agents need a shared memory layer - the Seven Questions framework I published in May 2026 names the Data row as the prior checkpoint. Before you pick the store, answer the contract question.

What I have described here is not a novel architecture. It is what you already have, if you have been running agents in production and paying attention to the failures. The model tiering incident, the heroImage destruction, the regressed Notion statuses - none of those were model failures. They were failures of implicit contract. The model did exactly what it was told. The problem was that nobody wrote down what it was entitled to expect.

The contract dimensions are not a new system to build. They are a description of what a functioning memory system already enforces - explicitly or accidentally. If yours enforces them accidentally, you will keep having incidents you cannot explain and cannot reproduce, because the contract is not written down and therefore cannot be checked.

Define the contract before choosing the store.

Part of The Unbuilt Layers series - a set of articles on the production infrastructure that most agentic builds skip until the failure makes it mandatory.

Agentic AIMemory ArchitectureAgent GovernanceInfrastructureRetrievalProduction SystemsContext Management

KEY_TAKEAWAYS

TAKEAWAY_01

A hallucination is often not a model failure - it is a contract failure. The agent assumed something about what memory would return. That assumption was never specified, so nothing caught the drift.

TAKEAWAY_02

Four things must be defined per memory source: retrieval shape (What), data format (Shape), maximum acceptable staleness (Freshness), and explicit degradation strategy (Behaviour-When-Missing).

TAKEAWAY_03

Behaviour-When-Missing is the dimension most builders skip. Fail silently is not a degradation strategy - it is the absence of one. Silent failure is where the real cost lives.

TAKEAWAY_04

The choice between fail-closed, fail-open, and surface-to-owner is determined by blast radius, not preference. Irreversible or high-cost actions fail closed. Actions where failing closed adds no safety can fail open. Ambiguous state routes to the owner.

TAKEAWAY_05

Define the contract before choosing the store. Pinecone, PageIndex, GraphRAG - the retrieval infrastructure is the last decision, not the first.

SYSTEM.INT // 2026 LABS_CORE v2.78.2

LATENCY: STATUS: NOMINAL