代谢协议规范 v2
本页地位
这是 kb-metabolism 代谢协议的权威规范,供兼容实现引用。工具可以被重写,协议和信号日志跟人走。 当前协议版本:2(与 .kb/config.json 的 version 字段对齐)。v1 → v2 变更见版本与演进承诺——数据格式不变,仅法医判定语义升级,无需迁移。
设计不变量
任何声称兼容本协议的实现必须满足:
- 文件 + git 是真相,一切索引均为派生物,可随时丢弃重建
- 访问日志是唯一不可再生的数据——追加式 JSONL,存于 vault 内,重建索引不得影响它
- 检索必须走门;没有日志就没有衰减判定
- AI 提案、人判决、git 兜底可反悔——不存在自动删除
- 零 LLM 时系统必须完整——智能只是省力插件
- vault 自包含:拷走目录 = 带走整个系统;秘密(
secrets.json)永不进 git
分层模型
L0 核心(人读) ≤ l0Cap(默认 100)条硬上限。每条 = 一句可复述判断 + 何时会再用。
L1 资料(AI 读) 能被检索到即可。零信号超过衰减窗口 → 处决候选。
inbox(暂存) inboxDays(默认 30 天)到期。到期前升级或进名单。
_graveyard/ 墓地。git mv 移入,可反悔;随时可真删(人工)。frontmatter 字段
被管理笔记的 YAML frontmatter 使用 kb_ 前缀命名空间:
| 字段 | 类型 | 必填 | 含义 |
|---|---|---|---|
kb_id | string(8 字符 base64url) | 系统分配 | 稳定身份:出生(capture)或索引自愈时分配,终生不变;信号按它认领,移动/改名不丢续命记录。撞号(文件被复制)时索引给后到者重发 |
kb_tier | "L0" | "L1" | "inbox" | 分诊后必有 | 层级;缺失 = 未分诊 |
kb_use_when | string | L0/L1 必填 | 一句话:什么时候会再用到(入口税) |
kb_triaged | YYYY-MM-DD | 分诊后必有 | 分诊日期 |
kb_expires | YYYY-MM-DD | 仅 inbox | 过期日,默认分诊日 + inboxDays |
kb_digested | boolean | 可选 | 已被消化为 L0,营养转移完毕 |
入口税铁律:写不出 kb_use_when 的内容,只能进 inbox 层。 兼容实现不得绕过。
信号日志(access.log.jsonl)
位置:<vault>/.kb/access.log.jsonl。追加式 JSONL,每行一条:
json
{"ts":"2026-07-09T10:23:29.390Z","tool":"kb_read","path":"sqlite-fts5.md","id":"aB3xK9pQ"}
{"ts":"2026-07-09T10:24:01.102Z","tool":"kb_search","query":"全文检索"}| 字段 | 类型 | 说明 |
|---|---|---|
ts | ISO 8601 | 信号时间(UTC) |
tool | string | 信号来源(见下表;命名空间开放,未知工具必须被容忍) |
path | string? | 记录时刻的路径——给人读日志用(读取/引用类信号必有) |
id | string? | 笔记稳定身份(frontmatter kb_id)——认领以它为准 |
query | string? | 检索词(检索类信号必有) |
信号认领规则
法医等消费方把信号归给笔记时:有 id 按 id 认领;无 id 的历史行按"记录时路径 = 当前路径"兜底。 含义:笔记移动后,带 id 的信号无损跟随;仅有 path 的历史行会失联。 一次性根治:kb migrate-signals 给可解析的历史行补 id(自动备份原日志)——这是对 "日志只允许追加"红线的唯一官方豁免,目录大整理前务必先跑。
信号金字塔(法医认定的效力等级)
| tool | 语义 | 免死窗口 |
|---|---|---|
kb_cite | 被引用进真实产出 | citeDays(默认 180 天) |
kb_read | 经门读取全文 | decayDays(默认 90 天) |
kb_inject | hooks 注入摘要且真相关(写入方必须做实词级相关性判定,如 idf 加权覆盖度) | injectDays(默认 30 天)——摘要即答案也是使用,效力最低 |
kb_search / kb_add | 检索、捕捉 | 不续命(记账用) |
kb_ui | 管理界面浏览/检索 | 不续命——观察 ≠ 使用 |
兼容实现新增信号类型时:默认不续命。让一种信号续命是协议级决定,必须升版本。
解析容错:读取方必须容忍撕裂行(进程中断产生的半行 JSON),跳过即可。
法医判定规则
法医只产出提案(处决名单),执行必须经人批准。一篇笔记成为候选,当且仅当:
- inbox 层:
kb_expires已过;或 - 非 L0 层同时满足全部五条:
- 最后一次
kb_read距今超过decayDays(或从未被读) - 最后一次
kb_cite距今超过citeDays(或从未被引用) - 最后一次
kb_inject距今超过injectDays(或从未被注入) - 活反链数 = 0(全 vault 扫描,含不受管理的目录;
exclude的除外)。链接只在两种情况下算担保:来源自身活着(内容年龄 ≤decayDays,或有窗口内 read/cite/inject 信号),或来源在创作目录(outputDirs,铁证不降级)。只算一层,不做图迭代——死簇互链同批上榜,被使用的索引页仍保护其子节点 - 最后内容变更距今超过
decayDays——年龄取 git 历史中最后一次真实修改:纯重命名与批量提交(单提交文件数 >bulkCommitThreshold,默认 30)不算触碰;触碰全被过滤的文件回退出生时间;非 git 仓库回退 mtime
- 最后一次
L0 永不上榜——挤掉 L0 是消化仪式里的显式人工动作,不是法医的职权。
处决与反悔
- 名单格式:Markdown checkbox 列表(
- [ ] \path` — 理由),人勾选[x]` 即批准 - 执行 =
git mv到_graveyard/(非 git 仓库降级为 rename),并建议自动提交 - 还魂 =
git mv回库内任意位置 - 墓地内容的真删除永远是人工操作,任何实现不得提供自动清空
配置文件(.kb/config.json)
jsonc
{
"version": 1, // 协议版本
"managed": ["**/*.md"], // 受管理范围(glob)
"exclude": ["_graveyard/**"],
"captureDir": ".",
"l0Cap": 100,
"inboxDays": 30,
"decayDays": 90,
"citeDays": 180,
"outputDirs": [], // 创作目录:其中的引用是铁证级吸收信号
"judgment": { "provider": "human", "triageModel": "…", "digestModel": "…" },
"embedding": { /* 可选,见语义检索 */ }
}完整字段语义见配置参考。
版本与演进承诺
version字段缺省视为1- 破坏性变更(字段语义改变、信号效力改变、法医规则改变)必须升
version,并随版本发布迁移说明 - 新增可选字段、新增不续命的信号类型属于兼容变更,不升版本
- 先例:
kb_id与信号id字段(0.4.0 引入)即兼容新增——旧行仍被兜底认领,协议版本保持1 - v1 → v2(信号效力与法医规则改变,故升版本):
kb_inject从不续命升为第三档存活证据(injectDays,默认 30 天,写入方必须做实词级相关性判定);反链从无条件豁免降级为活源担保;年龄口径从"最后提交"改为"最后内容变更"(重命名与批量提交不算触碰)。迁移:无——日志与 frontmatter 格式不变,旧 config 缺省字段按默认值生效;v1 时代记录的kb_inject历史行在 v2 下自动获得效力(30 天窗口早已过期的行无实际影响)