# Layered Memory

Canonical: https://auggy.dev/docs/augment-layered-memory
Status: Published
Package: auggy 0.5.0

Persist and recall peer-scoped episodic memory with the stable SQLite-backed layeredMemory augment.

## Outcome

**What it enables:** Remember names, preferences, commitments, and recurring topics for the current peer across turns.

- **Status:** Stable
- **Availability:** Install with ``auggy augment add` layeredMemory`.
- **Contributes:** `peer-scoped memory provider`, `memory tools`, `recent-memory context`, `Console administration`

layeredMemory is peer-scoped episodic memory. The default install stores entries in SQLite and gives the shared memory bus a writable namespace; the runtime binds writes and searches to the peer identity on the current turn.

## Install and defaults

**From the agent project**

```bash
auggy augment add layeredMemory
```

**Installed and runtime-created files**

```
agent.yaml                              # adds layeredMemory
augments/layeredMemory/augment.yaml   # generated config
skills/layeredMemory/SKILL.md          # bundled usage guidance
data/memory.db                         # created when the runtime boots
```

**augments/layeredMemory/augment.yaml for an agent named my-agent**

```yaml
type: layeredMemory
config:
  backend: sqlite
  dbPath: ./data/memory.db
  namespace: my-agent
  retentionDays: 90
  autoSave:
    enabled: false
```

The CLI sets `namespace` to the agent name and rewrites the mutable database path under `data/`. No extra package or environment variable is required. Explicit writes work immediately; automatic extraction is off in the generated config.

## Use it

When Sam states a preference that should survive this conversation, write a topic. Do not construct a peer ID or internal label; the runtime derives both from the current turn.

**Save and retrieve a preference**

```ts
memory_write({
  topic: "preferences",
  content: "Sam prefers concise replies with code examples.",
})

memory_search({ query: "concise code examples" })
```

> **Note: Persistence is explicit**
>
> Only tell the caller the preference was saved when the ``memory_write`` result starts with ``PERSISTED``. ``NOT_PERSISTED`` means it was not saved; ``PERSISTENCE_UNKNOWN`` means inspect logs before retrying.

## Runtime surfaces

| Surface | Exact behavior |
| --- | --- |
| ``memory_write`({ topic, content, provider? })` | Writes under a runtime-derived label for the current peer. Exact-label namespace writes are refused. |
| ``memory_search`({ query, providers? })` | Runs keyword matching and returns only entries scoped to the current peer. |
| ``memory_list`()` | Lists visible static labels and namespace providers such as `my-agent:*`; it does **not** list stored facts. |
| ``memory_read`({ label })` | Unsupported for layeredMemory because direct label reads would bypass peer scoping; use ``memory_search``. |
| ``memory_forget`({ peerId })` | Deletes all episodic entries for one peer across supporting providers; requires `creator` or `agent` trust. |
| Turn context | Adds up to five recent current-peer entries, plus keyword matches for the incoming message. |
| Console Memory panel | Shows counts and recent entries and exposes a confirmed **Erase peer** action. |

## Boundaries

| Boundary | What to design for |
| --- | --- |
| Trust | Peer isolation depends on runtime identity, not names or claims in chat. A caller cannot select another peer for reads or writes; only elevated trust can erase by peer ID. |
| Persistence | SQLite survives process restarts only while `data/memory.db` survives. Entries expire after the configured retention period; the generated default is 90 days. |
| Identity continuity | Cross-session recall requires the same durable recognized identity, normally from `visitorAuth` or a verified external app-auth assertion. Anonymous web identity is derived from the thread, so a new thread is not the same returning person. |
| Deployment | ``auggy deploy`` excludes local `data/` from the image. On **Railway** the resolver places the SQLite database directly under the admitted `/app/data` volume; it does not rely on a root-level database symlink. Local memories are not uploaded. Keep the SQLite service to one replica; on another platform, mount durable storage at the configured path. |
| Limitations | Search is keyword matching, not vector retrieval. ``memory_read`` is unavailable, ``memory_list`` is provider discovery, and the model-callable erase operation removes all memory for a peer rather than one fact. |

> **Warning: Do not store secrets**
>
> Treat peer memory as durable application data. Do not save credentials, tokens, content marked confidential, or sensitive personal data outside the agent's stated purpose.

## Verify

**Validate and start**

```bash
auggy doctor
auggy run
```

1. In ``/console/chat``, use the Creator caller and ask the agent to remember a specific preference.
2. Open the ``memory_write`` tool result and confirm its first word is ``PERSISTED``.
3. Confirm the database exists with `test -f data/memory.db && echo ok`.
4. Start a new Creator chat and ask about the preference. Inspect ``memory_search`` if the agent performs a targeted lookup.
5. For a browser visitor test, verify the visitor first, then repeat from a new session and confirm the same recognized peer ID is restored.

## Related

- [Memory and knowledge](https://auggy.dev/docs/memory-and-knowledge/markdown)
- [Visitor Auth](https://auggy.dev/docs/augment-visitor-auth/markdown)
- [Console](https://auggy.dev/docs/console/markdown)
- [Deploy and verify](https://auggy.dev/docs/deploy/markdown)
- [Skills](https://auggy.dev/docs/add-skills/markdown)