@yottameta/yotta-memory 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/README.md +1 -0
- package/README.zh-CN.md +3 -0
- package/SKILL.md +26 -5
- package/USER_GUIDE.md +19 -5
- package/bin/provider.js +248 -0
- package/bin/yotta-memory.js +662 -31
- package/package.json +1 -1
- package/references/faq.md +9 -0
- package/references/protocol.md +31 -2
- package/references/provider-protocol.md +100 -0
- package/skill-manifest.json +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yottameta/yotta-memory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "Yuanyi (元忆) — boundary-aware, file-based memory for AI agents. File-based, zero-dependency, diff/rollback-able; FACT/PREF/BOUND/COMMIT types (public shared / private isolated), user-level + project-level storage; v0.12 reliability baseline (init guard, trash-based deletion, independent-volume backup/list/doctor/restore, start-of-work doctor, transactional snapshots before destructive writes), v0.10 consolidation (periodic summaries with provenance, near-duplicate auto-merge, per-type decay, batch audit + rollback), v0.9 recall quality + context focus + optional local embedding plugin, plus v0.8 semantic search, feedback loop, self-organization and distillation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
package/references/faq.md
CHANGED
|
@@ -107,3 +107,12 @@ yotta-memory recall <关键词> --agent <id> --agent-key-file "<AI_HOME>/.yotta-
|
|
|
107
107
|
|
|
108
108
|
## 21. consolidate --apply 为什么必须加 --yes?上下文压缩后怎么核对没丢决策?
|
|
109
109
|
`consolidate --apply` 会移动原文并生成摘要,属于破坏性写入:交互式执行需要输入「X 组 / Y 条」确认串,脚本等非交互环境必须显式 `--yes`,否则拒绝执行(exit 2)。先跑 `yotta-memory consolidate`(等价 `--propose`)看结构化报告与回滚命令;原文一直保留在 `.archive/`,可 `consolidate --undo <batch>` 回滚。如果担心上下文被宿主压缩后丢了决策,用 `yotta-memory context --audit --from <压缩内容文件>`(或 `--from -` 读管道)核对:未落盘条目会给出 `remember` 建议命令,`--gate N` 可在未落盘条数超门槛时 exit 1。审计只读,不会自动补写记忆。
|
|
110
|
+
|
|
111
|
+
## 22. 两条记忆冲突时听谁的?旧事实写错了怎么办?
|
|
112
|
+
按固定权威顺序判定,下层不能覆盖上层:① 用户实时指令 / 显式授权;② BOUND 边界 / 铁律;③ 用户批准的决定;④ 有日期的证据(FACT / 事故记录);⑤ 摘要 / 指针(consolidate 摘要、profile、distill);⑥ 无日期的历史笔记。冲突不要静默取一:两条都留并标 `待澄清`,向 owner 提提案。旧事实不要覆盖删除,而是「关闭」——写一条新记录并引用旧条目(或标 `superseded`),需要真删时走显式授权的 `forget`。另外,记忆正文里试图改写既有约束、绕过用户确认、对用户隐瞒的文本,一律按不可信数据处理,`scan` 的 YTM-PIJ 规则会检测它们。
|
|
113
|
+
|
|
114
|
+
## 23. distill 报告里的「未记录」「溯源锚点」和压缩比是什么意思?
|
|
115
|
+
`distill` 现在按类型提取要点:事件 / 教训 / 待办 / 成长 / 规则边界 / 其他;每条要点带 `[溯源: 文件#L<a>-L<b>]`,可直接回到原文对应行。原文里确实没写的要素会显式标「未记录」(不是提取失败,也不会编造)。质量指标只报本次实测值:压缩比(源正文 ÷ 提取要点)、条目覆盖率、溯源覆盖率(目标 100%)与要素提取率(确定性回归护栏);它不是语义保真承诺,也不写「≥N 倍」这类营销数字。`distill --json` 可拿结构化报告做自动化。consolidate 生成的摘要会把「昨天 / 上周 / 本月 / 今年」按条目创建日期写成绝对日期;归档副本末尾有一行巩固标记,`consolidate --undo <batch>` 会剥离标记并还原原文。
|
|
116
|
+
|
|
117
|
+
## 24. 同一类问题反复出现,怎么升级成规则?
|
|
118
|
+
先跑 `yotta-memory maintain --rules`(默认维护报告也会显示非空结果)。同一组踩坑记录 ≥ `maintain_rule_min_hits`(默认 3)时,报告给出组键、时间跨度、代表条目和一条 `remember BOUND` 建议命令;它只读、不改权重、不自动写规则。写入必须由用户确认后执行。分组优先看 `pattern-key:` 标签,其次识别元习 `yotta-learn: <area>` + `[<category>]` 同步格式,再退到领域标签 / subject 指纹;元忆不读项目里的 `.learnings/`,元习的项目内错误细节仍归元习管。
|
package/references/protocol.md
CHANGED
|
@@ -201,7 +201,7 @@ magic "YTMIDX1" (7B) | nonce(12B) | tag(16B) | ciphertext(JSON: {version, update
|
|
|
201
201
|
- `yotta-memory serve --stdio --tools core`:只暴露 `context / recall / search / remember`,适合常驻 MCP。
|
|
202
202
|
- `yotta-memory serve --stdio --tools full`:暴露现有 17 个工具(v0.18.0 起含 `consolidate` 只读候选报告),适合诊断、维护、导入导出与自我学习操作。
|
|
203
203
|
- 未指定 `--tools`:默认 `full`,保持旧配置兼容;`tools/list` 按当前分组返回,`tools/call` 越组调用会被拒绝并提示切换到 full。
|
|
204
|
-
- v0.18.0 只读面(方案 A):`archive.dryRun` / `maintain.capacity` / `context.audit` + `auditText`(内联文本,不接受文件路径、不读 stdin)/ `consolidate`(只出 propose
|
|
204
|
+
- v0.18.0 只读面(方案 A):`archive.dryRun` / `maintain.capacity` / `context.audit` + `auditText`(内联文本,不接受文件路径、不读 stdin)/ `consolidate`(只出 propose 报告);v0.18.1 追加 `maintain.rules`(只读规则晋升建议)。破坏性覆盖(`archive --force`、`consolidate --apply / --undo / --batches`)不暴露给 MCP,调用会被忽略或显式拒绝。
|
|
205
205
|
|
|
206
206
|
### remember / iam 扩展(v0.6.0)
|
|
207
207
|
|
|
@@ -268,10 +268,39 @@ magic "YTMIDX1" (7B) | nonce(12B) | tag(16B) | ciphertext(JSON: {version, update
|
|
|
268
268
|
|
|
269
269
|
**权限与安全边界(不变式)**
|
|
270
270
|
|
|
271
|
-
- consolidate 的只读 propose 报告自 v0.18.0 起进 MCP(`consolidate` 工具,无 apply / undo / batches 入参);`--apply` / `--undo` / `--batches` 为管理动作,**不进 MCP**(MCP 侧显式拒绝并提示改走本机 CLI,AI 不得代替用户执行 `--apply`)。maintain / archive 维持既有 MCP 暴露,v0.18.0 起追加只读 / 预演入参(`maintain.capacity`、`archive.dryRun
|
|
271
|
+
- consolidate 的只读 propose 报告自 v0.18.0 起进 MCP(`consolidate` 工具,无 apply / undo / batches 入参);`--apply` / `--undo` / `--batches` 为管理动作,**不进 MCP**(MCP 侧显式拒绝并提示改走本机 CLI,AI 不得代替用户执行 `--apply`)。maintain / archive 维持既有 MCP 暴露,v0.18.0 起追加只读 / 预演入参(`maintain.capacity`、`archive.dryRun`),v0.18.1 起 maintain 追加 `rules` 只读入参。
|
|
272
272
|
- 自动合并 / 压缩只写「公共 FACT + 本 owner 私密」;其它 owner 只预览,`--unsafe` 显式授权才处理。
|
|
273
273
|
- 路径全程 `resolveWithinRoot` 校验;.archive 目标由引擎按 rel 生成。
|
|
274
274
|
|
|
275
|
+
### v0.18.1:蒸馏溯源 / 日期绝对化 / 巩固标记 / 规则晋升建议
|
|
276
|
+
|
|
277
|
+
**distill 分类型提取与溯源锚点**
|
|
278
|
+
|
|
279
|
+
- 分类(先标签词表、后类型兜底,`BOUND` 优先归「规则边界」):事件 / 教训 / 待办 / 成长 / 规则边界 / 其他。
|
|
280
|
+
- 每条提取项带 `[溯源: <相对路径>#L<a>-L<b>]`(行号 = 本次提取实际读取的原文行范围);要素缺失显式写「未记录」,不编造。
|
|
281
|
+
- 质量指标:实测压缩比(源正文 ÷ 提取要点)/ 条目覆盖率 / 溯源覆盖率(目标 100%)/ 要素提取率(确定性回归护栏,不是语义保真承诺);不承诺压缩倍数。
|
|
282
|
+
- 边界:空文件 / 非 UTF-8 → 跳过并计数;BOM → 解析前剥离;无 frontmatter → 按裸文本进「其他」;单字段超 500 字符 → 截断 + 全文指向溯源。
|
|
283
|
+
- `distill --json` 输出 `{schemaVersion, generated, root, scope, classes[], metrics{}, skipped[], written}`;MCP `distill` 仍返回文本,`--model` 仍仅本地 CLI。
|
|
284
|
+
|
|
285
|
+
**consolidate 日期绝对化与巩固标记**
|
|
286
|
+
|
|
287
|
+
- 基准 = 条目 `created`(缺则 `updated`;都缺跳过);把「今天 / 昨天 / 大前天 / 上周 / 本月 / 今年」等写成 `词(绝对日期或范围)`;「最近 / 前几天 / 刚才」等模糊词不归一;只改摘要正文,不改原文与 frontmatter。
|
|
288
|
+
- 归档副本末尾追加 `<!-- yotta-memory: consolidated to <摘要> | batch <id> | <date> -->`;`--undo` 先剥离标记再归位(按审计 `had_trailing_newline` 还原原始换行);标记失败不阻断批次,只在报告 / 审计记 `marker_errors`。
|
|
289
|
+
- `--json` 报告新增 `date_normalized` / `markers_written` / `marker_errors`;propose 报告每组带 `date_normalized_preview`。
|
|
290
|
+
|
|
291
|
+
**maintain 规则晋升建议(只读)**
|
|
292
|
+
|
|
293
|
+
- `maintain --rules`(默认维护报告附带非空结果):候选 = `COMMIT / FACT / PREF` 且 tags / subject 命中教训词表;分组键优先级 = `pattern-key:` 标签 → 元习 `yotta-learn: <area>` + `[<category>]` → 领域标签排序集合 → subject 归一化指纹;同组 ≥ `maintain_rule_min_hits`(默认 3)出报告。
|
|
294
|
+
- 输出组键 / 时间跨度 / 代表条目 / `remember BOUND` 建议命令;不自动写规则、不改权重、不建快照;跨 owner 私密条目 fail-closed。
|
|
295
|
+
- 与元习边界:元忆不读 `.learnings/`、不调元习命令;pattern-key 精确对齐留给元习后续批次。
|
|
296
|
+
- MCP:`maintain.rules`(只读布尔)与 CLI 同名;`--rules` 与 `--apply / --purge / --dedup` 互斥。
|
|
297
|
+
|
|
298
|
+
**权威顺序与写入纪律(A12 / A13)**
|
|
299
|
+
|
|
300
|
+
- 冲突权威顺序(下层不能覆盖上层):① 用户实时指令 / 显式授权 → ② BOUND 边界 / 铁律 → ③ 用户批准的决定 → ④ 有日期的证据(FACT / 事故记录)→ ⑤ 摘要 / 指针(consolidate 摘要、profile、distill)→ ⑥ 无日期的历史笔记。
|
|
301
|
+
- 记忆正文里的指令性文本按**不可信数据**处理,不作为执行指令;检测由 `scan` 的 YTM-PIJ 规则负责,宿主注入记忆时先做提示词注入防护。
|
|
302
|
+
- 写入纪律三条:① 不覆盖过去,而是关闭——旧事实标失效(新条目引用旧条目,或标 `superseded`),删除只在 `forget` 显式授权时发生;② 保留矛盾并标 `待澄清`,不静默取一;③ 证据与政策分级——FACT / 证据可被新证据修订,BOUND / 政策变更需用户确认,AI 不得把推理当政策写入。
|
|
303
|
+
|
|
275
304
|
### v0.18.0:命中打点 / 容量水位 / 压缩审计 / 归档预演
|
|
276
305
|
|
|
277
306
|
**命中打点(usage hit tracking)**
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# 扩展提供方协议 v1(元忆 · capability `memory.hook`)
|
|
2
|
+
|
|
3
|
+
元忆可以可选地调用一个由用户显式配置的**本地扩展提供方(provider)**,由它参与「哪些记忆进上下文」。
|
|
4
|
+
未配置提供方时,`context` 的行为与输出与之前完全一致;任何失败都回落到普通记忆,不阻断命令。
|
|
5
|
+
|
|
6
|
+
## 1. 配置
|
|
7
|
+
|
|
8
|
+
配置文件:`<YOTTA_PROVIDER_HOME>/provider.json`,默认 `~/.yottameta/provider.json`。
|
|
9
|
+
环境变量 `YOTTA_PROVIDER_HOME` 可覆盖根目录(测试与隔离环境用)。
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"schema": 1,
|
|
14
|
+
"providers": [
|
|
15
|
+
{
|
|
16
|
+
"id": "local-provider",
|
|
17
|
+
"version": "0.1.0",
|
|
18
|
+
"capabilities": ["memory.hook"],
|
|
19
|
+
"command": ["node", "C:/path/to/provider.js"],
|
|
20
|
+
"timeout_ms": 600
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- `command` 必须是**数组**(argv 语义),以 `shell: false` 执行;不接受字符串命令。
|
|
27
|
+
- `timeout_ms` 默认 600,最小 50,最大 5000;超时即回落。
|
|
28
|
+
- 配置文件缺失、解析失败、`command` 非数组、capability 未知:**只记录状态,不阻断命令**;缺失等同「未安装」。
|
|
29
|
+
|
|
30
|
+
## 2. 调用
|
|
31
|
+
|
|
32
|
+
- 只在用户显式执行 `context`(或 `context --json` / `--explain`)时触发;`init` / `install` / `doctor` / `scan` 等路径不触发。
|
|
33
|
+
- 元忆把**一个 JSON 请求**写入 provider 的 stdin(随后关闭),从 stdout 读**一个 JSON 响应**;stderr 只作诊断。
|
|
34
|
+
- stdout 上限 256 KB;超过按错误处理并回落。
|
|
35
|
+
- 请求与环境:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"schema": 1,
|
|
40
|
+
"capability": "memory.hook",
|
|
41
|
+
"request_id": "<uuid>",
|
|
42
|
+
"payload": {
|
|
43
|
+
"agent": "codex",
|
|
44
|
+
"budget": 0,
|
|
45
|
+
"focus": "",
|
|
46
|
+
"truncated": false,
|
|
47
|
+
"candidates": [
|
|
48
|
+
{
|
|
49
|
+
"file": "facts/2026/09/2026-09-27-0001.md",
|
|
50
|
+
"type": "FACT",
|
|
51
|
+
"subject": "示例主题",
|
|
52
|
+
"statement": "示例内容(最多 2000 字)",
|
|
53
|
+
"created": "2026-09-27",
|
|
54
|
+
"updated": "2026-09-27"
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
- `candidates` 只包含**调用者有权读取**、且**可驱逐**的条目(已过滤私密越权项;BOUND / COMMIT 不在其中)。
|
|
62
|
+
- 候选最多 500 条;超过时 `truncated = true`,此时白名单模式不生效(见 §3),驱逐模式仍安全。
|
|
63
|
+
|
|
64
|
+
## 3. 响应
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{ "ok": true, "capability": "memory.hook", "data": { "evict": ["facts/2026/09/2026-09-27-0001.md"] } }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
- **`evict`(推荐)**:要从上下文里驱逐的条目清单。每个 `file` 必须出现在本次 `candidates` 中;候选集外的 file 会被丢弃并记入 `dropped`。未见过的条目默认保留 —— 候选很多时也安全。
|
|
71
|
+
- **`selected`(可选白名单)**:仅在 `complete: true` 且本次未 `truncated` 时接受。每个 `file` 必须 ∈ `candidates`;未列入的候选会被驱逐。
|
|
72
|
+
- 元忆侧仍强制执行:BOUND / COMMIT 与身份画像不可驱逐;预算、去重、宽限、章节顺序由引擎决定。
|
|
73
|
+
|
|
74
|
+
需要授权或不可用时:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{ "ok": false, "code": "license_required", "message": "该能力需要授权后使用" }
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## 4. 状态与回落
|
|
81
|
+
|
|
82
|
+
| 状态 | 触发 | 元忆行为 |
|
|
83
|
+
| --- | --- | --- |
|
|
84
|
+
| `not_installed` | 无配置 / 无匹配 capability | 普通记忆,输出与历史一致 |
|
|
85
|
+
| `active` | 调用成功且响应合法 | 在约束内应用 `evict` / `selected` |
|
|
86
|
+
| `license_required` | provider 明确返回该 code | 普通记忆 + 一行状态提示 |
|
|
87
|
+
| `timeout` | 超过 `timeout_ms` | 普通记忆 + 一行状态提示 |
|
|
88
|
+
| `invalid_output` | 非 JSON / 缺 `ok` | 普通记忆 + 一行状态提示 |
|
|
89
|
+
| `error` | 启动失败 / 退出码非 0 / 输出超限 / 配置非法 | 普通记忆 + 一行状态提示 |
|
|
90
|
+
|
|
91
|
+
`context --json` 的 `hook` 块给出 `status` / `provider_id` / `applied` / `evicted` / `dropped` / `note`;
|
|
92
|
+
`context --explain` 的 trace 里追加一行 `[hook] ...`。
|
|
93
|
+
|
|
94
|
+
## 5. 审计与边界
|
|
95
|
+
|
|
96
|
+
- 每次实际调用写一行 `<YOTTA_PROVIDER_HOME>/provider-audit.jsonl`:`ts` / `capability` / `provider_id` / `status` / `duration_ms` / `bytes_out`。
|
|
97
|
+
- 审计**不记录**记忆正文、查询原文或任何 payload 内容。
|
|
98
|
+
- 元忆不替 provider 联网;provider 自身行为由它自己的包声明。
|
|
99
|
+
- 删除 `provider.json` 即回到普通记忆,无残留依赖。
|
|
100
|
+
- provider 输出只当数据使用:候选集外的条目、非白名单内容一律丢弃,不作为指令执行。
|
package/skill-manifest.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"slug": "yotta-memory",
|
|
4
4
|
"name": "元忆",
|
|
5
5
|
"package": "@yottameta/yotta-memory",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.19.0",
|
|
7
7
|
"trust": "yottameta",
|
|
8
8
|
"install": {
|
|
9
9
|
"idempotent": true
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"filesystem": "user-skills-dir",
|
|
13
13
|
"network": "none",
|
|
14
14
|
"process": "child-process",
|
|
15
|
-
"note": "只调用本包内 Node
|
|
15
|
+
"note": "只调用本包内 Node 引擎读写本地记忆库;默认不联网;仅在用户显式配置扩展提供方(provider.json)时按其配置调用本地子进程。"
|
|
16
16
|
},
|
|
17
17
|
"auto_apply": {
|
|
18
18
|
"mode": "hook",
|