@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 +6 -4
- package/bin/mneme.mjs +5 -5
- package/package.json +2 -2
- package/src/commands/auto.mjs +4 -4
- package/src/commands/compact.mjs +4 -4
- package/src/commands/doctor.mjs +3 -3
- package/src/commands/facts.mjs +5 -5
- package/src/commands/init.mjs +28 -10
- package/src/commands/propose.mjs +4 -4
- package/src/commands/review.mjs +3 -3
- package/src/commands/status.mjs +7 -7
- package/src/templates/cn/AGENTS.md +258 -0
- package/src/templates/cn/facts-architecture.md +6 -0
- package/src/templates/cn/facts-invariants.md +6 -0
- package/src/templates/cn/facts-performance_rules.md +5 -0
- package/src/templates/cn/facts-pitfalls.md +5 -0
- package/src/templates/cn/opencode-prompt.md +46 -0
- package/src/templates/{AGENTS.md → en/AGENTS.md} +14 -14
- package/src/templates/{opencode-prompt.md → en/opencode-prompt.md} +6 -6
- /package/src/templates/{facts-architecture.md → en/facts-architecture.md} +0 -0
- /package/src/templates/{facts-invariants.md → en/facts-invariants.md} +0 -0
- /package/src/templates/{facts-performance_rules.md → en/facts-performance_rules.md} +0 -0
- /package/src/templates/{facts-pitfalls.md → en/facts-pitfalls.md} +0 -0
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
|
-
│
|
|
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
|
-
| **
|
|
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 (`.
|
|
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
|
-
.
|
|
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
|
|
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 (
|
|
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
|
|
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(".
|
|
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.
|
|
4
|
-
"description": "Three-layer memory architecture for AI coding agents (
|
|
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"
|
package/src/commands/auto.mjs
CHANGED
|
@@ -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 +
|
|
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
|
|
196
|
+
* Read Ledger facts as context string.
|
|
197
197
|
*/
|
|
198
198
|
function readFacts() {
|
|
199
|
-
const factsDir = ".
|
|
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 (
|
|
246
|
+
context += "## Long-term Facts (Ledger)\n\n";
|
|
247
247
|
context += facts + "\n\n";
|
|
248
248
|
}
|
|
249
249
|
|
package/src/commands/compact.mjs
CHANGED
|
@@ -101,16 +101,16 @@ export async function compact() {
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
// Check 4:
|
|
105
|
-
console.log(`\n${color.bold("
|
|
106
|
-
if (existsSync(".
|
|
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 .
|
|
113
|
+
log.warn("No .ledger/facts/ directory");
|
|
114
114
|
warnings++;
|
|
115
115
|
}
|
|
116
116
|
|
package/src/commands/doctor.mjs
CHANGED
|
@@ -46,7 +46,7 @@ function checkDoltServer() {
|
|
|
46
46
|
function checkStructure() {
|
|
47
47
|
const checks = [
|
|
48
48
|
[".git/", "git repository"],
|
|
49
|
-
[".
|
|
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(".
|
|
67
|
-
const files = readdirSync(".
|
|
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(", ")}`);
|
package/src/commands/facts.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* mneme facts — View and manage
|
|
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 = ".
|
|
15
|
-
const PROPOSALS_DIR = ".
|
|
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
|
-
".
|
|
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("\
|
|
41
|
+
console.log(color.bold("\nLedger Facts"));
|
|
42
42
|
console.log(color.dim("──────────────────────────────────────────"));
|
|
43
43
|
|
|
44
44
|
for (const file of files) {
|
package/src/commands/init.mjs
CHANGED
|
@@ -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 .
|
|
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
|
-
".
|
|
29
|
-
".
|
|
30
|
-
".
|
|
31
|
-
".
|
|
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
|
-
|
|
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 =
|
|
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
|
package/src/commands/propose.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* mneme propose — Propose a new fact for
|
|
2
|
+
* mneme propose — Propose a new fact for Ledger.
|
|
3
3
|
*
|
|
4
|
-
* Creates a pending proposal in `.
|
|
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 = ".
|
|
24
|
-
const FACTS_DIR = ".
|
|
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.
|
package/src/commands/review.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* mneme review — Review, approve, or reject
|
|
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 = ".
|
|
23
|
-
const FACTS_DIR = ".
|
|
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.
|
package/src/commands/status.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* mneme status — Unified dashboard for all three memory layers.
|
|
3
3
|
*
|
|
4
4
|
* Shows:
|
|
5
|
-
* Layer 1 (
|
|
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:
|
|
14
|
+
// ── Layer 1: Ledger ───────────────────────────────────────────────────────
|
|
15
15
|
|
|
16
|
-
function
|
|
17
|
-
console.log(color.bold("\n Layer 1 —
|
|
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 = ".
|
|
20
|
+
const factsDir = ".ledger/facts";
|
|
21
21
|
if (!existsSync(factsDir)) {
|
|
22
|
-
log.warn(" .
|
|
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
|
-
|
|
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,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) | **
|
|
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
|
|
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 `.
|
|
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
|
|
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 `.
|
|
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
|
|
84
|
+
### Never modify Ledger facts directly
|
|
85
85
|
|
|
86
|
-
- Do not edit, delete, or overwrite files in `.
|
|
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 .
|
|
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
|
|
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" |
|
|
198
|
-
| "Never call the payments API without idempotency keys" |
|
|
199
|
-
| "Batch size over 1000 causes OOM" |
|
|
200
|
-
| "The config parser silently drops unknown keys" |
|
|
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 `.
|
|
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
|
|
3
|
+
## Step 1: Read Ledger facts (long-term knowledge)
|
|
4
4
|
|
|
5
5
|
Read all of these files completely:
|
|
6
|
-
- .
|
|
7
|
-
- .
|
|
8
|
-
- .
|
|
9
|
-
- .
|
|
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
|
|
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
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|