Apply P17: memory is three files read once per epoch; the memory tool with consolidate

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-24 13:11:31 -07:00
co-authored by Claude Opus 5.5
parent 85d9519d22
commit 428b87d31d
2 changed files with 16 additions and 8 deletions
+15 -7
View File
@@ -85,9 +85,9 @@ ordinary outbound networking can reach the whole tailnet and the internet as the
## Inference contract (the part existing harnesses get wrong)
1. **Baseline budget.** System prompt plus tool schemas at session start: 3,000 tokens or less,
measured with the server's tokenizer (`/tokenize`), enforced by a test. That test needs
straylight, so it runs in `make verify-device`, not in the offline `make gate`.
1. **Baseline budget.** System prompt, tool schemas and the three memory files at session start:
3,000 tokens or less, measured with the server's tokenizer (`/tokenize`), enforced by a test.
That test needs straylight, so it runs in `make verify-device`, not in the offline `make gate`.
2. **Append-only.** The request for turn N+1 is a strict extension of the request for turn N.
Nothing volatile (time, heartbeat notes, memory refreshes) goes anywhere but the newest message.
Enforced by a property test on the serialized message array. The session log stores each
@@ -173,9 +173,17 @@ a multi-turn tool conversation and tool parsing had no failures in 20 trials.
Memory is what carries continuity across epoch compaction, so it is required. It must not break
the inference contract, and it must not become a way for injected text to persist.
1. **Core block.** `memory/core.md`, owner-curated, 300 tokens or less, part of the baseline.
Edits take effect at the next epoch, never mid-session. The agent can propose changes; only an
`ask` approval or the owner's editor applies them.
1. **Memory files.** Three files, read once per epoch into the baseline, in this order after the
system prompt: `memory/soul.md`, the persona, written only by the owner (at most 4,000
characters); `memory/memory.md`, the agent's core notes on its work (at most 2,200 characters);
and `memory/user.md`, its core notes on the owner (at most 1,375 characters). Each file is shown
with how full it is. The agent edits the last two with a `memory` tool: `add`, `replace` and
`remove` an entry, and `consolidate`, one edit that marks every entry of a file kept,
rewritten, moved or dropped. Moved entries are appended to `memory/archive.md` (append-only,
each entry with the date and session it was first approved in), where `recall` finds them;
nothing leaves `memory.md` silently. Every edit is `ask`, and the approval shows `consolidate`
as a diff. An approved edit takes effect at the next epoch, never mid-session. A write over a
file's limit is refused with a pointer to `consolidate`.
2. **Everything else is retrieved, not injected.** A `recall(query, k)` tool returns size-capped
snippets with file, line and provenance. Results are appended like any tool result, so the
cache prefix is untouched.
@@ -204,7 +212,7 @@ the inference contract, and it must not become a way for injected text to persis
Files are the source of truth. SQLite is allowed only for rebuildable indexes and queues.
- `sessions/<id>/<epoch>.jsonl` — append-only session log
- `memory/core.md`, `memory/notes/*.md`, `memory/topics/*.md` — owner-readable memory
- `memory/soul.md`, `memory/memory.md`, `memory/user.md`, `memory/archive.md` — owner-readable memory
- `index/` — FTS5 and, later, vectors; disposable and rebuildable from `memory/`
- `grants/*.toml` — owner-written
- `audit/*.jsonl` — hash-chained