# 0.18.46 — 发布候选：全链路审计结论

候选版本 `0.18.46`（基准在 `0.18.46` 上复跑）。本文只记「查了什么、凭什么说它成立、还留着什么」，细节在对应 RELEASE 与 `docs/BENCH.md`。

## 七条链路的结论

| 链路 | 结论 | 证据 |
| --- | --- | --- |
| 召回边界 | 无关不注入、条件不匹配不召回、整卡装不下就整卡省、准备阶段不记账、归档不进常规检索 | `test/recall.test.mjs` A08/A09/A10/A11b/A18；A19 按规范化字节计预算 |
| 任务识别 | 短追问沿用上一句；明说换任务就断开旧线索；新话题可判定时旧动作线索不跟；认不出类型的换任务也不继承 | A02b/A25/A25b/A25c/A25d/A25e/A26/A29 |
| 学习收敛 | 每轮最多 2 处改动、试用到 30 天自动停、规则封顶 32 条、失败只留回执无副作用 | `test/learning.test.mjs` 59 项；`bench/evolution.mjs` 压到 32 条、`stateBytes 132 KB` |
| 待裁决审批 | 候选满就明说「先处理旧的」，不接受静默丢；确认后才写正式条目；已消费候选重放不写第二条 | `test/store.test.mjs` 候选门限与重放用例；`acceptCandidate` 同锁窗口内确认+消费+回执 |
| 全局写入 | 只有真人明确说「存到全局/所有项目」才跨项目写入；普通用词（如「全局变量」）不放行 | A31；全局层容量 200/1000 两档与项目层同一套裁决 |
| 使用统计 | 只有真正交付给模型的卡片才记 `lastUsed`/`hits`，检索与读正文是纯读；空召回不顺手记账 | A03/A12/A32；`test/store.test.mjs`「search and read leave hits and lastUsed alone」；10 分钟防抖避免每次检索抢锁 |
| 动作前触发 | npm 类原生命令在动作前拦一次并给凭据用法，同轮不重复；项目层优先于全局层；零命中时关键动作后补查一次且不重复注入 | A27/A27b/A28；A30 只读文件不花补查机会 |

## 轻量化

| 指标 | 0.18.41 | 候选 0.18.46 |
| --- | --- | --- |
| 常驻描述+参数+schema | 13 375 B | 13 375 B（上限 13 600） |
| 每轮平均注入 | 368 B | 368 B |
| 热点层 `state.json` | 132 KB | 约 132 KB；回执上限 256→64，再省约 27 KB |
| 热快照 P50 / P95 | 67.1 / 84.6 ms | 70.2 / 84.0 ms（0.18.46 实跑） |
| 每轮文件读 | 0.4 次 | 0.3 次 |
| npm tarball / 解包 / 文件数 | 377.6 KB / 1.4 MB / 97 | 252.3 KB / 861.7 KB / 74（含本文与候选说明） |

`npm run bench` 与 `npm run bench:evolution` 均 `ok:true`；`npm test` 21 个套件全绿。

## 明确没做与已知边界

- 不引向量库、图数据库、后台整理进程：召回是文本打分，同义改写靠 `TRIGGERS.md` 的触发词与词面覆盖，不承诺任意改写都能召回；承诺的是「只递相关卡、只对递出去的记账、标题纠错只重试一次」。
- 候选满时 `store.js` 抛错、`state.js` 遇候选超限静默留最近的：两条路径保留不对称，理由写在这里，不假装一致。
- 回执裁剪走写入路径：长期不写的层会保留旧回执，下一次写入即压回上限。旧进程写下的 256 条不会自己消失，靠这次写入自愈。
- 面板「第一视角宫殿」四间房、每页 24 条、4 格预览，预览格数已按内容铺（1 条就 1 格）；不做拖拽重排、不做跨房间合并。
- 发布候选即上述版本：CI 绿、`dist-tags.latest` 指向本版、profile 同步后 client 已 reload。
