Provenance
How zero-memory ranks memories by who wrote them and shows which client each memory came from.
Every memory carries provenance: who authored it (author_kind), which agent
or tool wrote it (agent_name), and how it entered the store (source).
Provenance is not just metadata. It is an authority signal that feeds
deduplication, conflict resolution, and recall ranking, and it is what the
dashboard uses to show which client created each memory.
Parallel write paths, unequal trust
Facts reach the store through parallel paths that all go through the same
write pipeline. In-band, the chat agent deliberately records a milestone with
remember; precision is high, because the model that wrote it had the full
conversation in view. Out-of-band, the watcher re-reads the session transcript
and extracts facts with a lightweight model. Two more paths are curated and
bootstrap: an import of already-atomic memories from another tool, and the
one-time harvest of a repository's own documents and history. The import is
curated by construction; the harvest runs the same extractor as the watcher and
inherits its trust level.
Left unranked, these two paths capture the same event twice: the agent's
remember and the watcher's extraction of the same discussion land as
near-duplicates and surface as conflicts. The guiding invariant: a lightweight
model is a weak author but a reliable checker. So the in-band agent writes,
and the watcher audits coverage — writing only what in-band capture missed,
and marking those writes as second-class.
Authority rank
Authority is ranked by role, deliberately not by which model did the writing (models change; roles are stable):
| Rank | Role | agent_name |
|---|---|---|
| 2 | Human | zm-web |
| 1 | In-band agent (direct remember), curated imports | client name / null |
| 0 | Provisional: watcher extraction, repository bootstrap | watcher, bootstrap |
A memory reaches rank 2 by being typed by a person: merging a conflicting
pair in the review queue writes the text you compose in the form, and that row
is recorded as human-authored. The two halves answer different questions.
author_kind says who wrote it, agent_name says through what, so a merge
reads human and zm-web together, and the badge shows human · Dashboard.
Approving something the system drafted is deliberately not authorship. A reflection distillate you accept keeps rank 1: you endorsed the text, you did not write it, and rank 2 is reserved for words a person chose.
The rank flows through three mechanisms. The first is audit-first capture. A provisional write does not land unconditionally: the write path first asks whether an authoritative memory already covers the same fact, a similarity probe across everything the owner has, at a threshold below same-scope deduplication so paraphrases are caught too. If one does, the provisional write yields and the existing memory's id is returned instead of a second, weaker copy. Authoritative writes skip the probe entirely. As in-band capture discipline grows, the watcher automatically writes less; its remaining value, capture when no cooperative agent is present, is preserved.
The second is automatic conflict resolution. When hygiene finds an authoritative memory in conflict with a provisional one, authority decides and no human is queued: the provisional side is reversibly superseded whatever the judge's verdict or confidence was. Two provisional memories are collapsed toward the newer one on the same reasoning — low trust, low stakes, recoverable. Two authoritative memories are never settled by rank alone; that pair is what the judge and the review queue are for.
The third is recall ranking. At equal relevance, provisional memories rank below authoritative ones.
Client attribution
Provenance also answers a simpler question: which tool created this memory?
A direct remember stores the MCP client's name (from the connection
handshake) into agent_name, so a memory written from one coding agent is
distinguishable from one written from another. Watcher ingest keeps
agent_name = 'watcher', because the trust level depends on it, and carries
the originating client as a separate dimension in source.client. Trust and
attribution never share a field. Imports are curated, authoritative writes and
carry no agent name.
Raw client identifiers are normalized to stable display labels in one place, so every surface shows the same names.
Attribution is forward-only. Memories written before client attribution
existed have no client to recover, because their identity was lost at write
time, so older rows may show only author_kind. No backfill is attempted.
Session marker
Provenance also records which conversation a fact was born in. A memory
written inside an attached conversation carries two more keys in source:
| Key | Value |
|---|---|
thread | The session-thread token (thr_…) — client-neutral, and it survives a transport reconnect. |
client_session_id | The client's own session id, opaque (for Claude Code, the transcript file's UUID). |
Both are pointers, never content: they say where a fact came from, and no part of the conversation itself is stored beside them. The transcript stays on your machine. The marker is what lets it be found again and re-read on demand, rather than being copied into the store to be searched there.
The thread is the primary of the two because it is ours rather than any one client's: clients number their sessions differently, and a single client session can split across reconnects. A thread also expires (24h), so the marker records the conversation's identity as of the write. Stitching a chain of conversations together is a separate question.
Marked: direct remember inside an attached conversation, and watcher ingest
(which always knows the client session id, and adds the thread when the
conversation has a live one). Unmarked, and honestly so: imports, the
repository bootstrap harvest, terminal quick-capture, dashboard actions, and
everything written before the marker existed. No backfill is attempted.
On a memory's page, the marker appears in the provenance panel, and a From
the same session section lists the other facts that came out of that same
conversation, a temporal neighbourhood rather than a claim that they are about
each other. Exports carry the marker in the frontmatter source field;
re-importing such a file does not re-apply it, since the import is a new write
with no conversation behind it.
Where you see it
The memory card renders a provenance badge, author_kind · client (for
example agent · Claude Code), alongside kind, scope, and visibility badges.
Ingested memories show both their provisional trust level and the client the
transcript came from.

The activity feed attributes every tool call (recall, remember, ingest) to its client as well, so read-side usage is broken down by tool independently of the memories themselves.
See Memory model for the memory fields provenance lives on, and Hygiene for how conflicts are detected and resolved.
Identity
Prefixed, self-describing domain identifiers, branded id contracts, the system-of-record rule that decides which ids are ours to shape, and how a project is identified.
Supersede and versioning
How a writer that knows it is updating a fact declares the replacement explicitly, and how superseded memories form version history.