Specify the system memory bucket before building it

7aba5407981e · AtlantisPleb · · parent 6f575f466a7b

Specify the system memory bucket before building it

Add the design spec for the third memory bucket (#52): system memories
that the network as a whole learns. The spec settles admission (evidence
receipts plus steward admission events), provenance and supersession on
the existing engram path, privacy tiers reusing dark/pulse/ledger/glass,
distribution on the engram Nostr sync seam, per-source recall caps with
challenge and refutation as first-class events, and the boundary with
the knowledge base (#49). Build issues follow the spec's section 10.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SoZMfWRSGnf6FZX2Ar9rQ2
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>

Deploy story

What this commit did to the running system — joined from the forge receipt chain, the part a commit page elsewhere cannot show.

Not deployed through the forge lane

No push, promotion, build, or deploy receipt references this commit (receipts are scanned over a bounded recent window). Changes shipped by full node replacement carry their proof in the release gate receipt instead.

Changed files

  • added docs/memory/2026-08-25-system-memory-spec.md

Diff

1 file changed, +389 -0

docs/memory/2026-08-25-system-memory-spec.md added +389

@@ -0,0 +1,389 @@

1
# System memory: specification
2
3
- Class: design specification
4
- Date: 2026-08-25
5
- Status: accepted design for the system bucket; no code lands under the
6
  owning issue
7
- Owning issue: OpenAgentsInc/openagents#52
8
- Base: the engram model and its live wiring in
9
  `packages/openagents-cli/src/memory/` (vendored from
10
  `packages/agent-experience-memory`), the user and learned buckets in #51,
11
  the knowledge base in #49, and the engram sync seam whose real Nostr
12
  transport is the remaining project-15 piece
13
- Vocabulary: transparency tiers reuse the forge's `dark/pulse/ledger/glass`
14
  names (`openagents.com` `lib/openagents/transparency.ex`)
15
16
## 1. What a system memory is
17
18
The memory system has two buckets today, both owner-local (#51):
19
20
- **user** — things the reader explicitly asked to have remembered.
21
- **learned** — heuristics the consolidation pass distills from episodes.
22
23
This document specifies the third bucket:
24
25
- **system** — things the network as a whole has learned and every agent
26
  should know. Examples: "the gateway returns 402 when the default model is
27
  retired; check upstream status before bisecting", "`mix precommit` installs
28
  the push guard; a GitHub push is overwritten by the next mirror".
29
30
A system memory differs from the other buckets in kind, not just in scope.
31
A wrong user memory misleads one session; a wrong system memory propagates to
32
every session on the network. A leaked user memory harms one owner; a system
33
memory derived from a private transcript is a privacy breach by construction.
34
An unattributed system memory cannot be challenged, corrected, or discounted.
35
Every decision below follows from those three failure modes.
36
37
The one-sentence design: **a system memory is an ordinary signed engram that
38
has passed an evidence-backed admission gate, carries a transparency tier of
39
`ledger` or above, distributes on the existing engram sync seam, and can be
40
challenged and superseded by further signed events — never edited.**
41
42
## 2. What stays unchanged
43
44
The system bucket adds no new event kind, no new store, and no new channel.
45
It reuses, unmodified:
46
47
- **The engram event model** (`memory/engram.ts`): NIP-AE `kind:30174`
48
  addressable events, the OpenAgents companion body, the hard-unsafe
49
  redaction gate before signing, content digests, and the
50
  `supersedes` correction path. A correction appends; it never edits.
51
- **The projection** (`memory/projection.ts`): derived, idempotent,
52
  order-independent; unresolved supersession chains are refused whole.
53
- **The ranking module** (`memory/ranking.ts`): deterministic cosine top-K,
54
  salience recall, token-budget packing.
55
- **The sync seam** (`memory/sync.ts`): `EngramTransport`,
56
  `EngramSyncQueue`, local-first, never blocks a turn.
57
- **The transparency vocabulary**: `dark` (nothing public), `pulse`
58
  (metadata only), `ledger` (content and metadata), `glass` (full access).
59
60
What the bucket adds is one companion extension (section 3), three event
61
roles (admission, challenge, refutation — sections 4 and 5), one relay
62
namespace on the coming Nostr transport (section 6), and recall caps
63
(section 7).
64
65
## 3. Event shape
66
67
A system memory is an engram whose companion body carries a `system` block.
68
The companion schema id bumps to name the extension; events without the block
69
are user- or learned-bucket engrams and nothing about them changes.
70
71
```jsonc
72
// content of a kind:30174 event, after redaction, before signing
73
{
74
  "slug": "sys:gateway-402-retired-model",
75
  "value": "A 402 from the inference gateway usually means the default model was retired upstream. Check gateway status before bisecting local lanes.",
76
  "openagents": {
77
    "schema": "openagents.agent_experience_memory.nip_ae_companion.v2",
78
    "admission": "candidate",          // existing field; see section 4
79
    "entityId": "inference-gateway",
80
    "contentDigest": "sha256:…",
81
    "sourceEventRefs": [
82
      { "eventId": "…64 hex…", "role": "tool_result" }
83
    ],
84
    "relations": [],
85
    "derivedFromSlugs": [],
86
    "supersedes": "…64 hex…",          // optional, existing path
87
    "system": {
88
      "schema": "openagents.system_memory.v1",
89
      "tier": "ledger",                 // "ledger" | "glass"; never lower
90
      "asOf": "2026-08-25",             // the date the claim was observed true
91
      "evidenceRefs": [                 // at least one, required
92
        {
93
          "kind": "receipt",            // "receipt" | "engram" | "url"
94
          "ref": "https://openagents.com/receipts/…",
95
          "digest": "sha256:…"          // required for kind "url"
96
        }
97
      ]
98
    }
99
  }
100
}
101
```
102
103
Field decisions, and why:
104
105
- **`source` is the event's own `pubkey`.** No separate source field: the
106
  signature already binds author to claim, and a claim nobody signed is a
107
  claim nobody can be held to. Unsigned or unverifiable events are never
108
  projected (existing behavior).
109
- **`asOf` is distinct from `created_at`.** `created_at` orders the chain;
110
  `asOf` dates the claim. Recall renders `asOf` so a stale truth reads as
111
  dated, the same way a knowledge-base stance carries its review date.
112
- **`evidenceRefs` is required and non-empty.** A system memory without
113
  evidence is an assertion, and assertions do not enter the shared store
114
  (section 4). `kind: "receipt"` points at a forge receipt or signed event;
115
  `kind: "engram"` points at a prior admitted engram; `kind: "url"` points at
116
  public material and must carry a content digest so the evidence cannot be
117
  swapped after admission.
118
- **`tier` is `ledger` or `glass`.** By definition a system memory's value
119
  reaches every agent, which is content-plus-metadata — `ledger`. `glass`
120
  additionally asserts that every evidence ref resolves publicly. `dark` and
121
  `pulse` are not valid values here: a claim that cannot ship its content is
122
  not a system memory (section 5 covers what happens to it instead).
123
- **`supersedes` is the only correction path.** Reused as-is from the engram
124
  model. Only the original author or a steward (section 4) may sign a
125
  superseding event for a system slug; the projection refuses a superseding
126
  event signed by anyone else. Anyone else who disagrees files a challenge
127
  (section 5.2).
128
- **Slug namespace.** System slugs carry the `sys:` prefix. The prefix is a
129
  routing convention, not a security boundary — the security boundary is the
130
  admission status and the signature.
131
132
## 4. Admission
133
134
### 4.1 The rule
135
136
**Anyone can propose. Only evidence admits. Only admitted memories surface.**
137
138
Any network identity can sign and publish a candidate system memory
139
(`admission: "candidate"`). Candidates are visible to tooling and to
140
challenge, but recall never surfaces a candidate to a session (section 7).
141
This is the same discipline as a promise flip: the registry does not turn a
142
promise green because someone said so; it turns green on verifiable evidence.
143
Admission is a receipt, not an assertion.
144
145
### 4.2 The pipeline
146
147
1. **Propose.** An author builds the engram (section 3), passes the
148
   hard-unsafe redaction gate, signs it, and publishes it through the sync
149
   queue with `admission: "candidate"` and at least one evidence ref.
150
   A candidate with no evidence refs is refused at build time, before
151
   signing — the schema makes the empty list unrepresentable.
152
2. **Verify.** A steward (section 4.3) checks the evidence: the refs resolve,
153
   digests match, the receipt supports the claim, and the value survives an
154
   independent pass of the redaction gate. Verification is a judgment call on
155
   whether the evidence supports the claim; everything else is mechanical and
156
   tooling performs it.
157
3. **Admit or reject.** The steward signs an **admission event**: an engram
158
   with slug `adm:<candidate-event-id>`, whose `sourceEventRefs` carry
159
   `{ eventId: <candidate>, role: "admission" }` and whose value records the
160
   verdict (`admitted` or `rejected`) and the ground. The admission event is
161
   itself signed, dated, published, and permanent — the receipt for the flip.
162
4. **Project.** The projection derives a candidate's effective status from
163
   the admission events that reference it, exactly as it derives a value from
164
   a supersession chain. The `admission` field on the candidate is the
165
   author's claim; the admission event is the authority. Recall trusts only
166
   the projected status.
167
168
The `EngramSourceRole` literal set gains three members for this and section
169
5: `"admission"`, `"challenge"`, `"refutation"`.
170
171
### 4.3 Who admits
172
173
The steward set is a published allowlist of pubkeys served by the forge
174
(`openagents.com`), bootstrapped to the operator's key. The list itself is
175
signed and dated; clients pin it and refuse admission events from keys not on
176
the list at the admission event's `created_at`.
177
178
This is deliberately centralized to start. Decentralized admission
179
(stake-weighted, reputation-weighted, or multi-steward quorum) is a
180
governance change, not a schema change: the event shapes above already
181
support any number of admitting keys, so broadening the set later touches the
182
allowlist, not the protocol. The spec records the centralization as a known
183
bootstrap posture, not a hidden assumption.
184
185
### 4.4 What qualifies
186
187
A system memory must be:
188
189
- **Network-general.** True for every agent, not one owner's preference.
190
  "The reader prefers pnpm" is a user memory; "the forge refuses non-forge
191
  pushes" is a system memory.
192
- **Operational, not doctrinal.** Claims about how the system behaves,
193
  backed by receipts. Product positions, roadmap status, and reviewed
194
  answers belong to the knowledge base (section 8).
195
- **Falsifiable and dated.** The claim names what would refute it, implicitly
196
  by being concrete: a vague claim ("the network is fast") cannot be
197
  challenged with evidence and does not qualify.
198
199
## 5. Privacy
200
201
### 5.1 The gate
202
203
Nothing crosses from a private transcript into the system bucket without
204
passing, in order:
205
206
1. **The redaction gate** (`guardEngramContent`) — mechanical, already
207
   enforced before any engram is signed. Hard-unsafe categories block
208
   signing outright.
209
2. **Consolidation** — session-derived material enters only as a distilled
210
   heuristic (the existing dream pass), never as a quoted episode. The
211
   synthesizer recombines already-redacted fragments; raw trajectory text has
212
   no path into a candidate.
213
3. **An explicit tier decision** — the owner of the originating scope signs
214
   the candidate (or a consent engram the candidate references) that names
215
   the tier. Redaction is necessary but not sufficient: a perfectly redacted
216
   fact about an owner's project is still the owner's fact. Default is
217
   `dark`; silence never publishes. This mirrors the trace-upload default
218
   (`owner_only`) and the thread default (`dark`).
219
220
### 5.2 What each tier means for memory
221
222
| Tier | Effect on the engram |
223
| --- | --- |
224
| `dark` | Never leaves the owner scope. Not a system memory. The default. |
225
| `pulse` | Existence, slug, and content digest may sync; the value may not. Useful for corroboration counts ("three owners report this pattern") without content. Not recallable as a system memory. |
226
| `ledger` | Value and metadata distribute. The floor for a system memory. |
227
| `glass` | `ledger` plus every evidence ref resolves publicly. |
228
229
A candidate that cites `pulse` evidence can be admitted — the steward
230
verifies against the digest and the owner's consent engram — but admitted
231
memories should prefer `glass` evidence, and the admission event records
232
which tier of evidence it verified.
233
234
## 6. Transport
235
236
Distribution rides the engram sync seam and nothing else. The remaining
237
project-15 piece — the real Nostr transport behind `EngramTransport`, built
238
on `nostr-effect` — is the same transport system memories use. No second
239
channel, no separate poll, no HTTP side door: a system memory is an
240
`EngramEvent`, `publish` enqueues it, `drain` delivers it, `fetch` retrieves
241
it by filter.
242
243
Decisions on top of that seam:
244
245
- **Plaintext-signed, not owner-encrypted.** User and learned engrams
246
  encrypt to the owner. A system memory is shared by definition, so its
247
  content field carries the redacted plaintext body. The tier decision
248
  (section 5) happens before publish; the transport never decides
249
  visibility.
250
- **One relay namespace.** System memories, admission events, challenges,
251
  and refutations publish to the OpenAgents relay under the existing
252
  `kind:30174` with a `t` tag `["t", "system-memory"]` so one subscription
253
  filter (`kinds: [30174], "#t": ["system-memory"]`) pulls the whole shared
254
  store. Clients merge fetched events into their local ledger and reproject;
255
  order-independence (section 2) makes replay and out-of-order arrival safe.
256
- **Local-first still holds.** A relay that is down costs freshness, not
257
  correctness: recall serves the last projected state, and the sync queue's
258
  degraded status is reportable. A turn never waits for the relay.
259
- **Verification on ingest.** Fetched events pass the same checks as local
260
  ones — event id, signature, chain resolution, schema — plus the
261
  steward-allowlist check for admission events. The relay is a carrier, not
262
  an authority; a malicious relay can withhold events but cannot forge
263
  status.
264
265
## 7. Recall and poisoning posture
266
267
### 7.1 Surfacing
268
269
System memories surface on the #51 rails: the per-prompt harness retrieval
270
ranks the projected store against the incoming message and attaches the top
271
memories above a floor as a bounded note. The note names the bucket, so a
272
session can weigh "the network learned" differently from "you asked me to
273
remember":
274
275
```
276
[From memory: (system, as of 2026-08-25, admitted) A 402 from the inference
277
gateway usually means…]
278
```
279
280
Only memories whose projected status is **admitted** and unchallenged (or
281
challenged and refuted — section 7.3) are eligible. Candidates, rejected
282
memories, and memories with an open challenge never surface.
283
284
### 7.2 Per-source caps
285
286
Ranking must not let one adversarial writer dominate recall. Two
287
deterministic caps apply after scoring, before packing:
288
289
- **Per-note cap:** at most **1** system memory per author pubkey in a
290
  single note, and at most **2** system memories per note total (matching
291
  the knowledge-base note limit — more is noise, not context).
292
- **Per-pool cap:** in the ranked candidate pool for a message, at most
293
  **25%** of slots from a single author, enforced by a stable round-robin
294
  over authors in rank order. Ties keep the existing deterministic
295
  tie-breaks, so equal inputs still give equal notes.
296
297
The caps are recall-side, not admission-side, on purpose: admission is the
298
gate on truth, caps are the gate on volume, and an attacker who passes the
299
first still cannot win by flooding.
300
301
### 7.3 Challenge and refutation
302
303
Disagreement is a first-class event, not an edit war:
304
305
- **Challenge.** Anyone may sign an engram with slug
306
  `chl:<target-event-id>`, a `sourceEventRefs` entry
307
  `{ eventId: <target>, role: "challenge" }`, and a value stating the ground.
308
  A challenge carrying its own `evidenceRefs` is an **evidenced challenge**;
309
  one without is recorded but does not change recall.
310
- **Effect.** An open evidenced challenge suspends the target from recall
311
  (section 7.1) until resolved. This is the fail-safe direction: a contested
312
  claim silently absent is cheaper than a poisoned claim silently present.
313
- **Resolution.** A steward resolves by signing either a **refutation** of
314
  the challenge (slug `ref:<challenge-event-id>`, role `"refutation"`,
315
  restoring the target) or a **superseding event** on the target's slug
316
  (correcting or tombstoning it — the existing supersession path, which
317
  stewards may exercise on any system slug). Both are signed, dated,
318
  permanent receipts; the projection derives the current state from the
319
  full set.
320
- **Rate limit.** The per-source caps apply to challenges too: one author's
321
  flood of unresolved challenges cannot suspend the whole store, because an
322
  author's open evidenced challenges suspend at most the same 25% share of
323
  any recall pool; beyond that they queue for steward attention without
324
  recall effect.
325
326
## 8. The knowledge-base line
327
328
The knowledge base (#49) and system memory both put network-level knowledge
329
in front of every session, and without a drawn line they become rival stores
330
of the same claims. The line:
331
332
**The KB owns what the project has reviewed and decided. Memory owns what
333
the network has observed and can evidence.** A stance is editorial; an
334
engram is evidentiary.
335
336
| | Knowledge base (#49) | System memory (this spec) |
337
| --- | --- | --- |
338
| Unit | Stance or doc summary | Signed engram |
339
| Authority | Human review; content checked into git | Evidence refs; steward admission receipt |
340
| Change | Regenerated from docs; edited like content | Superseded by signed events; never edited |
341
| Provenance | Source doc and review date | Author pubkey, `asOf`, evidence refs |
342
| Dispute | Doc PR | Challenge and refutation events |
343
| Typical claim | "Earning is parked; on the roadmap" | "The gateway 402s when the default model is retired" |
344
| Note label | `[From the OpenAgents knowledge base: …]` | `[From memory: (system, …) …]` |
345
346
Two rules keep them from diverging into rivals:
347
348
- **Promotion drains memory into the KB.** When a system memory stabilizes —
349
  admitted, unchallenged for a sustained period, repeatedly recalled — a
350
  human may promote it to a KB stance through the normal docs path. The
351
  promotion supersedes the engram with a tombstone whose value names the
352
  stance, so the claim has exactly one live home.
353
- **The KB wins collisions at recall.** When one message would attach both a
354
  KB hit and a system memory covering the same claim, the harness attaches
355
  the KB hit and drops the memory. Reviewed beats accumulated whenever both
356
  speak; memory's job is to cover the ground review has not reached yet.
357
358
## 9. What this spec deliberately excludes
359
360
- **Decentralized admission governance.** The steward allowlist is the
361
  bootstrap; broadening it is future governance (section 4.3) and blocks
362
  nothing here.
363
- **Cross-owner learned-memory sharing below `ledger`.** `pulse`-tier
364
  corroboration counting is sketched (section 5.2) but not required by any
365
  build issue; it lands only if a concrete need appears.
366
- **Reputation scoring of authors.** The caps in section 7.2 are flat and
367
  deterministic. Weighting authors by history is a later refinement that
368
  must not precede the challenge machinery it would depend on.
369
- **Any change to user or learned buckets.** #51 owns them; this spec only
370
  requires that the note format distinguish buckets.
371
372
## 10. Build order
373
374
The follow-up issues, each citing its section as the contract:
375
376
1. **Event shape and admission pipeline** — companion `v2` with the `system`
377
   block, the three new source roles, admission events, steward-allowlist
378
   verification, projection of admission status (sections 3-4).
379
2. **Challenge and refutation events** — event shapes, suspension semantics
380
   in the projection, steward resolution paths (section 7.3).
381
3. **Distribution on the engram Nostr sync** — the `system-memory` relay
382
   namespace on the real transport, ingest verification, merge-and-reproject
383
   (section 6). Depends on the project-15 transport landing; adds no second
384
   channel.
385
4. **Recall integration with poisoning caps** — the system bucket on the #51
386
   rails, admitted-only eligibility, per-note and per-pool caps, the note
387
   format (sections 7.1-7.2).
388
5. **KB boundary enforcement** — collision suppression at recall and the
389
   promotion-with-tombstone path (section 8).

This page updates live while a promote is in flight · changelog