open-memex 0.3.0 → 0.4.0-alpha.10
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/AGENTS.md +20 -1
- package/README.md +117 -9
- package/README.zh-CN.md +103 -9
- package/dist/cli.js +583 -14
- package/dist/config.js +12 -0
- package/dist/distill-agents.js +55 -0
- package/dist/doctor.js +1 -1
- package/dist/export.js +157 -0
- package/dist/github.js +215 -0
- package/dist/index.js +6 -0
- package/dist/init.js +43 -18
- package/dist/mcp.js +119 -12
- package/dist/paths.js +31 -0
- package/dist/providers/git.js +142 -0
- package/dist/retrieve/inject.js +2 -2
- package/dist/retrieve/search.js +31 -6
- package/dist/review.js +437 -0
- package/dist/store/db.js +3 -2
- package/dist/store/lifecycle.js +28 -13
- package/dist/store/markdown.js +57 -14
- package/dist/store/sync.js +74 -6
- package/dist/submit.js +347 -0
- package/dist/tools/ops.js +171 -8
- package/docs/CURATOR.md +59 -0
- package/docs/USER-GUIDE.md +197 -0
- package/docs/USER-GUIDE.zh-CN.md +161 -0
- package/docs/V2-DESIGN.md +287 -13
- package/package.json +1 -1
- package/scripts/smoke-mcp.ts +2 -2
- package/src/cli.ts +608 -15
- package/src/config.ts +26 -0
- package/src/distill-agents.ts +70 -0
- package/src/doctor.ts +1 -1
- package/src/export.ts +206 -0
- package/src/github.ts +257 -0
- package/src/index.ts +6 -0
- package/src/init.ts +43 -17
- package/src/mcp.ts +166 -11
- package/src/paths.ts +32 -0
- package/src/providers/git.ts +191 -0
- package/src/retrieve/inject.ts +2 -2
- package/src/retrieve/search.ts +33 -6
- package/src/review.ts +504 -0
- package/src/store/db.ts +3 -2
- package/src/store/lifecycle.ts +30 -12
- package/src/store/markdown.ts +91 -14
- package/src/store/sync.ts +85 -4
- package/src/submit.ts +424 -0
- package/src/tools/ops.ts +203 -9
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# OpenMemex 用户守则
|
|
2
|
+
|
|
3
|
+
> 本文档讲的是 open-memex 的**心智模型**:你的记忆住在哪里、怎么流动、谁能看到。
|
|
4
|
+
> in-repo 目录(§2、§6 的写路径)和 propose → promote → resolve 工作流(§5)
|
|
5
|
+
> 已在 `V2-dev-p2b` 分支实现;标有 **2B** 的功能属于 Phase 2B 待实现部分,
|
|
6
|
+
> 其余为 0.3.0 已有行为。
|
|
7
|
+
|
|
8
|
+
## 一句话
|
|
9
|
+
|
|
10
|
+
open-memex 是本地优先的记忆层:**Markdown 是真相,SQLite 只是可重建的索引**。索引丢了可以重建,
|
|
11
|
+
Markdown 丢了才是真的丢了。
|
|
12
|
+
|
|
13
|
+
## 1. 两种 Scope:personal 与 project
|
|
14
|
+
|
|
15
|
+
每条记忆都属于一个 scope,决定它**能走多远**:
|
|
16
|
+
|
|
17
|
+
| | personal | project |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| 存什么 | 关于你的事实:偏好、习惯、跨项目的信息 | 关于项目的事:技术栈、约定、决策、踩过的坑 |
|
|
20
|
+
| 存哪里 | 只在你本机(见 §2) | 本机 + 可进团队共享(见 §2、§6) |
|
|
21
|
+
| 一句话 | **永不离开这台机器** | 可以晋升为团队知识 |
|
|
22
|
+
|
|
23
|
+
关键词会自动路由(D18):「记住…/我觉得…/我喜欢…」(我)→ personal;
|
|
24
|
+
「我们认为…/我们决定…/帮我们记住…」(我们)→ project。
|
|
25
|
+
|
|
26
|
+
## 2. 两个家:appdata 与 repo 目录
|
|
27
|
+
|
|
28
|
+
| | appdata(书桌) | repo `.ai/open-memex/`(书架) |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| 位置 | Windows `%APPDATA%/open-memex`,Linux `~/.local/share/open-memex` | 项目根目录下,默认 `.ai/open-memex/`(D23,可配置 `memoryDir`) |
|
|
31
|
+
| 放什么 | `memories/personal/` 个人记忆;project scope **草稿箱(outbox)**;`index.db` 本地索引 | 已提交的 project 记忆(`proposed` 及以上) |
|
|
32
|
+
| 进 git 吗 | 不进 | 进,git 就是它的搬运工 |
|
|
33
|
+
| 索引呢 | `index.db` 可重建,**永远不入库** | 不存索引,用时从 Markdown 重建 |
|
|
34
|
+
|
|
35
|
+
个人笔记本(personal)永远不上书架。这是铁律,不是配置项。
|
|
36
|
+
|
|
37
|
+
project 记忆先以**草稿**身份住在 appdata outbox——git 看不见、跟分支无关。
|
|
38
|
+
只有你亲手点名的草稿,才会被 `open-memex submit` 移上书架(§5)。
|
|
39
|
+
一个阶段只住一个地方:submit 成功后 outbox 原件消失;submit 之前,
|
|
40
|
+
repo 里什么都不知道。
|
|
41
|
+
|
|
42
|
+
## 3. 首轮注入:8 条和 5 条是怎么选出来的
|
|
43
|
+
|
|
44
|
+
Agent 第一轮发言前,open-memex 会塞一个 `[OPEN-MEMEX]` 上下文块进去,省得每次先调一次搜索。
|
|
45
|
+
默认注入 **project 8 条、personal 5 条**(`maxProjectMemories` / `maxProfileItems`,可调)。
|
|
46
|
+
|
|
47
|
+
入选标准只有一个:**最近更新优先**(`ORDER BY updated_at DESC`),并过滤掉已撤回/归档、
|
|
48
|
+
解析掉被替代的旧版本。不是"最重要的 N 条",而是"最近在折腾的 N 条"——
|
|
49
|
+
你刚更新过的东西,最可能跟当前工作相关。
|
|
50
|
+
|
|
51
|
+
Token 账:每条压成一行(≤240 字符,约 60 token),8 条 ≈ 500 token 上限。
|
|
52
|
+
超过这个数收益递减——长尾靠 `memory_search` 按需查,全塞进首轮反而淹没信号。
|
|
53
|
+
|
|
54
|
+
调大:`open-memex config set maxProjectMemories 12`
|
|
55
|
+
|
|
56
|
+
## 4. 后续轮次:什么时候会再搜记忆
|
|
57
|
+
|
|
58
|
+
首轮注入只发生一次。之后**没有自动重搜机制**——MCP 是 request/response 模式,
|
|
59
|
+
server 不能主动推送,调不调 `memory_search` 全看 model 的判断。引导它的有两处:
|
|
60
|
+
|
|
61
|
+
- 注入块页脚:"Use the `memory_search` tool to look up more."
|
|
62
|
+
- Copilot instructions(`init` 写入的):"问用户以前说过的事之前,先 `memory_search`;
|
|
63
|
+
先试几个关键词变体,搜不到再问。"
|
|
64
|
+
|
|
65
|
+
也就是说:当对话触及历史决策、偏好、约定时,model **应该**先搜,但没有任何机制强制。
|
|
66
|
+
这是当前版本的已知缺口——Phase 2C 的原生插件 hooks(如 Claude Code 的
|
|
67
|
+
`UserPromptSubmit`)就是来补这块的。
|
|
68
|
+
|
|
69
|
+
## 5. 晋升工作流:记忆如何变成团队知识
|
|
70
|
+
|
|
71
|
+
个人观察变成团队知识只有一条路——**显式晋升,绝不自动同步**:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
个人想法 ──propose──▶ 草稿箱 ──submit──▶ proposed ──┬──promote──▶ approved ──promote──▶ 已发布/共享
|
|
75
|
+
│ │
|
|
76
|
+
--reject --reject
|
|
77
|
+
│ │ (合并前可撤回批准)
|
|
78
|
+
▼ ▼
|
|
79
|
+
rejected ──resubmit──▶ proposed
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
- `open-memex propose <id...> --to project`:把一条或多条 personal 记忆**复制**到
|
|
83
|
+
**appdata 草稿箱**进入评审(`review_state: draft`,每条独立新 id,
|
|
84
|
+
`derived_from` 指回 personal 原件)。**复制而非移动——personal 原件保留。**
|
|
85
|
+
全有或全无:id 有错整批回滚。这一步还不碰 repo——草稿箱 git 看不见、跟分支无关。
|
|
86
|
+
单人开发可用 `--local-approve` 自批。
|
|
87
|
+
- `open-memex sync-status`:看索引**上次同步的时间和触发方**(会话开始、
|
|
88
|
+
请求、CLI、submit)、草稿箱(待同步)、repo 里的评审状态
|
|
89
|
+
(`draft / proposed / approved / published / rejected`),以及 repo 里还没
|
|
90
|
+
commit 的记忆文件。你的 agent 会在会话开始、关键节点、你 commit 之后、
|
|
91
|
+
记忆动作之后跑这个,然后问你哪些草稿(如果有)要同步。你也可以直接说"同步记忆"。
|
|
92
|
+
- `open-memex submit <id...>`:把**你点名的草稿**移入 `<repo>/.ai/open-memex/`,
|
|
93
|
+
状态变为 `proposed`。它复制文件、改 `review_state`、在**当前分支**做一次
|
|
94
|
+
**本地** git commit——永不自动建分支(建分支你说了算,或 agent 拿到你明确
|
|
95
|
+
批准走全链时用 `--branch <name>`)。
|
|
96
|
+
全有或全无、幂等、crash-safe。它打印 `git push` +
|
|
97
|
+
`gh pr create` 命令;如果你的 agent 已经拿到你这次的 Yes,它会自己走完
|
|
98
|
+
push 和 PR。PR 默认 base 是当前分支;`--base` 可改到 `main` 或集成支。
|
|
99
|
+
分支上同 id 但内容不同——**直接中止**,等人裁决,绝不覆盖。
|
|
100
|
+
- 四个动作分工要分清:**propose 是跨界**(personal → project 草稿箱,
|
|
101
|
+
唯一跨越"私有/共享"边界的动作);**submit 把草稿搬进 repo**
|
|
102
|
+
(outbox → `.ai/open-memex/`,`draft → proposed`);**promote 只改状态标签**
|
|
103
|
+
(文件一直在 `.ai/open-memex/` 里没动过,只是 `review_state`
|
|
104
|
+
从 proposed → approved → published)——它不在目录之间搬文件;
|
|
105
|
+
**git 负责运输**(push、PR、合并)。
|
|
106
|
+
- 独立的记忆 PR **只含记忆文件,不含代码**,跟代码 PR 分开评审、分开审计。
|
|
107
|
+
审的是"这条是真的吗?能给全团队看吗?有没有 secret?"——代码 PR 的 CI 不会查这些。
|
|
108
|
+
想开分支时你自己建(或 agent 拿到批准后建)。
|
|
109
|
+
- "要求修改"不需要命令:PR 开着的时候,作者直接改同一个文件(自己改,
|
|
110
|
+
或在 chat 里让 agent 改),commit、push。状态一直是 `proposed`,
|
|
111
|
+
PR 本身就是评审机制。
|
|
112
|
+
- `open-memex promote <id>`:把记忆往阶梯上推一步
|
|
113
|
+
(`proposed → approved → published`)。`--reject --note "..."` 驳回并附注原因
|
|
114
|
+
(合并前也可从 `approved` 驳回,即撤回批准)。每次流转都追加到记忆的
|
|
115
|
+
`review_history`——谁动的、何时、从什么到什么、为什么——PR 关了很久以后
|
|
116
|
+
还能查到这条评审链。
|
|
117
|
+
PR 合并后,再跑一次 `promote <id>` 标记为 `published`——或者让下面的
|
|
118
|
+
`pr-status --apply` 代劳。(project 记忆提升到 org 级是 Phase 4 的事。)
|
|
119
|
+
- **驳回不删任何东西。**文件留在你的分支上,之后怎么处理由人决定:
|
|
120
|
+
1. **接受**:关 PR、删分支——文件跟着走(本地索引下次 sync 自己清掉);
|
|
121
|
+
2. **改完重提**:改文件,跑 `open-memex promote <id> --resubmit`,
|
|
122
|
+
commit、push——同一个 PR 里继续评审;
|
|
123
|
+
3. **留作记录**:不动它;它带着 `[rejected]` 标签和你的注记一直可见,
|
|
124
|
+
团队以后能看到"这个考虑过,为啥没要"。
|
|
125
|
+
- `open-memex pr-status [--apply]`:读当前分支的 GitHub PR,把它的状态映射
|
|
126
|
+
到每条 in-repo 记忆的评审状态——PR merged → `published`,PR approved →
|
|
127
|
+
`approved`(`approved_by` = reviewer),"request changes" 只给建议、从不自动
|
|
128
|
+
驳回。每条记忆保持自己的独立状态:人做出的 `rejected` 不会被 PR 信号覆盖。
|
|
129
|
+
默认只报告;`--apply` 在本地执行映射的流转(不 push)。团队在 GitHub 上做完
|
|
130
|
+
评审,这个命令把结论闭环回记忆索引,不用另造评审 UI。
|
|
131
|
+
- `open-memex resolve [id]`:不带参数列出冲突中的记忆文件;带 id 则尝试
|
|
132
|
+
**字段级 3-way 合并** YAML frontmatter(`tags` 取并集、`updated_at` 取最新、
|
|
133
|
+
只有一边改了 body 才合)。语义冲突——两边改了同一字段或 body 各改各的——
|
|
134
|
+
**只报告、不自动解决**:文件原样不动,等人来裁决。
|
|
135
|
+
- `list` / `search` 会在 project 记忆旁显示 `[draft]` / `[proposed]` /
|
|
136
|
+
`[approved]` / `[published]` / `[rejected]` 标签;检索会把已评审的知识
|
|
137
|
+
(`approved` / `published`)排在未评审的 outbox 草稿前面——草稿照样能搜到,
|
|
138
|
+
但不会冒充已审核的结论。
|
|
139
|
+
|
|
140
|
+
## 6. 同步:git 是搬运工,不是大脑
|
|
141
|
+
|
|
142
|
+
- **写**:`memory_add`(project scope)→ 写 **appdata 草稿箱**,同时更新本地索引。
|
|
143
|
+
**不碰 repo、不自动 commit、不自动 push**。
|
|
144
|
+
- **交**(显式,你说了算):`open-memex submit <id...>` → 本地分支 + 本地 commit
|
|
145
|
+
进 `.ai/open-memex/`;push/PR 命令打印给你(或你的 agent 拿着你的 Yes 自己做)。
|
|
146
|
+
- **拉** **2B**:`open-memex pull`(必须显式,没有自动)→ git fetch + fast-forward →
|
|
147
|
+
扫描 `.ai/open-memex/*.md` → 按文件 mtime 合进本地 `index.db`。检索永远走 SQLite,不 walk git。
|
|
148
|
+
- **personal scope**:永远不同步(§1 铁律)。
|
|
149
|
+
- **没 git 的项目**:照常用,project scope 降级为纯本地并明确提示,不会坏掉。
|
|
150
|
+
|
|
151
|
+
## 7. 安全底线
|
|
152
|
+
|
|
153
|
+
- 记忆默认是**数据**,不是指令——外来内容(同步拉回的、别人晋升的)入库前要过
|
|
154
|
+
admission 检查;共享文件的 prompt-injection 筛查只是启发式的,真正的边界是数据/指令分离。
|
|
155
|
+
- 每条记忆带出身证明:`source` + `confidence` + `via` + 作者。共享写操作进 audit log。
|
|
156
|
+
- pre-commit hook 扫描共享 scope 的 secret,防止 history rewrite。
|
|
157
|
+
- `<private>…</private>` 包裹的内容在写入时直接剥离;命中的 secret 模式做掩码后写入继续。
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
*配套设计文档:`docs/V2-DESIGN.md`(D1–D24 决策记录)。*
|
package/docs/V2-DESIGN.md
CHANGED
|
@@ -25,6 +25,12 @@ Decisions log; Prior Art; solo-dev adoption path.
|
|
|
25
25
|
6. **Adapters translate; they never implement memory logic.** All memory logic lives in Core.
|
|
26
26
|
7. **Memory is the entrance of knowledge, not its final form.** Terminal states are docs / ADRs /
|
|
27
27
|
AGENTS.md instructions — memory is how knowledge gets captured and found.
|
|
28
|
+
8. **Distill conversations; do not archive them.** The default unit of memory is the useful
|
|
29
|
+
conclusion from a conversation, not the full transcript: what was learned, how it was resolved,
|
|
30
|
+
and where the authoritative source lives.
|
|
31
|
+
9. **Portable second brain, not a walled garden.** Long-form personal notes are valid memories when
|
|
32
|
+
the user explicitly saves them; Markdown keeps them readable, exportable, and movable to other
|
|
33
|
+
tools or machines.
|
|
28
34
|
|
|
29
35
|
---
|
|
30
36
|
|
|
@@ -40,6 +46,9 @@ Decisions log; Prior Art; solo-dev adoption path.
|
|
|
40
46
|
- **MCP is an interface, not the identity.** MCP / CLI / REST / SDK are access layers over the protocol,
|
|
41
47
|
so the project is never locked to one transport or one agent tool (opencode, VS Code Copilot, Cursor,
|
|
42
48
|
Claude Code, Windsurf, …).
|
|
49
|
+
- **Second-brain lens:** for individuals, OpenMemex can also be a local Markdown second brain for
|
|
50
|
+
AI-assisted work — similar in spirit to users asking AI to save notes into Obsidian or Notion, but
|
|
51
|
+
with agent recall, scopes, review, and redaction built in from the start.
|
|
43
52
|
- **Company lens:** at organizational scale the same pain is tribal knowledge — senior engineers'
|
|
44
53
|
hard-won experience evaporates when they move on, and every incident gets re-debugged by someone
|
|
45
54
|
new. The current phase therefore prioritizes *capture*: valuable knowledge must land in memory
|
|
@@ -132,13 +141,37 @@ canonical_ref: docs/adr-003.md # memory holds a SUMMARY; the doc is canoni
|
|
|
132
141
|
|
|
133
142
|
### 3.1 Type taxonomy (content kind)
|
|
134
143
|
|
|
135
|
-
`
|
|
136
|
-
`
|
|
144
|
+
`fact` `preference` `decision` `constraint` `todo` `knowledge` `howto` `gotcha`
|
|
145
|
+
`lesson` `observation` `reference`
|
|
137
146
|
|
|
138
|
-
`type` describes **what the content is
|
|
147
|
+
`type` describes **what the content is** — single-valued, and it drives behavior
|
|
148
|
+
(lifecycle, review, rendering, retrieval). `role` describes **how it may be used**.
|
|
139
149
|
A `decision` with `role: knowledge` is retrievable history. Only `role: instruction` may enter
|
|
140
150
|
instruction context. (Separation adopted from review: mixing usage semantics into `type` was a design smell.)
|
|
141
151
|
|
|
152
|
+
One-line definitions:
|
|
153
|
+
|
|
154
|
+
- `fact` — a verifiable atomic statement (timezone, version number, path, account).
|
|
155
|
+
- `preference` — user likes, dislikes, working style.
|
|
156
|
+
- `decision` — a choice made + why; participates in supersede chains.
|
|
157
|
+
- `constraint` — a hard rule that must not be violated (release process, permission boundaries).
|
|
158
|
+
- `todo` — an actionable item with completion state.
|
|
159
|
+
- `knowledge` — declarative knowledge (how a system works, concept explanations).
|
|
160
|
+
- `howto` — steps to accomplish X.
|
|
161
|
+
- `gotcha` — a pitfall: don't do X because Y.
|
|
162
|
+
- `lesson` — a takeaway from experience, including incident postmortems (the incident id goes in `tags`).
|
|
163
|
+
- `observation` — noticed but not yet distilled.
|
|
164
|
+
- `reference` — a pointer to the authoritative doc via `canonical_ref`; the memory holds the summary.
|
|
165
|
+
|
|
166
|
+
A type earns its place only if the system treats it differently. If two candidates
|
|
167
|
+
share lifecycle, retrieval, and rendering, the loser becomes a tag. (D41 merged
|
|
168
|
+
`warning`→`gotcha`, `workflow`→`howto`, `incident`→`lesson`, `architecture`→`knowledge`.)
|
|
169
|
+
|
|
170
|
+
`tags` are retrieval hints, not a second type system: `type` says what the memory is, while tags say
|
|
171
|
+
which topics, tools, subsystems, paths, or incidents it relates to. Write paths should preserve
|
|
172
|
+
human-provided tags and may suggest simple normalized tags (for example `vscode`, `mcp`, `windows`,
|
|
173
|
+
`auth`, `onboarding`) to improve search without changing memory semantics.
|
|
174
|
+
|
|
142
175
|
### 3.2 Iron rules
|
|
143
176
|
|
|
144
177
|
- **Iron rule 1 — the instruction gate:** only memories with `role: instruction`
|
|
@@ -170,6 +203,34 @@ Content hash + fuzzy match against existing memories. A superseding write does *
|
|
|
170
203
|
the old memory becomes `status: superseded` with `superseded_by` pointing forward. History preserved;
|
|
171
204
|
queries rank `active` first.
|
|
172
205
|
|
|
206
|
+
### 3.5 Conversation distillation
|
|
207
|
+
|
|
208
|
+
OpenMemex does **not** store raw AI chat transcripts by default. A captured memory should usually be
|
|
209
|
+
a short, human-approved artifact distilled from the conversation: the final conclusion, important
|
|
210
|
+
facts, why the answer matters later, and how the issue was resolved. Good distilled memory candidates
|
|
211
|
+
answer some combination of:
|
|
212
|
+
|
|
213
|
+
- What did we learn or decide?
|
|
214
|
+
- What solved the problem, including key commands, files, links, or steps?
|
|
215
|
+
- What mistake or gotcha should the next developer avoid?
|
|
216
|
+
- Which scope owns it: `personal`, `project`, or future `org`?
|
|
217
|
+
- If the information already exists in project docs, where is the authoritative doc?
|
|
218
|
+
|
|
219
|
+
If stable knowledge already lives in a project document, prefer a `type: reference` memory with
|
|
220
|
+
`canonical_ref` pointing at that document over duplicating the full content. Memory should help the
|
|
221
|
+
agent find and apply authoritative docs, not become an outdated second copy of them.
|
|
222
|
+
|
|
223
|
+
Model-suggested captures use `source: inference` and should default to reviewable draft state. The
|
|
224
|
+
agent may propose 1-3 distilled memories at checkpoints or task end, but humans decide whether to
|
|
225
|
+
save them and which scope they belong to. The product goal is remembering the right conclusion at
|
|
226
|
+
the right scope, not remembering everything.
|
|
227
|
+
|
|
228
|
+
Long-form notes are still valid when the user explicitly asks to save a long note, write-up, meeting
|
|
229
|
+
summary, research log, or troubleshooting record. In that case OpenMemex behaves like a Markdown
|
|
230
|
+
second-brain target: store the note as user-authored content, preserve the body, tag it for retrieval,
|
|
231
|
+
and keep the same scope/privacy rules. The distinction is intent: implicit/model-suggested capture
|
|
232
|
+
distills; explicit "save this note" may preserve long-form text.
|
|
233
|
+
|
|
173
234
|
---
|
|
174
235
|
|
|
175
236
|
## 4. Scopes, Visibility & Namespaces
|
|
@@ -235,7 +296,7 @@ instructions are never candidates.)
|
|
|
235
296
|
|
|
236
297
|
```
|
|
237
298
|
<project-repo>/
|
|
238
|
-
├── .open-memex/ # default; configurable (alt: .ai/memory/)
|
|
299
|
+
├── .ai/open-memex/ # default (D23); configurable (alt: .ai/memory/)
|
|
239
300
|
│ ├── 01K6AB….md # one memory = one file ("reduces unrelated merge conflicts…")
|
|
240
301
|
│ └── …
|
|
241
302
|
├── AGENTS.md # constitution + ONE pointer line to the memory system
|
|
@@ -243,9 +304,9 @@ instructions are never candidates.)
|
|
|
243
304
|
└── docs/ # human-authored formal docs (ADRs, guides)
|
|
244
305
|
```
|
|
245
306
|
|
|
246
|
-
- The in-repo directory name is **configurable** (`memoryDir` in config): default
|
|
247
|
-
(
|
|
248
|
-
|
|
307
|
+
- The in-repo directory name is **configurable** (`memoryDir` in config): default
|
|
308
|
+
`.ai/open-memex/` (D23 — `.ai/` namespace + brand clarity, no collisions),
|
|
309
|
+
alternatives `.open-memex/` and `.ai/memory/`.
|
|
249
310
|
- `index.db` is **never committed** — rebuildable from markdown.
|
|
250
311
|
- Org repo layout (Phase 4): `company-memory/{engineering,architecture,decisions,lessons,policies}/…`
|
|
251
312
|
- AGENTS.md pointer: `> Project memory lives in .open-memex/ — query it with memory_search before answering.`
|
|
@@ -294,11 +355,21 @@ instructions are never candidates.)
|
|
|
294
355
|
| Implicit (opt-in) | end-of-session "should I remember X?"; implicit captures default to `confidence: low` and appear in a separate list view for batch cleanup (regret window). |
|
|
295
356
|
| Redaction (hard) | `<private>…</private>` stripped; secret patterns are **masked in place** (first 4 chars kept, rest → `x`) and the write proceeds (D14); pre-commit hook scans shared scopes. |
|
|
296
357
|
|
|
358
|
+
**Scope routing on capture:** when the user says "save", "remember", or "note this" without an
|
|
359
|
+
explicit scope, the agent should infer ownership from content and current context. Project-specific
|
|
360
|
+
knowledge (repo commands, architecture, code paths, product decisions, team conventions) routes to
|
|
361
|
+
`project`; personal preferences, private working notes, cross-project habits, or content unrelated to
|
|
362
|
+
the current repo routes to `personal`. Ambiguous captures should ask one short clarification instead
|
|
363
|
+
of guessing. `org` capture remains future/curated; a single user's chat never writes org memory
|
|
364
|
+
directly.
|
|
365
|
+
|
|
297
366
|
---
|
|
298
367
|
|
|
299
368
|
## 9. Sync
|
|
300
369
|
|
|
301
|
-
- **Git is transport; the local SQLite index is the query layer.**
|
|
370
|
+
- **Git is a transport, not the product boundary; the local SQLite index is the query layer.**
|
|
371
|
+
Retrieval never walks git. Git/GitHub is the default sharing provider because it gives teams branch,
|
|
372
|
+
PR, review, and audit semantics they already trust, but Core must remain provider-agnostic.
|
|
302
373
|
- one-memory-one-file ⇒ concurrent edits almost never conflict.
|
|
303
374
|
- **Pull is explicit** (`open-memex pull`), never automatic on session start — no surprise context changes.
|
|
304
375
|
`pull` = `fetch` + fast-forward only; never auto-commit/push (hard rule for enterprise environments).
|
|
@@ -314,6 +385,13 @@ instructions are never candidates.)
|
|
|
314
385
|
- **Git unavailable:** projects without git (or with unreachable remotes) remain fully usable.
|
|
315
386
|
`personal` scope works everywhere; `project` scope degrades to local-only and `open-memex status`
|
|
316
387
|
annotates it as such. Sync commands fail with a clear message, never with a broken state.
|
|
388
|
+
- **Portability:** because Markdown is the source of truth, memories should be exportable without
|
|
389
|
+
depending on git. A future `open-memex export` command can archive selected scopes/types/tags into a
|
|
390
|
+
portable zip/tar bundle (markdown + manifest) for moving to another computer or importing into
|
|
391
|
+
another application. Export excludes `visibility: private` memories by default; `--all` / `-a`
|
|
392
|
+
includes everything, for a full personal migration to a new machine. API-backed exporters/providers (Notion, Obsidian-compatible vaults, internal
|
|
393
|
+
knowledge systems, enterprise stores) are extension paths over the same memory files and admission
|
|
394
|
+
rules, not separate products.
|
|
317
395
|
|
|
318
396
|
---
|
|
319
397
|
|
|
@@ -421,7 +499,7 @@ Zero-config is survival for an open-source project. The opencode plugin remains
|
|
|
421
499
|
Ships in **`0.3.0-alpha`** (with bin/npx user-friendliness polish per §17 adoption path).
|
|
422
500
|
- **Phase 2B — Team sync.** GitProvider · `propose/promote/resolve` · in-repo dir · 1–2 colleague pilot
|
|
423
501
|
(pilot project selection is maintainer-private, not tracked in this doc).
|
|
424
|
-
Ships in **`0.3.0-beta
|
|
502
|
+
Ships in **`0.4.0`** (was labeled `0.3.0-beta` before 0.3.0 shipped as stable).
|
|
425
503
|
Embeddings/rerank run as a **parallel benchmark-gated experiment**, not on the critical path.
|
|
426
504
|
- **Phase 2C — Native agent plugins (candidates, not committed).** Claude Code plugin and/or
|
|
427
505
|
Codex plugin as hook-enhanced paths over the same MCP tool surface (`SessionStart` →
|
|
@@ -456,10 +534,13 @@ requirement: personal data never touches third-party services). Benchmarks to tr
|
|
|
456
534
|
| atlaso-labs/codex | Codex marketplace | long-term memory plugin for Codex (hooks + MCP + cloud-sync upsell) | **direct comparable** for a future Codex plugin; their cloud upsell vs our local-first |
|
|
457
535
|
|
|
458
536
|
(Star counts / funding as of Sep 2026 — re-verify before quoting publicly.)
|
|
459
|
-
- **Phase 3 — Org layer.** Org memory repo ·
|
|
460
|
-
|
|
537
|
+
- **Phase 3 — Org layer.** Org memory repo · `examples/remote-server/` ·
|
|
538
|
+
curator convention ✅ `docs/CURATOR.md` (2026-09-29, pulled forward) ·
|
|
539
|
+
distill-to-AGENTS.md assist ✅ `open-memex distill-agents` (2026-09-29, pulled forward) ·
|
|
540
|
+
export/import archive command ✅ `open-memex export` / `import` (2026-09-29, pulled forward, D40).
|
|
461
541
|
- **Phase 4 — Future, signal-gated.** Cloud `RemoteProvider` customization only on: multi-private-repo
|
|
462
|
-
sharing needs, fine-grained ACL, audit/compliance mandates
|
|
542
|
+
sharing needs, fine-grained ACL, audit/compliance mandates · optional API-backed exporters/providers
|
|
543
|
+
for enterprise knowledge systems.
|
|
463
544
|
|
|
464
545
|
## 19. Migration v1 → v2
|
|
465
546
|
|
|
@@ -488,7 +569,7 @@ requirement: personal data never touches third-party services). Benchmarks to tr
|
|
|
488
569
|
- **D7** — Embeddings are an optional capability, BM25+CJK is the default. *Rationale: zero-setup
|
|
489
570
|
default; no mandatory 100MB download or native dependency.*
|
|
490
571
|
- **D8** — Contested choices become **configurable with a popular default**, not hard-coded.
|
|
491
|
-
Applies to: in-repo dir name (default `.open-memex/`), CJK tokenizer (default bigram),
|
|
572
|
+
Applies to: in-repo dir name (default `.ai/open-memex/` per D23), CJK tokenizer (default bigram),
|
|
492
573
|
embeddings model (default `multilingual-e5-small`). *Rationale: the five-AI review split on all
|
|
493
574
|
three; maintainers shouldn't burn decision capital where config suffices.*
|
|
494
575
|
- **D9** — The LAN reference server lives at `examples/remote-server/`. *Rationale: maintainer decision
|
|
@@ -597,6 +678,199 @@ requirement: personal data never touches third-party services). Benchmarks to tr
|
|
|
597
678
|
keeps the old repo-level behavior for teams where everyone uses open-memex.
|
|
598
679
|
The instructions carry a guard clause ("ignore this section when the
|
|
599
680
|
`open-memex` MCP server is not available") as cheap insurance. 2026-09-27.*
|
|
681
|
+
- **D23** — Default in-repo memory dir is `.ai/open-memex/` (configurable via
|
|
682
|
+
`memoryDir`; rejects absolute paths and `..`). *Rationale: `.ai/` is the
|
|
683
|
+
emerging convention for AI-local project state; the `open-memex/` leaf keeps
|
|
684
|
+
brand clarity and avoids collisions with other tools' `.ai/` content.
|
|
685
|
+
2026-09-27.*
|
|
686
|
+
- **D24** — Project-scope markdown lives in the repo: writes with
|
|
687
|
+
`scope: project` go to `<projectRoot>/<memoryDir>/` (D23 default
|
|
688
|
+
`.ai/open-memex/`); `personal` never leaves appdata. Legacy appdata project
|
|
689
|
+
files are lazily migrated on first write/`syncScope` — the move is guarded by
|
|
690
|
+
the appdata dir name (which *is* the scope key), so it can only ever migrate
|
|
691
|
+
the current scope's files. The index's `file_path` is the single locator for
|
|
692
|
+
reads/deletes (`findMemoryFile`, `forget`); on the near-impossible id
|
|
693
|
+
collision between locations, the in-repo copy wins. *Rationale: one home per
|
|
694
|
+
scope, no silent data loss, no repo pollution before first use.* 2026-09-27.*
|
|
695
|
+
- **D25** — Review workflow semantics (`propose` / `promote` / `resolve`,
|
|
696
|
+
`src/review.ts`): (1) `review_state` frontmatter field
|
|
697
|
+
(`draft → proposed → approved/rejected → published`, default `draft`) plus
|
|
698
|
+
`proposed_by` / `approved_by` / `derived_from` / `review_note` provenance;
|
|
699
|
+
the SQLite index carries `review_state` (schema v6, rebuilt from markdown —
|
|
700
|
+
D1). (2) `propose` **copies** personal → project (new id, never moves — the
|
|
701
|
+
personal original stays private); one call takes several ids (one branch,
|
|
702
|
+
one PR; all-or-nothing — a bad id aborts the whole batch);
|
|
703
|
+
`--local-approve` skips the PR for solo
|
|
704
|
+
devs. (3) `promote` advances exactly one step up the ladder
|
|
705
|
+
(`proposed → approved → published`), `--reject`s with a note (also from
|
|
706
|
+
`approved`, withdrawing approval before merge), or `--resubmit`s a rejected
|
|
707
|
+
memory back to `proposed` for another round; `draft` and terminal states
|
|
708
|
+
refuse. (4) `resolve` lists conflicted memory files, or
|
|
709
|
+
attempts a field-level 3-way merge from git stages 1/2/3 (`tags` union,
|
|
710
|
+
`updated_at` takes latest, body merged only when one side changed); semantic
|
|
711
|
+
conflicts (same field / body changed differently on both sides) are reported
|
|
712
|
+
and the file is left untouched — **never auto-resolved**. (5) A rejection
|
|
713
|
+
never deletes anything: the file stays on the author's branch; the human
|
|
714
|
+
accepts (close PR, delete branch), revises + `--resubmit`s, or keeps it as
|
|
715
|
+
a `[rejected]` record. (6) No git
|
|
716
|
+
automation anywhere in the workflow: no branch creation, no commits, no PRs —
|
|
717
|
+
the commands print the exact next steps for the human. Org-level promotion is
|
|
718
|
+
Phase 4. *Rationale: the review ladder must be explicit and auditable; the
|
|
719
|
+
tool assists merging but a human always decides meaning.* 2026-09-27.*
|
|
720
|
+
- **D26** — **Supersedes D24.** Project-scope markdown has two homes, one per
|
|
721
|
+
lifecycle stage — never silently moved between them. (1) `memory_add` /
|
|
722
|
+
`memory_propose` with `scope: project` write to the **appdata outbox**
|
|
723
|
+
(`memories/<project_key>/<id>.md`, `review_state: draft`); the outbox is
|
|
724
|
+
git-invisible and branch-independent. The D24 lazy migration is deleted —
|
|
725
|
+
appdata project files are legitimate drafts, not legacy. (2) `open-memex
|
|
726
|
+
submit <id...>` / `memory_submit` moves user-named drafts into the repo's
|
|
727
|
+
`<memoryDir>/` (D23), flipping `review_state` to `proposed`: the file now
|
|
728
|
+
follows branches and PRs. `sync-status` / `memory_status` shows both sides
|
|
729
|
+
(outbox drafts, repo review states, uncommitted repo files). (3) The move is
|
|
730
|
+
one-stage-one-place: copy → verify hash → local commit → verify → delete
|
|
731
|
+
outbox original; re-running is idempotent (identical content skips, different
|
|
732
|
+
content aborts). `search` prefers the repo copy when both exist; conflicts
|
|
733
|
+
(same id, different content; push rejected) stop and ask the human — never
|
|
734
|
+
overwrite. *Rationale: an AI agent drafts constantly; the repo should only
|
|
735
|
+
ever see what the human explicitly approved for review. The outbox is the
|
|
736
|
+
agent's desk, the repo dir is the shared table. Approved 2026-09-28.*
|
|
737
|
+
- **D27** — **Revises D25 §6 (no git automation).** `submit` automates the
|
|
738
|
+
*local* half of the git workflow: create `mem/sync-<timestamp>` (or
|
|
739
|
+
`--onto` the current branch for code+memory PRs), copy, `git add` only the
|
|
740
|
+
memory files, local commit, verify. It prints the push + `gh pr create`
|
|
741
|
+
commands for the human — but an agent that already holds the user's Yes for
|
|
742
|
+
this sync carries through push and PR creation without re-asking (each step
|
|
743
|
+
is not a separate approval). Batch submit is all-or-nothing; an empty-branch
|
|
744
|
+
abort rolls the branch back. *Rationale: the old "no git automation" rule
|
|
745
|
+
assumed a human at the keyboard; the agent-driven flow needs local mechanics
|
|
746
|
+
automated while push/PR stay under the user's explicit per-sync Yes/No.
|
|
747
|
+
Approved 2026-09-28.*
|
|
748
|
+
- **D28** — Memory PR base defaults to the **current branch**; the user may
|
|
749
|
+
redirect to `main` or the project's integration branch (`--base`). A
|
|
750
|
+
standalone memory PR and a code+memory PR are both supported — the agent asks
|
|
751
|
+
which one each time; on "with code" it uses `--onto` and never commits
|
|
752
|
+
unrelated staged changes. *Rationale: memory usually reviews against the work
|
|
753
|
+
it describes (current branch); the integration branch is the exception, not
|
|
754
|
+
the default. Approved 2026-09-28.*
|
|
755
|
+
- **D29** — Every review transition is written to a per-memory audit trail
|
|
756
|
+
(`review_history`: at/by/from/to/note) — reject / resubmit / approve /
|
|
757
|
+
publish all append, never overwrite; `propose` and `submit` seed it; merge
|
|
758
|
+
conflict resolution unions both sides' histories. *Rationale: review is a
|
|
759
|
+
decision log, not a flag — "who rejected this and why" must be answerable
|
|
760
|
+
months later. Approved 2026-09-28.*
|
|
761
|
+
- **D30** — Retrieval ranks by review state: approved/published project
|
|
762
|
+
memories outrank unreviewed content; project drafts/rejected sink to the
|
|
763
|
+
bottom and are visibly tagged `[draft]` in search/list/inject output, while
|
|
764
|
+
personal memories (always draft by design) are never demoted or tagged.
|
|
765
|
+
Explicit search still finds drafts — they are deprioritized, not hidden.
|
|
766
|
+
*Rationale: reviewed knowledge should win the context window; drafts stay
|
|
767
|
+
discoverable but never masquerade as vetted. Approved 2026-09-28.*
|
|
768
|
+
- **D31** — Every index sync records when it ran, what triggered it
|
|
769
|
+
(`session` / `request` / `cli` / `submit`) and its stats, in
|
|
770
|
+
`<appdata>/sync-state.json`; `sync-status` shows the last sync first.
|
|
771
|
+
*Rationale: "is my index fresh?" must be answerable without guessing —
|
|
772
|
+
especially across branch switches where the in-repo dir changes underneath.
|
|
773
|
+
Approved 2026-09-28.*
|
|
774
|
+
- **D32** — The branch PR's GitHub state maps back onto each in-repo
|
|
775
|
+
memory's review_state via `pr-status` / `memory_pr_status`: merged PR →
|
|
776
|
+
published, PR approval → approved with `approved_by` = reviewer login,
|
|
777
|
+
changes-requested → suggestion only (never auto-rejects). Report by
|
|
778
|
+
default; `--apply` performs the mapped transitions locally (no push —
|
|
779
|
+
inside the D27 line). Each memory keeps its own state: a human `rejected`
|
|
780
|
+
is never overridden by a PR signal. *Rationale: the PR is where the team
|
|
781
|
+
actually reviews — the mapping closes the loop without inventing new
|
|
782
|
+
review UI. Approved 2026-09-28.*
|
|
783
|
+
- **D34** — The MCP server sends session-start guidance in the handshake
|
|
784
|
+
`instructions`: call `memory_status` at session start (and at work
|
|
785
|
+
checkpoints); if the outbox has drafts, summarize and ask the user which to
|
|
786
|
+
sync; proactive `memory_add`; `memory_search` before asking about the past;
|
|
787
|
+
personal never leaves the machine. *Rationale: the init-written instruction
|
|
788
|
+
files only exist if the user ran `init --client` — the handshake reaches
|
|
789
|
+
every MCP client at connect time. Still advisory: no MCP consumer offers a
|
|
790
|
+
hard session-start hook, and we do not claim otherwise. Approved 2026-09-28.*
|
|
791
|
+
- **D35** — "sync memory" (or "同步记忆") is a natural-language trigger for the
|
|
792
|
+
sync flow: the agent calls `memory_status`, summarizes the outbox drafts, and
|
|
793
|
+
asks the user which ones to sync — same flow as the session-start proposal,
|
|
794
|
+
but user-initiated. Taught in the MCP handshake instructions, the
|
|
795
|
+
init-written instruction files, and the `memory_status` tool description.
|
|
796
|
+
*Rationale: the user should not have to remember command names to sync;
|
|
797
|
+
saying it in words must work. Approved 2026-09-28.*
|
|
798
|
+
- **D36** — `submit` never creates a branch on its own (revises D26/D27): it
|
|
799
|
+
copies the named drafts into `.ai/open-memex/`, commits locally on the
|
|
800
|
+
CURRENT branch, and prints next-step commands. Branch creation is the human's
|
|
801
|
+
call — or the agent's, only with explicit approval for the full chain, via
|
|
802
|
+
`submit --branch <name>` / `memory_submit(branch=...)`. *Rationale: an
|
|
803
|
+
auto-created branch strands the user on it — they forget to switch back.
|
|
804
|
+
After a submit the agent asks ONE follow-up ("want me to create a branch +
|
|
805
|
+
push + open the PR, or will you handle it yourself?") instead of branching
|
|
806
|
+
silently. Checkpoints that trigger `memory_status`: session start, end of a
|
|
807
|
+
work chunk, after the user commits, and after any memory_* action.
|
|
808
|
+
The "sync memory" trigger ALWAYS goes through the `memory_status` tool —
|
|
809
|
+
never by browsing the appdata directory directly. Approved 2026-09-28.*
|
|
810
|
+
- **D33** — Every CLI command answers `open-memex <command> --help` (and `-h`)
|
|
811
|
+
with its own usage, flags, and examples; checked before config/DB load so
|
|
812
|
+
help works even in a broken environment. Unknown commands with `--help`
|
|
813
|
+
fall back to the global usage. *Rationale: AI assistants discover the CLI
|
|
814
|
+
through --help first — a command that silently swallows --help as a flag
|
|
815
|
+
teaches the agent nothing. Approved 2026-09-28.*
|
|
816
|
+
- **D37** — Conversation distillation is the memory unit; transcript storage is
|
|
817
|
+
not the default. Capture should preserve the useful conclusion from a human/AI
|
|
818
|
+
session — what was learned, what resolved the issue, what should be avoided,
|
|
819
|
+
and where the authoritative doc lives — as a short reviewable memory. If the
|
|
820
|
+
knowledge already exists in docs, store a `reference` memory with
|
|
821
|
+
`canonical_ref` instead of duplicating the doc. Tags are retrieval hints, not
|
|
822
|
+
content kinds: `type` classifies the memory, tags describe topics/tools/paths.
|
|
823
|
+
*Rationale: full chat logs are noisy, harder to review, and riskier for
|
|
824
|
+
privacy; the value is remembering the right conclusion at the right scope,
|
|
825
|
+
with enough context for the next human or AI session. Approved 2026-09-28.*
|
|
826
|
+
- **D38** — OpenMemex supports a Markdown second-brain use case while keeping
|
|
827
|
+
distillation as the default for implicit/model-suggested capture. If the user
|
|
828
|
+
explicitly asks to save a long note, meeting summary, troubleshooting record,
|
|
829
|
+
or write-up, preserve it as user-authored Markdown with tags and normal
|
|
830
|
+
scope/privacy rules. Git/GitHub sync is the default team-sharing provider, not
|
|
831
|
+
the product boundary: future export/import archives and API-backed providers
|
|
832
|
+
may move the same markdown memories to other computers, applications, or
|
|
833
|
+
enterprise systems. For generic "save/remember/note this" requests, the agent
|
|
834
|
+
routes project-specific knowledge to `project`, personal or repo-unrelated
|
|
835
|
+
knowledge to `personal`, and asks one clarification if ambiguous; `org` remains
|
|
836
|
+
curated/future, never a direct single-user chat write. *Rationale: users also
|
|
837
|
+
want a local AI-assisted second brain, but portability and ownership must stay
|
|
838
|
+
explicit; sharing mechanisms should be provider choices over the same memory
|
|
839
|
+
model, not the identity of the product. Approved 2026-09-28.*
|
|
840
|
+
- **D39** — `type` and `tags` are complementary axes, not alternatives. `type` is
|
|
841
|
+
single-valued: what the memory IS — it drives behavior (lifecycle, review,
|
|
842
|
+
rendering, retrieval: a `todo` can be completed, a `reference` resolves
|
|
843
|
+
`canonical_ref`, a `decision` participates in supersede chains). `tags` are
|
|
844
|
+
multi-valued: what the memory is ABOUT — pure retrieval hints
|
|
845
|
+
(topics, tools, subsystems, paths, incidents). *Rationale: without type the
|
|
846
|
+
system cannot tell "a todo I must do" from "a fact I must know" even when both
|
|
847
|
+
are tagged `auth`; without tags, cross-cutting retrieval ("everything about
|
|
848
|
+
onboarding") would need a combinatorial type explosion. Type answers "how do I
|
|
849
|
+
handle this?", tags answer "how do I find this?". Approved 2026-09-28.*
|
|
850
|
+
- **D40** — `open-memex export` excludes `visibility: private` memories by
|
|
851
|
+
default; `--all` / `-a` includes everything, for a full personal migration to
|
|
852
|
+
a new machine. *Rationale: the safe default protects privacy; the escape hatch
|
|
853
|
+
keeps the "no walled garden" promise — the user can always take everything
|
|
854
|
+
with them. Approved 2026-09-28.*
|
|
855
|
+
- **D42** — §3.5 checkpoint distillation is taught in the MCP handshake
|
|
856
|
+
instructions (`src/mcp.ts` `SERVER_INSTRUCTIONS`) and the `init`-written
|
|
857
|
+
instruction files (`src/init.ts` `INSTRUCTIONS`): at checkpoints the agent
|
|
858
|
+
DISTILLs the session and proposes 1–3 short memories (conclusion, not
|
|
859
|
+
transcript); nothing is saved without user approval. Approved captures are
|
|
860
|
+
saved via `memory_add` with the new optional `source` param set to
|
|
861
|
+
`"inference"` (default `"tool"`). *Rationale: closes the 0.4.0 TODO from D41 —
|
|
862
|
+
the design's capture loop now reaches the agent. Implemented 2026-09-29.*
|
|
863
|
+
- **D41** — The type taxonomy is reconciled to 11 types with one-line definitions
|
|
864
|
+
(§3.1): `fact` `preference` `decision` `constraint` `todo` `knowledge` `howto`
|
|
865
|
+
`gotcha` `lesson` `observation` `reference`. Merged away: `warning`→`gotcha`,
|
|
866
|
+
`workflow`→`howto`, `incident`→`lesson` (incident id goes in `tags`),
|
|
867
|
+
`architecture`→`knowledge` (tag `architecture`). *Rationale: a type earns its
|
|
868
|
+
place only if the system treats it differently (lifecycle, retrieval,
|
|
869
|
+
rendering); otherwise it is a tag. Fifteen types blur classification and hurt
|
|
870
|
+
agent accuracy — eleven keeps each type's behavioral slot distinct. `lesson`
|
|
871
|
+
is deliberately broader than `incident`: a postmortem's shape (timeline, root
|
|
872
|
+
cause, actions) is a template concern, not a type. Code
|
|
873
|
+
`MEMORY_TYPE_TAXONOMY` updated to match. Approved 2026-09-28.*
|
|
600
874
|
|
|
601
875
|
## Open Questions
|
|
602
876
|
|
package/package.json
CHANGED
package/scripts/smoke-mcp.ts
CHANGED
|
@@ -80,9 +80,9 @@ try {
|
|
|
80
80
|
const tools = await req("tools/list", {});
|
|
81
81
|
const names = (tools.result?.tools ?? []).map((t: any) => t.name).sort();
|
|
82
82
|
check(
|
|
83
|
-
"tools/list has
|
|
83
|
+
"tools/list has 11 memory tools",
|
|
84
84
|
JSON.stringify(names) ===
|
|
85
|
-
JSON.stringify(["memory_add", "memory_forget", "memory_list", "memory_search", "memory_supersede"]),
|
|
85
|
+
JSON.stringify(["memory_add", "memory_forget", "memory_list", "memory_pr_status", "memory_promote", "memory_propose", "memory_resolve", "memory_search", "memory_status", "memory_submit", "memory_supersede"]),
|
|
86
86
|
names.join(","),
|
|
87
87
|
);
|
|
88
88
|
const addSchema = tools.result.tools.find((t: any) => t.name === "memory_add").inputSchema;
|