@xqli02/mneme 0.1.2 → 0.1.4

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/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  **Three-layer memory architecture for AI coding agents.**
4
4
 
5
+ mneme separates long-lived facts, persistent work state, and disposable execution context, allowing AI coding agents to survive context compaction without relying on vector memory or RAG.
6
+
5
7
  mneme gives coding agents (like [OpenCode](https://opencode.ai)) persistent memory across sessions. It separates long-term facts, task state, and short-term execution into three distinct layers — so agents stop forgetting decisions, losing progress, and repeating work.
6
8
 
7
9
  ## The problem
@@ -18,7 +20,7 @@ Prompt engineering doesn't fix this. The issue is structural: agents have no sep
18
20
 
19
21
  ```
20
22
  ┌─────────────────────────────────────────┐
21
- OpenClaw — Facts (long-term) │ survives forever
23
+ Ledger — Facts (long-term) │ survives forever
22
24
  ├─────────────────────────────────────────┤
23
25
  │ Beads — Tasks (mid-term) │ survives across sessions
24
26
  ├─────────────────────────────────────────┤
@@ -28,7 +30,7 @@ Prompt engineering doesn't fix this. The issue is structural: agents have no sep
28
30
 
29
31
  | Layer | What it stores | Lifetime | Example |
30
32
  |-------|---------------|----------|---------|
31
- | **OpenClaw** | Verified engineering facts — architecture decisions, constraints, pitfalls | Project lifetime | "Database must use PostgreSQL" |
33
+ | **Ledger** | Verified engineering facts — architecture decisions, constraints, pitfalls | Project lifetime | "Database must use PostgreSQL" |
32
34
  | **Beads** | Task state — what's done, what's blocked, what's next | Cross-session | "Auth module: JWT signing done, verification pending" |
33
35
  | **OpenCode** | Current execution context — code analysis, file edits | Single session | "This function's third parameter is timeout" |
34
36
 
@@ -49,7 +51,7 @@ mneme
49
51
  `mneme init` sets up everything in one command:
50
52
  1. Installs [Dolt](https://www.dolthub.com/repositories) and [bd](https://github.com/steveyegge/beads) if missing
51
53
  2. Initializes a git repo (if needed)
52
- 3. Creates the three-layer structure (`.openclaw/`, `.beads/`, `.opencode/`, `AGENTS.md`)
54
+ 3. Creates the three-layer structure (`.ledger/`, `.beads/`, `.opencode/`, `AGENTS.md`)
53
55
  4. Starts the task database
54
56
 
55
57
  That's it. Run `mneme` to launch the agent, or `mneme doctor` to verify your setup.
@@ -135,7 +137,7 @@ mneme version Print version
135
137
  After `mneme init`, your project contains:
136
138
 
137
139
  ```
138
- .openclaw/
140
+ .ledger/
139
141
  facts/ Long-term facts (architecture, constraints, pitfalls)
140
142
  proposals/ Pending fact proposals awaiting human review
141
143
  .beads/ Task database (managed by bd, backed by Dolt)
package/bin/mneme.mjs CHANGED
@@ -14,7 +14,7 @@
14
14
  * mneme doctor Check dependencies and project health
15
15
  * mneme status Show three-layer memory dashboard
16
16
  * mneme compact Pre-compaction persistence check
17
- * mneme facts View OpenClaw facts
17
+ * mneme facts View Ledger facts
18
18
  * mneme ready Show ready tasks (bd ready)
19
19
  * mneme list List tasks (bd list)
20
20
  * mneme create Create task (bd create)
@@ -80,7 +80,7 @@ const BD_COMMANDS = new Set([
80
80
  switch (command) {
81
81
  case "init": {
82
82
  const { init } = await import("../src/commands/init.mjs");
83
- await init();
83
+ await init(args.slice(1));
84
84
  break;
85
85
  }
86
86
  case "doctor": {
@@ -132,7 +132,7 @@ mneme ${pkg.version} — Three-layer memory architecture for AI coding agents
132
132
  Usage:
133
133
  mneme Start opencode TUI
134
134
 
135
- ${bold("Memory management (OpenClaw):")}
135
+ ${bold("Memory management (Ledger):")}
136
136
  mneme facts [name] [--stats] View facts
137
137
  mneme propose --file=... --content=... --reason=...
138
138
  Propose a new fact (pending human review)
@@ -141,7 +141,7 @@ Usage:
141
141
  mneme review <id> --reject Reject proposal
142
142
 
143
143
  ${bold("Project health:")}
144
- mneme init Initialize mneme in the current directory
144
+ mneme init [cn] Initialize mneme (cn = Chinese templates)
145
145
  mneme doctor Check dependencies and project health
146
146
  mneme status Show three-layer memory dashboard
147
147
  mneme compact Pre-compaction persistence check
@@ -192,7 +192,7 @@ Quickstart:
192
192
  * If not, prompt user to run init.
193
193
  */
194
194
  async function ensureInitialized() {
195
- if (existsSync(".openclaw/facts") && existsSync("AGENTS.md")) {
195
+ if (existsSync(".ledger/facts") && existsSync("AGENTS.md")) {
196
196
  return; // already initialized
197
197
  }
198
198
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xqli02/mneme",
3
- "version": "0.1.2",
4
- "description": "Three-layer memory architecture for AI coding agents (OpenClaw + Beads + OpenCode)",
3
+ "version": "0.1.4",
4
+ "description": "Three-layer memory architecture for AI coding agents (Ledger + Beads + OpenCode)",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "mneme": "bin/mneme.mjs"
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Starts an opencode server (or attaches to existing), then continuously:
5
5
  * 1. Picks the highest-priority unblocked bead from `mneme ready`
6
- * 2. Composes a prompt with bead context + OpenClaw facts
6
+ * 2. Composes a prompt with bead context + Ledger facts
7
7
  * 3. Sends it to opencode via HTTP API
8
8
  * 4. Streams progress to terminal
9
9
  * 5. Accepts user input at any time (queued, injected between turns)
@@ -193,10 +193,10 @@ function parseBeadText(text) {
193
193
  // ── Prompt composition ──────────────────────────────────────────────────────
194
194
 
195
195
  /**
196
- * Read OpenClaw facts as context string.
196
+ * Read Ledger facts as context string.
197
197
  */
198
198
  function readFacts() {
199
- const factsDir = ".openclaw/facts";
199
+ const factsDir = ".ledger/facts";
200
200
  if (!existsSync(factsDir)) return "";
201
201
 
202
202
  const files = readdirSync(factsDir).filter((f) => f.endsWith(".md"));
@@ -243,7 +243,7 @@ function buildSystemContext() {
243
243
  }
244
244
 
245
245
  if (facts) {
246
- context += "## Long-term Facts (OpenClaw)\n\n";
246
+ context += "## Long-term Facts (Ledger)\n\n";
247
247
  context += facts + "\n\n";
248
248
  }
249
249
 
@@ -101,16 +101,16 @@ export async function compact() {
101
101
  }
102
102
  }
103
103
 
104
- // Check 4: OpenClaw facts
105
- console.log(`\n${color.bold("OpenClaw state:")}`);
106
- if (existsSync(".openclaw/facts/")) {
104
+ // Check 4: Ledger facts
105
+ console.log(`\n${color.bold("Ledger state:")}`);
106
+ if (existsSync(".ledger/facts/")) {
107
107
  log.ok("Facts directory exists");
108
108
  log.info(
109
109
  "Review: any new long-term facts discovered this session? Propose with human confirmation.",
110
110
  );
111
111
  passes++;
112
112
  } else {
113
- log.warn("No .openclaw/facts/ directory");
113
+ log.warn("No .ledger/facts/ directory");
114
114
  warnings++;
115
115
  }
116
116
 
@@ -46,7 +46,7 @@ function checkDoltServer() {
46
46
  function checkStructure() {
47
47
  const checks = [
48
48
  [".git/", "git repository"],
49
- [".openclaw/facts/", "OpenClaw facts directory"],
49
+ [".ledger/facts/", "Ledger facts directory"],
50
50
  [".opencode/prompt.md", "OpenCode session prompt"],
51
51
  ["AGENTS.md", "Agent behavior rules"],
52
52
  [".beads/", "Beads data directory"],
@@ -63,8 +63,8 @@ function checkStructure() {
63
63
  }
64
64
 
65
65
  // Check facts files
66
- if (existsSync(".openclaw/facts/")) {
67
- const files = readdirSync(".openclaw/facts/").filter((f) =>
66
+ if (existsSync(".ledger/facts/")) {
67
+ const files = readdirSync(".ledger/facts/").filter((f) =>
68
68
  f.endsWith(".md"),
69
69
  );
70
70
  log.info(` ${files.length} facts file(s): ${files.join(", ")}`);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * mneme facts — View and manage OpenClaw facts.
2
+ * mneme facts — View and manage Ledger facts.
3
3
  *
4
4
  * Usage:
5
5
  * mneme facts List all facts files with summaries
@@ -11,8 +11,8 @@ import { existsSync, readdirSync, readFileSync } from "node:fs";
11
11
  import { join } from "node:path";
12
12
  import { log, color } from "../utils.mjs";
13
13
 
14
- const FACTS_DIR = ".openclaw/facts";
15
- const PROPOSALS_DIR = ".openclaw/proposals";
14
+ const FACTS_DIR = ".ledger/facts";
15
+ const PROPOSALS_DIR = ".ledger/proposals";
16
16
  const LINE_BUDGET_PER_FILE = 200;
17
17
  const LINE_BUDGET_TOTAL = 800;
18
18
 
@@ -22,7 +22,7 @@ const LINE_BUDGET_TOTAL = 800;
22
22
  function listFacts(showStats) {
23
23
  if (!existsSync(FACTS_DIR)) {
24
24
  log.fail(
25
- ".openclaw/facts/ not found — run `mneme init` to create it.",
25
+ ".ledger/facts/ not found — run `mneme init` to create it.",
26
26
  );
27
27
  process.exit(1);
28
28
  }
@@ -38,7 +38,7 @@ function listFacts(showStats) {
38
38
 
39
39
  let totalLines = 0;
40
40
 
41
- console.log(color.bold("\nOpenClaw Facts"));
41
+ console.log(color.bold("\nLedger Facts"));
42
42
  console.log(color.dim("──────────────────────────────────────────"));
43
43
 
44
44
  for (const file of files) {
@@ -4,7 +4,7 @@
4
4
  * Steps:
5
5
  * 1. Install dependencies (git, dolt, bd)
6
6
  * 2. git init (if needed)
7
- * 3. Scaffold .openclaw/facts/, .opencode/prompt.md, AGENTS.md, .gitignore
7
+ * 3. Scaffold .ledger/facts/, .opencode/prompt.md, AGENTS.md, .gitignore
8
8
  * 4. Start dolt server + bd init
9
9
  */
10
10
 
@@ -17,6 +17,9 @@ const __filename = fileURLToPath(import.meta.url);
17
17
  const __dirname = dirname(__filename);
18
18
  const TEMPLATES_DIR = join(__dirname, "..", "templates");
19
19
 
20
+ // Supported locales: "en" (default), "cn" (Chinese)
21
+ const SUPPORTED_LOCALES = new Set(["en", "cn"]);
22
+
20
23
  // ── Template scaffolding ────────────────────────────────────────────────────
21
24
 
22
25
  /**
@@ -25,14 +28,24 @@ const TEMPLATES_DIR = join(__dirname, "..", "templates");
25
28
  const SCAFFOLD = {
26
29
  "AGENTS.md": "AGENTS.md",
27
30
  ".opencode/prompt.md": "opencode-prompt.md",
28
- ".openclaw/facts/architecture.md": "facts-architecture.md",
29
- ".openclaw/facts/invariants.md": "facts-invariants.md",
30
- ".openclaw/facts/performance_rules.md": "facts-performance_rules.md",
31
- ".openclaw/facts/pitfalls.md": "facts-pitfalls.md",
31
+ ".ledger/facts/architecture.md": "facts-architecture.md",
32
+ ".ledger/facts/invariants.md": "facts-invariants.md",
33
+ ".ledger/facts/performance_rules.md": "facts-performance_rules.md",
34
+ ".ledger/facts/pitfalls.md": "facts-pitfalls.md",
32
35
  ".gitignore": "gitignore",
33
36
  };
34
37
 
35
- function scaffoldFiles() {
38
+ // Templates that have locale-specific versions (everything except .gitignore)
39
+ const LOCALIZABLE = new Set([
40
+ "AGENTS.md",
41
+ "opencode-prompt.md",
42
+ "facts-architecture.md",
43
+ "facts-invariants.md",
44
+ "facts-performance_rules.md",
45
+ "facts-pitfalls.md",
46
+ ]);
47
+
48
+ function scaffoldFiles(locale = "en") {
36
49
  let created = 0;
37
50
  let skipped = 0;
38
51
 
@@ -49,7 +62,9 @@ function scaffoldFiles() {
49
62
  mkdirSync(dir, { recursive: true });
50
63
  }
51
64
 
52
- const templatePath = join(TEMPLATES_DIR, templateName);
65
+ const templatePath = LOCALIZABLE.has(templateName)
66
+ ? join(TEMPLATES_DIR, locale, templateName)
67
+ : join(TEMPLATES_DIR, templateName);
53
68
  const content = readFileSync(templatePath, "utf-8");
54
69
 
55
70
  // For .gitignore, we append rather than overwrite if it already exists
@@ -300,9 +315,12 @@ function initGit() {
300
315
 
301
316
  // ── Main ────────────────────────────────────────────────────────────────────
302
317
 
303
- export async function init() {
318
+ export async function init(args = []) {
319
+ // Parse locale from args: `mneme init cn` → locale "cn"
320
+ const locale = args.length > 0 && SUPPORTED_LOCALES.has(args[0]) ? args[0] : "en";
321
+
304
322
  console.log(`
305
- ${color.bold("mneme init")} — Three-layer memory architecture for AI agents
323
+ ${color.bold("mneme init")} — Three-layer memory architecture for AI agents${locale !== "en" ? ` (${locale})` : ""}
306
324
  `);
307
325
 
308
326
  const { os, arch } = getPlatform();
@@ -325,7 +343,7 @@ ${color.bold("mneme init")} — Three-layer memory architecture for AI agents
325
343
 
326
344
  // Step 3: Scaffold files
327
345
  log.step(3, 4, "Scaffold project structure");
328
- const { created, skipped } = scaffoldFiles();
346
+ const { created, skipped } = scaffoldFiles(locale);
329
347
  log.info(` ${created} file(s) created, ${skipped} already existed`);
330
348
 
331
349
  // Step 4: Dolt + Beads
@@ -1,7 +1,7 @@
1
1
  /**
2
- * mneme propose — Propose a new fact for OpenClaw.
2
+ * mneme propose — Propose a new fact for Ledger.
3
3
  *
4
- * Creates a pending proposal in `.openclaw/proposals/` that requires
4
+ * Creates a pending proposal in `.ledger/proposals/` that requires
5
5
  * human review via `mneme review` before being written to facts.
6
6
  *
7
7
  * Usage:
@@ -20,8 +20,8 @@ import { join } from "node:path";
20
20
  import { createHash } from "node:crypto";
21
21
  import { log, color } from "../utils.mjs";
22
22
 
23
- const PROPOSALS_DIR = ".openclaw/proposals";
24
- const FACTS_DIR = ".openclaw/facts";
23
+ const PROPOSALS_DIR = ".ledger/proposals";
24
+ const FACTS_DIR = ".ledger/facts";
25
25
 
26
26
  /**
27
27
  * Parse --key=value and --key "value" style args.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * mneme review — Review, approve, or reject OpenClaw fact proposals.
2
+ * mneme review — Review, approve, or reject Ledger fact proposals.
3
3
  *
4
4
  * Usage:
5
5
  * mneme review List all pending proposals
@@ -19,8 +19,8 @@ import {
19
19
  import { join } from "node:path";
20
20
  import { log, color } from "../utils.mjs";
21
21
 
22
- const PROPOSALS_DIR = ".openclaw/proposals";
23
- const FACTS_DIR = ".openclaw/facts";
22
+ const PROPOSALS_DIR = ".ledger/proposals";
23
+ const FACTS_DIR = ".ledger/facts";
24
24
 
25
25
  /**
26
26
  * Load all proposals, optionally filtered by status.
@@ -2,7 +2,7 @@
2
2
  * mneme status — Unified dashboard for all three memory layers.
3
3
  *
4
4
  * Shows:
5
- * Layer 1 (OpenClaw): Facts files summary (count, total lines)
5
+ * Layer 1 (Ledger): Facts files summary (count, total lines)
6
6
  * Layer 2 (Beads): Task counts by status, ready tasks
7
7
  * Layer 3 (OpenCode): Git working tree state, unpushed commits
8
8
  */
@@ -11,15 +11,15 @@ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
11
11
  import { join } from "node:path";
12
12
  import { run, log, color } from "../utils.mjs";
13
13
 
14
- // ── Layer 1: OpenClaw ───────────────────────────────────────────────────────
14
+ // ── Layer 1: Ledger ───────────────────────────────────────────────────────
15
15
 
16
- function showOpenClaw() {
17
- console.log(color.bold("\n Layer 1 — OpenClaw (Long-term Facts)"));
16
+ function showLedger() {
17
+ console.log(color.bold("\n Layer 1 — Ledger (Long-term Facts)"));
18
18
  console.log(color.dim(" ─────────────────────────────────────"));
19
19
 
20
- const factsDir = ".openclaw/facts";
20
+ const factsDir = ".ledger/facts";
21
21
  if (!existsSync(factsDir)) {
22
- log.warn(" .openclaw/facts/ not found — run `mneme init`");
22
+ log.warn(" .ledger/facts/ not found — run `mneme init`");
23
23
  return;
24
24
  }
25
25
 
@@ -156,7 +156,7 @@ function showOpenCode() {
156
156
  export async function status() {
157
157
  console.log(`\n${color.bold("mneme status")} — three-layer memory dashboard`);
158
158
 
159
- showOpenClaw();
159
+ showLedger();
160
160
  showBeads();
161
161
  showOpenCode();
162
162
 
@@ -0,0 +1,258 @@
1
+ # AGENTS.md
2
+
3
+ mneme 管理项目中 AI 编程 Agent 的行为规则。
4
+
5
+ 每次会话开始时,Agent 必须读取本文件。本文件定义了 Agent 允许做什么、禁止做什么,以及如何处理信息冲突。
6
+
7
+ ## 上下文优先级
8
+
9
+ 当信息冲突时,按以下优先级链解决(从高到低):
10
+
11
+ | 优先级 | 来源 | 示例 |
12
+ |--------|------|------|
13
+ | 1(最高) | **Ledger 事实** (`.ledger/facts/`) | "数据库必须使用 PostgreSQL" |
14
+ | 2 | **本文件** (AGENTS.md) | "不得跳过启动流程" |
15
+ | 3 | **Beads 任务状态** (`mneme ready`, `mneme list`) | "认证模块正在开发中" |
16
+ | 4 | **用户指令**(当前会话中) | "先聚焦认证模块" |
17
+ | 5(最低) | **Agent 推理**和对话历史 | "我觉得应该用 SQLite" |
18
+
19
+ 如果 Agent 的推理与 Ledger 事实矛盾,以事实为准。如果 Agent 认为事实已过时,必须向用户提出矛盾,而非默默覆盖。
20
+
21
+ ## Agent 允许做的事
22
+
23
+ ### 读取所有三层数据
24
+
25
+ - 会话开始时读取 `.ledger/facts/` 中的所有文件
26
+ - 运行 `mneme ready` 和 `mneme list` 检查任务状态
27
+ - 读取当前任务所需的任何项目文件
28
+
29
+ ### 通过 mneme 管理任务
30
+
31
+ - 认领任务:`mneme update <id> --status=in_progress`
32
+ - 记录进度:`mneme update <id> --notes="完成了什么"`
33
+ - 创建子任务:`mneme create --title="..." --description="..." --type=task -p 2`
34
+ - 添加依赖:`mneme dep add <子任务> <父任务>`
35
+ - 关闭已完成工作:`mneme close <id> --reason="完成了什么"`
36
+
37
+ ### 提议事实(需人工审批)
38
+
39
+ - 提议新的长期事实:`mneme propose --file=<name> --content="..." --reason="..."`
40
+ - 提议必须指明:哪个事实文件、具体内容、为什么它算长期事实
41
+ - 提议不会写入事实,直到人工通过 `mneme review` 审批
42
+
43
+ ### 执行代码操作
44
+
45
+ - 读取、分析、修改代码文件
46
+ - 运行命令(构建、测试、代码检查等)
47
+ - 创建提交并推送到远程仓库
48
+ - 所有代码操作必须服务于当前聚焦的任务
49
+
50
+ ### 压缩前持久化状态
51
+
52
+ 当上下文变长或达到里程碑时:
53
+ - 将确认的结论写入 Beads:`mneme update <id> --notes="..."`
54
+ - 将发现的事实提议给 Ledger
55
+ - 关闭已完成的任务或更新笔记(记录当前进度和阻塞项)
56
+ - 然后允许压缩继续
57
+
58
+ ### 干净地结束会话
59
+
60
+ 结束会话前:
61
+ 1. 为未完成的工作创建任务:`mneme create`
62
+ 2. 如果修改了代码,运行质量门禁(测试、代码检查、构建)
63
+ 3. 关闭已完成的任务,更新进行中任务的笔记
64
+ 4. 推送到远程 —— 这是强制的:
65
+ ```bash
66
+ git pull --rebase
67
+ git push
68
+ git status # 必须显示 "up to date with origin"
69
+ ```
70
+ 5. 如果推送失败,解决冲突并重试直到成功
71
+
72
+ ## Agent 禁止做的事
73
+
74
+ ### 不得跳过启动流程
75
+
76
+ 每次会话必须以以下步骤开始:
77
+ 1. 读取 `.ledger/facts/`(所有文件)
78
+ 2. 运行 `mneme ready` 和 `mneme list --status=open`
79
+ 3. 选择一个任务作为会话焦点
80
+ 4. 开始工作
81
+
82
+ 跳过任何步骤都是禁止的。不要在读取事实和任务之前就开始写代码。
83
+
84
+ ### 不得直接修改 Ledger 事实
85
+
86
+ - 不要编辑、删除或覆盖 `.ledger/facts/` 中的文件
87
+ - 不要将未验证的假设、临时结论或推测性分析写入事实
88
+ - 修改事实的唯一途径是 `mneme propose`,然后由人工 `mneme review --approve`
89
+
90
+ ### 不得从对话历史恢复状态
91
+
92
+ - 不要从会话中早期的消息重建任务进度
93
+ - 所有任务状态必须来自 Beads(`mneme list`、`mneme show`)
94
+ - 如果一个 bead 的笔记是空的,向用户询问而不是从上下文猜测
95
+
96
+ ### 不得同时处理多个不相关的任务
97
+
98
+ - 每次会话聚焦一个任务(一个 bead)
99
+ - 不要在单次会话中切换不相关的任务
100
+ - 如果发现新的紧急任务,创建为 bead,让下次会话处理
101
+
102
+ ### 不得创建模糊的任务
103
+
104
+ - 每个 bead 必须有清晰、可验证的完成条件
105
+ - 反例:"提升性能" —— 无法知道什么时候算完成
106
+ - 正例:"将 /users 接口的 API 响应时间降到 200ms 以下"
107
+
108
+ ### 不得使用 bd edit
109
+
110
+ - `bd edit` 会打开交互式编辑器(`$EDITOR`),会导致非交互式 Agent 挂起
111
+ - 始终使用 `mneme update <id>` 加参数(`--notes`、`--status`、`--title`、`--description`)
112
+
113
+ ### 不得使用 markdown TODO 跟踪任务
114
+
115
+ - 所有任务跟踪通过 mneme/beads 进行
116
+ - 不要在 markdown 文件、代码注释或任何其他格式中创建 TODO 列表
117
+ - 不要使用外部问题跟踪器
118
+
119
+ ### 不得在推送前停止
120
+
121
+ - 工作没有完成,直到 `git push` 成功
122
+ - 不要说"准备好了就推送" —— 立即推送
123
+ - 如果推送失败,解决冲突并重试
124
+
125
+ ## 会话生命周期
126
+
127
+ ### 1. 启动
128
+
129
+ ```bash
130
+ # 读取长期事实
131
+ cat .ledger/facts/*.md
132
+
133
+ # 检查可用工作
134
+ mneme ready
135
+ mneme list --status=open
136
+ mneme list --status=in_progress
137
+
138
+ # 认领任务
139
+ mneme update <id> --status=in_progress
140
+ ```
141
+
142
+ ### 2. 执行
143
+
144
+ 聚焦任务进行工作。每完成一个里程碑后:
145
+
146
+ ```bash
147
+ mneme update <id> --notes="完成了 X,下一步:Y"
148
+ ```
149
+
150
+ 如果发现子任务:
151
+
152
+ ```bash
153
+ mneme create --title="子任务标题" --description="上下文" --type=task -p 2
154
+ mneme dep add <新id> <父id>
155
+ ```
156
+
157
+ ### 3. 压缩前
158
+
159
+ 当上下文变长或完成了一个里程碑时:
160
+
161
+ 1. 将确认的结论写入 Beads 笔记
162
+ 2. 通过 `mneme propose` 提议新发现的事实
163
+ 3. 关闭已完成的任务或更新笔记(记录阻塞项)
164
+
165
+ 原则:**推理过程可以丢失,但状态和事实不能丢失。**
166
+
167
+ ### 4. 完成
168
+
169
+ ```bash
170
+ # 关闭已完成的工作
171
+ mneme close <id> --reason="完成内容摘要"
172
+
173
+ # 为剩余工作创建任务
174
+ mneme create --title="后续工作" --description="..." --type=task -p 2
175
+
176
+ # 推送所有内容
177
+ git pull --rebase && git push
178
+ ```
179
+
180
+ ## 信息路由
181
+
182
+ 遇到新信息时,立即分类:
183
+
184
+ ```
185
+ 新信息
186
+
187
+ ├─ 6 个月后还会需要吗?
188
+ │ ├─ 是 + 是事实/约束/教训 → 提议给 Ledger
189
+ │ ├─ 是 + 是任务或进度更新 → 写入 Beads
190
+ │ └─ 否 → 下次会话需要吗?
191
+ │ ├─ 是 → 写入 Beads(笔记或新任务)
192
+ │ └─ 否 → 保留在上下文中,不持久化
193
+ ```
194
+
195
+ | 信息 | 层级 | 操作 |
196
+ |------|------|------|
197
+ | "这个项目使用事件溯源" | Ledger | `mneme propose --file=architecture` |
198
+ | "调用支付 API 必须带幂等键" | Ledger | `mneme propose --file=invariants` |
199
+ | "批量大小超过 1000 会导致 OOM" | Ledger | `mneme propose --file=performance_rules` |
200
+ | "配置解析器会静默丢弃未知的键" | Ledger | `mneme propose --file=pitfalls` |
201
+ | "需要给 API 添加限流" | Beads | `mneme create --title="添加 API 限流"` |
202
+ | "限流:令牌桶已实现,需要写测试" | Beads | `mneme update <id> --notes="..."` |
203
+ | "这个函数在第 47 行返回 null" | 上下文 | 不持久化 |
204
+
205
+ ### 提议事实:阈值检查
206
+
207
+ 提议事实前,验证以下四个条件:
208
+
209
+ - [ ] 信息已被验证(不是假设或猜测)
210
+ - [ ] 未来的会话会反复需要它(不是一次性的)
211
+ - [ ] 不会很快过时(不是临时状态)
212
+ - [ ] `.ledger/facts/` 中不存在等价的事实
213
+
214
+ 四个条件都满足才能提议,然后等待人工审批。
215
+
216
+ ## 任务管理参考
217
+
218
+ ### 问题类型
219
+
220
+ | 类型 | 用途 |
221
+ |------|------|
222
+ | `bug` | 已损坏的功能 |
223
+ | `feature` | 新功能 |
224
+ | `task` | 工作项:测试、文档、重构 |
225
+ | `epic` | 包含子任务的大型功能 |
226
+ | `chore` | 维护:依赖、工具链 |
227
+
228
+ ### 优先级
229
+
230
+ | 优先级 | 级别 | 用途 |
231
+ |--------|------|------|
232
+ | `0` / P0 | 严重 | 安全问题、数据丢失、构建损坏 |
233
+ | `1` / P1 | 高 | 主要功能、重要 bug |
234
+ | `2` / P2 | 中(默认) | 默认优先级 |
235
+ | `3` / P3 | 低 | 优化、打磨 |
236
+ | `4` / P4 | 待办 | 未来想法 |
237
+
238
+ ### 命令
239
+
240
+ ```bash
241
+ # 查找工作
242
+ mneme ready # 无阻塞的任务
243
+ mneme list --status=open # 所有未完成的任务
244
+ mneme list --status=in_progress # 进行中的工作
245
+ mneme show <id> # 任务详情和依赖关系
246
+ mneme blocked # 被阻塞的任务
247
+
248
+ # 创建和关联
249
+ mneme create --title="..." --description="..." --type=task -p 2
250
+ mneme dep add <子任务> <父任务>
251
+
252
+ # 更新
253
+ mneme update <id> --status=in_progress
254
+ mneme update <id> --notes="进度笔记"
255
+
256
+ # 完成
257
+ mneme close <id> --reason="完成"
258
+ ```
@@ -0,0 +1,6 @@
1
+ # 架构
2
+
3
+ <!-- 在此记录项目的架构决策。示例: -->
4
+ <!-- - 数据库:PostgreSQL,使用 pg (node-postgres) 连接池 -->
5
+ <!-- - API:Express 5,JSON 信封格式响应 -->
6
+ <!-- - 部署:Docker 容器,nginx 反向代理 -->
@@ -0,0 +1,6 @@
1
+ # 不变量
2
+
3
+ <!-- 在此记录绝不能违反的硬性约束和规则。示例: -->
4
+ <!-- - 所有 API 端点都必须认证(不允许匿名访问) -->
5
+ <!-- - 数据库迁移必须向后兼容 -->
6
+ <!-- - P99 响应时间必须保持在 200ms 以下 -->
@@ -0,0 +1,5 @@
1
+ # 性能规则
2
+
3
+ <!-- 在此记录性能相关的规则和约束。示例: -->
4
+ <!-- - 批量操作优于逐行插入 -->
5
+ <!-- - 缓存 TTL 不得超过 5 分钟 -->
@@ -0,0 +1,5 @@
1
+ # 踩坑记录
2
+
3
+ <!-- 在此记录不易察觉的陷阱和经验教训。示例: -->
4
+ <!-- - MySQL 的 utf8 只有 3 字节;完整 Unicode 支持需使用 utf8mb4 -->
5
+ <!-- - Dockerfile 中的 COPY 会使构建缓存失效;注意层的排列顺序 -->
@@ -0,0 +1,46 @@
1
+ 这是一个长期工程项目。每次会话开始时,请严格按以下流程执行:
2
+
3
+ ## 第一步:读取 Ledger 事实(长期知识)
4
+
5
+ 完整读取以下所有文件:
6
+ - .ledger/facts/architecture.md
7
+ - .ledger/facts/invariants.md
8
+ - .ledger/facts/performance_rules.md
9
+ - .ledger/facts/pitfalls.md
10
+
11
+ 这些是经过验证的长期事实:
12
+ - 它们的优先级高于对话历史和你自己的推理
13
+ - 不要覆盖或忽视它们
14
+ - 如果发现矛盾,提出矛盾而不是默默修改事实
15
+
16
+ ## 第二步:从 Beads 读取当前任务状态
17
+
18
+ 使用 `mneme` 命令检查可用工作:
19
+ - `mneme ready` —— 无阻塞依赖的任务
20
+ - `mneme list --status=open` —— 所有未完成的任务
21
+ - `mneme show <id>` —— 具体任务的详细信息
22
+
23
+ ## 第三步:选择一个焦点
24
+
25
+ - 选择恰好一个任务(bead)作为本次会话的目标
26
+ - 优先选择 `mneme ready` 中的任务(无阻塞项)
27
+ - 认领它:`mneme update <id> --status=in_progress`
28
+ - 不要从对话历史重建进度
29
+
30
+ ## 信息路由(自动执行 —— 无需询问用户)
31
+
32
+ 工作过程中你会发现新信息,请立即分类:
33
+
34
+ - **长期事实或约束?** 提议给 Ledger:`mneme propose --file=<name> --content="..." --reason="..."`
35
+ - **任务或进度更新?** 写入 Beads:`mneme create` 或 `mneme update <id> --notes="..."`
36
+ - **只跟当前相关?** 保留在上下文中,不持久化
37
+
38
+ 提议事实前,请验证:它已被确认(不是猜测)、未来会话会需要它、不会很快过时、且不存在重复。
39
+
40
+ ## 关键规则
41
+
42
+ - 不要跳过以上步骤直接开始写代码
43
+ - 完成一个里程碑后:`mneme update <id> --notes="完成了什么"`
44
+ - 完成一个任务后:`mneme close <id> --reason="摘要"`
45
+ - 压缩前:将所有确认的结论持久化到 Beads
46
+ - 不要使用 `bd edit`(会打开交互式编辑器)—— 使用 `mneme update` 加参数
@@ -10,19 +10,19 @@ When information conflicts, resolve it using this priority chain (highest first)
10
10
 
11
11
  | Priority | Source | Example |
12
12
  |----------|--------|---------|
13
- | 1 (highest) | **OpenClaw facts** (`.openclaw/facts/`) | "Database must use PostgreSQL" |
13
+ | 1 (highest) | **Ledger facts** (`.ledger/facts/`) | "Database must use PostgreSQL" |
14
14
  | 2 | **This file** (AGENTS.md) | "Never skip the startup sequence" |
15
15
  | 3 | **Beads task state** (`mneme ready`, `mneme list`) | "Auth module is in progress" |
16
16
  | 4 | **User instructions** in the current session | "Focus on the auth module first" |
17
17
  | 5 (lowest) | **Agent reasoning** and conversation history | "I think we should use SQLite" |
18
18
 
19
- If an agent's reasoning contradicts an OpenClaw fact, the fact wins. If the agent believes the fact is outdated, it must raise the contradiction to the user rather than silently overriding it.
19
+ If an agent's reasoning contradicts an Ledger fact, the fact wins. If the agent believes the fact is outdated, it must raise the contradiction to the user rather than silently overriding it.
20
20
 
21
21
  ## What agents are allowed to do
22
22
 
23
23
  ### Read from all three layers
24
24
 
25
- - Read all files in `.openclaw/facts/` at session start
25
+ - Read all files in `.ledger/facts/` at session start
26
26
  - Run `mneme ready` and `mneme list` to check task state
27
27
  - Read any project file needed for the current task
28
28
 
@@ -51,7 +51,7 @@ If an agent's reasoning contradicts an OpenClaw fact, the fact wins. If the agen
51
51
 
52
52
  When context is getting long or a milestone is reached:
53
53
  - Flush confirmed conclusions to Beads: `mneme update <id> --notes="..."`
54
- - Propose any discovered facts to OpenClaw
54
+ - Propose any discovered facts to Ledger
55
55
  - Close completed tasks or update notes with current progress and blockers
56
56
  - Then allow compaction to proceed
57
57
 
@@ -74,16 +74,16 @@ Before ending a session:
74
74
  ### Never skip the startup sequence
75
75
 
76
76
  Every session must begin with:
77
- 1. Read `.openclaw/facts/` (all files)
77
+ 1. Read `.ledger/facts/` (all files)
78
78
  2. Run `mneme ready` and `mneme list --status=open`
79
79
  3. Pick one task as the session focus
80
80
  4. Begin work
81
81
 
82
82
  Skipping any step is prohibited. Do not start coding before reading facts and tasks.
83
83
 
84
- ### Never modify OpenClaw facts directly
84
+ ### Never modify Ledger facts directly
85
85
 
86
- - Do not edit, delete, or overwrite files in `.openclaw/facts/`
86
+ - Do not edit, delete, or overwrite files in `.ledger/facts/`
87
87
  - Do not write unverified hypotheses, temporary conclusions, or speculative analysis to facts
88
88
  - The only path to changing facts is `mneme propose` followed by human `mneme review --approve`
89
89
 
@@ -128,7 +128,7 @@ Skipping any step is prohibited. Do not start coding before reading facts and ta
128
128
 
129
129
  ```bash
130
130
  # Read long-term facts
131
- cat .openclaw/facts/*.md
131
+ cat .ledger/facts/*.md
132
132
 
133
133
  # Check available work
134
134
  mneme ready
@@ -185,7 +185,7 @@ When you encounter new information, classify it immediately:
185
185
  New information
186
186
 
187
187
  ├─ Will this matter in 6 months?
188
- │ ├─ Yes + it's a fact/constraint/lesson → Propose to OpenClaw
188
+ │ ├─ Yes + it's a fact/constraint/lesson → Propose to Ledger
189
189
  │ ├─ Yes + it's a task or progress update → Write to Beads
190
190
  │ └─ No → Will the next session need it?
191
191
  │ ├─ Yes → Write to Beads (notes or new task)
@@ -194,10 +194,10 @@ New information
194
194
 
195
195
  | Information | Layer | Action |
196
196
  |---|---|---|
197
- | "This project uses event sourcing" | OpenClaw | `mneme propose --file=architecture` |
198
- | "Never call the payments API without idempotency keys" | OpenClaw | `mneme propose --file=invariants` |
199
- | "Batch size over 1000 causes OOM" | OpenClaw | `mneme propose --file=performance_rules` |
200
- | "The config parser silently drops unknown keys" | OpenClaw | `mneme propose --file=pitfalls` |
197
+ | "This project uses event sourcing" | Ledger | `mneme propose --file=architecture` |
198
+ | "Never call the payments API without idempotency keys" | Ledger | `mneme propose --file=invariants` |
199
+ | "Batch size over 1000 causes OOM" | Ledger | `mneme propose --file=performance_rules` |
200
+ | "The config parser silently drops unknown keys" | Ledger | `mneme propose --file=pitfalls` |
201
201
  | "Need to add rate limiting to the API" | Beads | `mneme create --title="Add API rate limiting"` |
202
202
  | "Rate limiting: token bucket implemented, need tests" | Beads | `mneme update <id> --notes="..."` |
203
203
  | "This function returns null on line 47" | Context | Don't persist |
@@ -209,7 +209,7 @@ Before proposing a fact, verify all four conditions:
209
209
  - [ ] The information has been verified (not a hypothesis or guess)
210
210
  - [ ] Future sessions will repeatedly need it (not one-time)
211
211
  - [ ] It won't become outdated quickly (not a temporary state)
212
- - [ ] No equivalent fact already exists in `.openclaw/facts/`
212
+ - [ ] No equivalent fact already exists in `.ledger/facts/`
213
213
 
214
214
  All four must pass. Then propose and wait for human approval.
215
215
 
@@ -1,12 +1,12 @@
1
1
  This is a long-running engineering project. Follow this sequence strictly at session start:
2
2
 
3
- ## Step 1: Read OpenClaw facts (long-term knowledge)
3
+ ## Step 1: Read Ledger facts (long-term knowledge)
4
4
 
5
5
  Read all of these files completely:
6
- - .openclaw/facts/architecture.md
7
- - .openclaw/facts/invariants.md
8
- - .openclaw/facts/performance_rules.md
9
- - .openclaw/facts/pitfalls.md
6
+ - .ledger/facts/architecture.md
7
+ - .ledger/facts/invariants.md
8
+ - .ledger/facts/performance_rules.md
9
+ - .ledger/facts/pitfalls.md
10
10
 
11
11
  These are verified long-term facts:
12
12
  - They take priority over conversation history and your own reasoning
@@ -31,7 +31,7 @@ Use `mneme` commands to check what work is available:
31
31
 
32
32
  As you work, you will discover new information. Classify it immediately:
33
33
 
34
- - **Long-term fact or constraint?** Propose to OpenClaw: `mneme propose --file=<name> --content="..." --reason="..."`
34
+ - **Long-term fact or constraint?** Propose to Ledger: `mneme propose --file=<name> --content="..." --reason="..."`
35
35
  - **Task or progress update?** Write to Beads: `mneme create` or `mneme update <id> --notes="..."`
36
36
  - **Only relevant right now?** Keep in context, do not persist
37
37