Skip to main content

Memory

Blueprint · ← Session custody · Memory · Autonomy shape →

Memory is what this request is allowed to remember. The route row declares that as memory_profile. The agentic app reads, writes, and packs. The model never invents a store, and never sees that JSON.

THE CLAIM

The app branches on the pinned memory_profile. Session A cannot read Session B. Last week's story is retrieved, not stuffed into the prompt. Writes and erase are gated tools, not a memory-mode enum.

Four drawers, one example​

Jane is in chat about an ATM FX fee. Four drawers, not one blob:

DrawerWhat it holds in this exampleLives how long
Conversation"Why was I charged $42?" and the assistant's repliesThis chat
Workingaccount: ACC-4821, amount: 42, topic: ATM FXThis chat, this route
LoopTool 2 of 8 just finished fee_lookupThis run (so a crash can resume)
Long-termStanding: language: English. Episode: "12 Aug: disputed ATM FX on ACC-4821"Past the session

The first three die with the session (or its TTL). Long-term survives. It comes back only as a retrieve, never as "dump Jane's whole history into the system prompt."

You will also hear episodic (dated stories of past sessions) vs prefs (stable attributes). Both sit under the same field, long_term. There is no fifth route field.

Same split as G.A.I.N Agents. Corpus search (policy PDFs, clauses) is a different field: retrieval. See Memory vs RAG below.

The route is the only knob​

The intent router picks a route_id. That row's memory_profile is the only memory control for the request. After the decision, the app pins the profile. The LLM cannot flip "none" to "retrieve_only". The workflow cannot drop isolation keys.

FieldValuesPlain meaning
conversationnone / sessionKeep this chat's messages, or not
workingnone / sessionKeep task slots / stage outputs, or not
loopnone / checkpointKeep step count so a crash can resume, or not
long_termnone / retrieve_onlyMay query last week's prefs and episodes, or must not
ttl_hoursnumberSoft lifetime for this-chat stores only
isolatione.g. ["tenant", "user", "session"]Partition keys on every read and write

Changing memory_profile on the row is a route-table bump, same as policy_profile. Field dictionary: Route contract reference.

Fee explain route (JSON)
{
"route_id": "fee_explain",
"memory_profile": {
"conversation": "session",
"working": "session",
"loop": "none",
"long_term": "retrieve_only",
"ttl_hours": 24,
"isolation": ["tenant", "user", "session"]
}
}

The row does not hold store URLs, embedding models, or compression prompts. Those live in the memory service. The row also does not grant permission by itself: PEP still evaluates recall and write. Credentials stay in Token & session. That playbook is "credentials never reach the LLM." This one is "Jane's other chat never reaches this one."


This chat: conversation, working, loop​

These three live in the agentic app (or its checkpointer). Session custody is the engine (Postgres runs v1; Temporal when you must resume at step K). This page is the policy: loop: checkpoint means that record must exist.

RuleWhy it exists
Key every record with the full isolation listMissing session is how Jane's other chat leaks into this one. Missing tenant is a cross-bank read.
Apply ttl_hours here24h idle drop. Durable prefs do not use this clock.
Pin working and loop to this routeA freeze-card switch is a new pin. Old slots do not ride along.
Chat history is not an agent loopPattern 0 can keep conversation: session with loop: none.

User changes intent. Stickiness keeps "yes" / "$500" on the active route. A real new intent is a new run: new route, new pin, new downscoped token. Conversation may stay (same chat window). Working and loop stay under the old pin. Do not dump Analyse tool results into email_summarize unless policy names a governed handoff of specific slots.

Last week: long_term​

retrieve_only means this route may query the memory service. It does not mean "always fetch Jane's profile before the first token." "none" means skip the memory service and do not attach recall tools, even if another route's manifest has them.

Split two loads. They must not share one slot.

