@lh8ppl/claude-memory-kit 0.1.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/bin/cmk-compress-lazy.mjs +59 -0
- package/bin/cmk-daily-distill.mjs +67 -0
- package/bin/cmk-weekly-curate.mjs +56 -0
- package/bin/cmk.mjs +12 -0
- package/package.json +50 -0
- package/src/audit-log.mjs +103 -0
- package/src/auto-extract.mjs +742 -0
- package/src/capture-prompt.mjs +61 -0
- package/src/capture-turn.mjs +273 -0
- package/src/claude-md.mjs +212 -0
- package/src/compress-session.mjs +349 -0
- package/src/compressor.mjs +376 -0
- package/src/conflict-queue.mjs +796 -0
- package/src/cooldown.mjs +61 -0
- package/src/daily-distill.mjs +252 -0
- package/src/doctor.mjs +528 -0
- package/src/forget.mjs +335 -0
- package/src/frontmatter.mjs +73 -0
- package/src/import-anthropic-memory.mjs +266 -0
- package/src/index-db.mjs +154 -0
- package/src/index-rebuild.mjs +597 -0
- package/src/index.mjs +90 -0
- package/src/inject-context.mjs +484 -0
- package/src/install.mjs +327 -0
- package/src/lazy-compress.mjs +326 -0
- package/src/lock-discipline.mjs +166 -0
- package/src/mcp-server.mjs +498 -0
- package/src/memory-write.mjs +565 -0
- package/src/merge-facts.mjs +213 -0
- package/src/observe-edit.mjs +87 -0
- package/src/platform-commands.mjs +138 -0
- package/src/poison-guard.mjs +245 -0
- package/src/privacy.mjs +21 -0
- package/src/provenance.mjs +217 -0
- package/src/register-crons.mjs +354 -0
- package/src/reindex.mjs +134 -0
- package/src/repair.mjs +316 -0
- package/src/result-shapes.mjs +155 -0
- package/src/review-queue.mjs +345 -0
- package/src/roll.mjs +115 -0
- package/src/scratchpad.mjs +335 -0
- package/src/search.mjs +311 -0
- package/src/subcommands.mjs +1252 -0
- package/src/tier-paths.mjs +74 -0
- package/src/transcripts.mjs +234 -0
- package/src/trust.mjs +226 -0
- package/src/weekly-curate.mjs +454 -0
- package/src/write-fact.mjs +205 -0
- package/template/.claude/hooks/pre-tool-memory.js +78 -0
- package/template/.claude/hooks/transcript-capture.js +69 -0
- package/template/.claude/settings.json +27 -0
- package/template/.claude/skills/memory-write/SKILL.md +117 -0
- package/template/.gitignore.fragment +12 -0
- package/template/CLAUDE.md.template +49 -0
- package/template/docs/journey/journey-log.md.template +292 -0
- package/template/local/machine-paths.md.template +37 -0
- package/template/local/overrides.md.template +36 -0
- package/template/project/.index/.gitkeep +0 -0
- package/template/project/MEMORY.md.template +47 -0
- package/template/project/SOUL.md.template +35 -0
- package/template/project/memory/INDEX.md.template +47 -0
- package/template/project/memory/archive/superseded/.gitkeep +0 -0
- package/template/project/memory/archive/tombstones/.gitkeep +0 -0
- package/template/project/queues/.gitkeep +0 -0
- package/template/project/sessions/.gitkeep +0 -0
- package/template/project/transcripts/.gitkeep +0 -0
- package/template/support/cron-jobs/daily-memory-distill.md +15 -0
- package/template/support/cron-jobs/nightly-memsearch-index.md +17 -0
- package/template/support/cron-jobs/weekly-memory-curator.md +15 -0
- package/template/support/milvus-deploy/README.md +57 -0
- package/template/support/milvus-deploy/docker-compose.yml +66 -0
- package/template/support/scripts/auto-extract-memory.sh +102 -0
- package/template/support/scripts/memsearch-index-with-flush.sh +59 -0
- package/template/support/scripts/refresh-distill-timestamp.py +35 -0
- package/template/support/scripts/register-crons.py +242 -0
- package/template/support/scripts/run-daily-distill.sh +67 -0
- package/template/support/scripts/run-weekly-curate.sh +58 -0
- package/template/user/HABITS.md.template +18 -0
- package/template/user/LESSONS.md.template +18 -0
- package/template/user/USER.md.template +18 -0
- package/template/user/fragments/INDEX.md.template +23 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
//
|
|
3
|
+
// PreToolUse hook — guarantees the frozen memory snapshot loads
|
|
4
|
+
// before the first tool call of each session, without relying on
|
|
5
|
+
// Claude obeying CLAUDE.md's session-startup checklist.
|
|
6
|
+
//
|
|
7
|
+
// Reads context/USER.md, context/SOUL.md, context/MEMORY.md,
|
|
8
|
+
// context/memory/INDEX.md, and today's session log (if exists),
|
|
9
|
+
// formats them as a single block, and emits the block as
|
|
10
|
+
// additionalContext via the hook's output protocol.
|
|
11
|
+
//
|
|
12
|
+
// Fires once per session — uses a /tmp flag file to suppress subsequent
|
|
13
|
+
// firings within the same session. The flag is keyed by session_id when
|
|
14
|
+
// available, falling back to a per-day flag.
|
|
15
|
+
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
const path = require('path');
|
|
18
|
+
const os = require('os');
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
const raw = fs.readFileSync(0, 'utf8');
|
|
22
|
+
if (!raw) process.exit(0);
|
|
23
|
+
const input = JSON.parse(raw);
|
|
24
|
+
|
|
25
|
+
// Resolve project dir.
|
|
26
|
+
const projectDir = process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
27
|
+
const ctx = path.join(projectDir, 'context');
|
|
28
|
+
|
|
29
|
+
// Per-project flag prefix. Allows multiple projects to coexist on the
|
|
30
|
+
// same machine without their session flags colliding.
|
|
31
|
+
const projectSlug = path.basename(projectDir).replace(/[^a-z0-9-]/gi, '_');
|
|
32
|
+
|
|
33
|
+
// One-per-session guard.
|
|
34
|
+
const sid = input.session_id || input.sessionId || `day-${new Date().toISOString().slice(0, 10)}`;
|
|
35
|
+
const flagPath = path.join(os.tmpdir(), `cmk-${projectSlug}-mem-injected-${sid.replace(/[^a-z0-9-]/gi, '_')}`);
|
|
36
|
+
if (fs.existsSync(flagPath)) {
|
|
37
|
+
process.exit(0);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const parts = [];
|
|
41
|
+
const safeRead = (p, label) => {
|
|
42
|
+
if (fs.existsSync(p)) {
|
|
43
|
+
const content = fs.readFileSync(p, 'utf8');
|
|
44
|
+
if (content.trim()) {
|
|
45
|
+
parts.push(`\n--- ${label} (${p.replace(projectDir, '').replace(/^[/\\]+/, '')}) ---\n${content}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
safeRead(path.join(ctx, 'SOUL.md'), 'Project soul (persona / disposition)');
|
|
51
|
+
safeRead(path.join(ctx, 'USER.md'), 'User profile');
|
|
52
|
+
safeRead(path.join(ctx, 'MEMORY.md'), 'Working memory (scratchpad)');
|
|
53
|
+
safeRead(path.join(ctx, 'memory', 'INDEX.md'), 'Granular memory index');
|
|
54
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
55
|
+
safeRead(path.join(ctx, 'sessions', `${today}.md`), `Today's session log`);
|
|
56
|
+
|
|
57
|
+
if (parts.length === 0) {
|
|
58
|
+
process.exit(0);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const block = [
|
|
62
|
+
'# Memory snapshot (auto-injected on first tool call)',
|
|
63
|
+
'',
|
|
64
|
+
'The following files form this session\'s frozen memory snapshot. Reference them when responding; mid-session edits to these files persist to disk but take effect at the NEXT session.',
|
|
65
|
+
parts.join('\n'),
|
|
66
|
+
].join('\n');
|
|
67
|
+
|
|
68
|
+
process.stdout.write(JSON.stringify({
|
|
69
|
+
hookSpecificOutput: {
|
|
70
|
+
hookEventName: 'PreToolUse',
|
|
71
|
+
additionalContext: block,
|
|
72
|
+
},
|
|
73
|
+
}));
|
|
74
|
+
|
|
75
|
+
try { fs.writeFileSync(flagPath, String(Date.now())); } catch {}
|
|
76
|
+
} catch (e) {
|
|
77
|
+
process.exit(0);
|
|
78
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
//
|
|
3
|
+
// Stop hook — fires after every assistant turn.
|
|
4
|
+
//
|
|
5
|
+
// Does TWO things:
|
|
6
|
+
// 1. Captures the first ~500 chars of the turn into
|
|
7
|
+
// context/transcripts/{today}.md (verbatim transcript trail).
|
|
8
|
+
// 2. Spawns the auto-extract helper in the background (detached, fire-
|
|
9
|
+
// and-forget) which invokes `claude --print` on the turn and writes
|
|
10
|
+
// any durable facts to MEMORY.md / USER.md / granular archive via
|
|
11
|
+
// the memory-write skill.
|
|
12
|
+
//
|
|
13
|
+
// Step 1 is synchronous and fast. Step 2 is detached so the user never
|
|
14
|
+
// waits for the auto-extract subprocess to complete. If either step fails,
|
|
15
|
+
// the hook exits 0 — it must NEVER break the session.
|
|
16
|
+
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
const path = require('path');
|
|
19
|
+
const { spawn } = require('child_process');
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
const raw = fs.readFileSync(0, 'utf8');
|
|
23
|
+
if (!raw) process.exit(0);
|
|
24
|
+
const input = JSON.parse(raw);
|
|
25
|
+
|
|
26
|
+
// Defensive: payload shape varies across Claude Code versions.
|
|
27
|
+
const text =
|
|
28
|
+
(typeof input.response === 'string' && input.response) ||
|
|
29
|
+
(typeof input.assistant_message === 'string' && input.assistant_message) ||
|
|
30
|
+
(typeof input.last_assistant_message === 'string' && input.last_assistant_message) ||
|
|
31
|
+
'';
|
|
32
|
+
|
|
33
|
+
if (!text.trim()) process.exit(0);
|
|
34
|
+
|
|
35
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
36
|
+
const projectDir = process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
37
|
+
|
|
38
|
+
// ---- Step 1 — transcript capture (synchronous) ----
|
|
39
|
+
const tDir = path.join(projectDir, 'context', 'transcripts');
|
|
40
|
+
const tFile = path.join(tDir, `${today}.md`);
|
|
41
|
+
try {
|
|
42
|
+
fs.mkdirSync(tDir, { recursive: true });
|
|
43
|
+
const summary = text.slice(0, 500).replace(/\n{3,}/g, '\n\n');
|
|
44
|
+
const timestamp = new Date().toISOString().slice(11, 19);
|
|
45
|
+
fs.appendFileSync(tFile, `\n## ${timestamp}\n${summary}\n`);
|
|
46
|
+
} catch {}
|
|
47
|
+
|
|
48
|
+
// ---- Step 2 — auto-extract memory-worthy facts (background) ----
|
|
49
|
+
try {
|
|
50
|
+
const tmp = path.join(projectDir, 'context', 'transcripts', `.extract-${Date.now()}.tmp`);
|
|
51
|
+
fs.writeFileSync(tmp, text, 'utf8');
|
|
52
|
+
|
|
53
|
+
const extractScript = path.join(projectDir, 'scripts', 'auto-extract-memory.sh');
|
|
54
|
+
if (fs.existsSync(extractScript)) {
|
|
55
|
+
const child = spawn('bash', [extractScript, tmp], {
|
|
56
|
+
detached: true,
|
|
57
|
+
stdio: 'ignore',
|
|
58
|
+
cwd: projectDir,
|
|
59
|
+
});
|
|
60
|
+
child.unref();
|
|
61
|
+
} else {
|
|
62
|
+
try { fs.unlinkSync(tmp); } catch {}
|
|
63
|
+
}
|
|
64
|
+
} catch {}
|
|
65
|
+
} catch {
|
|
66
|
+
// Fire-and-forget. Never break the session.
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
process.exit(0);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": []
|
|
4
|
+
},
|
|
5
|
+
"hooks": {
|
|
6
|
+
"Stop": [
|
|
7
|
+
{
|
|
8
|
+
"hooks": [
|
|
9
|
+
{
|
|
10
|
+
"type": "command",
|
|
11
|
+
"command": "node .claude/hooks/transcript-capture.js"
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"PreToolUse": [
|
|
17
|
+
{
|
|
18
|
+
"hooks": [
|
|
19
|
+
{
|
|
20
|
+
"type": "command",
|
|
21
|
+
"command": "node .claude/hooks/pre-tool-memory.js"
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: memory-write
|
|
3
|
+
description: >
|
|
4
|
+
Saves durable facts to context/MEMORY.md or context/USER.md. Auto-triggers
|
|
5
|
+
on phrases the user uses to flag worth-remembering content: "remember this",
|
|
6
|
+
"remember that", "note this", "note that", "save this", "update memory",
|
|
7
|
+
"forget about", "let's remember", "going forward", "from now on", "i prefer",
|
|
8
|
+
"i don't like". Also triggers automatically from the auto-extract Stop hook
|
|
9
|
+
after every assistant turn when a durable fact is detected.
|
|
10
|
+
Three actions: add (append under correct section), replace (substring match
|
|
11
|
+
+ swap), remove (confirm with user first). Enforces caps (MEMORY.md 2,500
|
|
12
|
+
chars, USER.md 1,375 chars) with a dedup guard so duplicate or near-duplicate
|
|
13
|
+
facts don't accumulate.
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# memory-write
|
|
17
|
+
|
|
18
|
+
## Purpose
|
|
19
|
+
|
|
20
|
+
Make memory writes **automatic and reliable**. Instead of the user reminding Claude to "save this to memory," the skill captures durable facts the moment they're spoken or decided, with the right structure and the right file.
|
|
21
|
+
|
|
22
|
+
## When this skill fires
|
|
23
|
+
|
|
24
|
+
**User-explicit signals**:
|
|
25
|
+
|
|
26
|
+
- "remember this" / "remember that" / "remember our X"
|
|
27
|
+
- "note this" / "note that"
|
|
28
|
+
- "save this" / "save that"
|
|
29
|
+
- "update memory" / "add to memory"
|
|
30
|
+
- "forget about X" → remove operation
|
|
31
|
+
- "from now on" / "going forward" / "i prefer" / "i don't like" → preference signals
|
|
32
|
+
- "we decided" / "we agreed" / "let's use X not Y" → decision signals
|
|
33
|
+
|
|
34
|
+
**Auto-extract signals** (from the Stop hook):
|
|
35
|
+
|
|
36
|
+
- Assistant turn contains a "Why:" or "How to apply:" line implying a durable rule
|
|
37
|
+
- Assistant turn explicitly acknowledges a user correction ("you're right", "fair point", "i was wrong")
|
|
38
|
+
- Assistant turn states a new decision or environment fact that wasn't in MEMORY.md before
|
|
39
|
+
|
|
40
|
+
## Where to write — file routing
|
|
41
|
+
|
|
42
|
+
| Content type | File | Section |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| Current active work / open threads | `context/MEMORY.md` | `## Active Threads` |
|
|
45
|
+
| Tool versions, paths, URLs, env state | `context/MEMORY.md` | `## Environment Notes` |
|
|
46
|
+
| Things the user still has to decide | `context/MEMORY.md` | `## Pending Decisions` |
|
|
47
|
+
| Stable user identity, role, expertise | `context/USER.md` | `## About` |
|
|
48
|
+
| Persistent preferences ("i prefer X") | `context/USER.md` | `## Preferences` |
|
|
49
|
+
| How the user approaches work | `context/USER.md` | `## Working Style` |
|
|
50
|
+
| Typed durable fact with rationale | `context/memory/<type>_<slug>.md` | Granular archive, with frontmatter + `**Why:**` + `**How to apply:**` |
|
|
51
|
+
|
|
52
|
+
If unsure: scratchpad (MEMORY.md) is the default. If the fact has long-term reasoning, promote it to a granular file later.
|
|
53
|
+
|
|
54
|
+
## How to write — the steps
|
|
55
|
+
|
|
56
|
+
1. Read the target file in full (MEMORY.md or USER.md). Need current state to dedup against.
|
|
57
|
+
2. **Dedup check**: scan for substring or near-paraphrase match. If the fact already exists, skip; don't append a duplicate.
|
|
58
|
+
3. **Cap check**: `wc -c context/MEMORY.md` (or USER.md). If over the cap:
|
|
59
|
+
- For MEMORY.md: consolidate existing entries first (merge similar bullets, drop stale ones older than 14 days with no current reference), THEN add the new fact.
|
|
60
|
+
- For USER.md: same pattern. USER.md should rarely change — most additions go to MEMORY.md.
|
|
61
|
+
4. **Write** the new fact under the appropriate section. Single bullet, concise (< 200 chars).
|
|
62
|
+
5. **Confirm silently** — do not announce "saved to memory" unless the user explicitly asked. Auto-extract should be invisible.
|
|
63
|
+
|
|
64
|
+
## Actions
|
|
65
|
+
|
|
66
|
+
- **add** — default. Append a new bullet under the appropriate section.
|
|
67
|
+
- **replace** — when the user says "update memory: X is now Y", or "we decided to switch from X to Y". Find the existing bullet by substring match and swap.
|
|
68
|
+
- **remove** — when the user says "forget about X" or "we changed our mind on X". Confirm with the user FIRST before deleting. Removal is the only action that requires confirmation; add and replace are silent.
|
|
69
|
+
|
|
70
|
+
## Examples
|
|
71
|
+
|
|
72
|
+
**Explicit user trigger:**
|
|
73
|
+
|
|
74
|
+
> User: "remember that we're standardizing on Python 3.13"
|
|
75
|
+
|
|
76
|
+
Action: add to `MEMORY.md` § Environment Notes:
|
|
77
|
+
```
|
|
78
|
+
- Python 3.13 is the standard. Older 3.10 envs should be uninstalled to avoid PATH conflicts.
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Auto-extract trigger (silent):**
|
|
82
|
+
|
|
83
|
+
> Assistant turn (after a debugging session): "...so the issue was the system PATH resolving wrong. Fix uses absolute executable paths. Going forward, scheduled tasks should never rely on bare command names."
|
|
84
|
+
|
|
85
|
+
Auto-extract recognizes "Going forward" + concrete rule → add to `MEMORY.md` § Environment Notes:
|
|
86
|
+
```
|
|
87
|
+
- Scheduled tasks must use absolute executable paths (not bare command names) — system PATH can resolve to the wrong binary.
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Replace trigger:**
|
|
91
|
+
|
|
92
|
+
> User: "actually we bumped to v2.6.16 from v2.5.27"
|
|
93
|
+
|
|
94
|
+
Action: find existing "v2.5.27" bullet in MEMORY.md, replace the version. Silent.
|
|
95
|
+
|
|
96
|
+
**Remove trigger:**
|
|
97
|
+
|
|
98
|
+
> User: "forget about the daily-distill cron — we're going to do something different"
|
|
99
|
+
|
|
100
|
+
Action: Ask the user "Remove the daily-distill entries from MEMORY.md Active Threads? (y/n)" before deleting.
|
|
101
|
+
|
|
102
|
+
## Rules
|
|
103
|
+
|
|
104
|
+
- Never exceed the cap. Consolidate first if needed.
|
|
105
|
+
- Always check for duplicates / near-duplicates before adding.
|
|
106
|
+
- Replace is preferred over add when updating existing facts (avoids accumulating contradictory bullets).
|
|
107
|
+
- Removal requires user confirmation.
|
|
108
|
+
- For typed durable facts with explicit `**Why:**` / `**How to apply:**` structure, write to `context/memory/<type>_<slug>.md` and add a one-line entry to INDEX.md instead of MEMORY.md.
|
|
109
|
+
- **Silent by default.** Do not narrate memory writes unless the user explicitly asked. The whole point is invisible bookkeeping.
|
|
110
|
+
|
|
111
|
+
## Common mistakes to avoid
|
|
112
|
+
|
|
113
|
+
- Don't write conversational chatter to MEMORY.md ("user said hello"). Only durable facts.
|
|
114
|
+
- Don't duplicate. Always check first.
|
|
115
|
+
- Don't blow the cap. Consolidate first.
|
|
116
|
+
- Don't announce. Silent unless asked.
|
|
117
|
+
- Don't promote everything to the granular archive — the scratchpad is the default. Granular files are for facts with explicit rationale that have long shelf life.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# claude-memory-kit — added by `cmk install`. Do not edit by hand;
|
|
2
|
+
# `cmk install` refreshes these lines idempotently. Remove via
|
|
3
|
+
# `cmk uninstall`.
|
|
4
|
+
|
|
5
|
+
# Local-tier (per-machine, never committed)
|
|
6
|
+
context.local/
|
|
7
|
+
|
|
8
|
+
# SQLite + FTS5 read cache (regenerable from markdown)
|
|
9
|
+
context/.index/
|
|
10
|
+
|
|
11
|
+
# Run-time locks + transient state
|
|
12
|
+
context/.locks/
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
## Memory System — claude-memory-kit
|
|
2
|
+
|
|
3
|
+
This project uses **claude-memory-kit** for per-project, in-repo memory that survives session boundaries. Memory lives in `context/` (committed) and `context.local/` (gitignored). Cross-project memory lives at `~/.claude-memory-kit/` (or `$MEMORY_KIT_USER_DIR`).
|
|
4
|
+
|
|
5
|
+
> v0.1.0 is under active development. This block is the runtime contract. Specific mechanisms (auto-extract, memory-write skill, MCP search) come online incrementally — `cmk doctor` will tell you which layers are active in the current install. Full architecture: <https://github.com/LH8PPL/claude-memory-kit/blob/main/docs/journey/v0.1.0-build-log.md>
|
|
6
|
+
|
|
7
|
+
### Where memory lives
|
|
8
|
+
|
|
9
|
+
| Tier | Path | Travels with `git clone`? |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| **User** | `~/.claude-memory-kit/` | No — machine-local, cross-project |
|
|
12
|
+
| **Project** | `<repo>/context/` | **Yes** — committed |
|
|
13
|
+
| **Local** | `<repo>/context.local/` | No — gitignored, per-machine |
|
|
14
|
+
|
|
15
|
+
Precedence at session start: local > project > user (most-specific wins, others are logged as shadowed).
|
|
16
|
+
|
|
17
|
+
### How memory works
|
|
18
|
+
|
|
19
|
+
- **Session start** — the kit injects a frozen snapshot (≤10 KB) from the three tiers into Claude's context. Loaded once, never mutated mid-session — preserves the prefix cache.
|
|
20
|
+
- **During the session** — durable facts get captured automatically by the Stop hook + `memory-write` skill (once Layer 4 is live). The user can also explicitly say "remember this", "from now on", "we decided X".
|
|
21
|
+
- **End of session** — the rolling-window pipeline compresses `sessions/now.md` into a daily summary. Cron jobs distill into `recent.md` and `archive.md` over time (Layer 6, optional).
|
|
22
|
+
|
|
23
|
+
### Health checks (when `cmk doctor` is live)
|
|
24
|
+
|
|
25
|
+
Health checks (HC-1..HC-8) verify each layer is wired correctly: install integrity, hook registration, transcript capture freshness, INDEX accuracy, cron registration, semantic search backend, native Auto Memory coexistence. See [`docs/adr/`](docs/adr/) and [`specs/v0.1.0/design.md`](specs/v0.1.0/design.md) for the full contract.
|
|
26
|
+
|
|
27
|
+
### Memory write rules (for Claude)
|
|
28
|
+
|
|
29
|
+
When you learn something durable about this project or the user:
|
|
30
|
+
|
|
31
|
+
1. **Working state** (current threads, today's environment, open decisions) → write to `context/MEMORY.md` (≤2,500 chars). Consolidate at the cap.
|
|
32
|
+
2. **Typed durable fact** (user role / project decision / feedback / external reference) → create `context/memory/<type>_<slug>.md` with full YAML frontmatter; add a one-line entry to `context/memory/INDEX.md`.
|
|
33
|
+
3. **Cross-project lesson** → user-tier `~/.claude-memory-kit/LESSONS.md` (via `cmk lessons promote`).
|
|
34
|
+
4. **Never duplicate** between scratchpad and granular archive. If a working-state item becomes durable, MOVE it.
|
|
35
|
+
5. **Confirm silently.** Frozen-snapshot semantics mean the write takes effect next session.
|
|
36
|
+
|
|
37
|
+
### Privacy
|
|
38
|
+
|
|
39
|
+
Anything inside `<private>...</private>` tags in a user prompt is stripped before any disk write — never persisted in any form. Per-fact `private: true` frontmatter excludes a fact from the session-start digest.
|
|
40
|
+
|
|
41
|
+
### Uninstall / remove this block
|
|
42
|
+
|
|
43
|
+
This block is managed by `cmk install`. To remove it cleanly:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
cmk uninstall
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Everything outside the `claude-memory-kit:start` / `:end` markers is byte-preserved.
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
==================================================================
|
|
3
|
+
JOURNEY LOG — narrative behind the spec
|
|
4
|
+
==================================================================
|
|
5
|
+
|
|
6
|
+
What this file IS:
|
|
7
|
+
The story of HOW you and your AI assistant figured out what to
|
|
8
|
+
build, captured as it happens. Not WHAT you built (that's in
|
|
9
|
+
specs/) — but WHY each decision was made, what you tried first
|
|
10
|
+
that didn't work, what the AI got wrong, what you corrected.
|
|
11
|
+
|
|
12
|
+
What this file is FOR:
|
|
13
|
+
- Future-you, six months from now, asking "why did we decide X?"
|
|
14
|
+
- A future AI session bootstrapping into the project cold
|
|
15
|
+
- An article, talk, or retrospective derived from the build
|
|
16
|
+
|
|
17
|
+
How to update it:
|
|
18
|
+
Append, don't overwrite. New milestones go at the END of their
|
|
19
|
+
phase section. Old entries don't get rewritten — they stay as
|
|
20
|
+
the record of what was true at that point in time. When a
|
|
21
|
+
decision changes, add an "Update: YYYY-MM-DD" entry rather
|
|
22
|
+
than editing the original.
|
|
23
|
+
|
|
24
|
+
For inspiration:
|
|
25
|
+
See claude-memory-kit's own journey log as a worked example:
|
|
26
|
+
https://github.com/LH8PPL/claude-memory-kit/blob/main/docs/journey/v0.1.0-build-log.md
|
|
27
|
+
|
|
28
|
+
This template uses HTML comments (like this one) to coach the
|
|
29
|
+
user through each section. The comments are stripped from
|
|
30
|
+
Claude's context per Anthropic docs, so they don't waste tokens.
|
|
31
|
+
Delete a comment block once you've filled in that section.
|
|
32
|
+
==================================================================
|
|
33
|
+
-->
|
|
34
|
+
|
|
35
|
+
# {{PROJECT_NAME}} — journey log (v{{VERSION}})
|
|
36
|
+
|
|
37
|
+
**Started**: {{TODAY}}
|
|
38
|
+
**Status**: in progress
|
|
39
|
+
|
|
40
|
+
<!--
|
|
41
|
+
Pin the high-level "what is this project" in 1-2 sentences here.
|
|
42
|
+
Update when the project's mission changes.
|
|
43
|
+
-->
|
|
44
|
+
|
|
45
|
+
[One-paragraph project summary. Update on major mission changes.]
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 0. The frustration that started this
|
|
50
|
+
|
|
51
|
+
<!--
|
|
52
|
+
Why does this project exist? What pain were you in, what failed
|
|
53
|
+
attempt prompted it, what's the emotional/practical seed?
|
|
54
|
+
|
|
55
|
+
This section ages well. Future-you wants to remember why it
|
|
56
|
+
mattered. Be specific — "I was tired of re-explaining context
|
|
57
|
+
every morning" beats "the AI needed memory."
|
|
58
|
+
|
|
59
|
+
Length: 2-4 short paragraphs.
|
|
60
|
+
-->
|
|
61
|
+
|
|
62
|
+
[Write about the motivating frustration. Be honest, specific.]
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 1. The starting state
|
|
67
|
+
|
|
68
|
+
<!--
|
|
69
|
+
What existed before you started? Prior versions, existing tooling,
|
|
70
|
+
constraints inherited from elsewhere.
|
|
71
|
+
|
|
72
|
+
Honest about both what worked and what didn't in the prior state.
|
|
73
|
+
This grounds the rest of the log — readers see where you started.
|
|
74
|
+
|
|
75
|
+
Format suggestion: a bullet list of what existed + a short
|
|
76
|
+
paragraph on what was missing or broken.
|
|
77
|
+
-->
|
|
78
|
+
|
|
79
|
+
[What existed before; what worked; what was missing.]
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 2. Research
|
|
84
|
+
|
|
85
|
+
<!--
|
|
86
|
+
What did you read, what projects did you examine, what patterns
|
|
87
|
+
did you find converging?
|
|
88
|
+
|
|
89
|
+
Most useful pattern to record: specific corrections you made
|
|
90
|
+
along the way. "I initially thought X, then found out Y by
|
|
91
|
+
reading the actual source" — these become the article's anchor
|
|
92
|
+
moments and they decay from memory faster than anything else.
|
|
93
|
+
|
|
94
|
+
Tip: maintain a SOURCES.md alongside this file with verification
|
|
95
|
+
status (✓ verified primary source / ~ partial / ✗ retracted)
|
|
96
|
+
for every external claim you make in the spec.
|
|
97
|
+
-->
|
|
98
|
+
|
|
99
|
+
### Articles read
|
|
100
|
+
|
|
101
|
+
- [link or title] — what stuck with you in one sentence
|
|
102
|
+
|
|
103
|
+
### Projects examined (primary-source verified)
|
|
104
|
+
|
|
105
|
+
- [link] — pattern relevant to yours; what they got right; what you'd do differently
|
|
106
|
+
|
|
107
|
+
### Lessons that emerged
|
|
108
|
+
|
|
109
|
+
- **[The rule that crystallized]** — [the specific incident that taught it]
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 3. Design decisions
|
|
114
|
+
|
|
115
|
+
<!--
|
|
116
|
+
For each major architectural choice: what alternatives were on
|
|
117
|
+
the table, what you picked, why. Record the REJECTED options
|
|
118
|
+
too — they're more interesting than the chosen ones.
|
|
119
|
+
|
|
120
|
+
When a decision changes later: append "Update: YYYY-MM-DD"
|
|
121
|
+
rather than rewriting. The history is the value.
|
|
122
|
+
|
|
123
|
+
Format suggestion: one sub-section per decision, with the
|
|
124
|
+
4-field structure below.
|
|
125
|
+
-->
|
|
126
|
+
|
|
127
|
+
### Decision: [name]
|
|
128
|
+
|
|
129
|
+
- **Considered**: A / B / C
|
|
130
|
+
- **Chose**: B
|
|
131
|
+
- **Why**: [rationale, including what made B's tradeoffs preferable]
|
|
132
|
+
- **Tradeoff accepted**: [what you gave up by not picking A or C]
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 4. Working with an AI assistant
|
|
137
|
+
|
|
138
|
+
<!--
|
|
139
|
+
Skip this section if you're working solo or with humans only.
|
|
140
|
+
|
|
141
|
+
If you're using Claude / GPT / Cursor / Copilot / etc., this
|
|
142
|
+
section captures:
|
|
143
|
+
- Where the AI added the most value
|
|
144
|
+
- Where it failed and how you corrected it
|
|
145
|
+
- Specific corrections that became durable rules
|
|
146
|
+
|
|
147
|
+
This is the section most useful to a future AI session
|
|
148
|
+
bootstrapping into your project. Specific incidents beat
|
|
149
|
+
general principles every time — quote actual user messages
|
|
150
|
+
that became load-bearing.
|
|
151
|
+
|
|
152
|
+
Don't sanitize the failures. They're the article material.
|
|
153
|
+
-->
|
|
154
|
+
|
|
155
|
+
### Where the AI added value
|
|
156
|
+
|
|
157
|
+
- [pattern of value-add — drafting, synthesis, exhaustive comparison, etc.]
|
|
158
|
+
|
|
159
|
+
### Where the AI failed (and what corrected it)
|
|
160
|
+
|
|
161
|
+
- **[The failure mode]** — *"[verbatim user correction]"* — [what changed afterward]
|
|
162
|
+
|
|
163
|
+
### Durable rules that emerged
|
|
164
|
+
|
|
165
|
+
- **[rule]** — *Why*: [the incident that taught it]. *How to apply*: [when to invoke this rule]
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 5. Implementation log
|
|
170
|
+
|
|
171
|
+
<!--
|
|
172
|
+
One sub-section per major milestone (task, PR, sprint, layer).
|
|
173
|
+
|
|
174
|
+
Keep entries short. The discipline:
|
|
175
|
+
- What landed (3-5 bullets, file paths and counts)
|
|
176
|
+
- TDD evidence (real bugs caught vs test relaxations)
|
|
177
|
+
- Surprises or pivots (anything that didn't go as planned)
|
|
178
|
+
- Cumulative test count (so progress is visible)
|
|
179
|
+
|
|
180
|
+
Append; don't overwrite. The log grows.
|
|
181
|
+
-->
|
|
182
|
+
|
|
183
|
+
### [Task / Milestone N] — [title] ([YYYY-MM-DD])
|
|
184
|
+
|
|
185
|
+
**What landed**:
|
|
186
|
+
|
|
187
|
+
- [file or feature 1]
|
|
188
|
+
- [file or feature 2]
|
|
189
|
+
|
|
190
|
+
**TDD evidence**:
|
|
191
|
+
|
|
192
|
+
- Tests written first
|
|
193
|
+
- [N] real bugs caught by tests; [M] test relaxations resisted
|
|
194
|
+
- [cumulative test count] green
|
|
195
|
+
|
|
196
|
+
**Surprises**:
|
|
197
|
+
|
|
198
|
+
- [anything that didn't go as planned]
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## 6. Open questions / things deferred
|
|
203
|
+
|
|
204
|
+
<!--
|
|
205
|
+
Things you considered and explicitly deferred (with reasons),
|
|
206
|
+
so future-you knows why something ISN'T in the current version.
|
|
207
|
+
|
|
208
|
+
Format: bullet list with deferral reason.
|
|
209
|
+
-->
|
|
210
|
+
|
|
211
|
+
- **[thing]** — deferred to vX.Y because [reason]
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## 7. Working-style preferences (for future-AI sessions)
|
|
216
|
+
|
|
217
|
+
<!--
|
|
218
|
+
This section is the most important for AI-assisted projects.
|
|
219
|
+
A new AI reading this section should be able to calibrate to
|
|
220
|
+
your style without you having to re-explain it.
|
|
221
|
+
|
|
222
|
+
Capture:
|
|
223
|
+
- Tone preferences (terse / verbose / formal / casual)
|
|
224
|
+
- Action signals ("go" = start immediately, etc.)
|
|
225
|
+
- Anti-patterns you've explicitly rejected
|
|
226
|
+
- Specific corrections that landed (quote them verbatim)
|
|
227
|
+
- What you're OK with the AI doing without asking
|
|
228
|
+
- What you want the AI to confirm first
|
|
229
|
+
|
|
230
|
+
For inspiration, see how claude-memory-kit's CLAUDE.md
|
|
231
|
+
captures this:
|
|
232
|
+
https://github.com/LH8PPL/claude-memory-kit/blob/main/CLAUDE.md
|
|
233
|
+
-->
|
|
234
|
+
|
|
235
|
+
### Tone
|
|
236
|
+
|
|
237
|
+
- [preference 1]
|
|
238
|
+
- [preference 2]
|
|
239
|
+
|
|
240
|
+
### Action signals
|
|
241
|
+
|
|
242
|
+
- "[your signal word]" = [meaning]
|
|
243
|
+
|
|
244
|
+
### Anti-patterns I've rejected
|
|
245
|
+
|
|
246
|
+
- **[pattern]** — *why*: [reason; ideally a quoted user correction]
|
|
247
|
+
|
|
248
|
+
### What the AI can do without asking
|
|
249
|
+
|
|
250
|
+
- [low-stakes action 1]
|
|
251
|
+
- [low-stakes action 2]
|
|
252
|
+
|
|
253
|
+
### What the AI should confirm first
|
|
254
|
+
|
|
255
|
+
- [high-stakes action 1 — git push, destructive ops, etc.]
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## 8. Conversation as raw material
|
|
260
|
+
|
|
261
|
+
<!--
|
|
262
|
+
The meta-thread: AI conversations don't persist by default.
|
|
263
|
+
If your context window rolls or you start a new session, you
|
|
264
|
+
lose everything that's only in conversation memory.
|
|
265
|
+
|
|
266
|
+
This file is the bridge. What you write here survives. What
|
|
267
|
+
you only said in chat doesn't.
|
|
268
|
+
|
|
269
|
+
When something important comes up in conversation that you'd
|
|
270
|
+
want a future-you (or future-AI) to know, the discipline is:
|
|
271
|
+
write it here. Don't trust the conversation buffer.
|
|
272
|
+
|
|
273
|
+
This applies to: design rationale, working-style corrections,
|
|
274
|
+
surprising findings, anti-patterns discovered, anything that
|
|
275
|
+
took more than a few turns to figure out.
|
|
276
|
+
-->
|
|
277
|
+
|
|
278
|
+
[Add observations as they emerge. This section grows the most
|
|
279
|
+
of any — it's the running notebook.]
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
**Last updated**: {{TODAY}}
|
|
284
|
+
|
|
285
|
+
<!--
|
|
286
|
+
==================================================================
|
|
287
|
+
End of journey-log scaffold.
|
|
288
|
+
|
|
289
|
+
When you've filled in enough that the comments feel like noise,
|
|
290
|
+
delete them. The file is yours.
|
|
291
|
+
==================================================================
|
|
292
|
+
-->
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<!-- Cap: 1500 chars · Last distilled: {{TODAY}} · Last health check: {{TODAY}} -->
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
machine-paths.md = absolute paths specific to THIS machine for THIS project.
|
|
5
|
+
Local tier (gitignored — never committed). Highest priority in the 3-tier
|
|
6
|
+
precedence model — overrides anything in context/ or ~/.claude-memory-kit/.
|
|
7
|
+
3 fixed sections per design §2.1.
|
|
8
|
+
|
|
9
|
+
Bullet+provenance format (universal — see provenance.mjs):
|
|
10
|
+
- (L-XXXXXXXX) the bullet text on one line
|
|
11
|
+
<!-- source, source_line, sha1, write, trust, at -->
|
|
12
|
+
|
|
13
|
+
Auto-populated by `cmk persona generate` (Task N, design §16.16); empty is fine.
|
|
14
|
+
-->
|
|
15
|
+
|
|
16
|
+
# Machine paths (local tier)
|
|
17
|
+
|
|
18
|
+
## Tool Paths
|
|
19
|
+
|
|
20
|
+
<!-- Tool/binary paths. -->
|
|
21
|
+
|
|
22
|
+
- (L-aVFaHNDV) (example) node binary at /usr/local/bin/node
|
|
23
|
+
<!-- source: machine-paths.md, source_line: 19, sha1: 0000000000000000000000000000000000000000, write: manual-edit, trust: medium, at: 2020-01-01T00:00:00Z -->
|
|
24
|
+
|
|
25
|
+
## Project Paths
|
|
26
|
+
|
|
27
|
+
<!-- Project-specific paths on this machine. -->
|
|
28
|
+
|
|
29
|
+
- (L-CDHEKGDa) (example) primary data directory at ~/.local/share/cmk
|
|
30
|
+
<!-- source: machine-paths.md, source_line: 26, sha1: 0000000000000000000000000000000000000000, write: manual-edit, trust: medium, at: 2020-01-01T00:00:00Z -->
|
|
31
|
+
|
|
32
|
+
## Misc Paths
|
|
33
|
+
|
|
34
|
+
<!-- Other path types. -->
|
|
35
|
+
|
|
36
|
+
- (L-KWLHFMRN) (example) cache root at ~/.cache/cmk
|
|
37
|
+
<!-- source: machine-paths.md, source_line: 33, sha1: 0000000000000000000000000000000000000000, write: manual-edit, trust: medium, at: 2020-01-01T00:00:00Z -->
|