forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcanonical_memory_architecture.html
More file actions
291 lines (285 loc) · 12.1 KB
/
Copy pathcanonical_memory_architecture.html
File metadata and controls
291 lines (285 loc) · 12.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Canonical Memory Architecture</title>
<style>
:root {
--bg: #0f1419;
--surface: #1a2332;
--surface-soft: #151d28;
--border: #344258;
--text: #e7ecf3;
--muted: #9babc0;
--accent: #69a8d6;
--short: #3f7958;
--route: #4f718f;
--long: #98763f;
--archive: #6b7482;
--outbox: #337a79;
--warn: #c9a227;
}
* { box-sizing: border-box; }
body {
margin: 0;
color: var(--text);
background: var(--bg);
font: 15px/1.55 system-ui, -apple-system, "Segoe UI", sans-serif;
}
header, main {
width: min(1100px, calc(100% - 2rem));
margin: 0 auto;
}
header {
padding: 2rem 0 1.25rem;
border-bottom: 1px solid var(--border);
}
h1 { margin: 0 0 0.4rem; font-size: 1.8rem; }
h2 {
margin: 2rem 0 1rem;
padding-bottom: 0.35rem;
color: var(--accent);
border-bottom: 1px solid var(--border);
font-size: 1.25rem;
}
h3 { margin: 0 0 0.35rem; font-size: 1rem; }
p { margin: 0.45rem 0; }
code {
color: #c4d9ea;
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
a { color: var(--accent); }
.muted { color: var(--muted); }
main { padding-bottom: 3rem; }
.flow {
display: grid;
justify-items: center;
gap: 0.5rem;
padding: 1rem 0;
}
.box {
width: min(760px, 100%);
padding: 0.85rem 1rem;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 9px;
text-align: center;
}
.box.short { border-color: var(--short); }
.box.route { border-color: var(--route); }
.box.long { border-color: var(--long); }
.box.archive { border-color: var(--archive); }
.box.outbox { border-color: var(--outbox); }
.arrow { color: var(--muted); font-size: 1.25rem; line-height: 1; }
.routes {
display: grid;
width: min(900px, 100%);
grid-template-columns: repeat(4, 1fr);
gap: 0.75rem;
}
.route-card {
min-height: 112px;
padding: 0.8rem;
background: var(--surface-soft);
border: 1px solid var(--border);
border-radius: 8px;
text-align: center;
}
.route-card.promote { border-color: var(--long); }
.route-card.archive,
.route-card.review,
.route-card.reject { border-color: var(--archive); }
.split {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
width: min(900px, 100%);
}
.principles {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1rem;
}
.principle {
padding: 1rem;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
}
.principle strong { color: var(--accent); }
ul { color: var(--muted); }
.warning {
padding: 1rem 1.25rem;
background: #292619;
border: 1px solid var(--warn);
border-radius: 8px;
}
@media (max-width: 720px) {
.routes, .split, .principles { grid-template-columns: 1fr; }
}
</style>
</head>
<body>
<header>
<h1>Canonical Memory Architecture</h1>
<p class="muted">Broad Short-term intake, one terminal consolidation route, atomic graph-backed Long-term admission.</p>
<p>
<a href="canonical_memory_architecture.md">Markdown source</a>
·
<a href="../../../memory/domain_model.md">Domain model</a>
</p>
</header>
<main>
<h2>End-to-end lifecycle</h2>
<section class="flow" aria-label="Canonical memory lifecycle">
<div class="box">
<h3>New intake</h3>
<p class="muted">Conversation · explicit user memory · import · API · plugin · integration</p>
</div>
<div class="arrow">↓</div>
<div class="box short">
<h3>Short-term capture</h3>
<p>Every new memory starts broad, source-backed, and time-bounded; Conversation quote references must match a transcript segment.</p>
<p class="muted">Extraction failure preserves prior state; a successful empty reprocess fully retracts it.</p>
<code>memory_items · tier=short_term</code>
</div>
<div class="arrow">↓</div>
<div class="box">
<h3>Maintenance preparation</h3>
<p>Existing outbox drain → required normalization → TTL audit/expiry → consolidation → post-commit outbox drain</p>
<code>short_term_promotion.py · memory_outbox_worker.py</code>
</div>
<div class="arrow">↓</div>
<div class="box route">
<h3>One total consolidation decision</h3>
<p>Exactly one item-addressed route for every memory in the deterministic, server-bounded eligible set before any mutation.</p>
<code>canonical_consolidation.py</code>
</div>
<div class="arrow">↓</div>
<div class="routes">
<div class="route-card promote">
<h3>promote</h3>
<p class="muted">Atomic Long-term admission with receipt and graph assertion, preserving authoritative source subject identity and attribution.</p>
</div>
<div class="route-card archive">
<h3>archive</h3>
<p class="muted">Retained outside default access.</p>
</div>
<div class="route-card review">
<h3>review</h3>
<p class="muted">Archive outcome plus review projection.</p>
</div>
<div class="route-card reject">
<h3>reject</h3>
<p class="muted">Hidden Archive outcome.</p>
</div>
</div>
<div class="arrow">↓</div>
<div class="split">
<div class="box long">
<h3>Atomic canonical commit</h3>
<p>Item · admission receipt · graph assertion · ledger/head · operation · outbox</p>
<code>memory_apply_store.py</code>
</div>
<div class="box archive">
<h3>Non-promote settlement</h3>
<p>Archive/hidden state remains excluded from default reads.</p>
</div>
</div>
<div class="arrow">↓</div>
<div class="split">
<div class="box outbox">
<h3>Outbox-retried projections</h3>
<p>Keyword/compatibility and vector writes hydrate authoritative state; reclaimed leases repair current state before acknowledgement.</p>
<p>Privacy tombstones fence graph reads immediately; durable projection deletes remove each derived graph assertion before pruning shared citations, preserving the released 100-item batch contract.</p>
<p class="muted">Restricted content never reaches keyword, compatibility, embedding, or vector providers; only ID-scoped deletes purge prior state.</p>
<code>memory_outbox_worker.py</code>
</div>
<div class="box">
<h3>Default retrieval</h3>
<p>Eligible Short-term + Long-term → canonical-lineage dedupe.</p>
<code>canonical_memory_adapter.py</code>
</div>
</div>
</section>
<h2>Ownership rules</h2>
<section class="principles">
<div class="principle">
<p><strong>Capture owns breadth.</strong></p>
<p class="muted">No new intake writes Long-term or Archive directly.</p>
</div>
<div class="principle">
<p><strong>Consolidation owns routing.</strong></p>
<p class="muted">No generic promotion pass or user-asserted fast track exists.</p>
</div>
<div class="principle">
<p><strong>Atomic apply owns admission.</strong></p>
<p class="muted">A new active Long-term item cannot exist without its current receipt and per-memory graph assertion.</p>
</div>
<div class="principle">
<p><strong>Canonical state owns truth.</strong></p>
<p class="muted">Shared graph, keyword, vector, and compatibility stores are rebuildable projections. Public canonical or retained-assertion graph delete/rebuild returns HTTP 409.</p>
</div>
<div class="principle">
<p><strong>Review resolution is atomic.</strong></p>
<p class="muted">Revision-scoped review commands validate source commit, item revision, content hash, and route while committing the item and redacted queue row together.</p>
</div>
<div class="principle">
<p><strong>Privacy closes the lineage.</strong></p>
<p class="muted">Hidden and superseded aliases are scrubbed with the survivor; shared standalone evidence remains only while another non-deleted item owns it.</p>
</div>
</section>
<h2>Fail-closed boundaries</h2>
<ul>
<li>Conversation capture persists only transcript-grounded quote references; extraction failures preserve prior state and successful empty results fully retract it.</li>
<li>Incomplete, duplicate, or unknown consolidation routes mutate nothing.</li>
<li>Promotion conserves authoritative source subject identity and attribution.</li>
<li>Missing or stale admission receipts reject Short-term → Long-term.</li>
<li>The item and graph assertion commit or roll back together.</li>
<li>Knowledge-graph reads are bounded and return only edges whose endpoints are in the returned node page; filtering reports truncation.</li>
<li>Restricted content never reaches keyword, compatibility, embedding, or vector providers; only ID-scoped deletes purge prior state.</li>
<li>Reclaimed expired-processing events repair current authoritative provider state before acknowledgement.</li>
<li>Projection failures leave retryable outbox work; they do not rewrite canonical state.</li>
<li>Archive and pending raw text remain outside protected default retrieval.</li>
<li>Alias lineages return one logical survivor, preferring the active Long-term canonical row.</li>
<li>Stale or competing review decisions cannot mutate a newer canonical revision.</li>
<li>Consolidation leases each revision before an LLM call; three failed attempts use canonical review or blocked-review quarantine, and never call the model again.</li>
<li>Delete-all returns only after a final control-fenced rescan observes no remaining non-tombstoned item.</li>
<li>Account-deletion markers make projection delivery delete-only, and provider purge waits for active projection leases to drain.</li>
</ul>
<p>
Invalid output, recurrence handoff failure, and apply conflicts persist a
revision-scoped attempt under <code>memory_runs</code>. Retrying sources
are isolated from fresh items. After three failures the canonical apply
boundary commits review; an Archive-route conflict falls back to a
blocked Short-term review with projection deletes, which removes the
quarantined revision from the eligible query. If storage blocks both
terminal commits, later jobs retry only those routes without another LLM
call. A durable cursor advances the stable ordered scan past a blocked
page and resets after reaching later work, so the blocked page remains failed
rather than reporting silent success without pinning newer sources.
</p>
<p>
Required processing queries active pending required rows, and negative
user review moves a row to terminal <code>processing_rejected</code>. TTL
selects active, processed, expired Short-term rows in
<code>expires_at, memory_id</code> order; consolidation selects active,
processed, source-active Short-term rows in
<code>captured_at, memory_id</code> order. Eligibility filters precede
server-owned query limits, so unrelated rows cannot starve overflow. Each
pass drains every batch in its selected set; overflow remains immediately
eligible on the next Scheduler run, without a 24-hour watermark delay.
</p>
<h2>Scheduled maintenance gate</h2>
<div class="warning">
<p>
Scheduled maintenance is gated globally by
<code>MEMORY_CANONICAL_MAINTENANCE_ENABLED</code> and inventories the
bounded universal maintenance registry. Cloud Scheduler owns cadence;
no UID allowlist, promotion timer, or separate interval gate exists.
</p>
</div>
</main>
</body>
</html>