跳转至

数据模型:frontmatter 字段 + SQLite 表#

frontmatter schema#

源码:memoryd/src/memoryd/schema.py(Pydantic Frontmatter

---
# 标识
title: 2026-05-18 会话 a1b2c3d4         # 人类可读标题
slug: 2026-05-18-a1b2c3d4-e5f6-7890     # 唯一 id(也是文件名)
type: session                            # session/decision/preference/fact/playbook/warning
scope_hash: d8e86b48589e                 # 12 位 SHA256 前缀
source: claude-code                      # claude-code/codex/codex-rollout/openclaw/openclaw-fs/manual/importer-<which>
created_at: 2026-05-18T22:30:12Z
updated_at: 2026-05-18T22:30:12Z

# 索引 hint
tags: [react, solid]
triggers: [前端切换, 性能]                # 关键词列表,用于 keyword search 索引
category: tech/frontend                  # 顶层归类(Basic Memory 对齐)

# 治理
ttl_days: 90                             # null = 永久
decay_state: alive                       # alive/dim/soft-forgotten
recall_count: 0
last_recalled_at: 2026-05-18T22:30:12Z
dura_score:
  D: 0.7
  U: 0.8
  R: 0.6
  A: 0.9

# 演化
promoted_from: 2026-05-12-xyz...         # 从哪条 session 提升来的
supersedes: [2026-04-12-abc...]          # 这条覆盖了哪些旧条目

# 关系(KG 写入)
observations:
  - entity:library:React
  - entity:library:Solid
relations:
  - mentions:entity:library:React

---

加密状态不在 frontmatter

encrypted 不是 markdown frontmatter 字段。是否加密通过文件路径判断:明文文件叫 *.md,加密文件叫 *.md.enc(AES-256-GCM)。SQLite 索引在 memories.scope_sensitive 列里记录 per-memory 标记,sensitive_scopes 表里记录 per-scope 标记。encrypted: true/false 只在 memories.json 跨设备格式 里出现,那是同步用的 schema。

字段含义速查#

字段 类型 默认 说明
title str 必填 人类可读标题
slug str 必填 唯一 id
type MemoryType 必填 6 种之一
scope_hash str 必填 12 位
source str 必填 来源 tag
created_at datetime 必填 UTC ISO-8601
updated_at datetime None 修改时刷新
triggers list[str] [] 关键词索引
tags list[str] [] Basic Memory 标签
category str None 顶层归类
observations list[str] [] 抽到的 entity_id 列表
relations list[str] [] 关系字符串列表
promoted_from str None 提升来源 session slug
supersedes list[str] [] 覆盖的旧条目
ttl_days int None None = 永久
decay_state str "alive" 衰减状态
last_recalled_at datetime None 上次被召回时间
recall_count int 0 被召回次数
dura_score dict[str, float] None DURA 4 项

SQLite migrations#

源码:memoryd/src/memoryd/migrations/

文件 引入的表
001_initial_schema.sql memories · triggers · promotions
002_sensitive_scope.sql memories.scope_sensitive 字段(兼容旧表)
003_sensitive_scopes_table.sql sensitive_scopes
004_knowledge_graph.sql entities · relations · supersedes_chain
005_profile_self_learning.sql profile_versions · trigger_stats · profile_change_reports

每次 open_index() 自动跑未执行的 migration。

主索引:memories#

CREATE TABLE memories (
    slug             TEXT PRIMARY KEY,
    type             TEXT NOT NULL,
    scope_hash       TEXT NOT NULL,
    title            TEXT NOT NULL,
    source           TEXT NOT NULL,
    created_at       TEXT NOT NULL,
    updated_at       TEXT,
    ttl_days         INTEGER,
    decay_state      TEXT NOT NULL DEFAULT 'alive',
    last_recalled_at TEXT,
    recall_count     INTEGER NOT NULL DEFAULT 0,
    fingerprint      TEXT NOT NULL,
    body_path        TEXT NOT NULL UNIQUE
);

CREATE INDEX idx_memories_scope_type    ON memories (scope_hash, type);
CREATE INDEX idx_memories_fingerprint   ON memories (fingerprint);
CREATE INDEX idx_memories_decay         ON memories (decay_state, last_recalled_at);
CREATE INDEX idx_memories_created       ON memories (created_at);

fingerprint = sha1(body[:500]),用于跨路径去重。

triggers 反向索引#

CREATE TABLE triggers (
    slug     TEXT NOT NULL,
    trigger  TEXT NOT NULL,
    PRIMARY KEY (slug, trigger),
    FOREIGN KEY (slug) REFERENCES memories(slug) ON DELETE CASCADE
);

promotions 待审批#

CREATE TABLE promotions (
    id                   INTEGER PRIMARY KEY AUTOINCREMENT,
    source_session_slug  TEXT NOT NULL,
    proposed_type        TEXT NOT NULL,
    proposed_title       TEXT NOT NULL,
    proposed_body        TEXT NOT NULL,
    proposed_triggers    TEXT NOT NULL,   -- JSON array
    dura_score           TEXT NOT NULL,   -- JSON object
    reasoning            TEXT,
    proposed_supersedes  TEXT NOT NULL DEFAULT '[]',
    scope_hash           TEXT NOT NULL,
    status               TEXT NOT NULL DEFAULT 'pending',  -- pending/approved/rejected/merged
    created_at           TEXT NOT NULL,
    decided_at           TEXT,
    FOREIGN KEY (source_session_slug) REFERENCES memories(slug) ON DELETE CASCADE
);

sensitive_scopes#

CREATE TABLE sensitive_scopes (
    scope_hash    TEXT PRIMARY KEY,
    marked_at     TEXT NOT NULL,
    key_source    TEXT NOT NULL DEFAULT 'random'    -- random / passphrase
);

entities#

完整定义:migrations/004_knowledge_graph.sql

CREATE TABLE entities (
  id              TEXT PRIMARY KEY,    -- entity:person:abble
  name            TEXT NOT NULL,
  type            TEXT NOT NULL,       -- 7 类:person/organization/place/library/tool/project/concept
  aliases         TEXT,                -- JSON array
  context         TEXT,
  first_seen_at   TEXT NOT NULL,
  last_seen_at    TEXT NOT NULL,
  mention_count   INTEGER NOT NULL DEFAULT 1,
  scope_hash      TEXT,
  decay_state     TEXT NOT NULL DEFAULT 'fresh'
);

relations#

CREATE TABLE relations (
  id                INTEGER PRIMARY KEY AUTOINCREMENT,
  subject_id        TEXT NOT NULL,
  subject_kind      TEXT NOT NULL,     -- entity / memory
  predicate         TEXT NOT NULL,
  object_id         TEXT NOT NULL,
  object_kind       TEXT NOT NULL,
  source_memory_id  TEXT,
  scope_hash        TEXT,
  confidence        REAL,
  created_at        TEXT NOT NULL,
  superseded_at     TEXT,
  UNIQUE(subject_id, predicate, object_id, source_memory_id)
);

11 种 predicate:mentions / works_on / uses / prefers / supersedes / superseded_by / conflicts_with / cites / runs_on / belongs_to / located_at

supersedes_chain#

CREATE TABLE supersedes_chain (
  newer_memory_id  TEXT NOT NULL,
  older_memory_id  TEXT NOT NULL,
  entity_id        TEXT,
  confidence       REAL NOT NULL,
  decided_at       TEXT NOT NULL,
  decided_by       TEXT NOT NULL,      -- auto / user / digest
  reason           TEXT,
  PRIMARY KEY(newer_memory_id, older_memory_id)
);

profile_versions#

CREATE TABLE profile_versions (
    id                   INTEGER PRIMARY KEY AUTOINCREMENT,
    version_num          INTEGER NOT NULL UNIQUE,
    written_at           TEXT NOT NULL,
    trigger              TEXT NOT NULL,   -- weekly_cron / manual / on_event / monthly_report
    content_md           TEXT NOT NULL,
    diff_from_prev       TEXT,
    change_summary       TEXT,
    sources_count        INTEGER,
    sources_window_start TEXT,
    sources_window_end   TEXT
);

trigger_stats#

CREATE TABLE trigger_stats (
    trigger     TEXT NOT NULL,
    scope_hash  TEXT NOT NULL DEFAULT '_global',
    day         TEXT NOT NULL,            -- YYYY-MM-DD
    hits        INTEGER NOT NULL DEFAULT 1,
    PRIMARY KEY (trigger, scope_hash, day)
);

profile_change_reports#

CREATE TABLE profile_change_reports (
    id                INTEGER PRIMARY KEY AUTOINCREMENT,
    period            TEXT NOT NULL UNIQUE,    -- YYYY-MM
    generated_at      TEXT NOT NULL,
    content_md        TEXT NOT NULL,
    versions_count    INTEGER,
    supersedes_count  INTEGER,
    entities_added    INTEGER,
    entities_dropped  INTEGER
);

audit.jsonl(不在 SQLite 里)#

~/.local/share/memoryd/audit/audit.jsonl 一行一事件:

{
  "seq": 42,
  "ts": "2026-05-18T22:30:12Z",
  "actor": "cli",
  "event_type": "capture",
  "scope_hash": "d8e86b48589e",
  "target_id": "2026-05-18-...",
  "details": "{...}",
  "prev_hash": "sha256:abc...",
  "this_hash": "sha256:def..."
}

this_hash = sha256(prev_hash || canonical_json(record_without_hash)),篡改单行让后面所有行链断。

grants(不在 SQLite 里)#

~/.local/share/memoryd/grants/<scope_hash>.json

{
  "scope_hash": "d8e86b48589e",
  "granted_at": "2026-05-18T22:30:12Z",
  "duration": "session",
  "expires_at": "2026-05-19T06:30:12Z",
  "task": null
}

跨设备:memories.json#

详见 memories.json 格式