Governed Memory: OAMP 1.2 ships, 1.3 puts the gate on the data buffet
“I’ve seen things you people wouldn’t believe…”
Roy Batty got to choose which memories he kept. Your agents do not. Every memory an agent writes today either sits trapped in a vendor blob or, worse, sits in a shared backend where any agent your user has ever logged into can read everything else they’ve ever stored. There is no granted scope. There is no sensitivity ceiling. There is no audit trail when memories cross a boundary they were never meant to cross.
That is the buffet model. Memories go in, every agent helps itself.
OAMP v1.2 is the spec rev that names the problem properly, and v1.3 (draft) is the one that picks up the cutlery. Both are out now, in the repo at deep-thinking-llc/open-agent-memory-protocol, with reference fixtures, schemas, OpenAPI surfaces, and matching validator updates.
This post explains what is new, why governed memory matters more than people think it does, and walks through four high-impact use cases across finance, healthcare, government, and legal. There is also a substrate framing at the end that is the part most people miss the first time around.
What v1.2 adds: descriptive governance
v1.2 is strictly additive over v1.0 and v1.1. No required fields change. Nothing breaks. The new surface area is three optional pieces of metadata and one capability flag.
The new governance object hangs off a KnowledgeEntry:
{
"governance": {
"sensitivity_class": "confidential",
"labels": ["finance", "hr"],
"handling": {
"retrieval": "governed",
"export": "governed",
"stream": "governed"
}
}
}
Four sensitivity classes are defined and ordered: public, internal, confidential, restricted. Labels are tenant-defined strings that describe what the memory is about. The handling block is a per-surface hint that says whether the entry should be filtered on read, export, or stream paths.
v1.2 also adds an extended provenance block. The original source field stays mandatory and unchanged. provenance is the richer optional structure for entries that came from multiple sessions, agents, or turns. It is what lets you trace a synthesised memory back through every observation it was built from:
{
"provenance": {
"sources": [
{ "session_id": "sess-42", "agent_id": "agent-a", "turn_id": "turn-3" },
{ "session_id": "sess-43", "agent_id": "agent-a", "turn_id": "turn-7" }
],
"derived": true
}
}
Finally, the v1.1 capabilities endpoint gains a governance block. Backends declare whether they store these fields, which sensitivity classes they accept, whether labels are preserved, and whether extended provenance is supported.
That is the entire v1.2 wire change. Descriptive. Additive. Stable. Cross-implementation interop was verified on 2026-05-09 between kizuna-mem and cosmictron, both directions, empty diff, no surprises.
What v1.2 deliberately does not do is tell a backend what to do with the metadata. That is v1.3.
What v1.3 (draft) adds: enforcement
v1.3 is the part that turns descriptive labels into operational rules. It adds zero new KnowledgeEntry fields. It adds one capabilities sub-block, one portable grant format, and a set of normative MUSTs for what a compliant backend has to do when a request shows up wearing a grant.
The grant format is a JWT claim shape (or an OAMP-Grant header for deployments without JWT bearer tokens):
{
"sub": "user-abc",
"oamp_agent_id": "medical-assistant-v3",
"oamp_grant_id": "grant-2026-05-07-001",
"oamp_read_labels": ["health", "preferences"],
"oamp_write_labels": ["health", "preferences"],
"oamp_sensitivity_max": "restricted",
"oamp_export_full": false,
"exp": 1746662400
}
That JSON says: this agent, for this user, may read memories labelled health or preferences, may write the same, may go up to restricted sensitivity, and may not do full unfiltered exports. The grant is scoped, portable, and signed.
The label match is hierarchical and prefix-based. A grant for health matches health.condition and health.condition.diagnosis. A grant for finance.income does not match finance.holdings. v1.3 reserves ten top-level labels for cross-vendor interop: identity, location, health, finance, relationships, work, preferences, creative, beliefs, behaviour. Vendor-specific labels live under x.<vendor>.*.
When a backend advertises governance.enforcement.supported: true, the rules become MUSTs:
- Read filtering: an entry passes only if its effective retrieval handling is not exempt, at least one of its labels matches a granted read label, and its sensitivity class is at or below the grant ceiling.
- Existence hiding: out-of-scope entries return
404 Not Found, not403 Forbidden. The difference matters. A403tells an unauthorised agent that the entry exists. A404does not. - Write rejection: writes outside the grant get
403, and writes that try to claim a differentagent_idthan the grant carries also fail. - Import accounting: rejected entries are counted in the import response so callers can detect partial loads.
- Export filtering: only readable entries come out, unless the grant carries
oamp_export_full: trueand the call is on a direct user authentication path. - Stream filtering: v1.1 streaming events for out-of-scope entries are dropped on the floor. No notification, no entry id, nothing.
There is also a small audit vocabulary addition: grant_issue, grant_revoke, scope_denied_read, scope_denied_write. The denial events deliberately do not log filtered entry ids on agent surfaces, because logging the id would defeat existence hiding.
What v1.3 explicitly does not standardise is the withheld-stub document. There is no portable “this entry exists but you cannot see it” envelope yet. The reason is technical: the v1.x KnowledgeEntry schema requires non-empty content, so a portable redacted stub is a breaking change. That work is parked in the v2.0 RFC and will land properly there.
This split is deliberate. v1.2 gets the descriptive shape interoperable across implementations without a single breaking change. v1.3 turns those fields into normative behaviour. Anything that would require a breaking schema change waits for v2.0, where the major version earns the break.
Why governed memory matters
Most people treat agent memory like log files. Throw stuff in, search it later, hope nothing leaks. That works fine until two things happen.
The first is that you start running more than one agent for the same person. A coding copilot, a scheduler, a health tracker, a finance assistant. Each of them wants memory. If you give them all the same memory pool, they all see everything. Your scheduler now knows your blood pressure. Your finance copilot now knows your therapist’s name. Nobody intended that. There was just no protocol layer to stop it.
The second is regulation. The moment a memory entry contains protected health information, or material non-public financial data, or privileged legal correspondence, or a constituent record covered by a sovereign data regime, the storage system inherits the legal obligations of the data class. “We forgot to scope our memory backend” is not a defence under HIPAA, MiFID II, GDPR Article 9, ABA Rule 1.6, or any of the dozen frameworks that govern these categories.
Governed memory is not a feature. It is the bare minimum required to use agent memory in any setting where the data has a legal classification. v1.2 lets backends carry the classification. v1.3 lets backends enforce it.
The four scenarios below are the ones that hit hardest in conversations with customers.
Example 1: Finance, the wealth desk and the cafeteria
A wealth management platform runs three internal agents. A research assistant that drafts client letters. A portfolio copilot that runs scenario analyses. And a customer service agent that handles inbound chat.
Without governed memory, all three agents share a memory backend. The portfolio copilot writes detailed entries every time an analyst opens a position: client names, holdings, price levels, the analyst’s view of where the market is going next quarter. Material non-public information by any reasonable definition.
The customer service agent fields inbound chat. A user starts a session. The agent retrieves “memory” to personalise the reply. If retrieval is ungoverned, that pull might surface a portfolio note from a different desk. The leak is technically a chat completion. Practically, it is an information barrier breach under Section 15(g) of the Exchange Act and FINRA Rule 5270, with parallel exposure under FCA Principle 8 on conflicts of interest.
With v1.3 enforcement, the portfolio copilot writes entries with governance.labels: ["finance.holdings", "finance.research"] and sensitivity_class: "confidential". The customer service agent’s grant is oamp_read_labels: ["preferences", "work.calendar"] with oamp_sensitivity_max: "internal". The retrieval call returns a 404 for any holdings entry. The audit log shows scope_denied_read without logging the entry id. The information barrier is a property of the protocol, not a property of the agent’s prompt engineering.
This is the case that compliance teams care about most. Information barriers in finance have historically been a matter of access control on databases. Once agents share memory through a common substrate, the barrier has to live in the substrate too. v1.3 puts it there.
Example 2: Healthcare, the consult that should not bleed
A hospital pilots two agents inside a single Epic deployment. An ambient documentation agent that listens to consultations and drafts notes. A patient portal agent that answers patient questions about appointments and lab results.
Both touch the same patient. Both could, in principle, share a memory backend. Both have wildly different sensitivity profiles. The documentation agent hears differential diagnoses, medication histories, family-history disclosures, mental health discussion. The portal agent should know nothing beyond what the patient already knows about their own care.
A naive shared memory means the portal agent can retrieve a “this patient was screened for substance use disorder last Tuesday” entry that the documentation agent wrote. That is a HIPAA Privacy Rule incident. It is also a clinical safety event, because the disclosure happens through a channel the clinician never authorised.
Under v1.3, the documentation agent writes entries with governance.labels: ["health.condition", "health.medication", "health.consult"] and sensitivity_class: "restricted". The portal agent’s grant is oamp_read_labels: ["health.appointment", "health.result.released"] with oamp_sensitivity_max: "confidential". The consult-level entries are invisible to the portal agent. Hierarchical label matching means a single grant of health.appointment does not silently widen to cover everything under health. The clinician can override per consultation by extending the portal agent’s grant temporarily, signed, with an expiry.
This is the difference between “we trust the agent to be careful” and “the substrate physically cannot deliver out-of-scope content”. The first one fails sooner or later. The second one is something a hospital compliance officer can actually sign off on.
Example 3: Government, sovereign data and contractor agents
A national tax authority deploys an internal agent stack. Some agents are run by the authority itself on sovereign infrastructure. Others are run by contracted suppliers under data processing agreements that scope what the supplier can and cannot see. Citizen records cross between them.
The sovereignty question is not whether the data is encrypted. It is whether a third-party agent, running in a contractor’s environment, can pull memory entries that exceed the contractor’s data processing scope. Under most current memory stacks, the answer is yes, because the backend has no concept of agent-scoped retrieval. The contractor agent authenticates as itself, the backend returns whatever matches the query, the contractor’s audit log shows the access after the fact.
OAMP v1.3 inverts the order. The contractor agent presents a grant signed by the authority’s grant issuer. The grant carries oamp_read_labels: ["identity.public", "work.case_status"] and an explicit oamp_sensitivity_max: "internal". Citizen records labelled identity.private, finance.income, or health.condition are not in scope. The backend returns 404. Existence hiding matters here too: a 403 would tell the contractor that a private record exists for a given citizen id, which is itself sometimes a disclosure under sovereign data frameworks.
The audit log carries grant_issue and grant_revoke events. The authority can revoke a contractor’s grant in seconds. The contractor’s running agents lose access on the next request. No backend migration, no schema rewrite, no code change.
For governments standing up sovereign AI stacks, this is the protocol layer that lets multiple agents share a memory substrate without the contractor envelope leaking sovereign data. It is also the layer that lets agents from different sovereign deployments talk to each other under bilateral grants without merging their data planes.
Example 4: Legal, privilege without exception
A law firm runs three agents on a matter-management platform. A research agent that drafts memos. A discovery agent that processes opposing counsel’s productions. A client-facing agent that handles intake.
Attorney-client privilege is the most fragile data class in the model. Once privilege is broken, you cannot unbreak it. A single retrieval call that surfaces a privileged communication to an agent operating outside privilege is enough to taint the matter. Some jurisdictions treat the disclosure as a waiver of privilege over the entire subject matter, not just the leaked document.
Under v1.3, privileged entries carry governance.labels: ["work.matter.privileged"] and sensitivity_class: "restricted". The research agent’s grant includes work.matter.privileged because privileged research is in scope. The discovery agent’s grant deliberately does not, because exposing privileged material to discovery workflows is the exact failure mode privilege exists to prevent. The intake agent’s grant is narrower still, limited to work.matter.intake and identity.public.
When the discovery agent issues a search and the backend has a privileged entry that would otherwise match, v1.3 says the entry MUST NOT appear in the response and MUST NOT contribute to the total count. The discovery agent has no way to know the entry exists. There is no surface area for a leak, accidental or otherwise.
For legal teams, the value of governed memory is not new functionality. It is that they can finally adopt agent memory at all without inheriting an enterprise-grade liability through the back door.
OAMP as a substrate
Here is the part that takes a second pass to land.
OAMP is not just a memory protocol for any single agent. It is a substrate protocol that lets multiple AI tools and agents share the same memory layer for the same user without the trust boundaries collapsing.
The reason this matters is that users do not have one agent. They have several. A coding assistant in their editor. A meeting summariser in their calendar. A scheduler. A health tracker. A budgeting copilot. In the current ecosystem, every one of those agents either runs its own siloed memory store, in which case the user retrains every tool on the same preferences and history every quarter, or they share a memory pool that has no concept of scope, in which case private context bleeds across boundaries the user never agreed to.
A substrate protocol is the third option. One memory backend, one user, many agents, each one bound by a grant that says exactly what it can read, what it can write, what sensitivity it can touch, and for how long. The protocol enforces the boundary. The user controls the grants. The memory itself is portable across compliant backends, so the user is not locked into the first vendor who happened to write the first entry.
What this looks like in practice:
- The coding assistant gets
read: ["work", "preferences"],max: internal. It sees what you are working on and how you like things written. It does not see your medical history. - The meeting summariser gets
read: ["work.calendar", "work.contacts", "preferences"],max: internal. It can personalise summaries without ever pulling a finance entry. - The health tracker gets
read: ["health", "preferences"],max: restricted. It is the only agent that gets to see clinical context. - The finance copilot gets
read: ["finance", "work.calendar"],max: confidential. It can correlate spend against your calendar without touching anything else.
Every one of those agents writes to the same backend. Every one of those entries is portable to a different backend on request. None of them can read each other’s entries. The audit log shows every grant issued, every grant revoked, every denied read.
That is what we mean when we say OAMP is a substrate. Memory becomes a shared service that respects scope, the way a filesystem becomes a shared service that respects permissions. Until governed memory existed, agent memory could not be a shared service. It could only be a data buffet, with all the consequences that implies.
What this means if you are building right now
If you are building a memory backend, look at the v1.2 fixtures under spec/v1.2/examples/. The interop fixture pack is the same one used to verify kizuna-mem and cosmictron round-trip cleanly. Carry the governance and provenance fields, advertise them on /v1/capabilities, and you are compliant with v1.2. Implement the v1.3 enforcement rules and the grant claim shape, and you are compliant with v1.3.
The upgrade path from a v1.0 backend is small. The schemas are additive, so existing entries stay valid. You add a grant validator on the auth path, a label-prefix matcher on the read/search/export/stream paths, and an enforcement block on the capabilities response. There is no migration of historical data, no protocol break for v1.0 clients, and no requirement to support withheld stubs (that work waits for v2.0).
If you are building an agent, start by writing entries with governance.labels set, even if you are running against a v1.0 or v1.1 backend that ignores them. The fields are additive. They survive on backends that preserve unknown metadata. When you eventually move to a v1.3 backend, your historical memory is already labelled.
If you are building a product on top of agent memory, the question to ask your backend vendor is no longer “do you store memory”. It is “do you implement v1.3 governance enforcement”, followed by “can I see your /v1/capabilities response”. If the answer is no on either, the substrate is not ready for production use in any regulated setting.
The spec is at github.com/deep-thinking-llc/open-agent-memory-protocol. The v1.2 normative text is in spec/v1.2/oamp-v1.2.md. The v1.3 draft is in spec/v1.3/oamp-v1.3-draft.md. The interop matrix that lists which backends implement which capabilities is in docs/governed-memory-interop-matrix.md.
Memories should be the user’s. The substrate should make sure they stay that way.
Links:
- Spec: github.com/deep-thinking-llc/open-agent-memory-protocol
- v1.2 spec:
spec/v1.2/oamp-v1.2.md - v1.2 governance design note:
spec/v1.2/oamp-v1.2-governed-memory.md - v1.3 draft:
spec/v1.3/oamp-v1.3-draft.md - Interop matrix:
docs/governed-memory-interop-matrix.md - Reference implementations: Rust, TypeScript, Python, Go, Elixir
- License: MIT
- Contact: [email protected]