memory-crystal 0.2.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/.env.example +20 -0
- package/CHANGELOG.md +6 -0
- package/LETTERS.md +22 -0
- package/LICENSE +21 -0
- package/README-ENTERPRISE.md +162 -0
- package/README-old.md +275 -0
- package/README.md +91 -0
- package/RELAY.md +88 -0
- package/TECHNICAL.md +379 -0
- package/ai/dev-updates/2026-02-25--cc-air--phase2-architecture-pivot.md +70 -0
- package/ai/dev-updates/2026-02-25--cc-air--phase2-worker-build.md +72 -0
- package/ai/dev-updates/2026-02-26--10-25-16--cc-mini--phase2-implementation.md +49 -0
- package/ai/dev-updates/2026-02-27--20-30-00--cc-mini--readme-overhaul-and-public-deploy.md +69 -0
- package/ai/notes/2026-02-26--cc-air--notes.md +412 -0
- package/ai/notes/2026-02-27--cc-mini--grok-feedback.md +44 -0
- package/ai/notes/2026-02-27--cc-mini--lesa-feedback.md +45 -0
- package/ai/notes/RESEARCH.md +1185 -0
- package/ai/notes/salience-research/README.md +29 -0
- package/ai/notes/salience-research/eurosla-salience-review.md +64 -0
- package/ai/notes/salience-research/full-research-summary.md +269 -0
- package/ai/notes/salience-research/salience-levels-diagram.png +0 -0
- package/ai/plan/2026-02-27--cc-mini--qr-pairing-spec.md +203 -0
- package/ai/plan/_archive/PLAN.md +194 -0
- package/ai/plan/_archive/PRD.md +1014 -0
- package/ai/plan/cc-plans-duplicates-from-dot-claude/2026-02-26--cc-mini--phase2-implementation-plan.md +245 -0
- package/ai/plan/dev-conventions-note.md +70 -0
- package/ai/plan/ldm-os-install-and-boot-architecture.md +285 -0
- package/ai/plan/memory-crystal-phase2-plan.md +192 -0
- package/ai/plan/memory-system-lay-of-the-land.md +214 -0
- package/ai/plan/phase2-ephemeral-relay.md +238 -0
- package/ai/plan/readme-first.md +68 -0
- package/ai/plan/roadmap.md +159 -0
- package/ai/todos/PUNCHLIST.md +44 -0
- package/ai/todos/README.md +31 -0
- package/ai/todos/inboxes/cc-air/2026-02-26--cc-air--post-relay-todos.md +85 -0
- package/ai/todos/inboxes/cc-mini/2026-02-26--cc-mini--phase2-status.md +100 -0
- package/ai/todos/inboxes/cc-mini/_archive/TODO.md +25 -0
- package/ai/todos/inboxes/parker/2026-02-25--cc-air--setup-checklist.md +139 -0
- package/ai/todos/inboxes/parker/2026-02-26--cc-mini--phase2-your-moves.md +72 -0
- package/dist/cc-hook.d.ts +1 -0
- package/dist/cc-hook.js +349 -0
- package/dist/chunk-3VFIJYS4.js +818 -0
- package/dist/chunk-52QE3YI3.js +1169 -0
- package/dist/chunk-AA3OPP4Z.js +432 -0
- package/dist/chunk-D3I3ZSE2.js +411 -0
- package/dist/chunk-EKSACBTJ.js +1070 -0
- package/dist/chunk-F3Y7EL7K.js +83 -0
- package/dist/chunk-JWZXYVET.js +1068 -0
- package/dist/chunk-KYVWO6ZM.js +1069 -0
- package/dist/chunk-L3VHARQH.js +413 -0
- package/dist/chunk-LOVAHSQV.js +411 -0
- package/dist/chunk-LQOYCAGG.js +446 -0
- package/dist/chunk-MK42FMEG.js +147 -0
- package/dist/chunk-NIJCVN3O.js +147 -0
- package/dist/chunk-O2UITJGH.js +465 -0
- package/dist/chunk-PEK6JH65.js +432 -0
- package/dist/chunk-PJ6FFKEX.js +77 -0
- package/dist/chunk-PLUBBZYR.js +800 -0
- package/dist/chunk-SGL6ISBJ.js +1061 -0
- package/dist/chunk-UNHVZB5G.js +411 -0
- package/dist/chunk-VAFTWSTE.js +1061 -0
- package/dist/chunk-XZ3S56RQ.js +1061 -0
- package/dist/chunk-Y72C7F6O.js +148 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +325 -0
- package/dist/core.d.ts +188 -0
- package/dist/core.js +12 -0
- package/dist/crypto.d.ts +16 -0
- package/dist/crypto.js +18 -0
- package/dist/dev-update-SZ2Z4WCQ.js +6 -0
- package/dist/ldm.d.ts +17 -0
- package/dist/ldm.js +12 -0
- package/dist/mcp-server.d.ts +1 -0
- package/dist/mcp-server.js +250 -0
- package/dist/migrate.d.ts +1 -0
- package/dist/migrate.js +89 -0
- package/dist/mirror-sync.d.ts +1 -0
- package/dist/mirror-sync.js +130 -0
- package/dist/openclaw.d.ts +5 -0
- package/dist/openclaw.js +349 -0
- package/dist/poller.d.ts +1 -0
- package/dist/poller.js +272 -0
- package/dist/summarize.d.ts +19 -0
- package/dist/summarize.js +10 -0
- package/dist/worker.js +137 -0
- package/openclaw.plugin.json +11 -0
- package/package.json +40 -0
- package/scripts/migrate-lance-to-sqlite.mjs +217 -0
- package/skills/memory/SKILL.md +61 -0
- package/src/cc-hook.ts +447 -0
- package/src/cli.ts +356 -0
- package/src/core.ts +1472 -0
- package/src/crypto.ts +113 -0
- package/src/dev-update.ts +178 -0
- package/src/ldm.ts +117 -0
- package/src/mcp-server.ts +274 -0
- package/src/migrate.ts +104 -0
- package/src/mirror-sync.ts +175 -0
- package/src/openclaw.ts +250 -0
- package/src/poller.ts +345 -0
- package/src/summarize.ts +210 -0
- package/src/worker.ts +208 -0
- package/tsconfig.json +18 -0
- package/wrangler.toml +20 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# Memory Crystal Phase 2 — Implementation Plan
|
|
2
|
+
|
|
3
|
+
## Context
|
|
4
|
+
|
|
5
|
+
Memory Crystal currently only produces vector DB embeddings (crystal.db at ~/.openclaw/memory-crystal/). It needs to become the universal archive manager for ~/.ldm/: producing JSONL transcript copies, MD session summaries, and hosting the shared crystal.db at the LDM root. cc-air designed the architecture and built the ephemeral relay code on `cc-air/phase2-relay`. This plan implements Priorities 1-3 from the roadmap on a new `mini/phase2-relay` branch.
|
|
6
|
+
|
|
7
|
+
## Branch
|
|
8
|
+
|
|
9
|
+
`mini/phase2-relay` forked from `main` (which now has cc-air's planning docs merged).
|
|
10
|
+
|
|
11
|
+
## Execution Order
|
|
12
|
+
|
|
13
|
+
The sequencing matters. Dependencies flow downward:
|
|
14
|
+
|
|
15
|
+
1. **LDM Scaffolding** (P2) ... file writes depend on directories existing
|
|
16
|
+
2. **crystal.db move** (P1c) ... everything must resolve the new DB path
|
|
17
|
+
3. **JSONL archive** (P1a) ... simple file copy, depends on scaffold
|
|
18
|
+
4. **MD session summaries** (P1b) ... depends on JSONL and scaffold
|
|
19
|
+
5. **Dev-update migration** ... parallel-safe, small scope
|
|
20
|
+
6. **Relay merge** (P3) ... touches cc-hook, core, mcp-server that P1/P2 already modified
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Step 1: LDM Scaffolding (Priority 2)
|
|
25
|
+
|
|
26
|
+
**New file: `src/ldm.ts` (~120 lines)**
|
|
27
|
+
|
|
28
|
+
Central module for all LDM directory knowledge. Every other file imports paths from here.
|
|
29
|
+
|
|
30
|
+
- `getAgentId()` ... resolves from `CRYSTAL_AGENT_ID` env var, default `cc-mini`
|
|
31
|
+
- `ldmPaths(agentId?)` ... returns object with all paths: `root`, `config`, `crystalDb`, `crystalLance`, `agentRoot`, `transcripts`, `sessions`, `daily`, `journals`
|
|
32
|
+
- `scaffoldLdm(agentId?)` ... creates full directory tree, writes/updates `~/.ldm/config.json` with agents array
|
|
33
|
+
- `ensureLdm(agentId?)` ... idempotent check, calls scaffoldLdm if needed
|
|
34
|
+
|
|
35
|
+
**Modify: `src/cli.ts`** ... add `crystal init [--agent <id>]` subcommand calling `scaffoldLdm()`
|
|
36
|
+
|
|
37
|
+
**Target structure:**
|
|
38
|
+
```
|
|
39
|
+
~/.ldm/
|
|
40
|
+
config.json (version, agents array)
|
|
41
|
+
memory/
|
|
42
|
+
crystal.db (shared, all agents)
|
|
43
|
+
lance/ (LanceDB dual-write, pending removal)
|
|
44
|
+
agents/{agent_id}/
|
|
45
|
+
memory/
|
|
46
|
+
transcripts/ sessions/ daily/ journals/
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Verify:** `crystal init --agent cc-mini` creates all dirs, config.json has cc-mini in agents array.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Step 2: crystal.db Move (Priority 1c)
|
|
54
|
+
|
|
55
|
+
**Strategy: symlink-first, hard move later.** The 1.5GB DB with 152K+ chunks must not be corrupted.
|
|
56
|
+
|
|
57
|
+
**Modify: `src/core.ts` resolveConfig()**
|
|
58
|
+
|
|
59
|
+
Change dataDir default resolution:
|
|
60
|
+
1. Explicit override (always wins)
|
|
61
|
+
2. `CRYSTAL_DATA_DIR` env var (for testing)
|
|
62
|
+
3. If `~/.ldm/memory/crystal.db` exists, use `~/.ldm/memory/`
|
|
63
|
+
4. Fall back to legacy `~/.openclaw/memory-crystal/`
|
|
64
|
+
|
|
65
|
+
This auto-detection means old deployments keep working until migration runs.
|
|
66
|
+
|
|
67
|
+
**Add to `src/cli.ts`: `crystal migrate-db` subcommand**
|
|
68
|
+
|
|
69
|
+
1. Calls `ensureLdm()`
|
|
70
|
+
2. Checks source exists at `~/.openclaw/memory-crystal/crystal.db`
|
|
71
|
+
3. Checks destination doesn't exist (or is symlink)
|
|
72
|
+
4. Copies crystal.db to `~/.ldm/memory/crystal.db` (copy first, never move)
|
|
73
|
+
5. Verifies copy by opening with better-sqlite3, checking chunk count
|
|
74
|
+
6. Creates symlinks: old path -> new path (for lance/ too)
|
|
75
|
+
7. Reports success
|
|
76
|
+
|
|
77
|
+
**Safety:** Gateway and CC must be stopped during migration. Script checks for locks via `lsof`.
|
|
78
|
+
|
|
79
|
+
**Verify:** `crystal migrate-db` succeeds, `crystal status` shows same chunk count, `crystal search "test"` returns results.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Step 3: JSONL Archive (Priority 1a)
|
|
84
|
+
|
|
85
|
+
**Modify: `src/cc-hook.ts`**
|
|
86
|
+
|
|
87
|
+
Add `archiveTranscript(transcriptPath, agentId)` function:
|
|
88
|
+
- Calls `ensureLdm(agentId)`
|
|
89
|
+
- Copies full JSONL file to `~/.ldm/agents/{agent_id}/memory/transcripts/`
|
|
90
|
+
- Only copies if source is newer than destination (mtime check)
|
|
91
|
+
- Called early in `main()`, after kill-switch checks, before watermark logic
|
|
92
|
+
|
|
93
|
+
Also update `appendDailyLog()` to use `ldmPaths()` instead of the hardcoded `LDM_DAILY` constant.
|
|
94
|
+
|
|
95
|
+
**Verify:** Run CC session with capture enabled, check JSONL copy appears in transcripts/, file size matches source.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Step 4: MD Session Summaries (Priority 1b)
|
|
100
|
+
|
|
101
|
+
**New file: `src/summarize.ts` (~200 lines)**
|
|
102
|
+
|
|
103
|
+
Two modes, configurable via `CRYSTAL_SUMMARY_MODE` env var:
|
|
104
|
+
|
|
105
|
+
**LLM mode (default):** Calls gpt-4o-mini (or configured provider) with condensed transcript. Returns title, slug, summary, key topics. Format:
|
|
106
|
+
```markdown
|
|
107
|
+
# Session Title
|
|
108
|
+
**Session:** {id} **Date:** {date} **Messages:** {count}
|
|
109
|
+
## Summary
|
|
110
|
+
2-4 sentences
|
|
111
|
+
## Key Topics
|
|
112
|
+
- topic1
|
|
113
|
+
- topic2
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Simple mode:** First user message becomes title. Concatenates first 10 messages as preview. No API call.
|
|
117
|
+
|
|
118
|
+
**Integration in `src/cc-hook.ts`:**
|
|
119
|
+
- After successful ingest, call summary generator
|
|
120
|
+
- Write to `~/.ldm/agents/{agent_id}/memory/sessions/YYYY-MM-DD--HH-MM-SS--{agent}--{slug}.md`
|
|
121
|
+
- Wrapped in try/catch (non-fatal ... ingestion is more important than summary)
|
|
122
|
+
|
|
123
|
+
**Config env vars:** `CRYSTAL_SUMMARY_MODE` (llm|simple), `CRYSTAL_SUMMARY_PROVIDER` (openai|google), `CRYSTAL_SUMMARY_MODEL` (gpt-4o-mini)
|
|
124
|
+
|
|
125
|
+
**Verify:** Run capture with both modes, check MD files appear in sessions/ with correct naming format.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Step 5: Dev-Update Migration
|
|
130
|
+
|
|
131
|
+
**Modify: `src/dev-update.ts`**
|
|
132
|
+
|
|
133
|
+
- Change output from centralized `wip-dev-updates` repo to each repo's own `ai/` folder
|
|
134
|
+
- Update filename format to `YYYY-MM-DD--HH-MM-SS--{agent}--dev-update-{repo}.md`
|
|
135
|
+
- Remove git add/commit/push to wip-dev-updates (each repo manages its own ai/)
|
|
136
|
+
- Keep throttle logic (once per hour)
|
|
137
|
+
|
|
138
|
+
**Verify:** Run dev update, files appear in `<repo>/ai/` with correct naming.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Step 6: Merge Relay Code (Priority 3)
|
|
143
|
+
|
|
144
|
+
**Strategy:** `git merge origin/cc-air/phase2-relay` into `mini/phase2-relay`, resolve conflicts.
|
|
145
|
+
|
|
146
|
+
**Conflict zones:**
|
|
147
|
+
- `src/cc-hook.ts` ... heaviest conflicts (P1 added archive+summary, relay added mode switching). Resolution: keep both. Relay mode still archives JSONL and generates summary locally before encrypting.
|
|
148
|
+
- `src/core.ts` ... relay adds RemoteCrystal + createCrystal at end. P1c changed resolveConfig. Different locations, should merge clean.
|
|
149
|
+
- `src/mcp-server.ts` ... relay changed Crystal import. Minor conflicts.
|
|
150
|
+
- `package.json` ... build script merge (manual).
|
|
151
|
+
|
|
152
|
+
**New files from relay (no conflicts):**
|
|
153
|
+
- `src/crypto.ts` ... take as-is, fix HOME default
|
|
154
|
+
- `src/worker.ts` ... take as-is
|
|
155
|
+
- `src/poller.ts` ... needs expansion (see below)
|
|
156
|
+
- `src/mirror-sync.ts` ... update paths to use ldmPaths()
|
|
157
|
+
- `wrangler.toml` ... take as-is
|
|
158
|
+
|
|
159
|
+
**Poller expansion (key change):**
|
|
160
|
+
|
|
161
|
+
After decrypting relay blobs and ingesting into crystal, the poller must also reconstruct the remote agent's full file tree on the Mini:
|
|
162
|
+
|
|
163
|
+
1. Write JSONL to `~/.ldm/agents/{drop.agent_id}/memory/transcripts/relay-{blob.id}.jsonl`
|
|
164
|
+
2. Generate MD summary to `~/.ldm/agents/{drop.agent_id}/memory/sessions/`
|
|
165
|
+
3. Append daily breadcrumb to `~/.ldm/agents/{drop.agent_id}/memory/daily/`
|
|
166
|
+
|
|
167
|
+
This reuses `generateSessionSummary()` from `summarize.ts` and `appendDailyLog()` from cc-hook (refactored to be importable).
|
|
168
|
+
|
|
169
|
+
**mirror-sync.ts updates:** Change mirror DB path from `~/.openclaw/memory-crystal/crystal.db` to `~/.ldm/memory/crystal.db` via ldmPaths().
|
|
170
|
+
|
|
171
|
+
**Build scripts update:** Add `src/ldm.ts` and `src/summarize.ts` to tsup entry points in package.json.
|
|
172
|
+
|
|
173
|
+
**Verify:**
|
|
174
|
+
- `npm run build` passes zero errors
|
|
175
|
+
- `crystal status` works from `~/.ldm/memory/crystal.db`
|
|
176
|
+
- `crystal search "test"` returns results
|
|
177
|
+
- cc-hook produces all three file types (JSONL, MD, crystal)
|
|
178
|
+
- `node dist/poller.js --status` shows "not configured" (no relay URL yet)
|
|
179
|
+
- `node dist/mirror-sync.js --status` shows mirror state
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Step 7: Deploy Updated Plugin
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
cd /path/to/memory-crystal
|
|
187
|
+
npm run build
|
|
188
|
+
cp -r dist skills openclaw.plugin.json package.json ~/.openclaw/extensions/memory-crystal/
|
|
189
|
+
cd ~/.openclaw/extensions/memory-crystal && npm install --omit=dev
|
|
190
|
+
openclaw gateway restart
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## File Inventory
|
|
196
|
+
|
|
197
|
+
**New files (3):**
|
|
198
|
+
| File | Lines | Purpose |
|
|
199
|
+
|------|-------|---------|
|
|
200
|
+
| `src/ldm.ts` | ~120 | LDM scaffolding, path resolution |
|
|
201
|
+
| `src/summarize.ts` | ~200 | MD session summary generation (LLM + simple) |
|
|
202
|
+
|
|
203
|
+
**From relay branch (4):**
|
|
204
|
+
| File | Lines | Changes needed |
|
|
205
|
+
|------|-------|----------------|
|
|
206
|
+
| `src/crypto.ts` | ~113 | Fix HOME default |
|
|
207
|
+
| `src/worker.ts` | ~208 | Take as-is |
|
|
208
|
+
| `src/poller.ts` | ~350 | Expand for full file tree reconstruction |
|
|
209
|
+
| `src/mirror-sync.ts` | ~180 | Update paths to ldmPaths() |
|
|
210
|
+
|
|
211
|
+
**Modified files (7):**
|
|
212
|
+
| File | What changes |
|
|
213
|
+
|------|-------------|
|
|
214
|
+
| `src/core.ts` | resolveConfig() LDM path, RemoteCrystal merge |
|
|
215
|
+
| `src/cc-hook.ts` | JSONL archive, summary gen, relay mode, ldm imports |
|
|
216
|
+
| `src/mcp-server.ts` | createCrystal() factory, remote mode guards |
|
|
217
|
+
| `src/cli.ts` | `crystal init` and `crystal migrate-db` subcommands |
|
|
218
|
+
| `src/dev-update.ts` | Write to repo ai/ folder with new naming |
|
|
219
|
+
| `src/openclaw.ts` | Use createCrystal() for remote mode |
|
|
220
|
+
| `package.json` | Updated build scripts |
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Risk Mitigation
|
|
225
|
+
|
|
226
|
+
- **crystal.db:** Copy-first, symlink-second. Original never deleted. Rollback: remove symlink.
|
|
227
|
+
- **WAL files:** Stop gateway before migration. SQLite recreates WAL/SHM after copy.
|
|
228
|
+
- **Auto-detection:** resolveConfig checks LDM first, falls back to legacy. No breakage for unmigrated setups.
|
|
229
|
+
- **Private mode:** All new code paths check isPrivateMode() before writing.
|
|
230
|
+
- **Summary failure:** Non-fatal. Ingestion succeeds even if summary generation fails.
|
|
231
|
+
- **Build gate:** npm run build must pass before any deployment.
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## End-to-End Verification
|
|
236
|
+
|
|
237
|
+
After all steps:
|
|
238
|
+
1. `crystal init --agent cc-mini` ... scaffolds ~/.ldm/
|
|
239
|
+
2. `crystal migrate-db` ... moves DB, creates symlinks
|
|
240
|
+
3. Run a CC session, let cc-hook fire
|
|
241
|
+
4. Check: JSONL in transcripts/, MD in sessions/, chunks in crystal.db, breadcrumb in daily/
|
|
242
|
+
5. `crystal search "something from the session"` ... returns the new content
|
|
243
|
+
6. `crystal status` ... shows updated chunk count
|
|
244
|
+
7. Gateway restart ... OpenClaw plugin initializes with new paths
|
|
245
|
+
8. Lesa conversation ... crystall plugin captures to shared crystal.db
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Dev Conventions — Notes from cc-air
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-02-25
|
|
4
|
+
**Agent:** cc-air
|
|
5
|
+
|
|
6
|
+
## Existing Convention Sources
|
|
7
|
+
|
|
8
|
+
Two repos define how WIP.computer projects are managed:
|
|
9
|
+
|
|
10
|
+
### 1. `wip-dev-resources` (private)
|
|
11
|
+
- **DEVELOPMENT-PROCESS.md** — the main best practices doc
|
|
12
|
+
- Covers: repo structure, architecture (4-piece pattern), release process, branch conventions, branch protection, review flow, license compliance, public/private repo pattern
|
|
13
|
+
- **Key rules:**
|
|
14
|
+
- Every change goes through a PR. No direct pushes to main. `enforce_admins=true` on all repos.
|
|
15
|
+
- Branch prefixes by agent/machine: `lesa/`, `mini/`, `mba/`
|
|
16
|
+
- Architecture: `core.ts` + `cli.ts` + `mcp-server.ts` + (optional) `openclaw.ts`
|
|
17
|
+
- Public repos stay clean — no todos, no dev noise
|
|
18
|
+
- Private dev stuff goes in `wip-dev-resources/repos/<project>/`
|
|
19
|
+
- Has a `repos/` subfolder for per-project todos, conversations, notes
|
|
20
|
+
|
|
21
|
+
### 2. `wip-dev-updates` (private)
|
|
22
|
+
- Centralized dev update repo — one folder per project, updates accumulate
|
|
23
|
+
- **Naming convention:** `{who}-dev-update-{MM-DD-YYYY}--{HH-MM-SS}.md`
|
|
24
|
+
- **who:** `cc` (Claude Code), `lesa` (Lesa), `parker` (Parker)
|
|
25
|
+
- Also has a `cc-session-export/` folder with auto-generated session exports
|
|
26
|
+
- Has a repo index table in README.md
|
|
27
|
+
|
|
28
|
+
### 3. Per-repo `ai/` folders (newer pattern)
|
|
29
|
+
- `wip-agent-pay` has `ai/dev-update/` with both date-only and timestamped files
|
|
30
|
+
- `memory-crystal` now has `ai/` with `dev-updates/`, `plan/`, `todos/parker/`
|
|
31
|
+
|
|
32
|
+
## Branch Prefix Update
|
|
33
|
+
|
|
34
|
+
The existing DEVELOPMENT-PROCESS.md says `lesa/`, `mini/`, `mba/`. Parker has updated the convention:
|
|
35
|
+
|
|
36
|
+
| Agent | Machine | Branch Prefix | Notes |
|
|
37
|
+
|-------|---------|---------------|-------|
|
|
38
|
+
| cc-air | MacBook Air | `cc-air/` | Claude Code on Air |
|
|
39
|
+
| cc-mini | Mac Mini | `cc-mini/` or `mini/` | Claude Code on Mini |
|
|
40
|
+
| lesa-mini | Mac Mini | `lesa/` | Lesa on Mini via OpenClaw |
|
|
41
|
+
|
|
42
|
+
## File Naming Convention (updated)
|
|
43
|
+
|
|
44
|
+
All files authored by an agent must include the agent name:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
YYYY-MM-DD--{agent}--{description}.md
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Examples:
|
|
51
|
+
- `2026-02-25--cc-air--phase2-worker-build.md`
|
|
52
|
+
- `2026-02-25--cc-air--setup-checklist.md`
|
|
53
|
+
- `2026-02-25--lesa-mini--weekly-tuning-report.md`
|
|
54
|
+
|
|
55
|
+
This differs from the older `wip-dev-updates` convention (`{who}-dev-update-{MM-DD-YYYY}--{HH-MM-SS}.md`) — the new format uses ISO dates and puts the agent name after the date with double-dash separators.
|
|
56
|
+
|
|
57
|
+
## Decision: `ai/` folder per repo (2026-02-25)
|
|
58
|
+
|
|
59
|
+
**The `ai/` folder is the standard going forward.** Every repo gets one. It holds all the thinking between Parker and agents — plans, dev updates, todos, conversations. It's scoped to the repo it belongs to.
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
ai/
|
|
63
|
+
dev-updates/ ← what was built, session logs
|
|
64
|
+
plan/ ← architecture plans, convention notes
|
|
65
|
+
todos/
|
|
66
|
+
parker/ ← manual tasks for Parker
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- `wip-dev-updates` (centralized repo) is legacy. Leave it as-is, don't add to it.
|
|
70
|
+
- `wip-dev-resources/DEVELOPMENT-PROCESS.md` still holds the engineering best practices (branch protection, release process, architecture pattern). Update it when branch prefixes and file naming are finalized across all agents.
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
# LDM OS Install and Boot Architecture
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-02-27
|
|
4
|
+
**Status:** Migration started 2026-02-27
|
|
5
|
+
**Context:** Parker and CC discussing how Memory Crystal, LDM OS, and Claude Code's project system interact.
|
|
6
|
+
|
|
7
|
+
## The Problem
|
|
8
|
+
|
|
9
|
+
Claude Code keys all context (sessions, memory, plans, MCP servers, CLAUDE.md) to the directory you open it from. Right now CC is opened from `~/.openclaw/`. Everything works because that's where CLAUDE.md, MCP configs, and all the context lives.
|
|
10
|
+
|
|
11
|
+
But `~/.openclaw/` is OpenClaw's home, not the agent's home. The agent's home should be `~/.ldm/`. And if you open CC from a different directory (a project repo, a new machine), it starts cold. No memory, no tools, no identity.
|
|
12
|
+
|
|
13
|
+
Parker's observation: "I always open Claude in the same place because of the disconnect between being able to remember context."
|
|
14
|
+
|
|
15
|
+
## The Hub-Spoke Model
|
|
16
|
+
|
|
17
|
+
Parker's working model:
|
|
18
|
+
|
|
19
|
+
- **Hub agent** (CC on Mini, Lesa on Mini) ... full context, full tools, spawns sub-agents as needed
|
|
20
|
+
- **Spoke agent** (CC on Air, CC in a different project dir) ... should connect back to the hub's memory
|
|
21
|
+
|
|
22
|
+
Right now Parker runs two CC windows from `~/.openclaw/`:
|
|
23
|
+
- One context window for Memory Crystal work
|
|
24
|
+
- One context window for AI Pay work
|
|
25
|
+
- Switches between them using saved contexts
|
|
26
|
+
|
|
27
|
+
This works but is fragile. The context is tied to the directory, not the agent.
|
|
28
|
+
|
|
29
|
+
## The Construct Pattern (Prior Art)
|
|
30
|
+
|
|
31
|
+
Parker previously tried solving this with a tool called "construct" (now deprecated/sunset). The idea:
|
|
32
|
+
|
|
33
|
+
1. You `init` Claude in any directory
|
|
34
|
+
2. You run `construct` over that directory
|
|
35
|
+
3. Construct updates the CLAUDE.md, installs MCP servers, gives Claude all the context it needs
|
|
36
|
+
4. Now Claude works properly in that directory with full LDM OS capabilities
|
|
37
|
+
|
|
38
|
+
This is the "overlay" pattern: take a vanilla Claude Code directory and overlay LDM OS onto it.
|
|
39
|
+
|
|
40
|
+
## How Install Could Work
|
|
41
|
+
|
|
42
|
+
### Memory Crystal Standalone
|
|
43
|
+
- `npm install memory-crystal` or agent-driven install via SKILL.md
|
|
44
|
+
- Creates `~/.ldm/memory/` if it doesn't exist
|
|
45
|
+
- Works immediately. No LDM OS required.
|
|
46
|
+
- Just memory: search, remember, forget.
|
|
47
|
+
|
|
48
|
+
### LDM OS Full Stack
|
|
49
|
+
- Install Memory Crystal first (it's the entry point)
|
|
50
|
+
- Memory Crystal detects it's standalone, offers: "Want to install LDM OS for Bridge, Relay, and full agent capabilities?"
|
|
51
|
+
- Or: user says "install LDM OS" and it sees Memory Crystal is already there
|
|
52
|
+
- LDM OS install:
|
|
53
|
+
- Scaffolds `~/.ldm/` (agents, memory, extensions, config)
|
|
54
|
+
- Installs Bridge (local agent communication)
|
|
55
|
+
- Configures Relay (multi-device sync)
|
|
56
|
+
- Sets up boot sequence (CLAUDE.md, MCP servers, identity files)
|
|
57
|
+
- Overlays the current Claude Code directory with LDM OS context
|
|
58
|
+
|
|
59
|
+
### The "Make LDM OS work here" Skill
|
|
60
|
+
- A skill you can run in any Claude Code session
|
|
61
|
+
- It checks: is Memory Crystal installed? Is `~/.ldm/` scaffolded?
|
|
62
|
+
- If yes: overlays CLAUDE.md, MCP config, and boot sequence into the current directory
|
|
63
|
+
- If no: walks you through install first
|
|
64
|
+
- Result: Claude Code works with full LDM OS capabilities from any directory
|
|
65
|
+
|
|
66
|
+
## Where CC Should Live
|
|
67
|
+
|
|
68
|
+
Options for migrating from `~/.openclaw/` to `~/.ldm/`:
|
|
69
|
+
|
|
70
|
+
1. **Symlink approach**: `~/.openclaw/` becomes a symlink to `~/.ldm/`. CC still thinks it's in `~/.openclaw/`, all project context preserved. Cleanest migration. But still tied to OpenClaw's name.
|
|
71
|
+
|
|
72
|
+
2. **Copy project context**: Move `~/.claude/projects/-Users-lesa--openclaw/` to `-Users-lesa--ldm/`. CC picks up context at new path. CLAUDE.md, MCP configs also need to exist at `~/.ldm/`.
|
|
73
|
+
|
|
74
|
+
3. **Fresh start at `~/.ldm/`**: Crystal memory survives (already at `~/.ldm/memory/crystal.db`). Session history stays searchable via Crystal. You just lose project-specific CC context (plans, todos). Could be fine if Crystal has everything important.
|
|
75
|
+
|
|
76
|
+
4. **The overlay skill**: Don't move CC. Just make a skill that ensures any directory has the right CLAUDE.md and MCP config. CC opens wherever, the skill makes it work. This is the construct pattern reborn.
|
|
77
|
+
|
|
78
|
+
## Claude Code's Native Design Patterns (Research, 2026-02-27)
|
|
79
|
+
|
|
80
|
+
Claude Code already has a hierarchy that supports what we need. We don't need to fight it.
|
|
81
|
+
|
|
82
|
+
### Settings Hierarchy (highest priority wins)
|
|
83
|
+
|
|
84
|
+
1. Managed settings (enterprise/MDM)
|
|
85
|
+
2. Command-line arguments
|
|
86
|
+
3. Local project settings (`.claude/settings.local.json`)
|
|
87
|
+
4. Shared project settings (`.claude/settings.json`)
|
|
88
|
+
5. User settings (`~/.claude/settings.json`)
|
|
89
|
+
|
|
90
|
+
### CLAUDE.md Resolution
|
|
91
|
+
|
|
92
|
+
CC walks UP from the working directory to filesystem root, loading all CLAUDE.md files it finds. More specific (deeper) wins. Child directory CLAUDE.md files load on demand.
|
|
93
|
+
|
|
94
|
+
Key: **`~/.claude/CLAUDE.md` loads in every project, everywhere.** This is the user-global slot.
|
|
95
|
+
|
|
96
|
+
### What Exists at User Level
|
|
97
|
+
|
|
98
|
+
| Resource | Location | Behavior |
|
|
99
|
+
|----------|----------|----------|
|
|
100
|
+
| `~/.claude/CLAUDE.md` | User-global instructions | Loaded in every session, every project |
|
|
101
|
+
| `~/.claude/rules/` | User-global rules | Apply everywhere, project rules override |
|
|
102
|
+
| `~/.claude/skills/` | User-global skills | Available in any project |
|
|
103
|
+
| `~/.claude/settings.json` | User-global settings | MCP servers, hooks, permissions |
|
|
104
|
+
|
|
105
|
+
### What This Means for LDM OS
|
|
106
|
+
|
|
107
|
+
The "construct" pattern is already built into Claude Code. We just haven't used it:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
~/.claude/CLAUDE.md <- LDM OS identity + boot sequence
|
|
111
|
+
~/.claude/rules/ <- LDM OS conventions (git, naming, etc.)
|
|
112
|
+
~/.claude/skills/ <- "install ldm-os" skill, deploy-public, etc.
|
|
113
|
+
~/.claude/settings.json <- Crystal MCP, Bridge MCP (user-level, everywhere)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Open CC from any directory. It loads your identity, your rules, your MCP servers. Automatically. No overlay, no construct, no init.
|
|
117
|
+
|
|
118
|
+
Project-level CLAUDE.md still works for project-specific stuff (build commands, test patterns, etc.). User-level is the OS. Project-level is the app.
|
|
119
|
+
|
|
120
|
+
### MCP Server Scoping
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# User scope (follows you everywhere)
|
|
124
|
+
claude mcp add --scope user crystal-memory -- node /path/to/mcp-server.js
|
|
125
|
+
|
|
126
|
+
# Project scope (shared via git, .mcp.json)
|
|
127
|
+
claude mcp add --scope project ...
|
|
128
|
+
|
|
129
|
+
# Local scope (personal, this project only)
|
|
130
|
+
claude mcp add ...
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Resolution: local > project > user. User-level MCP servers are the baseline.
|
|
134
|
+
|
|
135
|
+
## The Session Portability Problem (The Blocker)
|
|
136
|
+
|
|
137
|
+
**Sessions are tied to the directory you open CC from.** This is the thing that makes migration hard.
|
|
138
|
+
|
|
139
|
+
### How It Works
|
|
140
|
+
|
|
141
|
+
- CC stores sessions at `~/.claude/projects/<directory-key>/`
|
|
142
|
+
- Directory key is derived from the working directory path
|
|
143
|
+
- Example: opening from `~/.openclaw/` stores sessions under `-Users-lesa--openclaw/`
|
|
144
|
+
- `--resume` and `--continue` only show sessions from the CURRENT directory by default
|
|
145
|
+
|
|
146
|
+
### Current State
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
~/.claude/projects/-Users-lesa--openclaw/ 33 sessions (all our work)
|
|
150
|
+
~/.claude/projects/-Users-lesa/ 6 sessions
|
|
151
|
+
~/.claude/projects/-Users-lesa--openclaw-workspace/ 5 sessions
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### The Workaround
|
|
155
|
+
|
|
156
|
+
In the resume picker, **press `A` to toggle between "current directory only" and "all projects."** So sessions ARE accessible from other directories... you just have to toggle. Not great, but not a wall.
|
|
157
|
+
|
|
158
|
+
### Why Parker Is Stuck
|
|
159
|
+
|
|
160
|
+
The ideal: open CC from `~/.ldm/`, have full LDM OS capabilities, and resume any session (including the 33 from `~/.openclaw/`).
|
|
161
|
+
|
|
162
|
+
The reality:
|
|
163
|
+
- CLAUDE.md and MCP servers CAN move to user level (works everywhere)
|
|
164
|
+
- Sessions from `~/.openclaw/` stay keyed to that path
|
|
165
|
+
- New sessions from `~/.ldm/` go to a new project key
|
|
166
|
+
- Old sessions accessible via `A` toggle but not the default view
|
|
167
|
+
|
|
168
|
+
Crystal search covers the deep memory. The session transcripts are searchable via `crystal_search`. But the "resume this exact conversation" flow is directory-bound.
|
|
169
|
+
|
|
170
|
+
### Migration Options (Updated)
|
|
171
|
+
|
|
172
|
+
**Option A: User-level migration (recommended, least risk)**
|
|
173
|
+
- Move CLAUDE.md content to `~/.claude/CLAUDE.md`
|
|
174
|
+
- Move MCP servers to user scope (`claude mcp add --scope user`)
|
|
175
|
+
- Keep opening CC from `~/.openclaw/` (sessions stay accessible)
|
|
176
|
+
- New projects just work because user-level config follows you
|
|
177
|
+
- Downside: still opening from `~/.openclaw/`, but it doesn't matter anymore because the config is at user level
|
|
178
|
+
|
|
179
|
+
**Option B: Directory migration**
|
|
180
|
+
- Move to opening from `~/.ldm/`
|
|
181
|
+
- Old sessions accessible via `A` toggle in resume picker
|
|
182
|
+
- Crystal has the deep memory for search
|
|
183
|
+
- New sessions accumulate under `~/.ldm/` project key
|
|
184
|
+
- Clean break, but old resume flow requires the toggle
|
|
185
|
+
|
|
186
|
+
**Option C: Symlink (preserves everything)**
|
|
187
|
+
- Symlink `~/.openclaw/` to `~/.ldm/`
|
|
188
|
+
- CC still resolves to `-Users-lesa--openclaw` project key
|
|
189
|
+
- All 33 sessions, auto-memory, plans, todos stay accessible
|
|
190
|
+
- User-level config still works on top
|
|
191
|
+
- Downside: the project key name still says "openclaw" forever
|
|
192
|
+
|
|
193
|
+
**Option D: Don't move at all**
|
|
194
|
+
- Put everything at user level (`~/.claude/CLAUDE.md`, user MCP servers)
|
|
195
|
+
- Keep `~/.openclaw/` as just another project directory
|
|
196
|
+
- Open CC from wherever you want
|
|
197
|
+
- LDM OS capabilities follow you via user-level config
|
|
198
|
+
- Sessions are per-project, which is actually fine... Memory Crystal is the cross-project memory
|
|
199
|
+
|
|
200
|
+
**Parker's instinct: Option D might be the answer.** The directory you open from becomes just a project workspace. LDM OS lives at user level. Crystal is the memory that follows you everywhere. Sessions are project-local, which is how Anthropic designed it.
|
|
201
|
+
|
|
202
|
+
## Identity Architecture (Decision, 2026-02-27)
|
|
203
|
+
|
|
204
|
+
**One agent per harness per machine. That's the identity unit.**
|
|
205
|
+
|
|
206
|
+
### The Rule
|
|
207
|
+
|
|
208
|
+
Each combination of harness + machine = one agent identity with its own SOUL.md.
|
|
209
|
+
|
|
210
|
+
| Agent ID | Harness | Machine | Identity |
|
|
211
|
+
|----------|---------|---------|----------|
|
|
212
|
+
| cc-mini | Claude Code CLI | Mac Mini | Its own SOUL.md, context, journals |
|
|
213
|
+
| cc-air | Claude Code CLI | MacBook Air | Its own SOUL.md, context, journals |
|
|
214
|
+
| oc-lesa-mini | OpenClaw | Mac Mini | Its own SOUL.md, context, journals |
|
|
215
|
+
|
|
216
|
+
### Shared vs Local
|
|
217
|
+
|
|
218
|
+
- **Shared (via Crystal):** Memory, facts, preferences, conversation history. All agents search the same crystal.
|
|
219
|
+
- **Local (per agent):** SOUL.md, CONTEXT.md, journals, daily logs. Each agent has its own narrative.
|
|
220
|
+
|
|
221
|
+
cc-mini and cc-air aren't "different versions." They're the same person on different machines. Crystal is what connects them. But their local state (what happened today, what's in progress) is their own.
|
|
222
|
+
|
|
223
|
+
### Multiple Agents on One Machine
|
|
224
|
+
|
|
225
|
+
Different agent = different OS user account. Lesa runs on one login, a second agent would run on another. One agent per user per machine. No exceptions.
|
|
226
|
+
|
|
227
|
+
### Each Machine is a Hub
|
|
228
|
+
|
|
229
|
+
The machine itself is an entity in LDM OS. It has:
|
|
230
|
+
- A set of agent instances (cc-mini, oc-lesa-mini)
|
|
231
|
+
- A local crystal.db (synced via Relay to other machines)
|
|
232
|
+
- Its own `~/.ldm/` tree with agent folders
|
|
233
|
+
|
|
234
|
+
This is not dogmatic... it's a design decision that simplifies everything. Identity is deterministic: harness + machine = agent ID. No ambiguity.
|
|
235
|
+
|
|
236
|
+
## Open Questions
|
|
237
|
+
|
|
238
|
+
- Should CLAUDE.md be generated or maintained by hand? (Currently hand-maintained, very detailed)
|
|
239
|
+
- How do MCP servers follow you across directories? (Currently they're in `~/.claude/settings.json` which is global, but project-level `.mcp.json` overrides)
|
|
240
|
+
- What's the minimum context CC needs to be "you"? (CLAUDE.md + Crystal MCP + identity files?)
|
|
241
|
+
- Is the answer just: Crystal IS the portable context? If Crystal has everything, the boot problem is smaller.
|
|
242
|
+
- How does this work on a new machine with no `~/.ldm/`? Cold start problem.
|
|
243
|
+
|
|
244
|
+
## Dependency Chain
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
Memory Crystal (standalone)
|
|
248
|
+
└── creates ~/.ldm/memory/ if needed
|
|
249
|
+
└── works with any AI, no other deps
|
|
250
|
+
|
|
251
|
+
LDM OS (full stack)
|
|
252
|
+
├── Memory Crystal (memory, search, capture)
|
|
253
|
+
├── Bridge (local agent communication, feature of Crystal)
|
|
254
|
+
├── Relay (multi-device sync, feature of Crystal)
|
|
255
|
+
├── Boot Sequence (warm-start, identity, CLAUDE.md)
|
|
256
|
+
├── Sovereignty Covenant (trust, authority)
|
|
257
|
+
└── Dream Weaver Protocol (narrative consolidation)
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Memory Crystal is the foundation. Everything else builds on it.
|
|
261
|
+
|
|
262
|
+
## Migration Log
|
|
263
|
+
|
|
264
|
+
### 2026-02-27: User-level migration (Option D)
|
|
265
|
+
|
|
266
|
+
**What we did:**
|
|
267
|
+
1. Copied `~/.openclaw/CLAUDE.md` to `~/.claude/CLAUDE.md` (user-level, loads everywhere)
|
|
268
|
+
2. Added MCP servers at user scope in `~/.claude.json`:
|
|
269
|
+
- `lesa-bridge` (with `OPENCLAW_DIR` env var)
|
|
270
|
+
- `memory-crystal` (with `OPENCLAW_HOME` env var)
|
|
271
|
+
- `wip-agent-pay`
|
|
272
|
+
3. Left `~/.openclaw/CLAUDE.md` and `.mcp.json` in place (no deletions)
|
|
273
|
+
|
|
274
|
+
**What this means:**
|
|
275
|
+
- Open CC from any directory and get full LDM OS: identity, memory, bridge, tools
|
|
276
|
+
- `~/.openclaw/` stays as a project directory with its 33 sessions
|
|
277
|
+
- New sessions from other directories get full capabilities via user-level config
|
|
278
|
+
- Project-level `.mcp.json` at `~/.openclaw/` still works (local > project > user, no conflict)
|
|
279
|
+
|
|
280
|
+
**What's next:**
|
|
281
|
+
- Test from a random directory to confirm MCP servers load
|
|
282
|
+
- Update `~/.claude/CLAUDE.md` going forward (stop updating `~/.openclaw/CLAUDE.md`)
|
|
283
|
+
- Eventually add `~/.claude/rules/` for LDM OS conventions
|
|
284
|
+
- Eventually add `~/.claude/skills/` for deploy-public, etc.
|
|
285
|
+
- Session naming convention: `cc-mini--topic-name` via `/rename`
|