Docs/Memory Schema
Reference
Memory Schema
Categories, tags, TypeScript types, ciphertext format, shared vaults, and AI enrichment fields.
Categories
Every memory belongs to one of six categories, mapped to the six MNEMOS product modules. Categories determine vault module routing, graph colouring, and MCP recall filtering.
| Category | Module | Use for |
|---|---|---|
| context | MODULE_01 | General notes, second-brain context, anything that doesn't fit elsewhere |
| relationship | MODULE_02 | People, connections, interactions, pre-meeting context |
| goal | MODULE_03 | Objectives, milestones, kanban items, aspirations |
| decision | MODULE_04 | Choices made, reasoning recorded, outcomes tracked |
| health | MODULE_05 | Mood, energy, sleep, symptoms, patterns over time |
| api | MODULE_06 | Externally ingested via API gateway (plaintext, not wallet-encrypted) |
Tags
Tags are free-form strings stored unencrypted for fast filtering and search.
Format rules
- →Lowercase, hyphens only —
follow-upnotfollow up - →Max 10 tags per memory
- →Max 50 characters per tag
Suggested conventions
text
# People (relationship module) danno, alice, team-engineering # Projects / work q2-review, mnemos-launch, client-acme # Time weekly, monthly, 2026-q1 # Status / action follow-up, in-progress, completed, blocked, archived
TypeScript types
Full type definitions from src/lib/types.ts:
typescript
/** Categories map to the six MNEMOS product modules */
export type MemoryCategory =
| "relationship" // MODULE_02
| "goal" // MODULE_03
| "decision" // MODULE_04
| "health" // MODULE_05
| "context" // MODULE_01 — general second-brain context
| "api"; // MODULE_06 — third-party API writes
/** Raw storage record (server-side, contains ciphertext) */
export interface MemoryStreamContent {
ciphertext: string; // AES-256-GCM blob: base64url(iv) + "." + base64url(ct)
walletAddress: string; // owner wallet (lowercase)
category: MemoryCategory;
tags: string[]; // unencrypted, used for filtering
title?: string; // AI-generated, stored unencrypted
createdAt: string; // ISO timestamp
updatedAt: string; // ISO timestamp
deletedAt?: string; // set on soft delete
vaultId?: string; // shared vault FK — undefined for personal memories
}
/** Hydrated record returned by the API (post-decrypt on client) */
export interface MemoryRecord {
streamId: string; // "mem_" + nanoid(8)
content?: string; // decrypted plaintext — only after client-side decrypt
title?: string; // AI-generated title (always present if enriched)
walletAddress: string;
category: MemoryCategory;
tags: string[];
createdAt: string;
updatedAt: string;
deletedAt?: string;
ciphertext: string; // always present — raw encrypted blob
vaultId?: string;
}Ciphertext format
text
Format: base64url(iv[12 bytes]) + "." + base64url(AES-GCM ciphertext) Example: "aBcD1234EFGH.xYz9876uvWXabcdef..." ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ 12-byte IV encrypted content + 16-byte GCM auth tag Properties: - New random 96-bit IV per write → same plaintext never produces same ciphertext - GCM auth tag: any tampering causes decryption to throw (integrity guarantee) - base64url encoding: URL-safe, no padding
Shared vault types
Shared vaults use ECDH P-256 key exchange so multiple wallets can read the same encrypted content without sharing private keys.
typescript
export interface SharedVault {
id: string;
name: string;
ownerWallet: string;
createdAt: string;
updatedAt: string;
members?: VaultMember[];
}
export interface VaultMember {
vaultId: string;
walletAddress: string;
role: "owner" | "writer" | "viewer";
wrappedVaultKey: string; // AES-GCM wrapped vault key: base64url(iv).base64url(wrapped)
ephemeralPubkey: string; // SPKI base64url P-256 public key used during wrapping
joinedAt: string;
}
export interface VaultInvite {
id: string;
vaultId: string;
inviteeWallet: string;
role: "owner" | "writer" | "viewer";
wrappedVaultKey: string;
ephemeralPubkey: string;
status: "pending" | "accepted" | "declined" | "revoked";
createdAt: string;
expiresAt?: string;
}Session memory (MCP bridge)
When you sync to the AI Vault Bridge, decrypted plaintext is temporarily cached server-side so MCP tools can recall it. This cache is separate from your encrypted vault storage.
typescript
export interface SessionMemory {
id: string;
title?: string;
content: string; // decrypted plaintext — only in session cache
category: string;
tags: string[];
createdAt: string;
}
export interface SessionData {
walletAddress: string;
memories: SessionMemory[];
syncedAt: string;
expiresAt: string; // 60 minutes from sync time
}NOTE
Session memories are stored in a separate session cache (not the main memories table) and automatically expire. Revoking the session immediately clears this cache.