WhatWhenSize
Standing prefs (language, opt-out)Context assembly, around every inference callTiny. Needed on the first token.
Episodes (last week's session summary)Inside the pattern, as a retrieveQuery-specific. Do not dump 40 summaries before a payment.

Who starts episode recall follows the autonomy pattern (pack on Pattern 0; tool on Pattern 1; named stage on Pattern 2; current-stage allowlist on Pattern 3). Detail: Autonomy shape.

The model never sees the flag. It sees either a small pack in this context, or a recall tool the app attached because the flag and the manifest both allowed it.

Last week's fee dispute must not steer today's wire​

Working and loop are already bound to this pin. They do not follow Jane from fee_explain last week into payment_initiate today.

Episodes and prefs are user-scoped. If both routes set long_term: retrieve_only and the query is only user_id, last week's fee dispute can appear on a wire. isolation: ["tenant", "user", "session"] does not stop that. Session is this chat, not last week's summary.

Use these together:

ControlWhat it does
long_term: none on high-risk rowsPayments, freeze, KYC: no memory service, no recall tools. Default for writes.
Tag on writeEvery episode stores source_route_id (and optional data_class)
Filter on readQuery is current route_id, or an allowlist of routes that may share (e.g. fee_explain may read account_history; payment_initiate reads none)
Split prefs vs episodesLanguage / opt-out may be global. Narratives ("disputed the FX fee") stay route-scoped. Do not pack them in one blob.
PEPrecall_episodes includes source_route_id ∩ allowlist. Widen to "all episodes for this user" is DENY.

Do not prefetch "everything we know about Jane" because retrieve_only is on. Pack standing prefs if the row allows. Load episodes only as a filtered retrieve (or a named Pattern 2 stage). Eval Plane ⑥: "route A episode on route B" must be 0 leaks.

Payment route: long_term none (JSON)

High-risk writes usually skip cross-session memory.

{
"route_id": "payment_initiate",
"memory_profile": {
"conversation": "session",
"working": "session",
"loop": "checkpoint",
"long_term": "none",
"ttl_hours": 8,
"isolation": ["tenant", "user", "session"]
}
}

Memory vs RAG​

Two stores. Two route fields. Do not put customer prefs in retrieval.scope.

Memory serviceRetrieval gateway
Route fieldmemory_profileretrieval
HoldsPrefs, facts, session summariesPolicy / product / clause corpora
Isolationtenant, user, sessionCorpus id + document ACL
Typical query"this customer, this intent""this question, this scope"

You can prefetch policy chunks and still only tool-recall episodes, or the reverse. Same PEP discipline. How-to for corpora: RAG retrieval.

Writes and erase​

retrieve_only is read. There is no "read_write" on the profile on purpose.

ActionHowGate
Upsert a preferenceAllowlisted tool, e.g. upsert_preferenceSchema of known keys. Model cannot invent free-text "facts" onto the profile.
Append an episodeApp job at session close, or gated append_episodeCompress the thread. Do not keep the raw transcript forever unless retention says so.
Forget / deleteErase API keyed by subject (+ tenant)Must empty prefs, episodes, and session-scoped stores.

Session-close compression is not implied by retrieve_only. Schedule it in the app after the run, with the same isolation keys.

Policy on recall and write​

Recall and write are governed actions, same as any other tool. Policy contracts.

PDP checks: long_term on the pinned route is retrieve_only, isolation keys match the session, entitlement for memory read, no widen to another user, episode source_route_id is on this route's allowlist. DENY means no pack and no tool result. Prefetch of standing prefs is still a PEP-gated retrieve the app starts, not a prompt instruction.

Writes use a different action (upsert_preference, append_episode) and a tighter resource (allowed key list). "none" on the route: do not send these tools to the LLM. PEP would still DENY if they leaked through.

Recall episodes SARAC (JSON)
{
"subject": {
"sub": "customer-jane",
"roles": ["retail_customer"]
},
"action": "recall_episodes",
"resource": {
"type": "memory",
"kind": "episodic",
"subject_id": "customer-jane"
},
"context": {
"tenant": "bank-au",
"session_id": "sess-8f2a",
"route_id": "fee_explain",
"query": "ATM FX fee ACC-4821"
}
}

What goes in the prompt​

DoDo not
Pack only hits for this turnDump every past session into the system prompt
Log pack id, keys, token count, PEP verdictTreat "the model remembered" as audit
Re-retrieve on the next turn if neededCarry an episode into a new route pin by default
Keep prefs tiny (language, opt-out)Store KYC decisions as chat vibes

If this breaks​

FailureWhat you will see
Isolation missing sessionCross-session leak for the same user
Episode query is user-onlyLast week's fee_explain summary appears on payment_initiate
Isolation missing tenantCross-bank read
long_term: none but recall tools on the payloadCross-session memory on a write path
All episodes stuffed into the system promptretrieve_only ignored; unauditable pack
Prefs and episodes in one unqueried blobStale narrative treated as standing policy
Write via prompt ("remember that I am hostile")Profile poison; no PDP
Erase API only clears conversationPrefs / episodes remain; GDPR fail
Token playbook used as memory playbookCredentials mixed with chat state
Customer prefs in retrieval.scopeWrong store; corpus ACL is not user memory

Trace: session_id, route_id, memory_profile, memory_reads, memory_writes, memory_pack_id, ttl_policy, prompt_memory_tokens, isolation_keys, pep_verdict.

Prove it on Eval Plane ⑥ Memory: session isolation, TTL, write policy, forget/delete. Leakage adversarial set must be 0 failures.

Who owns what​

PlaybookJob
Route contractDeclare memory_profile
This pageStore, isolation, TTL, pack, write/erase, PEP on recall
Session custodyDurable run pin; checkpointer vs runs vs Temporal
Autonomy shapeWho starts episode recall on Patterns 0-3
RAG retrievalCorpus retrieve. Not customer prefs.
Eval Plane ⑥Prove isolation, TTL, erase

See: G.A.I.N Agents · Agents Blueprint · Governance Blueprint

Autonomy shape →