docs/book/src/architecture/memory-payload-lifecycle.md
ZeroClaw carries several kinds of "remembered" information during a turn. They do not all have the same owner, durability, privacy boundary, or review risk.
Use this page when a change touches memory, history, session persistence, tool results, files, media attachments, summaries, context trimming, or prompt assembly. The most important question is not "does the agent remember this?" but "which surface owns this data, and how long does it live?"
| Surface | Owner | Durability | What reviewers should check |
|---|---|---|---|
| Long-term memory | zeroclaw-memory behind Arc<dyn Memory> | Backend-specific: SQLite/Postgres/Lucid/Qdrant/shared stores, or per-agent Markdown files | Stores and recalls must stay agent-scoped. A tool result, log line, or session row is not long-term memory unless a memory write happened. |
| Relationship memory | knowledge tool and knowledge graph | Graph backend, when enabled | Capture is explicit. Enabling the graph does not automatically ingest conversations, files, or channel data. |
| Session history | zeroclaw-infra session backends, ACP store, and live RPC/session maps | Chat/ACP history can persist; live RPC handles are process-local | History preserves conversation continuity. It is not the canonical store for user preferences, config, or files. |
| Current prompt context | Agent loop prompt assembly | Ephemeral provider request | Recalled memory, hardware RAG, current input, system prompt, skills, and tool results may be sent to the provider. This does not make them durable. |
| History trimming | agent::history and agent::history_trim | Lossy change to the request/session history shape | Trimming must be visible, preserve tool-call/tool-result pairing, and avoid pretending old context is still available. |
| Tool result payloads | ToolResult, ToolResultMessage, and the tool dispatcher | Current turn and any persisted session history that records the turn | Bound size and provenance. Large outputs should be capped or summarized intentionally; image-path promotion must only happen for producing tools, not path-listing tools. |
| Files and workspaces | Per-agent workspace security policy | Files persist according to the filesystem, not memory | File contents are not memory just because a tool read them. Writes belong in the agent workspace unless policy explicitly allows more. |
| Media attachments | Channel/gateway media pipeline and MediaAttachment | Inbound payload by default; persistence depends on the receiving path | Raw bytes should stay bounded and path-validated. Store summaries or references deliberately rather than silently copying media into memory. |
| Logs and observer events | zeroclaw-log, ObserverEvent, runtime trace | Optional runtime trace and live observers | Logs are evidence and diagnostics, not source-of-truth memory. Scrub or bound user/tool payloads before logging. |
| Cost and usage records | Cost tracker and provider usage events | Cost ledger when enabled | Usage records describe model calls. They should not carry prompt bodies, tool outputs, or memory contents. |
This table complements Runtime state and persistence. That page says where state lives; this page says how user-facing payloads move through memory, history, tools, files, media, and provider requests.
An agent receives its memory handle from the memory factory. Shared backends and Markdown storage have different concrete layouts, but the review rule is the same: memory access must stay bound to the agent identity and configured peer allowlist described in Runtime internals.
There are two normal ways information becomes durable memory:
memory_store;Do not treat prompt context, tool output, files, or logs as durable memory by default. A PR that makes one of those surfaces persistent must name the memory category, session scope, agent scope, retention behavior, and operator-visible control.
At turn start, the runtime can recall relevant memories and inject a bounded
[Memory context] block into the user-visible prompt context. Related entry
points do not all apply identical filters. The channel/interactive loop filters
generated autosave noise, stale <tool_result> blocks, and Conversation entries
when the turn has no safe session scope or is not user-initiated. Generic memory
loading filters autosave noise and relevance, but does not by itself enforce
that channel-loop Conversation exclusion.
The provider request can therefore contain recalled memory without making the current turn a new memory. Review prompt-assembly changes by asking:
Session history is the continuity record for a conversation. It can include chat messages, assistant tool calls, and tool results. It is not the same thing as long-term memory.
History management owns the trimming mechanics. This page only names the lifecycle boundary: trimming is a lossy change to provider-visible/session-visible context, not a memory delete, and it must be visible rather than silently pretending old context remains available.
Tool-call pairing matters more than byte savings. A history change must not
leave a provider request with a dangling tool_use without the matching
tool_result, or the reverse.
Tools return a small structured result: success, output, and error. The
dispatcher converts those results into provider messages for the next model
call, while streaming clients can receive correlated ToolCall and
ToolResult events during the turn.
Tool result payloads are easy to over-preserve. Reviewers should check:
max_tool_result_chars;If a PR says a tool result is "remembered", require it to say whether that means provider-visible history, persisted session history, a memory backend row, a file artifact, a receipt, or a log event.
File contents and media bytes are payloads, not memories. The filesystem owner is the per-agent workspace policy described in Filesystem components and Runtime internals. A file read can place content in a tool result or prompt; a file write can create durable filesystem state; neither automatically creates a memory row.
Inbound channel messages can carry MediaAttachment values with a file name,
bytes, and optional MIME type. MediaKind is derived from MIME type or file
extension. The low-level attachment loader reads caller-supplied paths verbatim,
so callers that accept untrusted paths must validate or constrain those paths
before loading.
For files and media, reviewers should look for:
Observer events and runtime logs help explain what happened. They should not become hidden payload stores. Memory recall events carry a scrubbed/truncated query summary and counts. Memory store events carry bounded category and backend identifiers.
Tool-call observability needs extra care because the sinks do not share one payload contract. Current typed tool-call observer events can carry full arguments and credential-scrubbed full result output, and OTel forwards those values into span attributes. Do not describe that path as "summaries" unless the code actually bounds or summarizes it. New telemetry should prefer bounded identifiers, counts, durations, success flags, and operator-useful summaries. Put raw content in logs or observer events only when the feature explicitly requires it and the privacy boundary is documented.
For memory, payload, history, file, or media changes, answer these before reviewer sign-off:
Canonical docs:
Key code entry points:
crates/zeroclaw-api/src/memory_traits.rscrates/zeroclaw-memory/src/lib.rs,
crates/zeroclaw-memory/src/agent_scoped.rs, and
crates/zeroclaw-memory/src/agent_scoped_markdown.rscrates/zeroclaw-tools/src/lib.rs
(MEMORY_TOOL_NAMES), crates/zeroclaw-tools/src/memory_store.rs, and
crates/zeroclaw-tools/src/memory_recall.rscrates/zeroclaw-runtime/src/agent/memory_inject.rs
(recall policy plus the [Memory context] renderer), injected engine-side in
crates/zeroclaw-runtime/src/agent/turn/mod.rs; the per-turn memory handle is
threaded through crates/zeroclaw-runtime/src/agent/loop_.rscrates/zeroclaw-runtime/src/agent/history.rs,
crates/zeroclaw-runtime/src/agent/history_trim.rs, and
crates/zeroclaw-runtime/src/agent/turn/results_collect.rscrates/zeroclaw-api/src/tool.rs and
crates/zeroclaw-api/src/model_provider.rscrates/zeroclaw-api/src/channel.rs and
crates/zeroclaw-api/src/media.rs