Memory¶
Owners: pi-devbox (how the image
wires observational memory, docs/observational-memory.md at 47b4506),
mempalace-toolkit (the palace
bridge and the fleet design, at c04d488), and the upstream
pi-observational-memory and
MemPalace projects
A language model remembers nothing between requests. Everything it knows about the current work has to be in its context window, the text sent with each request, and that window has a fixed size. We add memory at three levels. Each solves a different problem.
| Level | Problem | Mechanism |
|---|---|---|
| Within one session | a long session outgrows the context window | observational memory |
| Across sessions | a new session, or a recreated container, starts knowing nothing | MemPalace |
| Across the fleet | several machines work on the same things without knowing about each other | one shared palace, and its coordination log |
In short: observational memory keeps a session coherent, and the palace keeps the fleet coherent.
Within a session: observational memory¶
The problem¶
When a session outgrows the context window, pi compacts it. It replaces the older part of the conversation with a summary and keeps recent messages word for word. The summary is written by a model at the moment the window is full, about text that is about to disappear. Detail is chosen in a hurry, and once the summary is written the original wording is out of reach.
What we do instead¶
The pi-observational-memory package, which the image installs, changes when the remembering happens. While the session runs, background workers keep a ledger:
- Observations: dated events from the conversation, each tied to its source. "The user rejected option B because it needs a base rebuild."
- Reflections: lasting conclusions drawn from several observations. "The user avoids changes that need a base rebuild."
- Drops: observations retired because they no longer matter, such as the details of a bug that is now fixed.
When compaction comes, it does not ask a model to summarise. It folds the ledger into the compacted memory, which takes no model call. Every line of the result carries a 12-character id.
flowchart LR
a0["Plain compaction"] --> a1["Model summarises<br/>under pressure"]
a1 --> a2["Prose summary,<br/>no way back"]
b0["Observational<br/>memory"] --> b1["Ledger written<br/>as you work"]
b1 --> b2["Compaction<br/>folds the ledger"]
b2 --> b3["Lines with ids<br/>you can recall"]
What it gives the agent¶
- Nothing important vanishes silently. Compaction still drops detail, but the
recalltool takes an id from the compacted memory and returns the exact source: the original wording, file paths, error text. The agent recalls before an action that depends on a remembered detail. - Compaction is not a stall. The slow work happened earlier, in the background.
- It costs little. The workers run on a cheaper, faster model than the session. The ledger lives in the session file and takes no context space until it is folded.
- It needs no habit. It runs on its own.
recall is not a search tool. It takes one specific id, never a topic. Searching
by topic is what the palace is for.
Where it lives¶
The ledger is stored as entries inside the ordinary pi session file, on the volume that holds pi's configuration, so it survives a container recreate. Memory follows the session's branch: a forked or resumed branch sees its own ledger, not another branch's.
Across sessions: MemPalace¶
MemPalace is a memory store for agents. It holds several kinds of memory, each retrieved in a different way:
| Store | What it holds | Found by |
|---|---|---|
| Drawers | verbatim text: a finding, a decision and its reasons, a runbook. Grouped into wings (a project) and rooms (an aspect of it) | similarity of meaning |
| Diaries | each agent's own account of a session, including what did not work | agent and date |
| Knowledge graph | facts that change over time, each with the time it became true and, when it stops, the time it stopped | entity and point in time |
| Coordination log | messages between agents | address and order (see below) |
The agent's instructions tell it to search the palace before answering about earlier work, and to write a diary entry before a session ends.
The bridge into pi¶
A pi extension from mempalace-toolkit connects each session to the palace:
- Tools. Every palace operation becomes a tool the agent can call.
- Wake-up. When a fresh session starts, the extension injects the palace's status, recent diary entries and any messages waiting for this machine, so the agent starts oriented.
- Transcript feeding. When a session ends, and at quiet moments during a long one, the extension exports the session's transcript and files it in the palace. No cron job or manual step is needed. Secret values the machine holds are removed from the export before it leaves the machine.
- Provenance. Everything the extension writes is stamped with
<harness>@<device>, such aspi@laptop, so every record says which machine it came from.
Across the fleet: one shared palace¶
Every device's sessions use one central palace, reached over HTTPS, instead of a palace of their own. The devices are thin clients of one server. What one machine files is visible to all the others at once.
flowchart LR
a["Device A<br/>pi session"] --> p["Central palace"]
b["Device B<br/>pi session"] --> p
c["Device C<br/>pi session"] --> p
This changes what memory is for:
- Awareness. An agent starting on a project can read what other machines did on it yesterday.
- Work is not repeated. An investigation that took three hours on one machine is a single search on the next.
- Corrections travel. When a machine finds that something it filed was wrong, the correction is filed where every other machine will find it.
It also has costs, and the agents' instructions spell them out:
- Everything is visible to everyone. There is one shared access token and no per-agent scoping. Nothing secret may be filed. That is why erdc-palace-check exists.
- Provenance is no longer obvious. Most records came from other machines, and the file paths in them do not exist locally. Some maintenance commands that are safe on a private palace would delete other machines' records on a shared one.
The palace is backed up on the server with a tool that copies its databases consistently; a plain file copy of a live palace can be corrupt. The same document covers restoring a palace and proving that the restore worked.
The coordination log: a mailbox between agents¶
Agents on different machines hand each other work through the palace's coordination log. It is an append-only list of events. Nothing is edited after it is written, and a correction is a new event.
- A directed ask is addressed to one agent on one device (
pi@laptop) and carries a correlation id that joins the thread. - The ask is owed until the recipient appends a reply on the same correlation
id with a terminal status:
applied,superseded,failedorblocked. An acknowledgement, or a status such asclaimed, keeps the ask visible as taken but unfinished. - A broadcast (addressed to
*) is a notice on a wall. Every machine can read it, but nobody owes a reply, so a broadcast never lands in a mailbox. To make the whole fleet act, send one directed ask per device with a shared correlation id.
The bridge works out which asks this device still owes and shows them at session start. During a session it checks every few minutes. It does not wake the model: a new message waits until the next turn, which a person starts. The message says so, so the person watching knows to send something.
The log is durable, not a chat. A machine that sleeps for three weeks finds its asks when it wakes. Nothing expires, and nothing is re-routed.
Asks that wait for a condition¶
Some asks describe work that only becomes possible later. The first-boot acceptance round, for example, can only run once the container has been recreated on a new release. Announcing such an ask in every session, for days, buries the messages that matter.
An ask can therefore name the condition it is waiting for, as a short list of checks on local files: a field in the image's build manifest, or a file's modification time. While every check still matches, the ask is dormant: it stays owed but is only counted, not announced. The moment one check differs, it is announced again. A check that cannot be evaluated, such as a missing file, counts as changed. That way an ask cannot disappear because its condition was unreadable.
Shared results: claims¶
When one device has verified something that holds for every device, such as a release's contents or an image's digest, it publishes a claim: a broadcast keyed on exactly what was verified. The next device checks the claim's keys against its own readings and, if they match, skips that work. A device honours a claim only when its own readings match the claim's keys. Claims are a convention of the first-boot acceptance round, built on the log. See Fleet operations.
Which memory to use¶
| Question | Where the answer is |
|---|---|
| What did we decide 200 turns ago in this session? | observational memory, then recall for the exact wording |
| What did we decide last month, or on another machine? | palace search and diaries |
| What is true right now about a version or an owner? | the knowledge graph |
| Does another machine need something from me? | the coordination log |
Sources¶
- pi-devbox
docs/observational-memory.md - mempalace-toolkit
docs/fleet-memory.md,docs/rfc-003-coordination-log.md,docs/secret-hygiene.md,docs/backup-and-recovery.md,extensions/pi/README.md - the baked
mempalaceskill, and thepi-devbox-firstbootskill for claims