# How MMW works

> Records, workspaces, projects, keys and statuses — the big picture of what happens to a fact after remember.

On this page you will learn:

1. what MMW memory is made of: records, workspaces, projects and keys;
2. what the `unverified`, `stale` and `conflict` statuses mean, and why there is no "verified" status;
3. what happens on the server between a `remember` call and the moment `search` finds the record.

The running example: in the `backend` project the agent saved the fact "staging is deployed with the systemd unit `app-staging`", citing the document `docs/deploy.md`. Later the document changed.

## The big picture

```text
  Your assistant                     MMW server
  (Claude, Cursor, Codex, ChatGPT)
        │
        │  MCP over HTTP, key mmw_…  ─────────►  Account
        │  (directly or through                   └─ Project (key is bound to a project)
        │   the local mmw-agent)                      └─ Workspace
        │                                                └─ Records
        │                                                     ├─ content, fact_key
        │  remember(content, ...)                             ├─ source_id / source_hash
        │  ───────────────────────────►  Memory Guard          ├─ status
        │                                → record              ├─ derived_from
        │                                → archivist           └─ graph links
        │  search(query)
        │  ───────────────────────────►  records + source + status
        ◄──────────────────────────────
```

## Records

A record is one fact, decision or agreement. The main field is `content` (the text). Everything else is optional but makes memory more useful:

| Field | Why it matters |
|---|---|
| `fact_key` | A topic key such as `deploy-staging`. Records with the same key are compared with each other. |
| `source_id`, `source_hash`, `source_revision` | Where the fact came from (a document, file or session) and a hash of its content. |
| `confidence` | Confidence from 0 to 1, default 0.5. |
| `derived_from` | IDs of the records this one summarizes (up to 50). |
| `scope` | A label for filtering (`shared`, `private`). It does not restrict access. |

`remember` never deletes or overwrites records. Saving a fact again with the same `fact_key` adds a newer version; the earlier ones are kept and marked. Deletion happens only through an explicit `forget` call, and it is a soft delete: the record and its graph links leave search, while the fact of deletion is kept for audit.

## Workspaces, projects and keys

- An **account** is split into **projects**, and a project into **workspaces** (`workspace`).
- The default workspace is called `default` and is created on the first write. Use separate workspaces to keep topics apart, for example `backend` and `personal`.
- A **key** can be bound to a project: an agent with that key sees only that project. Issuing one key per project or per computer works well.
- Accounts, projects and workspaces are isolated from each other. Inside an organization, record visibility rules apply on top of that; see [Visibility](/organizations/visibility/).

## Statuses

| Status | When it appears | What the agent should do |
|---|---|---|
| `unverified` | Always, on every new record. | Use it as information with a stated source. |
| `stale` | The source changed: a different `current_source_hash` was passed to `search` or `validate_memory`. | Re-read the source and save the current fact. |
| `conflict` | Other records share the `fact_key` but have different content. | Show the discrepancy to a person instead of picking one silently. |

There is no `verified` status. A `source_hash` is provenance, not proof: a client can send any hash, so the server never treats a record as confirmed.

In the example: after `docs/deploy.md` is edited, the agent calls `validate_memory` with `source_id="docs/deploy.md"` and the new hash. The report lists the old record as stale, and `search` with the same hash marks it `stale`. More in [Source and freshness](/memory/source-and-freshness/).

## Summaries and derived_from

An agent can condense several records into one summary and pass their IDs in `derived_from`. The summary **inherits** the status of its sources: if one of them is in conflict or stale, the summary is marked `conflict` or `stale` too. That way a summary never hides an unresolved discrepancy. More in [Conflicts and summaries](/memory/conflicts-and-summaries/).

## What happens after remember

1. **Checks.** Empty or overlong `content`, `source_hash` without `source_id`, `confidence` outside 0..1, more than 50 IDs in `derived_from` or IDs that do not exist: the request is rejected with a clear error. The plan's record limit is checked too.
2. **Memory Guard.** Secrets (API keys, tokens, passwords) in any field are replaced with placeholders. A record that looks like an attempt to plant instructions in the agent's memory is rejected with `Memory rejected by Security Guard: …`.
3. **Storage.** The record gets an ID and the `unverified` status. If the client sends an `X-Idempotency-Key` header, repeating the same request returns the same record; the same key with different content returns `409 Conflict`.
4. **Archivist.** A model analyses the new record: it links it to recent records (visible in `search` as `graph_relations`) and may mark an older record as refined or outdated. Inside an organization the archivist only works with records the author can see.
5. **Search.** `search` matches by meaning and by keywords and returns records with their source, confidence, status, `derived_from` and links.

Without an active subscription memory is unavailable. Once a subscription expires, memory becomes read-only for a grace period: you can still search, but not save.

## The local agent

mmw-agent is an optional helper on your computer. It forwards every call to the server, adds the `mmw_sync_status` tool and, only after you consent in a terminal (`mmw-agent consent`), uploads Claude Code and Codex session history. Search over uploaded sessions is not available yet. See [The mmw-agent](/agent/overview/).

## What's next
