Live Agent Memory
Agent memory persists state across sessions. LODE encodes each memory snapshot as a verified Vein binary, and a parentHash field chains snapshots together — creating a tamper-evident history of everything the agent has learned.
Schema: MemorySnapshot
memory-snapshot-v1.lode
{
"schema": "lode",
"version": 1,
"name": "MemorySnapshot",
"fields": [
{ "id": 1, "name": "agentName", "type": "string", "required": true },
{ "id": 2, "name": "sessionId", "type": "string", "required": true },
{ "id": 3, "name": "timestamp", "type": "string", "required": true },
{ "id": 4, "name": "state", "type": "map<string,string>", "required": true },
{ "id": 5, "name": "keys", "type": "string[]", "required": true },
{ "id": 6, "name": "parentHash", "type": "string", "required": false },
{ "id": 7, "name": "ttl", "type": "string", "required": false }
]
}Example: Research Session
session-001.json
{
"agentName": "research-assistant",
"sessionId": "sess_20260315_001",
"timestamp": "2026-03-15T10:30:00Z",
"state": {
"lastQuery": "LODE encoding benchmarks",
"resultCount": "47",
"confidence": "0.92"
},
"keys": ["lastQuery", "resultCount", "confidence"],
"parentHash": "a1b2c3d4e5f6...",
"ttl": "7d"
}$ lodec compile session-001.json -s memory-snapshot-v1.lode -o memory/sess_001.vein
Compiled session-001.json → memory/sess_001.vein (198 bytes)
Fingerprint: d4e5f6a7...Hash Chain
Each snapshot’s parentHash points to the fingerprint of the previous snapshot. This creates a verifiable chain:
Snapshot 0 Snapshot 1 Snapshot 2
parentHash: parentHash: parentHash:
null → a1b2c3... → d4e5f6...To verify the chain, walk backwards from the latest snapshot and confirm each parentHash matches the fingerprint of the preceding snapshot.
async function verifyMemoryChain(snapshots: string[]): Promise<boolean> {
const schema = loadLode("memory-snapshot-v1.lode");
let expectedParent: string | null = null;
for (const path of snapshots) {
const vein = await readFile(path);
const snap = decode(vein, schema);
const fp = fingerprint(snap);
if (expectedParent !== null && snap.parentHash !== expectedParent) {
console.error(`Chain broken at ${snap.sessionId}`);
return false;
}
expectedParent = fp;
}
return true;
}Session Restore
When an agent starts a new session, it loads and verifies the latest snapshot:
async function restoreMemory(agentName: string): Promise<Record<string, string>> {
const latest = await fetchLatestSnapshot(agentName);
const schema = loadLode("memory-snapshot-v1.lode");
const vein = new Uint8Array(await latest.arrayBuffer());
const expected = latest.headers.get("X-Lode-Fingerprint");
if (!verify(vein, expected, schema)) {
throw new Error("Memory snapshot verification failed — possible tampering");
}
const snap = decode(vein, schema);
return snap.state;
}TTL and Garbage Collection
The ttl field enables automatic expiration. A memory manager can prune expired snapshots while maintaining chain integrity by updating the parentHash of the next surviving snapshot.
function isExpired(snap: MemorySnapshot): boolean {
const ttlMs = parseDuration(snap.ttl); // "7d" → 604800000
const created = new Date(snap.timestamp).getTime();
return Date.now() - created > ttlMs;
}Last updated on