pmem-ai 0.5.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 +57 -0
- package/LICENSE +21 -0
- package/README.md +349 -0
- package/dist/commands/ask.d.ts +3 -0
- package/dist/commands/ask.d.ts.map +1 -0
- package/dist/commands/ask.js +303 -0
- package/dist/commands/ask.js.map +1 -0
- package/dist/commands/distill.d.ts +6 -0
- package/dist/commands/distill.d.ts.map +1 -0
- package/dist/commands/distill.js +425 -0
- package/dist/commands/distill.js.map +1 -0
- package/dist/commands/graph.d.ts +6 -0
- package/dist/commands/graph.d.ts.map +1 -0
- package/dist/commands/graph.js +216 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +566 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/integration.d.ts +2 -0
- package/dist/commands/integration.d.ts.map +1 -0
- package/dist/commands/integration.js +216 -0
- package/dist/commands/integration.js.map +1 -0
- package/dist/commands/migrate.d.ts +6 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +379 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/rebuild.d.ts +8 -0
- package/dist/commands/rebuild.d.ts.map +1 -0
- package/dist/commands/rebuild.js +299 -0
- package/dist/commands/rebuild.js.map +1 -0
- package/dist/commands/recall.d.ts +3 -0
- package/dist/commands/recall.d.ts.map +1 -0
- package/dist/commands/recall.js +140 -0
- package/dist/commands/recall.js.map +1 -0
- package/dist/commands/session.d.ts +3 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +147 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +275 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/update.d.ts +14 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +536 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/verify.d.ts +4 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +296 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/core/db.d.ts +47 -0
- package/dist/core/db.d.ts.map +1 -0
- package/dist/core/db.js +326 -0
- package/dist/core/db.js.map +1 -0
- package/dist/core/format.d.ts +3 -0
- package/dist/core/format.d.ts.map +1 -0
- package/dist/core/format.js +221 -0
- package/dist/core/format.js.map +1 -0
- package/dist/core/fs.d.ts +16 -0
- package/dist/core/fs.d.ts.map +1 -0
- package/dist/core/fs.js +175 -0
- package/dist/core/fs.js.map +1 -0
- package/dist/core/git.d.ts +6 -0
- package/dist/core/git.d.ts.map +1 -0
- package/dist/core/git.js +20 -0
- package/dist/core/git.js.map +1 -0
- package/dist/core/hash.d.ts +10 -0
- package/dist/core/hash.d.ts.map +1 -0
- package/dist/core/hash.js +25 -0
- package/dist/core/hash.js.map +1 -0
- package/dist/core/manifest.d.ts +6 -0
- package/dist/core/manifest.d.ts.map +1 -0
- package/dist/core/manifest.js +207 -0
- package/dist/core/manifest.js.map +1 -0
- package/dist/core/yaml.d.ts +11 -0
- package/dist/core/yaml.d.ts.map +1 -0
- package/dist/core/yaml.js +94 -0
- package/dist/core/yaml.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +167 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +351 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/docs/Voorlopige projekidee.md +695 -0
- package/docs/handover-v0.3.md +355 -0
- package/docs/handover-v0.4.md +367 -0
- package/docs/prd.md +318 -0
- package/docs/project-roadmap.md +279 -0
- package/docs/release-checklist-v0.5.md +109 -0
- package/docs/v0.2 pre-design.md +182 -0
- package/docs/v0.2 pre-roadmap.md +270 -0
- package/docs/v0.3 pre-design.md +686 -0
- package/docs/v0.4 pre-design.md +417 -0
- package/docs/v0.5 pre-design.md +481 -0
- package/package.json +67 -0
|
@@ -0,0 +1,686 @@
|
|
|
1
|
+
# v0.3 前置设计决策
|
|
2
|
+
|
|
3
|
+
本文档记录 pmem v0.3 开工前的最终技术决策。v0.3 的核心定位:
|
|
4
|
+
|
|
5
|
+
> **SQLite-backed Agent CLI Runtime**
|
|
6
|
+
>
|
|
7
|
+
> 不是 SQLite 主数据化系统,不是 MCP-first Memory Server,不是 REST-first Memory Service。
|
|
8
|
+
> 而是:Markdown 主数据 + SQLite 运行时索引 + Agent-first CLI + Skills 使用协议 + Content Hash 增量 rebuild + 可解释召回。
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 一、SQLite Schema 设计
|
|
13
|
+
|
|
14
|
+
### 核心原则
|
|
15
|
+
|
|
16
|
+
SQLite 的职责是:**索引层、查询层、运行时状态层、会话状态层、缓存层**。不是主数据层。
|
|
17
|
+
|
|
18
|
+
### P0 表结构(必须实现)
|
|
19
|
+
|
|
20
|
+
#### `cards` — 卡片索引
|
|
21
|
+
|
|
22
|
+
```sql
|
|
23
|
+
CREATE TABLE cards (
|
|
24
|
+
id TEXT PRIMARY KEY,
|
|
25
|
+
type TEXT NOT NULL,
|
|
26
|
+
title TEXT NOT NULL,
|
|
27
|
+
status TEXT,
|
|
28
|
+
priority TEXT,
|
|
29
|
+
file_path TEXT NOT NULL UNIQUE,
|
|
30
|
+
|
|
31
|
+
summary TEXT,
|
|
32
|
+
schema_version TEXT,
|
|
33
|
+
card_version INTEGER DEFAULT 1,
|
|
34
|
+
|
|
35
|
+
created_at TEXT,
|
|
36
|
+
updated_at TEXT,
|
|
37
|
+
last_verified_at TEXT,
|
|
38
|
+
|
|
39
|
+
file_hash TEXT NOT NULL,
|
|
40
|
+
frontmatter_hash TEXT NOT NULL,
|
|
41
|
+
body_hash TEXT NOT NULL,
|
|
42
|
+
|
|
43
|
+
token_count INTEGER DEFAULT 0,
|
|
44
|
+
section_count INTEGER DEFAULT 0,
|
|
45
|
+
|
|
46
|
+
is_deleted INTEGER DEFAULT 0,
|
|
47
|
+
is_candidate INTEGER DEFAULT 0
|
|
48
|
+
);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### `edges` — 图关系
|
|
52
|
+
|
|
53
|
+
```sql
|
|
54
|
+
CREATE TABLE edges (
|
|
55
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
56
|
+
from_id TEXT NOT NULL,
|
|
57
|
+
to_id TEXT NOT NULL,
|
|
58
|
+
type TEXT NOT NULL,
|
|
59
|
+
|
|
60
|
+
source TEXT NOT NULL, -- explicit | inferred | mention
|
|
61
|
+
confidence REAL DEFAULT 1.0,
|
|
62
|
+
|
|
63
|
+
created_at TEXT,
|
|
64
|
+
updated_at TEXT,
|
|
65
|
+
|
|
66
|
+
UNIQUE(from_id, to_id, type, source)
|
|
67
|
+
);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
v0.3 暂时不生成 `same_tag` 弱关系边。
|
|
71
|
+
|
|
72
|
+
#### `aliases` — 别名
|
|
73
|
+
|
|
74
|
+
```sql
|
|
75
|
+
CREATE TABLE aliases (
|
|
76
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
77
|
+
card_id TEXT NOT NULL,
|
|
78
|
+
alias TEXT NOT NULL,
|
|
79
|
+
normalized_alias TEXT NOT NULL,
|
|
80
|
+
language TEXT,
|
|
81
|
+
UNIQUE(card_id, normalized_alias)
|
|
82
|
+
);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### `tags` — 标签
|
|
86
|
+
|
|
87
|
+
```sql
|
|
88
|
+
CREATE TABLE tags (
|
|
89
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
90
|
+
card_id TEXT NOT NULL,
|
|
91
|
+
tag TEXT NOT NULL,
|
|
92
|
+
normalized_tag TEXT NOT NULL,
|
|
93
|
+
UNIQUE(card_id, normalized_tag)
|
|
94
|
+
);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### `paths` — 代码/文档路径关联
|
|
98
|
+
|
|
99
|
+
```sql
|
|
100
|
+
CREATE TABLE paths (
|
|
101
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
102
|
+
card_id TEXT NOT NULL,
|
|
103
|
+
path TEXT NOT NULL,
|
|
104
|
+
relation TEXT NOT NULL, -- source_path | test_path | doc_path | config_path
|
|
105
|
+
UNIQUE(card_id, path, relation)
|
|
106
|
+
);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
对 stale detection 非常关键。
|
|
110
|
+
|
|
111
|
+
#### `dirty_flags` — 脏状态
|
|
112
|
+
|
|
113
|
+
```sql
|
|
114
|
+
CREATE TABLE dirty_flags (
|
|
115
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
116
|
+
scope TEXT NOT NULL,
|
|
117
|
+
target TEXT NOT NULL,
|
|
118
|
+
reason TEXT NOT NULL,
|
|
119
|
+
created_at TEXT NOT NULL,
|
|
120
|
+
resolved_at TEXT,
|
|
121
|
+
session_id TEXT
|
|
122
|
+
);
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
#### `schema_meta` — 数据库元信息
|
|
126
|
+
|
|
127
|
+
```sql
|
|
128
|
+
CREATE TABLE schema_meta (
|
|
129
|
+
key TEXT PRIMARY KEY,
|
|
130
|
+
value TEXT NOT NULL
|
|
131
|
+
);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### P1 表结构(强烈建议)
|
|
135
|
+
|
|
136
|
+
#### `sessions`
|
|
137
|
+
|
|
138
|
+
```sql
|
|
139
|
+
CREATE TABLE sessions (
|
|
140
|
+
id TEXT PRIMARY KEY,
|
|
141
|
+
agent_name TEXT,
|
|
142
|
+
started_at TEXT NOT NULL,
|
|
143
|
+
ended_at TEXT,
|
|
144
|
+
task_summary TEXT,
|
|
145
|
+
base_index_hash TEXT,
|
|
146
|
+
status TEXT,
|
|
147
|
+
dirty INTEGER DEFAULT 0
|
|
148
|
+
);
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
#### `update_log`
|
|
152
|
+
|
|
153
|
+
```sql
|
|
154
|
+
CREATE TABLE update_log (
|
|
155
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
156
|
+
action TEXT NOT NULL,
|
|
157
|
+
summary TEXT,
|
|
158
|
+
session_id TEXT,
|
|
159
|
+
created_at TEXT NOT NULL,
|
|
160
|
+
affected_cards TEXT,
|
|
161
|
+
affected_paths TEXT,
|
|
162
|
+
success INTEGER NOT NULL,
|
|
163
|
+
error TEXT
|
|
164
|
+
);
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### `card_fts` — FTS5 全文检索(如环境支持)
|
|
168
|
+
|
|
169
|
+
```sql
|
|
170
|
+
CREATE VIRTUAL TABLE card_fts USING fts5(
|
|
171
|
+
card_id UNINDEXED,
|
|
172
|
+
title,
|
|
173
|
+
summary,
|
|
174
|
+
body,
|
|
175
|
+
aliases,
|
|
176
|
+
tags
|
|
177
|
+
);
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
FTS5 是 v0.3 `ask` 升级的重要基础。
|
|
181
|
+
|
|
182
|
+
### P2 暂缓
|
|
183
|
+
|
|
184
|
+
embeddings 真向量检索、SQLite-only memory card、复杂 section-level merge、图可视化、远程多用户服务。这些留给 v0.4。
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 二、Markdown 主数据策略
|
|
189
|
+
|
|
190
|
+
### 最终决策
|
|
191
|
+
|
|
192
|
+
> **Markdown cards 继续作为唯一主数据,SQLite 只是索引、缓存和运行时状态。**
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
.pmem/**/*.md canonical source of truth
|
|
196
|
+
.pmem/pmem.db generated runtime index/cache/state
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### 为什么不让 SQLite 存主数据?
|
|
200
|
+
|
|
201
|
+
pmem 核心价值:人类可读、Git 友好、可 diff、可手动修复、可迁移、不被数据库锁死。
|
|
202
|
+
|
|
203
|
+
### 正文缓存(可选)
|
|
204
|
+
|
|
205
|
+
```sql
|
|
206
|
+
CREATE TABLE card_content_cache (
|
|
207
|
+
card_id TEXT PRIMARY KEY,
|
|
208
|
+
file_path TEXT NOT NULL,
|
|
209
|
+
body TEXT,
|
|
210
|
+
body_hash TEXT NOT NULL,
|
|
211
|
+
extracted_summary TEXT,
|
|
212
|
+
updated_at TEXT
|
|
213
|
+
);
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
用途:FTS 检索、快速 recall/ask、distill 分组、减少重复读 Markdown。但一致性规则:Markdown 改了 → cache 重建,永不手修 cache。
|
|
217
|
+
|
|
218
|
+
### 数据一致性模型
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
写入路径:
|
|
222
|
+
pmem update / distill / migrate
|
|
223
|
+
→ 写 Markdown(atomicWrite)
|
|
224
|
+
→ 更新 SQLite(transaction)
|
|
225
|
+
|
|
226
|
+
读取路径:
|
|
227
|
+
pmem recall / ask / related / trace
|
|
228
|
+
→ 读 SQLite
|
|
229
|
+
→ 如果 SQLite 过期,提示或自动 rebuild
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
核心原则:Markdown 是事实,SQLite 是索引,SQLite 可以丢,Markdown 不能乱。
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## 三、`pmem serve` 架构方向
|
|
237
|
+
|
|
238
|
+
### 最终决策
|
|
239
|
+
|
|
240
|
+
> **v0.3 不做 MCP-first,也不做 REST-first。主线是 Agent-first CLI + Skills。**
|
|
241
|
+
|
|
242
|
+
`pmem serve` 不进入 P0。CLI 对比 MCP/REST 的优势:低 token、简单可组合、无需 server 生命周期、适合任意 coding agent、容易集成到 AGENTS.md / CLAUDE.md。
|
|
243
|
+
|
|
244
|
+
如需 serve,仅作 experimental:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
pmem serve --mcp --experimental
|
|
248
|
+
pmem serve --rest --experimental
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### CLI 输出协议(P0)
|
|
252
|
+
|
|
253
|
+
所有核心查询命令支持:
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
--format compact # Agent 低 token 直接阅读
|
|
257
|
+
--format json # Agent 程序化处理
|
|
258
|
+
--format paths # 只返回文件路径,极低 token
|
|
259
|
+
--format pack # 受 token budget 控制的上下文包
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
`--format compact` 示例:
|
|
263
|
+
|
|
264
|
+
```txt
|
|
265
|
+
PROJECT: pmem
|
|
266
|
+
STAGE: v0.3 planning
|
|
267
|
+
FOCUS: SQLite-backed Agent CLI Runtime
|
|
268
|
+
|
|
269
|
+
NEXT:
|
|
270
|
+
- Implement SQLite schema
|
|
271
|
+
- Migrate JSON indexes to SQLite
|
|
272
|
+
|
|
273
|
+
READ_IF_NEEDED:
|
|
274
|
+
- .pmem/modules/sqlite_runtime.md
|
|
275
|
+
- .pmem/decisions/markdown-source-of-truth.md
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
`--format json` 示例:
|
|
279
|
+
|
|
280
|
+
```json
|
|
281
|
+
{
|
|
282
|
+
"query": "SQLite schema 怎么设计",
|
|
283
|
+
"matched": [
|
|
284
|
+
{"id": "module.sqlite_runtime", "match_type": "alias", "score": 1.0, "file": ".pmem/modules/sqlite_runtime.md"}
|
|
285
|
+
],
|
|
286
|
+
"expanded": [
|
|
287
|
+
{"id": "decision.markdown_source_of_truth", "edge": "constrains", "file": ".pmem/decisions/markdown-source-of-truth.md"}
|
|
288
|
+
],
|
|
289
|
+
"recommended_files": [
|
|
290
|
+
".pmem/modules/sqlite_runtime.md",
|
|
291
|
+
".pmem/decisions/markdown-source-of-truth.md"
|
|
292
|
+
]
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
`--format paths` 示例:
|
|
297
|
+
|
|
298
|
+
```txt
|
|
299
|
+
.pmem/modules/distill_runtime.md
|
|
300
|
+
.pmem/skills/distill.md
|
|
301
|
+
.pmem/decisions/trace-distillation-policy.md
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## 四、增量 Rebuild 策略
|
|
307
|
+
|
|
308
|
+
### 最终决策
|
|
309
|
+
|
|
310
|
+
> **以 content hash 为准,timestamp 只作为预筛。不用 timestamp 作为一致性依据。**
|
|
311
|
+
|
|
312
|
+
原因:git checkout 影响 mtime、复制文件改变 mtime、编辑器保存但内容未变、系统时间不准。
|
|
313
|
+
|
|
314
|
+
### Hash 设计
|
|
315
|
+
|
|
316
|
+
每张 card 计算三个 hash:
|
|
317
|
+
|
|
318
|
+
```
|
|
319
|
+
file_hash 整个 Markdown 文件
|
|
320
|
+
frontmatter_hash frontmatter 部分
|
|
321
|
+
body_hash 正文部分
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
用途:
|
|
325
|
+
- `file_hash` 变化 → 文件整体变化
|
|
326
|
+
- `frontmatter_hash` 变化 → 更新 cards / edges / aliases / tags / paths
|
|
327
|
+
- `body_hash` 变化 → 更新 FTS / summary / token_count / section_count
|
|
328
|
+
|
|
329
|
+
### Rebuild 命令
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
pmem rebuild # 默认增量(--changed)
|
|
333
|
+
pmem rebuild --changed # hash 相同跳过,hash 不同重解析
|
|
334
|
+
pmem rebuild --full # 清空 SQLite 后全量重建
|
|
335
|
+
pmem rebuild --card <id> # 只重建单张 card
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### verify 与 rebuild 关系
|
|
339
|
+
|
|
340
|
+
`pmem verify` 检查 SQLite 是否与 Markdown 一致。不一致时:不手修 SQLite,运行 `pmem rebuild`。`pmem verify --fix` = `pmem rebuild --changed` + `pmem verify`。
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## 五、Embeddings 选型
|
|
345
|
+
|
|
346
|
+
### 最终决策
|
|
347
|
+
|
|
348
|
+
> **v0.3 不强绑定 embedding,不默认启用。只设计 Embedding Provider Interface。**
|
|
349
|
+
|
|
350
|
+
三种模式预留:`none | api | local`。默认 `none`。
|
|
351
|
+
|
|
352
|
+
原因:v0.3 主线是 SQLite runtime + CLI output contract + hash rebuild + migrate。embedding 引入模型选择、API key、向量维度、成本、隐私等额外复杂度。
|
|
353
|
+
|
|
354
|
+
### v0.3 的 ask 召回顺序
|
|
355
|
+
|
|
356
|
+
```
|
|
357
|
+
1. exact match:id / title / alias
|
|
358
|
+
2. graph expansion:related / depends_on / constrains / next_step_of
|
|
359
|
+
3. FTS keyword match(SQLite FTS5)
|
|
360
|
+
4. optional embedding semantic match(默认关闭)
|
|
361
|
+
5. rerank:match_type + graph_distance + priority + freshness
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
核心原则:pmem 是项目记忆系统,不是普通文档搜索系统。**图关系优先于语义猜测。**
|
|
365
|
+
|
|
366
|
+
### 配置预留
|
|
367
|
+
|
|
368
|
+
```yml
|
|
369
|
+
embedding:
|
|
370
|
+
enabled: false
|
|
371
|
+
provider: none
|
|
372
|
+
model: null
|
|
373
|
+
dimension: null
|
|
374
|
+
store: sqlite
|
|
375
|
+
index: none
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## 六、File Lock + AtomicWrite 与 SQLite 事务共存
|
|
381
|
+
|
|
382
|
+
### 最终决策
|
|
383
|
+
|
|
384
|
+
> **两者保留,职责不同。File lock 保护 Markdown 文件写入,SQLite transaction 保护数据库索引和状态更新。**
|
|
385
|
+
|
|
386
|
+
### v0.3 写入流程
|
|
387
|
+
|
|
388
|
+
```
|
|
389
|
+
1. acquire global pmem write lock
|
|
390
|
+
2. prepare update
|
|
391
|
+
3. write Markdown atomically
|
|
392
|
+
4. update SQLite inside transaction
|
|
393
|
+
5. write update_log
|
|
394
|
+
6. release lock
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### 为什么仍需要 file lock?
|
|
398
|
+
|
|
399
|
+
SQLite transaction 只能保护数据库,不能保护 `.md` 文件。两个 Agent 同时写同一张 Markdown card,SQLite 无法自动阻止文件层面的覆盖。
|
|
400
|
+
|
|
401
|
+
### 如果 Markdown 写成功但 SQLite 更新失败?
|
|
402
|
+
|
|
403
|
+
不是灾难。主数据是 Markdown。处理方式:SQLite 标记 stale → 提示或自动 `pmem rebuild --changed`。原则:Markdown 成功写入后,SQLite 永远可重建。不需要为 SQLite 回滚 Markdown。
|
|
404
|
+
|
|
405
|
+
### v0.3 并发模型
|
|
406
|
+
|
|
407
|
+
```
|
|
408
|
+
读操作 → 直接读 SQLite,不加锁
|
|
409
|
+
写操作 → acquire .pmem/.lock → atomicWrite Markdown → SQLite transaction → release lock
|
|
410
|
+
锁超时 → 默认 abort,不排队,不覆盖
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
v0.3 不追求多写并发,单写模型已足够支撑 v0.5 上线。
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
## 七、v0.2 → v0.3 迁移路径
|
|
418
|
+
|
|
419
|
+
### 最终决策
|
|
420
|
+
|
|
421
|
+
> **从 Markdown cards 重建 SQLite,而不是从 JSON indexes 迁移主数据。**
|
|
422
|
+
|
|
423
|
+
v0.2 的 JSON indexes 本质是缓存,不是事实来源。
|
|
424
|
+
|
|
425
|
+
### 迁移原则
|
|
426
|
+
|
|
427
|
+
- Markdown cards 不搬家
|
|
428
|
+
- JSON indexes 不作为主迁移来源
|
|
429
|
+
- SQLite 从 Markdown rebuild
|
|
430
|
+
- 旧 JSON indexes 仅用于校验或备份
|
|
431
|
+
- manifest 增加 `runtime.mode = sqlite`
|
|
432
|
+
|
|
433
|
+
### dry-run
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
pmem migrate --to 0.3 --dry-run
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
输出:将创建 .pmem/pmem.db、创建 schema、导入 cards/edges/aliases/tags/paths、构建 FTS、更新 manifest。不删除 Markdown cards,不删除 JSON indexes。
|
|
440
|
+
|
|
441
|
+
### 正式迁移
|
|
442
|
+
|
|
443
|
+
```bash
|
|
444
|
+
pmem migrate --to 0.3
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
执行流程:备份 .pmem → 创建 pmem.db → 创建 schema → 扫描 Markdown → 解析 frontmatter → 写入 tables → 构建 FTS → 校验 hash → 更新 manifest → 标记 legacy JSON indexes → 运行 verify。
|
|
448
|
+
|
|
449
|
+
### 备份策略
|
|
450
|
+
|
|
451
|
+
迁移前自动备份到 `.pmem/backups/YYYY-MM-DD-before-v0.3-migration/`。不支持降级 migration,如需回退用备份恢复。
|
|
452
|
+
|
|
453
|
+
### JSON indexes 处理
|
|
454
|
+
|
|
455
|
+
迁移后不删除,默认保留。manifest 标记:
|
|
456
|
+
|
|
457
|
+
```yml
|
|
458
|
+
indexes:
|
|
459
|
+
primary: sqlite
|
|
460
|
+
legacy_json:
|
|
461
|
+
enabled: false
|
|
462
|
+
retained: true
|
|
463
|
+
path: ".pmem/indexes"
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
|
|
468
|
+
## 八、v0.3 Manifest 最终形态
|
|
469
|
+
|
|
470
|
+
```yml
|
|
471
|
+
pmem:
|
|
472
|
+
schema_version: "0.3"
|
|
473
|
+
protocol_version: "0.3"
|
|
474
|
+
created_by: "0.2.0"
|
|
475
|
+
last_migrated_by: "0.3.0"
|
|
476
|
+
|
|
477
|
+
project:
|
|
478
|
+
name: ""
|
|
479
|
+
language: "zh-CN"
|
|
480
|
+
status: "active"
|
|
481
|
+
|
|
482
|
+
runtime:
|
|
483
|
+
mode: sqlite
|
|
484
|
+
db_path: ".pmem/pmem.db"
|
|
485
|
+
markdown_source: true
|
|
486
|
+
|
|
487
|
+
source_of_truth:
|
|
488
|
+
type: markdown_cards
|
|
489
|
+
card_globs:
|
|
490
|
+
- ".pmem/modules/**/*.md"
|
|
491
|
+
- ".pmem/features/**/*.md"
|
|
492
|
+
- ".pmem/decisions/**/*.md"
|
|
493
|
+
- ".pmem/tasks/**/*.md"
|
|
494
|
+
- ".pmem/traces/**/*.md"
|
|
495
|
+
- ".pmem/risks/**/*.md"
|
|
496
|
+
|
|
497
|
+
indexes:
|
|
498
|
+
primary: sqlite
|
|
499
|
+
legacy_json:
|
|
500
|
+
enabled: false
|
|
501
|
+
retained: true
|
|
502
|
+
path: ".pmem/indexes"
|
|
503
|
+
|
|
504
|
+
rebuild:
|
|
505
|
+
strategy: content_hash
|
|
506
|
+
hash:
|
|
507
|
+
file_hash: true
|
|
508
|
+
frontmatter_hash: true
|
|
509
|
+
body_hash: true
|
|
510
|
+
|
|
511
|
+
concurrency:
|
|
512
|
+
write_lock:
|
|
513
|
+
enabled: true
|
|
514
|
+
path: ".pmem/.lock"
|
|
515
|
+
timeout: "3s"
|
|
516
|
+
stale_after: "60s"
|
|
517
|
+
on_timeout: "abort"
|
|
518
|
+
sqlite_transaction: true
|
|
519
|
+
atomic_write: true
|
|
520
|
+
|
|
521
|
+
cli:
|
|
522
|
+
default_format: compact
|
|
523
|
+
supported_formats:
|
|
524
|
+
- compact
|
|
525
|
+
- json
|
|
526
|
+
- paths
|
|
527
|
+
- pack
|
|
528
|
+
default_budget: 1600
|
|
529
|
+
|
|
530
|
+
embedding:
|
|
531
|
+
enabled: false
|
|
532
|
+
provider: none
|
|
533
|
+
model: null
|
|
534
|
+
dimension: null
|
|
535
|
+
store: sqlite
|
|
536
|
+
index: none
|
|
537
|
+
|
|
538
|
+
serve:
|
|
539
|
+
enabled: false
|
|
540
|
+
mode: none
|
|
541
|
+
experimental:
|
|
542
|
+
mcp: false
|
|
543
|
+
rest: false
|
|
544
|
+
|
|
545
|
+
integrations:
|
|
546
|
+
active: []
|
|
547
|
+
compatibility: {}
|
|
548
|
+
|
|
549
|
+
migrations:
|
|
550
|
+
applied: []
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
---
|
|
554
|
+
|
|
555
|
+
## 九、v0.3 命令优先级
|
|
556
|
+
|
|
557
|
+
### P0 — 必须完成
|
|
558
|
+
|
|
559
|
+
| 命令 | 说明 |
|
|
560
|
+
|------|------|
|
|
561
|
+
| `pmem rebuild` | 切换到 SQLite-backed,支持 `--changed`/`--full`/`--card` |
|
|
562
|
+
| `pmem recall` | SQLite 查询 + `--format compact/json/paths/pack` |
|
|
563
|
+
| `pmem ask` | SQLite + aliases + FTS + graph expansion + 可解释召回 |
|
|
564
|
+
| `pmem related` | SQL edges 查询 + `--depth` + `--type` |
|
|
565
|
+
| `pmem verify` | SQLite ↔ Markdown 一致性检查 |
|
|
566
|
+
| `pmem migrate --to 0.3 --dry-run` | 预览迁移 |
|
|
567
|
+
| `pmem migrate --to 0.3` | 执行迁移(自动备份) |
|
|
568
|
+
|
|
569
|
+
所有核心查询命令必须支持 `--format` 和 `--budget`。
|
|
570
|
+
|
|
571
|
+
### P1 — 强烈建议
|
|
572
|
+
|
|
573
|
+
| 命令 | 说明 |
|
|
574
|
+
|------|------|
|
|
575
|
+
| `pmem trace` | SQLite-backed 溯源 |
|
|
576
|
+
| `pmem distill` | SQLite-backed 蒸馏分组 |
|
|
577
|
+
| `pmem mark-dirty` | 写入 dirty_flags table |
|
|
578
|
+
| `pmem session start/end` | 会话追踪 |
|
|
579
|
+
| FTS5 全文检索 | card_fts 表 |
|
|
580
|
+
| Integration 模板更新 | Claude Code / Cursor / Codex |
|
|
581
|
+
|
|
582
|
+
### P2 — 推迟
|
|
583
|
+
|
|
584
|
+
| 功能 | 目标版本 |
|
|
585
|
+
|------|---------|
|
|
586
|
+
| embedding 真接入 | v0.4 |
|
|
587
|
+
| Graph UI | v0.4+ |
|
|
588
|
+
| 多用户远程服务 | v0.5+ |
|
|
589
|
+
| SQLite-only card | 不做 |
|
|
590
|
+
| 复杂 merge | v0.4+ |
|
|
591
|
+
|
|
592
|
+
---
|
|
593
|
+
|
|
594
|
+
## 十、v0.3 的 ask / recall / related 工作方式
|
|
595
|
+
|
|
596
|
+
### `pmem recall`
|
|
597
|
+
|
|
598
|
+
目标:快速恢复项目状态。
|
|
599
|
+
|
|
600
|
+
数据来源:SQLite cards + state/next cards + recent update_log + dirty_flags。
|
|
601
|
+
|
|
602
|
+
输出:项目是什么、当前阶段、当前焦点、下一步、可能过期的记忆、建议读取的文件。
|
|
603
|
+
|
|
604
|
+
### `pmem ask`
|
|
605
|
+
|
|
606
|
+
目标:根据问题返回可解释召回包。
|
|
607
|
+
|
|
608
|
+
```
|
|
609
|
+
1. normalize query
|
|
610
|
+
2. exact id/title/alias match(SQLite)
|
|
611
|
+
3. graph expansion(edges table)
|
|
612
|
+
4. FTS keyword match(card_fts)
|
|
613
|
+
5. optional embedding(默认关闭)
|
|
614
|
+
6. rerank:match_type + graph_distance + priority + freshness
|
|
615
|
+
7. output context pack / paths / json / compact
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
输出必须包含 matched nodes、match_type、expanded nodes、recommended files、evidence paths。不要把 `pmem ask` 做成黑盒聊天机器人。它是**可解释召回器**。
|
|
619
|
+
|
|
620
|
+
### `pmem related`
|
|
621
|
+
|
|
622
|
+
目标:查询图邻居。数据来源:edges + cards + aliases + tags + paths。
|
|
623
|
+
|
|
624
|
+
```bash
|
|
625
|
+
pmem related module.agent_runtime
|
|
626
|
+
pmem related module.agent_runtime --depth 2
|
|
627
|
+
pmem related module.agent_runtime --type depends_on
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
---
|
|
631
|
+
|
|
632
|
+
## 十一、v0.3 最终决策表
|
|
633
|
+
|
|
634
|
+
| 问题 | 最终决策 |
|
|
635
|
+
|------|---------|
|
|
636
|
+
| SQLite schema | P0: cards / edges / aliases / tags / paths / dirty_flags / schema_meta;P1: sessions / update_log / card_fts |
|
|
637
|
+
| Markdown 主数据 | Markdown 是唯一主数据;SQLite 是索引、缓存、运行时状态 |
|
|
638
|
+
| `pmem serve` | 不做 MCP-first;v0.3 主线是 Agent-first CLI + Skills |
|
|
639
|
+
| 增量 rebuild | 基于 content hash;timestamp 只做预筛 |
|
|
640
|
+
| embeddings | v0.3 默认关闭,只设计 provider interface |
|
|
641
|
+
| file lock + SQLite | file lock 保护 Markdown;SQLite transaction 保护 DB;多读单写 |
|
|
642
|
+
| v0.2 → v0.3 migrate | 从 Markdown 重建 SQLite;JSON indexes 只作校验/备份 |
|
|
643
|
+
|
|
644
|
+
---
|
|
645
|
+
|
|
646
|
+
## 十二、v0.3 一句话定义
|
|
647
|
+
|
|
648
|
+
> **pmem v0.3 是一个以 Markdown 为主数据、SQLite 为运行时索引、CLI 为 Agent 操作入口的项目图记忆系统。**
|
|
649
|
+
|
|
650
|
+
更工程化:
|
|
651
|
+
|
|
652
|
+
```
|
|
653
|
+
pmem v0.3 =
|
|
654
|
+
Markdown canonical memory cards
|
|
655
|
+
+ SQLite-backed graph/index/runtime
|
|
656
|
+
+ content-hash incremental rebuild
|
|
657
|
+
+ Agent-first CLI output contract
|
|
658
|
+
+ skills-based usage protocol
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
## 十三、核心开发链路
|
|
662
|
+
|
|
663
|
+
v0.3 不要扩散方向。优先跑通这条链路:
|
|
664
|
+
|
|
665
|
+
```
|
|
666
|
+
Markdown cards
|
|
667
|
+
→ pmem migrate
|
|
668
|
+
→ SQLite index
|
|
669
|
+
→ pmem rebuild
|
|
670
|
+
→ pmem recall
|
|
671
|
+
→ pmem ask
|
|
672
|
+
→ pmem related
|
|
673
|
+
→ compact/json/paths/pack 输出
|
|
674
|
+
→ Agent 根据输出按需读取
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
这条链路跑通,v0.3 就成功了。
|
|
678
|
+
|
|
679
|
+
## 十四、v0.3 → v0.5 路线
|
|
680
|
+
|
|
681
|
+
| 版本 | 主题 |
|
|
682
|
+
|------|------|
|
|
683
|
+
| v0.2 | 文件模式稳定(防损坏) |
|
|
684
|
+
| v0.3 | SQLite-backed CLI Runtime(强一致) |
|
|
685
|
+
| v0.4 | Agent workflow 自动化 + embedding |
|
|
686
|
+
| v0.5 | 可上线 Beta |
|