oficina / memoria Public

docs(spec): memoria is not less sealed than Sheets, it holds more

Paul asked why memoria is more exposed if its data is sealed too. The
honest answer is that it isn't less sealed — the earlier draft leant on
a weak argument (Sheets holds decrypted handles only for open sheets)
that does not survive a host holding the DEK.

§3.3 now works the comparison properly: identical sealing, but a corpus
that is the union of every source, and strictly a subset of each source
taken alone. The RAM distinction is kept, narrowed to the threat class
where it actually bites — partial memory disclosure, where a core file
or a hypervisor snapshot leaks what is in memory rather than what the
key could reach.

The README claim in §3.6 is rewritten to match, since it repeated the
retracted framing.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SiWVaR69Vb2Lzc9wgfit1v
Paul Campbell pushed by paul@keymail.dev de2f9dd19d8fdc1c9f8f0ca83fe160141ab48d39 parent 641b8f6
1 file changed, +62 −15
  • docs/superpowers/specs/2026-09-03-memoria-design.md +62 −15
diff --git a/docs/superpowers/specs/2026-09-03-memoria-design.md b/docs/superpowers/specs/2026-09-03-memoria-design.md
index 78f085f..ea233b9 100644
--- a/docs/superpowers/specs/2026-09-03-memoria-design.md
+++ b/docs/superpowers/specs/2026-09-03-memoria-design.md
@@ -144,13 +144,11 @@ app and coordinates per chunk, which stay plaintext exactly as Sheets
sources are busy and when; embedding dimension, therefore the model.
**From a live host — the largest entry, and new.** A compromised memoria
-host holds the team's whole corpus across every app, plaintext in RAM,
-plus the key to a sealed blob that is the same corpus inverted. This
-aggregation point did not previously exist: a Sheets host holds handles
-only for *open* sheets (§2.5). Home §2's "blast radius is bounded by what
-a service holds" is now the argument *against* memoria, because memoria
-holds the most. Decision 1 accepts this knowingly; §3.4 lists what
-shrinks it.
+host reaches the team's corpus across every app at once. Home §2's
+"blast radius is bounded by what a service holds" is now the argument
+*against* memoria, because memoria holds the most. Decision 1 accepts
+this knowingly; §3.3 works through exactly how it compares to Sheets,
+and §3.5 lists what shrinks it.
**From logs, errors and metrics:** a question is content — *"what does
Bob earn"* is a cell value phrased as a query. Sheets AGENTS.md's rule
@@ -171,7 +169,56 @@ questions a day that is half a million tokens a day of the team's
the corpus has left in full. This is the entry most likely to be
understated, so it is stated in volume rather than in principle.
-### 3.3 A citation is exactly as trustworthy as the app it cites
+### 3.3 memoria is not less sealed than Sheets. It is a bigger target.
+
+Asked directly by Paul, 2026-09-03, and worth answering in the spec
+because every future reader will ask it too: *if memoria's data is sealed
+too, why is it more exposed?*
+
+**At rest there is no difference.** memoria seals under its own DEK with
+the same construction as Sheets, and the same plaintext-grep gate runs
+against its bucket from the first commit. Nothing here is weaker.
+
+**An earlier draft of this section argued the difference was RAM** — that
+a Sheets host holds decrypted handles only for *open* sheets (§4.4) while
+memoria holds everything. That argument is mostly wrong and is recorded
+here so it is not reintroduced. A compromised Sheets host holds the DEK,
+so it can decrypt its entire bucket on demand; the open-handle
+distinction is the difference between reading memory and running a
+decrypt loop, which is no barrier to anyone with code execution.
+
+**The real difference is that the corpus is a union.** Compromise Sheets
+and an attacker gets that team's sheets. Compromise memoria and they get
+sheets *and* docs *and* calendar *and* Notion *and* uploads *and*
+forwarded mail. Same lock, more in the room. That is the whole of it, and
+it is enough.
+
+**Two refinements, and the first favours memoria.**
+
+- **Per app, memoria holds strictly less than the app does.** Decision 3
+ keeps individually-granted content out entirely, so memoria's copy of
+ Sheets is a strict subset — team-visible items only. The union is
+ larger; every part of it is smaller. An attacker who wants a guest's
+ individually-granted sheet gains nothing by taking memoria.
+- **The RAM point is real, but narrow, and worth keeping for that.**
+ memoria's index must be fully decrypted to be searchable at all (§3.1:
+ BM25 and cosine do not run over sealed bytes), so its whole corpus sits
+ in cleartext memory as routine operation, where Sheets decrypts per
+ sheet and evicts on idle. Against RCE this is marginal. Against
+ **partial memory disclosure** it is the entire difference: a crash
+ dump, a core file, swap, a hypervisor snapshot or a Heartbleed-class
+ over-read leaks what is *in memory*, not what the key could reach. For
+ that threat class alone, memoria is meaningfully worse than Sheets, and
+ §3.5's idle eviction is the mitigation that matters most.
+
+**What memoria does not do is weaken its sources.** It holds no sibling's
+DEK. Compromising memoria yields a copy of team-visible content, not the
+ability to decrypt Sheets' bucket, and not a write path (§6.4). It does
+yield the sibling read tokens, so an attacker keeps reading team-visible
+content going forward — but that is the same content memoria already
+holds, so it widens the window rather than the blast radius.
+
+### 3.4 A citation is exactly as trustworthy as the app it cites
A compromised sibling has no inbound path to memoria and holds no memoria
token, so it cannot read or write. What it *can* do is lie: serve
@@ -180,7 +227,7 @@ not, withhold tombstones. memoria's re-check asks the same lying app.
There is no mitigation, only disclosure. The README says this sentence.
-### 3.4 Cheap mitigations
+### 3.5 Cheap mitigations
- **memoria hibernates.** Home §2.1 made the home the one exception on the
estate; memoria is not another. It reloads its sealed index on wake.
@@ -191,16 +238,16 @@ There is no mitigation, only disclosure. The README says this sentence.
- **Refusing sources by kind.** Calendar bodies off by default.
- **Idle eviction** of the decrypted handle.
-### 3.5 The honest claim
+### 3.6 The honest claim
The README's first paragraph, in substance:
> memoria's index and passages are sealed at rest under this team's own
-> key. Nothing readable reaches storage. But an index of this kind cannot
-> be searched without decrypting it, so a compromised running instance
-> can read the whole corpus — not just what someone has open. memoria
-> holds more of your team's work in one place than any other app in the
-> suite, and that is the point of it and the risk of it. When the
+> key, the same way your sheets and documents are. Nothing readable
+> reaches storage. What is different about memoria is not the lock, it is
+> what is behind it: memoria gathers your team's work from every app into
+> one place, so whoever breaks into it gets all of it at once rather than
+> one app's worth. That is the point of it and the risk of it. When the
> assistant is switched on, the passages used to answer a question are
> sent to the provider named on that answer, who can read them; we rely
> on their retention terms and cannot verify them. We never claim we