Memory is not a longer prompt
A personal assistant gets dramatically better when it knows that you protect mornings, that Karthik belongs in launch decisions, or that yoga is the first thing to preserve when tomorrow gets crowded. The obvious implementation is to keep appending summaries to a system prompt. I did not do that.
A summary blob has no stable identity, no principled conflict model, and no answer to “which sentence caused this behavior?” Orbit treats memory as a versioned data system with a model at the proposal boundary, not as model-owned state.
The pipeline
Every durable claim must be traceable back to immutable owner-authored evidence. The model can nominate memory; deterministic code decides whether the nomination is admissible, and a separate resolver decides whether that version belongs in a future turn.
owner message
→ immutable evidence
→ ≤5 structured claim proposals
→ deterministic admission gate
→ immutable claim versions
→ per-turn resolution
→ usage lineage1. Evidence is append-only
Pluto records an owner message with source identity, event time, observation time, exact text, and a content hash. Event time answers when the thing happened; observation time answers when Orbit learned it. Keeping both prevents a late-arriving source from masquerading as fresh information.
Assistant messages are derived output, not evidence about the owner. Connector documents and external events are attributed context. Neither is allowed to silently manufacture a personal fact.
evidence = {
subject_id, source_id, event_time, observed_at,
content_hash, exact_text, attachment_provenance
}2. The model proposes; code disposes
For an owner-authored turn, the model may propose at most five structured claims. Each proposal includes a bounded predicate, entity, value, confidence, temporal fields, and a verbatim quote from the current message.
The admission gate is deterministic. It rejects malformed identities, unsupported predicates, low-confidence proposals, quotes that do not exist in the evidence, invalid temporal ranges, and values that look like credentials or secrets. An external event never enters this owner-claim path, even if it contains a convincing sentence about the user.
- The LLM is an untrusted parser at this boundary.
- The supporting quote must be recoverable from the current evidence.
- Admission policy is versioned independently from the model prompt.
- No external source can promote itself into owner memory.
3. A claim is an identity plus immutable versions
The stable key is the tuple `(subject, predicate, entity)`. The value is not part of the identity. “No meetings before 9:30” and a later correction to “before 10:00” are two versions of the same claim, not unrelated memories competing in vector space.
Versions are immutable. A correction appends a new version and a state transition that supersedes the old one. Orbit preserves the earlier assertion, its evidence, and the point at which it stopped being active instead of overwriting history.
claim_id = (subject_id, predicate, entity)
version = {
value, confidence, valid_from, valid_to,
evidence_id, policy_version, created_at
}4. Resolution is a recorded computation
At the beginning of a turn, Pluto loads candidate versions for the relevant claim identities and resolves them under a bounded policy. It records the candidates, selected versions, conflicts, resolution-policy version, and a memory watermark representing the state the turn observed.
That watermark matters under concurrency. If two messages are being processed, each turn can say which memory snapshot it reasoned over instead of pretending there was one timeless prompt. A later write does not retroactively change the explanation for an earlier answer.
resolution = {
candidate_version_ids, selected_version_ids, conflicts,
policy_version, memory_watermark
}5. Retrieval lives in a different namespace
Connected Google data goes through Charon, not the claim ledger. Charon normalizes resources, content-hashes them, atomically replaces changed chunks, and retains source attribution. Only bounded excerpts selected for the active turn are decrypted for inference.
A retrieved sentence can influence one answer without becoming durable owner memory. This is a deliberately hard boundary: retrieval answers “what source material is relevant now?” while memory answers “what owner-authored claim should persist across turns?”
6. Usage lineage closes the loop
After inference, Pluto records which selected claim versions were actually used. Candidate memory, resolved memory, and used memory are three different sets. Keeping them separate lets me debug over-personalization without dumping an entire prompt or pretending every retrieved claim affected the answer.
The portal is therefore reading a real ledger: stable claim identity, current version, confidence, evidence time, state, and usage. It is not a synthetic list generated on page load.
Why all this ceremony
The architecture is more work than a vector database full of chat summaries. It buys properties I think a personal assistant needs: reproducible context selection, correction without historical amnesia, a boundary against third-party memory injection, and a path from behavior back to evidence.
Orbit’s job is to carry context forward. Your job should never be to wonder what it carried, where it came from, or whether you can take it back.