๐Ÿ’ Ming's Note

โ† Back to Concepts

Structured Memory System for Long-Term AI Assistants

How to make AI remember you across sessions โ€” three card types, cardinality rules, half-life decay, conflict arbitration, and time anchoring. From fibon design log Chapter 3.

The Core Problem: Cross-Session Memory

Mainstream AI (ChatGPT, Claude, Gemini) remembers within a session but forgets everything when you open a new chat. Three industry approaches:

Approach Mechanism Fatal Flaw
Long Context Stuff 1M+ tokens of history Token cost explosion, "Lost in the Middle" degradation
Auto-Summary LLM summarizes at session end Loses details, distorts context, no fact auditability
Structured Memory Atomic cards with metadata Complex schema design (fibon's choice)

The Container: Projects

Before cards, you need scope isolation. A "Project" is a topic-scoped container โ€” each card carries a hard project_id, and retrieval defaults to the current project only.

Three-Layer Scope Model

Scope What Goes Here Cross-Project?
Personal Permanent user facts (address, job title, diet) Yes โ€” all projects see these
Project Topic-specific memories (hotel list, design notes) No โ€” isolated by project_id
Global Shared public knowledge Reserved for future

The scope model is designed as a ladder โ€” today it's Personal/Project, but adding group_id scales to Family โ†’ Team โ†’ Department โ†’ Enterprise without redesign.

Key insight: Same fact, different perspectives. "Mom's birthday on Sunday" โ€” Dad remembers "wife's birthday, prepare gift"; child remembers "mom's birthday, prepare cake." Shared scope needs perspective tagging.

Three Card Types (The Building Blocks)

้•ทๆœŸ่จ˜ๆ†ถไธ่ฉฒๅ„ฒๅญ˜ใ€Œๅฐ่ฉฑ็ด€้Œ„ใ€๏ผŒ่€Œ่ฉฒๅ„ฒๅญ˜ใ€Œ็‹€ๆ…‹ใ€ไบ‹ไปถ่ˆ‡็Ÿฅ่ญ˜ใ€ใ€‚

Inspired by Bullet Journal (category discipline), Zettelkasten (atomic cards), and Digital Garden (bidirectional linking).

State Card (็‹€ๆ…‹ๅก)

Records: Dynamic facts true at this moment.

[State Card: fibon Open Source Plan]
current_stage = Pre-launch verification
effective_at  = 2026-05-05
superseded_at = NULL (still active)

Cardinality matters: - Single-value (replaced): Address, job title, browser preference โ†’ new fact triggers Supersede-Fork - Multi-value (accumulated): Skills, interests, topics discussed โ†’ new fact inserts alongside old

Event Card (ไบ‹ไปถๅก)

Records: Facts that happened at a specific time.

[Event Card: 2026-04-30 Decision Meeting]
event    = Self-evolution evaluated (3 options)
decision = Option B (degraded to safe reference design)
reason   = Lowest security narrative risk

Rule: Write-once, read-only, never modified. History is immutable.

Practical tension: LLM extracts the text, and LLM can get it wrong. So the description should be human-editable (ๆ ก็จฟ), but the fact that the event happened is not. Edit = correcting a bad summary; fabrication = inserting something that never happened.

Knowledge Card (็Ÿฅ่ญ˜ๅก)

Records: Abstract concepts, architectural decisions, learned principles.

Example: [JWT Stateless Auth Principles], [Reflection Pattern Implementation]

Cross-session merging and renaming allowed.

Why Cards Beat Raw Conversations

LLMs suffer from "Lost in the Middle" โ€” key facts buried in long context get ignored. A structured card like [current_company: Anthropic] delivers higher information density than a paragraph of chat history. Cards are an engineering patch against Lost in the Middle โ€” separate the skeleton of facts from the flesh of conversation.

Honest caveat: The "cards reduce hallucination" hypothesis hasn't been rigorously tested with controlled experiments. Token savings is a goal, not a verified guarantee โ€” card extraction costs LLM calls, and the static prompt overhead (GUARD rules, known entities, aging warnings) eats tokens too.

Four Hard Rules for State Cards

Rule 1: Supersede-Fork (ๅˆ†ๅ‰ๅผๅ–ไปฃ)

When a state card updates, the old card is never deleted โ€” it's marked superseded:

Old card: stage = "Previous phase", superseded_at = 2026-05-05
New card: stage = "Pre-launch verification", effective_at = 2026-05-05

Like legal amendments โ€” old laws aren't burned, they're annotated "replaced by amendment on [date]." Query "current?" โ†’ WHERE superseded_at IS NULL. Query "April status?" โ†’ time-range scan.

Real bug that happened: A longitudinal aging test produced 166 state cards with ALL superseded_at fields NULL โ€” the fork mechanism never triggered once. Root cause: LLM-extracted labels didn't match the replacement detection criteria, so every card was misclassified as multi-value. Result: user appeared to "live in both Taipei and Kyoto simultaneously." This is why these rules must be hard-coded, not prompt-suggested.

Rule 2: Cardinality (ๅŸบๆ•ธๆ€ง)

Type Behavior Example
Single-value New replaces old (Supersede-Fork) Address, job title
Multi-value New inserts alongside old Skills, interests

The conflict_resolver checks the card's cardinality flag before deciding the write path. SUPERSEDE_FORK_ENABLED is the gate for single-value cards.

Rule 3: Half-Life Decay (่จ˜ๆ†ถๅŠ่กฐๆœŸ)

Time is memory's greatest enemy. The retrieval score formula applies exponential decay:

final_score = raw_vector_score ร— e^(โˆ’ฮป ร— ฮ”t)
Fact Type ฮป (decay coefficient) Half-life 30-day weight 90-day weight
Single-value (browser, address) 0.02 ~35 days ร—0.55 ร—0.17
Multi-value (interests, languages) 0.005 ~140 days ร—0.86 ร—0.64

Aging warning: If a single-value card sits unverified for 180+ days, it enters <aging_facts> block โ€” AI proactively asks: "I remember you lived in Taipei, is this still accurate?"

Honest caveat: ฮป = 0.02 and 0.005 were "suggested by Claude and Henry said yes" โ€” no rigorous memory psychology behind them. But they match intuition: preferences shift monthly, interests shift semi-annually.

Rule 4: Conflict Arbitration (่ก็ชไปฒ่ฃ)

Three-layer conflict filter:

  1. Same-turn self-correction โ€” "I live in Taipei... wait, I mean Kaohsiung" โ†’ direct overwrite, don't bother user
  2. Cross-session low-frequency โ€” <3 changes in 30 days โ†’ normal fact evolution, auto-process (single-value: Supersede-Fork; multi-value: overwrite with audit log)
  3. High-frequency or large-span contradiction โ€” โ‰ฅ30 days apart OR โ‰ฅ3 changes โ†’ enters arbitration queue, front-end shows conflict panel with three buttons: [Keep Old] / [Accept New] / [Both True]

Final safety net โ€” Contradiction Detector: After retrieval, before injection into prompt, backend scans for two cards with same label but conflicting content โ†’ injects <contradiction_alert> โ†’ AI asks user to clarify.

Time Anchoring (ๆ™‚้–“้Œจๅฎš)

Problem 1: "Today" stored as string "ไปŠๅคฉ" โ†’ temporal chaos one week later.

Problem 2: LLM has no clock โ€” its training data has a cutoff, it doesn't know the current date.

Solution โ€” Ingest Flow (ๅฏซๅ…ฅ็ซฏ):

  1. Grab server time in user timezone
  2. Inject <current_time>2026-05-08T16:44:10+08:00</current_time> into LLM's System Prompt
  3. Force LLM to output occurred_at_hint (absolute date) for every extracted card
  4. Backend writes to occurred_at column; fallback to server timestamp if LLM fails

Retrieval Flow (่ฎ€ๅ–็ซฏ): User says "what did I do yesterday?" โ†’ system converts to absolute date โ†’ SQL range query on occurred_at. Both ends hold a synchronized clock.

Edge case โ€” "weekend": If user says "this weekend" on Saturday, fibon interprets as "today + tomorrow" (not next weekend), because "if you're already inside the relative window, it means this window."

Comparison with Big Tech Approaches (2026)

Feature ChatGPT Projects Claude Projects Gemini Projects fibon
Container Folder + files + system prompt Folder + RAG knowledge base Folder (rolling out) Project with hard project_id
Memory type Saved memories + chat history Cross-session Memory (summary) Past Chats profile Atomic cards with metadata
Structure Prose paragraphs Prose summaries Prose State/Event/Knowledge cards
Scope Personal memories bleed into project Memory and project are separate silos Not unified Clean scope field (Personal/Project/Global)
Cardinality None None None Single-value vs multi-value
Time decay None None None Exponential half-life
Conflict handling Last-write-wins Summary overwrite Unknown 3-layer arbitration + contradiction detection

Bottom line: Big Tech built storage boxes with prose notes attached. fibon built a self-maintaining structured memory engine.

The Core Thesis

่จ˜ๆ†ถ็ณป็ตฑ็œŸๆญฃ็š„ๆ•ตไบบไธๆ˜ฏๅฟ˜่จ˜๏ผŒ่€Œๆ˜ฏ้Œฏ่ชคๅœฐไธ€็›ด่จ˜ๅพ—ใ€‚

The real enemy isn't forgetting โ€” it's remembering wrongly and persistently. A system that never forgets your old address is worse than one that forgets; it will confidently give wrong information forever. The four rules (Supersede-Fork, Cardinality, Half-Life, Arbitration) exist to prevent this silent memory rot.

Key Design Decisions

  1. Cards, not conversations โ€” atomic facts beat raw chat history for LLM consumption
  2. Supersede, never delete โ€” historical audit trail preserved
  3. Time is a dimension, not a card type โ€” every card lives in time, but time isn't its own category
  4. Scope is a ladder โ€” designed to scale from Personal to Enterprise
  5. Hard rules in code, not prompts โ€” same philosophy as multi-agent-hierarchy-brakes

Open Questions

Related