Anthropic's Managed Agents memory stores can keep text across sessions. For an application that must give two agents the same reviewed fact, persistence is only the first step. The application must decide whose record it is, check the original evidence, select one stored revision and preserve its exact bytes before either agent sees it. This guide is for developers with authorized Managed Agents beta access and control of their application's authentication, store selection and agent configurations. It is based on Anthropic's current memory documentation and API references checked on 20 October 2026; BIG CHANGE did not run an account or model test.
The big change
- What changed: A reviewed, typed JSON memory can persist in a Managed Agents store. The application checks its source and exact stored bytes, freezes one private snapshot, then sends those same approved bytes to two separate authorized sessions without a memory-store attachment.
- Why it matters: A later store edit cannot change the inputs already constructed for those sessions.
- What to watch: Source accuracy, user authorization and answer quality still require separate checks.
Before you start
Bring one real fact, preference or project rule with a permissioned original, its stable source ID and revision, and an owner who approves storage and disclosure to both agent roles. Decide a review-freshness limit suitable for that record before reviewing it. Confirm Managed Agents beta access, a private API key, an authorized workspace, two configured agent IDs, an environment and a permitted model in your account. Inspect current usage and pricing before allowing the four bounded consumer sessions in this procedure. Keep the key out of prompts and receipts.
Your application needs authenticated principal-to-scope mapping. In trusted application state, bind the principal to an approved ownerScopeId, workspace ID, store ID and the two permitted agent IDs. Give private users or projects separate stores where their access rules differ. A workspace API key does not authenticate an end user, a path is not a tenant boundary, and a prompt cannot remove a tool or credential. Verify that both consumer configurations lack a store attachment and any connector, environment credential or tool route to the mutable store. If you cannot establish that boundary, stop before sending the record.
1. Approve a record against its source
Use this structural template, replacing every bracketed value with real approved evidence. It is not a sample fact or a claimed result. Serialize the completed object into one exact UTF-8 JSON text before approval. Your validator should accept precisely these fields and types, reject unknown fields, require nonblank strings and valid UTC timestamps, restrict kind to fact, preference or project_rule, and restrict status to active, disputed or superseded. Only active records may be injected. The approved claim must match the cited original, including its effective date and scope.
{
"schemaVersion": "memory-record/v1",
"recordId": "<opaque stable record ID>",
"ownerScopeId": "<trusted mapped scope ID>",
"kind": "<fact | preference | project_rule>",
"claim": "<precise source-supported claim>",
"sourceId": "<private original-source ID>",
"sourceRevision": "<original revision or exact source hash>",
"sourceQuoteOrPointer": "<minimal permitted quote or stable pointer>",
"validFrom": "<UTC timestamp>",
"checkedAt": "<UTC timestamp>",
"status": "active",
"reviewerId": "<approved human reviewer ID>",
"reviewedAt": "<UTC timestamp>"
}The application's private approval receipt must identify the real approver, owner permission, original source and revision, scope and permitted agents, freshness rule, and SHA-256 of those exact UTF-8 JSON bytes. It records a human decision on the actual claim. A reviewerId string in the record is not authentication. Do not persist a record with an unresolved contradiction or missing permission. Anthropic stores the text; it does not validate this schema or establish the claim's truth.
2. Persist it and read it back
Create or select a narrow memory store in the authorized workspace and record its real memstore_... ID. Use a non-sensitive path such as /records/{opaque-record-id}.json. Before the request, journal actor, UTC time, source revision, approved byte hash, store/path and pending state. On direct memory-store calls use agent-memory-2026-07-22; session calls use managed-agents-2026-04-01. Anthropic says combining those beta headers on a store request returns HTTP 400. The create reference and memory manual show this SDK form; check the installed SDK against the current reference:
mem = client.beta.memory_stores.memories.create(
store.id,
path="/records/<opaque-record-id>.json",
content=approved_json_text,
)Creation does not overwrite an existing path. Save the returned mem_... ID, then list /records/ in the scoped store, following each next_page as the next page. The default basic list omits content. Retrieve the selected memory by ID for its full text; compare store ID, memory ID, path, content and content_sha256 with the approved bytes. Record the response and direct readback in the journal and registry. A create response alone is not the completion check. If the response is uncertain, inspect the exact path and direct record before deciding what happened; a missing search hit alone does not justify repeating the create.
3. Freeze the selected revision
For each later run, authenticate the caller and resolve its scope, store and selected record ID from the trusted registry. List the scoped prefix through every page if you need discovery, then retrieve the selected mem_... directly. Compute SHA-256 over the UTF-8 encoding of the returned content, compare it with the provider's content_sha256 and the human approval's exact byte hash, and validate the JSON again. Check record ID, owner scope, source revision, active status, source currency and the predetermined freshness limit. If any check fails, send nothing.
Write the exact retrieved bytes once to private storage addressed by their hash, using exclusive-create semantics such as Python's open(path, "xb"). Re-read and hash the file immediately and before each send. Never overwrite an existing snapshot. A partial file or an existing file with different bytes at that address is a hold requiring reconciliation. Keep the original approval, store ID, memory ID, provider hash, snapshot hash and scope decision in a private retrieval receipt. This write-once snapshot is an application design, not a version-pinned Anthropic mount.
4. Supply the same bytes to two fresh sessions
Create agent A's fresh session with its real authorized agent and environment IDs and no memory-store entry in resources. Confirm the returned session's resources and effective agent tools and credentials leave no alternate route to the store. Anthropic's session guide documents separate creation and user.message sending:
session = client.beta.sessions.create(
agent=approved_agent_id,
environment_id=approved_environment_id,
)
client.beta.sessions.events.send(
session.id,
events=[{"type": "user.message", "content": [{"type": "text", "text": message_text}]}],
)Before events.send, re-read and hash the private snapshot. Construct message_text deterministically from an explicit “reviewed data” label, the record/source/review identifiers, the unchanged JSON text and its SHA-256, followed by a narrow question the original source can answer. The displayed fields are an application message format, not provider response fields. Journal the full UTF-8 message bytes and hash, selected snapshot hash, authorized agent ID, session ID and send state before sending. Retain the send outcome and real sent-event ID or event-list readback when available. An unknown send outcome calls for event readback, not a blind resend.
Make a second fresh session for agent B with its separately approved agent ID and the same absence of store access. Re-read the same write-once snapshot, verify its byte hash, construct and journal B's complete message, then send. Both messages may have different task questions or recipient metadata; verify that the embedded JSON bytes and approved record hash are identical. Inspect each agent's answer and any tool events against the original source. A plausible answer or a citation does not prove the model's internal reliance on the injected text; the message and provider event receipts establish what the application supplied. If either session has a live mount or alternate store path, do not send to it.
5. Update only after a new source review
When the original changes, retrieve the current memory directly and compare old and new evidence with the owner. Have the human approve exact replacement JSON bytes with the stable record ID, corrected claim or source pointer, new source revision and check/review times. Preserve the old receipt and hash. Journal the mem_... ID, current directly read content_sha256, intended replacement hash, actor, approval and pending state. The documented conditional update is:
client.beta.memory_stores.memories.update(
memory_id=memory_id,
memory_store_id=store_id,
content=approved_replacement_json_text,
precondition={"type": "content_sha256", "content_sha256": fresh_old_hash},
)The provider hashes exact UTF-8 content without normalization. A mismatch returns HTTP 409 memory_precondition_failed_error. On that response, or an uncertain network result, retrieve the live memory again and inspect the version history as needed. Compare the competing source revisions and ask the owner to merge, reject or approve a new exact replacement; never blindly retry the stale write. On success, direct retrieval must confirm path, full replacement text, hash and memory version ID before the journal becomes confirmed.
Freeze a new approved snapshot from that verified revision. Start new authorized A and B sessions without store mounts and repeat the two sends and source checks. Do not alter old snapshots or claim that already sent messages update themselves. Mark the earlier snapshot ineligible for future injection. If the owner withdraws a record, stop new sends and apply their retention and redaction policy: deleting a current memory does not necessarily remove retained versions. Whole-store archive or deletion is a separate decision.
What counts as done
Your private receipts should connect original permission and source revision to the exact approved JSON hash; real workspace/store/path/mem_... identity and direct create readback; one immutable snapshot; two distinct authorized, unmounted session IDs with sent message hashes and source-checked answers; and the approved conditional update with new direct readback and new-session checks. If any link is unknown, mark the whole exercise incomplete and retain the precise hold. Record actual session/tool usage and account-specific cost if you run it; this documentation-only guide measured neither savings nor model performance.
For related but different work, reviewing one Dream output for a later session addresses a generated store proposal. The process here starts with an owner-approved source record and pins exactly what two consumers receive.



