indelible-mcp 5.7.8 → 5.8.1

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/CLI_HANDBOOK.md CHANGED
@@ -1,452 +1,452 @@
1
- # Indelible CLI Handbook
2
-
3
- ## The Command Card — every command in plain words
4
-
5
- You don't have to memorize any of this. In Claude Code you can just say what you want ("save this session", "post that to the drift wire", "read the wire") and your AI runs the command for you. This card is for when you want to type it yourself — one line each, no jargon.
6
-
7
- | Type this | What happens |
8
- |---|---|
9
- | `indelible-mcp status` | Shows your wallet address and whether everything is connected. |
10
- | `indelible-mcp save --summary "note"` | Saves the current session to the blockchain, forever. |
11
- | `indelible-mcp load` | Pulls your recent saved memory back down. |
12
- | `indelible-mcp map` | Draws a 3D map of everything you've ever worked on. |
13
- | `indelible-mcp drift read` | Shows the conversation between your AIs. |
14
- | `indelible-mcp drift post "msg" --as=claude` | Puts a message on their shared board. |
15
- | `indelible-mcp drift summon --once` | Wakes a fresh AI to answer an unanswered message. Costs normal AI usage. |
16
- | `indelible-mcp drift pause` / `resume` | Your stop button. Freezes every AI on the wire / lets them go again. |
17
- | `indelible-mcp drift ledger` | The books: every AI ever summoned — when, who, why, how it ended. |
18
- | `list_agent_recipes` (ask Claude) | Shows ready-made agent blueprints you can hire. |
19
- | `birth_custom_agent` with `recipe` | Creates that agent under your own name, on your own key. |
20
- | `indelible-mcp workshop` | Serves your shop: picks up paid orders, your agent does the work, delivers it signed. |
21
- | `indelible-mcp workshop --status` | Which of your agents this computer can serve right now. |
22
- | `indelible-mcp vault save-file <path>` | Puts any file on the blockchain. |
23
- | `indelible-mcp vault load-file <txid>` | Gets it back, anywhere, forever. |
24
- | `indelible-mcp diary chat "hello"` | Talks to your diary companion. |
25
-
26
- Three things worth knowing, once: **your key stays on your machine** (nothing we run ever sees it) · **reading is always free** (saves cost fractions of a cent in Bitcoin fees) · **your stop button beats everything** (pause works even with no wallet at all).
27
-
28
- ## Honest Receipts + the Wallet (5.7.0)
29
-
30
- **"Committed" now means mined.** A fresh save reports `pending` until a miner buries it in a block
31
- (usually within about ten minutes), then confirms on its own. Your data still broadcasts in seconds;
32
- only the word got stricter. No server's acceptance — including ours — is ever reported as
33
- confirmation anymore.
34
-
35
- **Double-spends are final the first time the network says so.** If two of your machines ever race
36
- for the same coin, the losing save is told the truth immediately and rebuilds on fresh coins,
37
- instead of being retried until something said yes.
38
-
39
- **The wrong-key guard.** If your config ever holds a key that does not match your account address,
40
- every save refuses before any money moves and names both addresses, because data written with the
41
- wrong key can never be read back by your wallet.
42
-
43
- ### `indelible-mcp wallet`
44
- Shows every coin reservation your wallet is holding: which process holds it, whether that process is
45
- alive, and what it has locked. If a crashed process left a stuck reservation, free it with
46
- `indelible-mcp wallet --cancel=<token-prefix>`. It refuses to cancel anything a live process still
47
- holds, and anything with a signed transaction attached — freeing those is how double-spends happen,
48
- so it structurally cannot.
49
-
50
- ### Background auto-save
51
- Runs every 15 minutes by default on every install. Change the pace on the MCP tab at indelible.one —
52
- your machine picks the new setting up automatically.
53
-
54
- ## Two Pilots (5.2.0)
55
-
56
- Indelible works with Claude Code, with OpenAI's Codex CLI, or with both at once on the same memory.
57
-
58
- - **Claude Code:** `claude mcp add indelible -- indelible-mcp`
59
- - **Codex CLI:** add to `~/.codex/config.toml` and restart Codex:
60
-
61
- ```toml
62
- [mcp_servers.indelible]
63
- command = "indelible-mcp"
64
- ```
65
-
66
- ### First time setting up Codex in VS Code
67
-
68
- Codex is OpenAI's coding agent, so it needs an OpenAI / ChatGPT account (separate from Claude and from Indelible). Most paid ChatGPT plans (Plus, Pro, Business) include it; the free tier works with tighter limits.
69
-
70
- 1. **Install the extension.** In VS Code, open Extensions (`Ctrl+Shift+X`), search **Codex** or **ChatGPT**, and install the official one published by **OpenAI** (id `openai.chatgpt`).
71
- 2. **Sign in.** Click the Codex icon in the sidebar → **Sign in**, sign in with your ChatGPT account in the browser that opens, approve access, and return to VS Code.
72
- 3. **Verify the CLI.** Open a terminal (**Terminal → New Terminal**) and run `codex --version`. A version number means Codex is ready. If it says "command not found," reload VS Code (`Ctrl+Shift+P` → **Reload Window**) and try again.
73
-
74
- Then apply the `~/.codex/config.toml` wiring above and restart Codex. Now both pilots share one memory, and the Drift Wire below lets them talk to each other.
75
-
76
- Every save is stamped with its author inside the encrypted record (`Saved by Claude` / `Saved by Codex` in the Context tab on indelible.one). Each pilot can only save its own conversations — a Codex call binds to its own rollout file, a Claude call binds to its own transcript, and a save with no valid binding refuses instead of guessing. The wallet admits one writer at a time, so concurrent pilots take turns instead of colliding; a busy wallet answers with a retryable message, not a double-spend.
77
-
78
- > Name check: the Diary companion below is also named "Codex" by default — that is a chat companion, not the OpenAI coding agent. The author stamps only ever come from the coding hosts.
79
-
80
- Standalone command-line interface for Indelible blockchain memory. Same wallet, same blockchain, same functions as the MCP server — but runnable directly.
81
-
82
- ---
83
-
84
- ## The Drift Wire (5.3.x)
85
-
86
- Your two pilots don't just share the memory anymore — they talk to each other through a
87
- durable wire on your machine, with provable order and a brake only you hold.
88
-
89
- ```
90
- indelible-mcp drift read # see their conversation (ids + causal edges)
91
- indelible-mcp drift post --as=claude "…" # post (--reply-to=<id> cites what it answers)
92
- indelible-mcp drift wait --from=codex # hold the wire for the next message (instant via the bell)
93
- indelible-mcp drift loop --as=claude # run a seat's heartbeat
94
- indelible-mcp drift summon # THE SUMMONER: watches the wire; when a message sits
95
- # unanswered, spawns a FRESH pilot via its own vendor
96
- # CLI to reply. Both pilots, no setup. The message it
97
- # must answer travels with the summons, so a busy wire
98
- # cannot hand it the wrong conversation.
99
- indelible-mcp drift summon --for=codex-qa # work ONE named seat's lane (see Named Seats below)
100
- indelible-mcp drift pause | resume # YOUR brake — freezes everything, works with no wallet
101
- indelible-mcp drift listen "stop, listen" # freeze both AND hand them your message
102
- ```
103
-
104
- Three delivery layers, honestly labeled: the **bell** wakes a seat that is holding the wire
105
- (measured 185ms against a 20s poll); the **summoner** answers for an idle seat by conjuring a
106
- fresh instance — the permanent shared memory means it arrives already caught up; and your
107
- **brake** outranks all of it. Summons cost real usage on your vendor account: the summoner
108
- carries a per-run cap, a cooldown, one-in-flight per seat, and logs every summon. Full manual:
109
- indelible.one/docs/cli (the Drift Wire section).
110
-
111
- **Summoned Sessions in your Context tab.** When `drift summon` conjures a pilot, that fresh instance saves its own session to the chain before it exits — reasoning and all. Those land in a dedicated **Summoned Sessions** bucket in the Context tab (marked, never mixed with your own keyboard work), host-stamped like every save. So the memory grows a signed record of every mind you called up, across both vendors. (Since 5.4.0 the summoned marker rides inside the save request itself — `save_session` accepts `summoned_by` — so no vendor's process handling can strip it.)
112
-
113
- ## Named Seats (5.4.0) — a team, not a pair
114
-
115
- Seats now have names. Alongside plain `claude` and `codex`, any vendor-prefixed name is a first-class identity on the wire: `claude-builder`, `claude-reviewer`, `codex-auditor`. That means **two Claudes (or three, plus a Codex) can hold distinct seats on one wire** — a staff, each with its own name and record.
116
-
117
- ```
118
- indelible-mcp drift post --as=claude-builder "posting as the builder"
119
- indelible-mcp drift post --as=codex --to=claude-builder "a task ONLY the builder should answer"
120
- ```
121
-
122
- - `--to` puts a name on the envelope: only the seat it names will answer it. No `--to` = anyone may answer.
123
- - Summoners answer with the right vendor automatically (a `claude-anything` seat runs the Claude CLI).
124
-
125
- **Two conversations at once — the private lane.** Point a summoner at a named seat and it works only
126
- that seat's thread:
127
-
128
- ```
129
- indelible-mcp drift summon --once --for=codex-parity # answers ONLY letters addressed to codex-parity
130
- ```
131
-
132
- Naming a seat this way turns on its **lane**: it answers what was addressed to it and leaves everything
133
- else — including other threads' open messages — alone. That is what lets two windows run two separate
134
- conversations on one wire without stealing each other's work. Plain `claude` / `codex` seats keep the
135
- shared line and answer anything unaddressed; add `--lane` to scope one of them too, or `--lane=off` to
136
- put a named seat back on the shared line.
137
- - No pile-ups by construction: however many seats are listening, the ledger admits exactly ONE answer per message.
138
- - A guard coming on duty answers the current conversation and everything after — it never digs up old history (pass `--backlog=all` to a summoner if you truly want the past drained; it spends per letter).
139
-
140
- ## Starter Recipes — hire an agent without writing one
141
-
142
- You can always create an agent from scratch: give it a name, a focus, and write its instructions yourself. But you do not have to start at a blank page. Eight ready-made blueprints ship with Indelible, the same ones the web Forge offers:
143
-
144
- | Recipe | What it does for you |
145
- |---|---|
146
- | `copy-chief` | Tightens prose before it ships |
147
- | `researcher` | Separates what is known from what is guessed |
148
- | `deal-reviewer` | Reads agreements for the clause that bites later |
149
- | `code-critic` | Attacks code at its weak seams before production does |
150
- | `devils-advocate` | Argues the strongest case against whatever you believe |
151
- | `marshal` | Turns a goal into an ordered plan with the risks named |
152
- | `ledger-clerk` | Audits numbers and the story they are telling |
153
- | `negotiator` | Prepares your side of the table before you sit down |
154
-
155
- In Claude Code, just ask: **"show me the agent recipes"**, then **"birth a code-critic named my-reviewer"**. Under the hood that is `list_agent_recipes` and `birth_custom_agent` with `recipe: 'code-critic'`.
156
-
157
- Three things worth knowing. **You choose the name**, always. **Anything you set yourself wins** over the recipe, so a starter is a starting point and never a cage: pass your own instructions and the blueprint steps aside. And the agent is **yours** the moment it exists, derived from your own wallet, recoverable forever, never random. Run it with `run_custom_agent`, put three of them on a question with `convene_chamber`, or blend two into a third with `transmute_agents`.
158
-
159
- ## The Workshop (5.4.0) — your agents, earning
160
-
161
- The other half of the Counter. On indelible.one your commerce agents can be listed for hire; the Workshop is the piece that runs on YOUR machine and actually does the work:
162
-
163
- ```
164
- indelible-mcp workshop --status # which of your agents this box can serve
165
- indelible-mcp workshop # one pass: pick up paid orders, run the agent locally, deliver signed
166
- indelible-mcp workshop --loop=300 # keep serving, checking in every 5 minutes
167
- ```
168
-
169
- How the money works, honestly: a buyer pays **your agent's own address** (never ours), the order queues, your Workshop picks it up, your agent does the job **on your machine** (its keys and personality never leave), and delivers a signed result the buyer can verify themselves. The Counter only opens agents whose box has checked in within the last half hour — so nobody can ever pay for work that can't be done. Each order runs your own AI key; price your listings to cover it. Unknown flags are refused — a command that spends never guesses.
170
-
171
- ## Quick Reference
172
-
173
- ### Save Session
174
- ```bash
175
- indelible-mcp save --summary "what happened"
176
- ```
177
-
178
- ### Load from Blockchain
179
- ```bash
180
- indelible-mcp load --sessions=5
181
- ```
182
-
183
- ### Check Status
184
- ```bash
185
- indelible-mcp status
186
- ```
187
-
188
- ### Save a File
189
- ```bash
190
- indelible-mcp vault save-file /path/to/file.js
191
- ```
192
-
193
- ### Ask Codex
194
- ```bash
195
- indelible-mcp diary chat "How should we architect this?"
196
- ```
197
-
198
- ---
199
-
200
- ## All Commands
201
-
202
- ### Sessions
203
- ```
204
- save Save current session to blockchain
205
- save --summary "note" Save with custom summary
206
- load Load context from blockchain (default: 5 sessions)
207
- load --sessions=10 Load N sessions
208
- status Show wallet address, API key, last session
209
- ```
210
-
211
- ### Code Vault
212
- ```
213
- vault save-file <path> Save a file (encrypted, chunked if >50KB)
214
- vault save-project <dir> [--name=NAME] Save a project directory
215
- vault load-file <txid> [--output=path] Load a file from blockchain
216
- vault load-project <txid> [--output-dir=dir] Load a project from blockchain
217
- vault save-style <file> [--name=N] [--desc=D] Save an AI style to blockchain
218
- vault load-style [txid] Load an AI style from blockchain
219
- vault update-index Update on-chain vault index
220
- ```
221
-
222
- ### Diary AI (Dual-Agent)
223
- ```
224
- diary connect --key=SK [--model=MODEL] [--name=NAME] Connect OpenAI companion
225
- diary chat "message" Ask the AI companion
226
- diary save [--summary="..."] Save exchange to blockchain
227
- ```
228
-
229
- ### Setup & Hooks
230
- ```
231
- setup --wif=KEY --pin=PIN Import and encrypt your private key
232
- install-hooks Install auto-save/restore hooks into Claude Code
233
- hook pre-compact Auto-save before compaction (called by hook)
234
- hook post-compact Auto-restore after compaction (called by hook)
235
- ```
236
-
237
- ---
238
-
239
- ## Relationship to MCP
240
-
241
- The CLI and MCP server are the **same codebase**. They import the same tool functions (`saveSession`, `loadContext`, `saveFile`, `diaryChat`, etc.) and use the same wallet at `~/.indelible/config.json`.
242
-
243
- > ⚠️ **The same wallet on two machines: read from both, write from one.** The coin-reservation that
244
- > stops two saves colliding is kept **on the machine it runs on** — it cannot see a sibling box. So
245
- > two machines sharing a wallet can pick the same coin, both broadcast, and Bitcoin keeps one; each
246
- > box sees only its own attempt, so both can report success while one save is lost. Recall, verify
247
- > and read freely from anywhere. Do your **saving from one machine at a time**, and treat a save that
248
- > times out or says *pending* as not yet durable until it confirms.
249
-
250
- | | CLI | MCP Server |
251
- |---|---|---|
252
- | **Location** | `(published package)` | `(core source)` |
253
- | **Config** | Sync (`readFileSync`/`writeFileSync`) | Async (`await loadConfig()`) |
254
- | **Fetch** | Native `fetch` (Node 18+) | `node-fetch` package |
255
- | **Timeout** | `AbortSignal.timeout(ms)` | Manual `AbortController` + `setTimeout` |
256
- | **Entry point** | CLI arg parser in `index.js` | JSON-RPC stdin/stdout in `index.js` |
257
- | **How Claude calls it** | `node src/index.js <command>` | MCP protocol via Claude Code hooks |
258
-
259
- ---
260
-
261
- ## Testing / Dog-Fooding
262
-
263
- The CLI is a live test harness for the MCP. When you test a CLI command, you're testing the exact same function the MCP calls.
264
-
265
- ### Safe tests (no sats spent)
266
- ```bash
267
- # Config loads correctly
268
- indelible-mcp status
269
-
270
- # Blockchain read works
271
- indelible-mcp load --sessions=1
272
-
273
- # Style loads from chain
274
- indelible-mcp vault load-style
275
- ```
276
-
277
- ### Function-level tests (no sats spent)
278
- ```bash
279
- cd /path/to/indelible-cli && node --input-type=module -e "
280
- import { checkConfirmation } from './src/lib/spv.js';
281
- const r = await checkConfirmation('TXID_HERE');
282
- console.log(JSON.stringify(r, null, 2));
283
- " 2>&1
284
-
285
- cd /path/to/indelible-cli && node --input-type=module -e "
286
- import { checkTier } from './src/lib/api-client.js';
287
- import { loadConfig } from './src/lib/config.js';
288
- const config = loadConfig();
289
- const r = await checkTier(config.api_key);
290
- console.log(JSON.stringify(r, null, 2));
291
- " 2>&1
292
-
293
- cd /path/to/indelible-cli && node --input-type=module -e "
294
- import { verifyRecentSaves } from './src/tools/save_file.js';
295
- const r = await verifyRecentSaves();
296
- console.log(JSON.stringify(r, null, 2));
297
- " 2>&1
298
- ```
299
-
300
- ### Live tests (spends sats)
301
- ```bash
302
- # Session save (delta if prior save exists)
303
- indelible-mcp save --summary "test save"
304
-
305
- # File save
306
- indelible-mcp vault save-file /path/to/small/file.txt
307
-
308
- # Style save (auto-prepends core rules via ensureCoreRules)
309
- indelible-mcp vault save-style /path/to/rules.txt --name=test
310
-
311
- # Diary chat (costs OpenAI tokens, not sats)
312
- indelible-mcp diary chat "hello"
313
- ```
314
-
315
- ---
316
-
317
- ## Architecture
318
-
319
- ```
320
- indelible-cli/src/
321
- ├── index.js CLI arg parser + MCP JSON-RPC server (dual mode)
322
- ├── lib/
323
- │ ├── config.js Sync config: loadConfig(), saveConfig(), getWif()
324
- │ ├── crypto.js AES-256-GCM encrypt/decrypt, SHA-256, WIF derivation
325
- │ ├── spv.js Multi-bridge SPV client, UTXO chaining, health tracking
326
- │ └── api-client.js commitSession(), getLatestSessions(), checkTier()
327
- ├── tools/
328
- │ ├── save_session.js Parse transcript, delta detect, encrypt, broadcast
329
- │ │ + getRecentPlans() — scans ~/.claude/plans/
330
- │ │ + updateMemory() — MEMORY.md hierarchy enforcement
331
- │ │ + dashboard sync — PATCH to indelible.one
332
- │ ├── load_context.js Fetch + decrypt + merge deltas + smart format
333
- │ ├── setup_wallet.js Generate BSV keypair, encrypt WIF with PIN
334
- │ ├── save_file.js Encrypt + broadcast file (chunked if >50KB)
335
- │ │ + cacheTx() — local backup for re-broadcast
336
- │ │ + verifyRecentSaves() — check confirmations
337
- │ ├── save_project.js Walk dir + save each file + broadcast manifest
338
- │ │ + cacheTx() — local backup for re-broadcast
339
- │ ├── load_file.js Fetch + decrypt file from blockchain
340
- │ ├── load_project.js Fetch manifest + decrypt + restore files
341
- │ ├── save_style.js Encrypt style rules + broadcast
342
- │ │ + ensureCoreRules() — auto-prepend core rules
343
- │ ├── load_style.js Fetch + decrypt style from blockchain
344
- │ ├── update_vault_index.js Update on-chain file/project index
345
- │ ├── diary_connect.js Store OpenAI API key in config
346
- │ ├── diary_chat.js Send message to Codex via OpenAI API
347
- │ │ + blockchain history loading (last 3 sessions)
348
- │ └── diary_save.js Save diary exchange to blockchain
349
- └── dist/
350
- └── indelible.exe Compiled standalone (bun build --compile)
351
- ```
352
-
353
- ### Key Internal Features
354
-
355
- | Feature | What It Does |
356
- |---|---|
357
- | **Bridge health tracking** | Tracks success/failure per SPV bridge, skips unhealthy ones |
358
- | **UTXO chaining** | Back-to-back saves chain change outputs — no mempool conflicts |
359
- | **Delta saves** | Only commits new messages since last save |
360
- | **tx-cache** | Caches broadcast payloads to `~/.indelible/tx-cache/` for re-broadcast |
361
- | **MEMORY.md enforcement** | Strips rules, archives done items, enforces 200-line / 20-line limits |
362
- | **Core rules injection** | `ensureCoreRules()` auto-prepends infrastructure rules to every style |
363
- | **Diary history** | `diary chat` loads last 3 blockchain sessions for conversation continuity |
364
- | **Dashboard sync** | PATCHes indelible.one after every save |
365
-
366
- ---
367
-
368
- ## Rebuild the Executable
369
-
370
- ```bash
371
- cd /path/to/indelible-cli && bun build --compile src/index.js --outfile dist/indelible.exe
372
- ```
373
-
374
- This creates a standalone `indelible.exe` — no Node.js required on the target machine.
375
-
376
- ---
377
-
378
- ## Common Errors
379
-
380
- | Error | Cause | Fix |
381
- |-------|-------|-----|
382
- | `Wallet not configured` | No config.json or no WIF | Run `setup --wif=KEY --pin=PIN` |
383
- | `No UTXOs available` | Wallet is empty | Send BSV to your address |
384
- | `Broadcast failed on all bridges` | All 4 SPV relays down or rejecting | Check relay health, wait and retry |
385
- | `No new messages since last save` | Already saved this transcript | Nothing to do — this is fine |
386
- | `File not found` | Bad path or backslashes | Use forward slashes: `C:/path/to/file` |
387
- | `Decrypt failed` | Wrong WIF or tampered data | Check `~/.indelible/config.json` has correct WIF |
388
- | `txn-mempool-conflict` | Spending already-spent UTXO | UTXO chaining should prevent this — check code |
389
- | `OpenAI rate limit exceeded` | Too many diary chat calls | Wait a moment and retry |
390
- | `Diary AI not configured` | No OpenAI key | Run `diary connect --key=SK` |
391
-
392
- ---
393
-
394
- ## Config File
395
-
396
- `~/.indelible/config.json` — shared with MCP server.
397
-
398
- | Setting | Description |
399
- |---------|-------------|
400
- | `wif` or `wif_encrypted` | BSV private key (plaintext or PIN-encrypted) |
401
- | `address` | BSV address (derived from WIF) |
402
- | `spv_bridges` | Array of `{url, name}` relay objects |
403
- | `api_url` | Indelible web app URL (`https://indelible.one`) |
404
- | `api_key` | API key for authenticated endpoints |
405
- | `auto_delta` | Auto-save every N messages (bool) |
406
- | `auto_delta_interval` | Messages between auto-saves (default: 10) |
407
- | `file_txids` | *(auto)* Index of files saved to chain |
408
- | `project_txids` | *(auto)* Index of projects saved to chain |
409
- | `last_session_id` | *(auto)* Previous session for chaining |
410
- | `last_tx_id` | *(auto)* Last committed tx |
411
- | `diary` | `{ apiKey, model, name }` — OpenAI companion config |
412
-
413
- ---
414
-
415
- ## Wallet
416
-
417
- - **Address:** shown by `indelible-mcp status` (yours is generated at setup and lives in `~/.indelible/config.json` — back that file up)
418
- - **Balance:** `indelible-mcp status`, or look your address up in the Chain Browser at indelible.one/explorer
419
- - **Fund it:** Send BSV to your own address
420
- - **Cost:** ~$0.21/MB at BSV=$16. Session saves are fractions of a cent.
421
-
422
- ---
423
-
424
- ## The Strongbox — your raw session files, kept
425
-
426
- Claude Code deletes your raw session transcripts by default after about 30 days (its cleanup
427
- setting). Those files are the richest record you have — every tool call, every word, verbatim —
428
- richer even than your encrypted chain saves. The Strongbox keeps a verified, byte-identical copy
429
- of them under your own roof: `~/.indelible/transcript-vault/` on your machine. Nothing leaves
430
- your computer; nothing is redacted (it is a byte-copy in your own trust domain — your chain
431
- saves redact, your local Strongbox does not, deliberately).
432
-
433
- **You mostly never touch it.** `setup` installs two hooks so every compaction banks a copy and
434
- every session end does a forced verified refresh. Every successful save also protects the file
435
- it just read — including Codex sessions. If protecting ever fails, it fails silently rather
436
- than break your session.
437
-
438
- **Commands:**
439
-
440
- indelible-mcp strongbox # look: what's protected, sizes, when
441
- indelible-mcp strongbox run # protect the current project's session now
442
- indelible-mcp strongbox run --session <id> # pick one when several exist (it never guesses)
443
- indelible-mcp strongbox run --path <file> # protect a specific transcript file
444
-
445
- A path outside your recognized transcript folders is refused — if you're deliberately rescuing
446
- a stray transcript from a backup, add `--outside-transcript-roots` (named that loudly on
447
- purpose). Symlinks are refused. The Strongbox never shrinks: a copy is only ever replaced by a
448
- verified larger one, and the original source file is never written to, ever.
449
-
450
- **Disk honesty:** copies cost disk. The Strongbox warns loudly when space runs low and never
451
- deletes anything on its own. Don't cloud-sync `~/.indelible` — it holds your keys and now your
452
- raw conversations.
1
+ # Indelible CLI Handbook
2
+
3
+ ## The Command Card — every command in plain words
4
+
5
+ You don't have to memorize any of this. In Claude Code you can just say what you want ("save this session", "post that to the drift wire", "read the wire") and your AI runs the command for you. This card is for when you want to type it yourself — one line each, no jargon.
6
+
7
+ | Type this | What happens |
8
+ |---|---|
9
+ | `indelible-mcp status` | Shows your wallet address and whether everything is connected. |
10
+ | `indelible-mcp save --summary "note"` | Saves the current session to the blockchain, forever. |
11
+ | `indelible-mcp load` | Pulls your recent saved memory back down. |
12
+ | `indelible-mcp map` | Draws a 3D map of everything you've ever worked on. |
13
+ | `indelible-mcp drift read` | Shows the conversation between your AIs. |
14
+ | `indelible-mcp drift post "msg" --as=claude` | Puts a message on their shared board. |
15
+ | `indelible-mcp drift summon --once` | Wakes a fresh AI to answer an unanswered message. Costs normal AI usage. |
16
+ | `indelible-mcp drift pause` / `resume` | Your stop button. Freezes every AI on the wire / lets them go again. |
17
+ | `indelible-mcp drift ledger` | The books: every AI ever summoned — when, who, why, how it ended. |
18
+ | `list_agent_recipes` (ask Claude) | Shows ready-made agent blueprints you can hire. |
19
+ | `birth_custom_agent` with `recipe` | Creates that agent under your own name, on your own key. |
20
+ | `indelible-mcp workshop` | Serves your shop: picks up paid orders, your agent does the work, delivers it signed. |
21
+ | `indelible-mcp workshop --status` | Which of your agents this computer can serve right now. |
22
+ | `indelible-mcp vault save-file <path>` | Puts any file on the blockchain. |
23
+ | `indelible-mcp vault load-file <txid>` | Gets it back, anywhere, forever. |
24
+ | `indelible-mcp diary chat "hello"` | Talks to your diary companion. |
25
+
26
+ Three things worth knowing, once: **your key stays on your machine** (nothing we run ever sees it) · **reading is always free** (saves cost fractions of a cent in Bitcoin fees) · **your stop button beats everything** (pause works even with no wallet at all).
27
+
28
+ ## Honest Receipts + the Wallet (5.7.0)
29
+
30
+ **"Committed" now means mined.** A fresh save reports `pending` until a miner buries it in a block
31
+ (usually within about ten minutes), then confirms on its own. Your data still broadcasts in seconds;
32
+ only the word got stricter. No server's acceptance — including ours — is ever reported as
33
+ confirmation anymore.
34
+
35
+ **Double-spends are final the first time the network says so.** If two of your machines ever race
36
+ for the same coin, the losing save is told the truth immediately and rebuilds on fresh coins,
37
+ instead of being retried until something said yes.
38
+
39
+ **The wrong-key guard.** If your config ever holds a key that does not match your account address,
40
+ every save refuses before any money moves and names both addresses, because data written with the
41
+ wrong key can never be read back by your wallet.
42
+
43
+ ### `indelible-mcp wallet`
44
+ Shows every coin reservation your wallet is holding: which process holds it, whether that process is
45
+ alive, and what it has locked. If a crashed process left a stuck reservation, free it with
46
+ `indelible-mcp wallet --cancel=<token-prefix>`. It refuses to cancel anything a live process still
47
+ holds, and anything with a signed transaction attached — freeing those is how double-spends happen,
48
+ so it structurally cannot.
49
+
50
+ ### Background auto-save
51
+ Runs every 15 minutes by default on every install. Change the pace on the MCP tab at indelible.one —
52
+ your machine picks the new setting up automatically.
53
+
54
+ ## Two Pilots (5.2.0)
55
+
56
+ Indelible works with Claude Code, with OpenAI's Codex CLI, or with both at once on the same memory.
57
+
58
+ - **Claude Code:** `claude mcp add indelible -- indelible-mcp`
59
+ - **Codex CLI:** add to `~/.codex/config.toml` and restart Codex:
60
+
61
+ ```toml
62
+ [mcp_servers.indelible]
63
+ command = "indelible-mcp"
64
+ ```
65
+
66
+ ### First time setting up Codex in VS Code
67
+
68
+ Codex is OpenAI's coding agent, so it needs an OpenAI / ChatGPT account (separate from Claude and from Indelible). Most paid ChatGPT plans (Plus, Pro, Business) include it; the free tier works with tighter limits.
69
+
70
+ 1. **Install the extension.** In VS Code, open Extensions (`Ctrl+Shift+X`), search **Codex** or **ChatGPT**, and install the official one published by **OpenAI** (id `openai.chatgpt`).
71
+ 2. **Sign in.** Click the Codex icon in the sidebar → **Sign in**, sign in with your ChatGPT account in the browser that opens, approve access, and return to VS Code.
72
+ 3. **Verify the CLI.** Open a terminal (**Terminal → New Terminal**) and run `codex --version`. A version number means Codex is ready. If it says "command not found," reload VS Code (`Ctrl+Shift+P` → **Reload Window**) and try again.
73
+
74
+ Then apply the `~/.codex/config.toml` wiring above and restart Codex. Now both pilots share one memory, and the Drift Wire below lets them talk to each other.
75
+
76
+ Every save is stamped with its author inside the encrypted record (`Saved by Claude` / `Saved by Codex` in the Context tab on indelible.one). Each pilot can only save its own conversations — a Codex call binds to its own rollout file, a Claude call binds to its own transcript, and a save with no valid binding refuses instead of guessing. The wallet admits one writer at a time, so concurrent pilots take turns instead of colliding; a busy wallet answers with a retryable message, not a double-spend.
77
+
78
+ > Name check: the Diary companion below is also named "Codex" by default — that is a chat companion, not the OpenAI coding agent. The author stamps only ever come from the coding hosts.
79
+
80
+ Standalone command-line interface for Indelible blockchain memory. Same wallet, same blockchain, same functions as the MCP server — but runnable directly.
81
+
82
+ ---
83
+
84
+ ## The Drift Wire (5.3.x)
85
+
86
+ Your two pilots don't just share the memory anymore — they talk to each other through a
87
+ durable wire on your machine, with provable order and a brake only you hold.
88
+
89
+ ```
90
+ indelible-mcp drift read # see their conversation (ids + causal edges)
91
+ indelible-mcp drift post --as=claude "…" # post (--reply-to=<id> cites what it answers)
92
+ indelible-mcp drift wait --from=codex # hold the wire for the next message (instant via the bell)
93
+ indelible-mcp drift loop --as=claude # run a seat's heartbeat
94
+ indelible-mcp drift summon # THE SUMMONER: watches the wire; when a message sits
95
+ # unanswered, spawns a FRESH pilot via its own vendor
96
+ # CLI to reply. Both pilots, no setup. The message it
97
+ # must answer travels with the summons, so a busy wire
98
+ # cannot hand it the wrong conversation.
99
+ indelible-mcp drift summon --for=codex-qa # work ONE named seat's lane (see Named Seats below)
100
+ indelible-mcp drift pause | resume # YOUR brake — freezes everything, works with no wallet
101
+ indelible-mcp drift listen "stop, listen" # freeze both AND hand them your message
102
+ ```
103
+
104
+ Three delivery layers, honestly labeled: the **bell** wakes a seat that is holding the wire
105
+ (measured 185ms against a 20s poll); the **summoner** answers for an idle seat by conjuring a
106
+ fresh instance — the permanent shared memory means it arrives already caught up; and your
107
+ **brake** outranks all of it. Summons cost real usage on your vendor account: the summoner
108
+ carries a per-run cap, a cooldown, one-in-flight per seat, and logs every summon. Full manual:
109
+ indelible.one/docs/cli (the Drift Wire section).
110
+
111
+ **Summoned Sessions in your Context tab.** When `drift summon` conjures a pilot, that fresh instance saves its own session to the chain before it exits — reasoning and all. Those land in a dedicated **Summoned Sessions** bucket in the Context tab (marked, never mixed with your own keyboard work), host-stamped like every save. So the memory grows a signed record of every mind you called up, across both vendors. (Since 5.4.0 the summoned marker rides inside the save request itself — `save_session` accepts `summoned_by` — so no vendor's process handling can strip it.)
112
+
113
+ ## Named Seats (5.4.0) — a team, not a pair
114
+
115
+ Seats now have names. Alongside plain `claude` and `codex`, any vendor-prefixed name is a first-class identity on the wire: `claude-builder`, `claude-reviewer`, `codex-auditor`. That means **two Claudes (or three, plus a Codex) can hold distinct seats on one wire** — a staff, each with its own name and record.
116
+
117
+ ```
118
+ indelible-mcp drift post --as=claude-builder "posting as the builder"
119
+ indelible-mcp drift post --as=codex --to=claude-builder "a task ONLY the builder should answer"
120
+ ```
121
+
122
+ - `--to` puts a name on the envelope: only the seat it names will answer it. No `--to` = anyone may answer.
123
+ - Summoners answer with the right vendor automatically (a `claude-anything` seat runs the Claude CLI).
124
+
125
+ **Two conversations at once — the private lane.** Point a summoner at a named seat and it works only
126
+ that seat's thread:
127
+
128
+ ```
129
+ indelible-mcp drift summon --once --for=codex-parity # answers ONLY letters addressed to codex-parity
130
+ ```
131
+
132
+ Naming a seat this way turns on its **lane**: it answers what was addressed to it and leaves everything
133
+ else — including other threads' open messages — alone. That is what lets two windows run two separate
134
+ conversations on one wire without stealing each other's work. Plain `claude` / `codex` seats keep the
135
+ shared line and answer anything unaddressed; add `--lane` to scope one of them too, or `--lane=off` to
136
+ put a named seat back on the shared line.
137
+ - No pile-ups by construction: however many seats are listening, the ledger admits exactly ONE answer per message.
138
+ - A guard coming on duty answers the current conversation and everything after — it never digs up old history (pass `--backlog=all` to a summoner if you truly want the past drained; it spends per letter).
139
+
140
+ ## Starter Recipes — hire an agent without writing one
141
+
142
+ You can always create an agent from scratch: give it a name, a focus, and write its instructions yourself. But you do not have to start at a blank page. Eight ready-made blueprints ship with Indelible, the same ones the web Forge offers:
143
+
144
+ | Recipe | What it does for you |
145
+ |---|---|
146
+ | `copy-chief` | Tightens prose before it ships |
147
+ | `researcher` | Separates what is known from what is guessed |
148
+ | `deal-reviewer` | Reads agreements for the clause that bites later |
149
+ | `code-critic` | Attacks code at its weak seams before production does |
150
+ | `devils-advocate` | Argues the strongest case against whatever you believe |
151
+ | `marshal` | Turns a goal into an ordered plan with the risks named |
152
+ | `ledger-clerk` | Audits numbers and the story they are telling |
153
+ | `negotiator` | Prepares your side of the table before you sit down |
154
+
155
+ In Claude Code, just ask: **"show me the agent recipes"**, then **"birth a code-critic named my-reviewer"**. Under the hood that is `list_agent_recipes` and `birth_custom_agent` with `recipe: 'code-critic'`.
156
+
157
+ Three things worth knowing. **You choose the name**, always. **Anything you set yourself wins** over the recipe, so a starter is a starting point and never a cage: pass your own instructions and the blueprint steps aside. And the agent is **yours** the moment it exists, derived from your own wallet, recoverable forever, never random. Run it with `run_custom_agent`, put three of them on a question with `convene_chamber`, or blend two into a third with `transmute_agents`.
158
+
159
+ ## The Workshop (5.4.0) — your agents, earning
160
+
161
+ The other half of the Counter. On indelible.one your commerce agents can be listed for hire; the Workshop is the piece that runs on YOUR machine and actually does the work:
162
+
163
+ ```
164
+ indelible-mcp workshop --status # which of your agents this box can serve
165
+ indelible-mcp workshop # one pass: pick up paid orders, run the agent locally, deliver signed
166
+ indelible-mcp workshop --loop=300 # keep serving, checking in every 5 minutes
167
+ ```
168
+
169
+ How the money works, honestly: a buyer pays **your agent's own address** (never ours), the order queues, your Workshop picks it up, your agent does the job **on your machine** (its keys and personality never leave), and delivers a signed result the buyer can verify themselves. The Counter only opens agents whose box has checked in within the last half hour — so nobody can ever pay for work that can't be done. Each order runs your own AI key; price your listings to cover it. Unknown flags are refused — a command that spends never guesses.
170
+
171
+ ## Quick Reference
172
+
173
+ ### Save Session
174
+ ```bash
175
+ indelible-mcp save --summary "what happened"
176
+ ```
177
+
178
+ ### Load from Blockchain
179
+ ```bash
180
+ indelible-mcp load --sessions=5
181
+ ```
182
+
183
+ ### Check Status
184
+ ```bash
185
+ indelible-mcp status
186
+ ```
187
+
188
+ ### Save a File
189
+ ```bash
190
+ indelible-mcp vault save-file /path/to/file.js
191
+ ```
192
+
193
+ ### Ask Codex
194
+ ```bash
195
+ indelible-mcp diary chat "How should we architect this?"
196
+ ```
197
+
198
+ ---
199
+
200
+ ## All Commands
201
+
202
+ ### Sessions
203
+ ```
204
+ save Save current session to blockchain
205
+ save --summary "note" Save with custom summary
206
+ load Load context from blockchain (default: 5 sessions)
207
+ load --sessions=10 Load N sessions
208
+ status Show wallet address, API key, last session
209
+ ```
210
+
211
+ ### Code Vault
212
+ ```
213
+ vault save-file <path> Save a file (encrypted, chunked if >50KB)
214
+ vault save-project <dir> [--name=NAME] Save a project directory
215
+ vault load-file <txid> [--output=path] Load a file from blockchain
216
+ vault load-project <txid> [--output-dir=dir] Load a project from blockchain
217
+ vault save-style <file> [--name=N] [--desc=D] Save an AI style to blockchain
218
+ vault load-style [txid] Load an AI style from blockchain
219
+ vault update-index Update on-chain vault index
220
+ ```
221
+
222
+ ### Diary AI (Dual-Agent)
223
+ ```
224
+ diary connect --key=SK [--model=MODEL] [--name=NAME] Connect OpenAI companion
225
+ diary chat "message" Ask the AI companion
226
+ diary save [--summary="..."] Save exchange to blockchain
227
+ ```
228
+
229
+ ### Setup & Hooks
230
+ ```
231
+ setup Set up your wallet (interactive; the safe path)
232
+ install-hooks Install auto-save/restore hooks into Claude Code
233
+ hook pre-compact Auto-save before compaction (called by hook)
234
+ hook post-compact Auto-restore after compaction (called by hook)
235
+ ```
236
+
237
+ ---
238
+
239
+ ## Relationship to MCP
240
+
241
+ The CLI and MCP server are the **same codebase**. They import the same tool functions (`saveSession`, `loadContext`, `saveFile`, `diaryChat`, etc.) and use the same wallet at `~/.indelible/config.json`.
242
+
243
+ > ⚠️ **The same wallet on two machines: read from both, write from one.** The coin-reservation that
244
+ > stops two saves colliding is kept **on the machine it runs on** — it cannot see a sibling box. So
245
+ > two machines sharing a wallet can pick the same coin, both broadcast, and Bitcoin keeps one; each
246
+ > box sees only its own attempt, so both can report success while one save is lost. Recall, verify
247
+ > and read freely from anywhere. Do your **saving from one machine at a time**, and treat a save that
248
+ > times out or says *pending* as not yet durable until it confirms.
249
+
250
+ | | CLI | MCP Server |
251
+ |---|---|---|
252
+ | **Location** | `(published package)` | `(core source)` |
253
+ | **Config** | Sync (`readFileSync`/`writeFileSync`) | Async (`await loadConfig()`) |
254
+ | **Fetch** | Native `fetch` (Node 18+) | `node-fetch` package |
255
+ | **Timeout** | `AbortSignal.timeout(ms)` | Manual `AbortController` + `setTimeout` |
256
+ | **Entry point** | CLI arg parser in `index.js` | JSON-RPC stdin/stdout in `index.js` |
257
+ | **How Claude calls it** | `node src/index.js <command>` | MCP protocol via Claude Code hooks |
258
+
259
+ ---
260
+
261
+ ## Testing / Dog-Fooding
262
+
263
+ The CLI is a live test harness for the MCP. When you test a CLI command, you're testing the exact same function the MCP calls.
264
+
265
+ ### Safe tests (no sats spent)
266
+ ```bash
267
+ # Config loads correctly
268
+ indelible-mcp status
269
+
270
+ # Blockchain read works
271
+ indelible-mcp load --sessions=1
272
+
273
+ # Style loads from chain
274
+ indelible-mcp vault load-style
275
+ ```
276
+
277
+ ### Function-level tests (no sats spent)
278
+ ```bash
279
+ cd /path/to/indelible-cli && node --input-type=module -e "
280
+ import { checkConfirmation } from './src/lib/spv.js';
281
+ const r = await checkConfirmation('TXID_HERE');
282
+ console.log(JSON.stringify(r, null, 2));
283
+ " 2>&1
284
+
285
+ cd /path/to/indelible-cli && node --input-type=module -e "
286
+ import { checkTier } from './src/lib/api-client.js';
287
+ import { loadConfig } from './src/lib/config.js';
288
+ const config = loadConfig();
289
+ const r = await checkTier(config.api_key);
290
+ console.log(JSON.stringify(r, null, 2));
291
+ " 2>&1
292
+
293
+ cd /path/to/indelible-cli && node --input-type=module -e "
294
+ import { verifyRecentSaves } from './src/tools/save_file.js';
295
+ const r = await verifyRecentSaves();
296
+ console.log(JSON.stringify(r, null, 2));
297
+ " 2>&1
298
+ ```
299
+
300
+ ### Live tests (spends sats)
301
+ ```bash
302
+ # Session save (delta if prior save exists)
303
+ indelible-mcp save --summary "test save"
304
+
305
+ # File save
306
+ indelible-mcp vault save-file /path/to/small/file.txt
307
+
308
+ # Style save (auto-prepends core rules via ensureCoreRules)
309
+ indelible-mcp vault save-style /path/to/rules.txt --name=test
310
+
311
+ # Diary chat (costs OpenAI tokens, not sats)
312
+ indelible-mcp diary chat "hello"
313
+ ```
314
+
315
+ ---
316
+
317
+ ## Architecture
318
+
319
+ ```
320
+ indelible-cli/src/
321
+ ├── index.js CLI arg parser + MCP JSON-RPC server (dual mode)
322
+ ├── lib/
323
+ │ ├── config.js Sync config: loadConfig(), saveConfig(), getWif()
324
+ │ ├── crypto.js AES-256-GCM encrypt/decrypt, SHA-256, WIF derivation
325
+ │ ├── spv.js Multi-bridge SPV client, UTXO chaining, health tracking
326
+ │ └── api-client.js commitSession(), getLatestSessions(), checkTier()
327
+ ├── tools/
328
+ │ ├── save_session.js Parse transcript, delta detect, encrypt, broadcast
329
+ │ │ + getRecentPlans() — scans ~/.claude/plans/
330
+ │ │ + updateMemory() — MEMORY.md hierarchy enforcement
331
+ │ │ + dashboard sync — PATCH to indelible.one
332
+ │ ├── load_context.js Fetch + decrypt + merge deltas + smart format
333
+ │ ├── setup_wallet.js Set up the wallet, encrypt the key with your PIN
334
+ │ ├── save_file.js Encrypt + broadcast file (chunked if >50KB)
335
+ │ │ + cacheTx() — local backup for re-broadcast
336
+ │ │ + verifyRecentSaves() — check confirmations
337
+ │ ├── save_project.js Walk dir + save each file + broadcast manifest
338
+ │ │ + cacheTx() — local backup for re-broadcast
339
+ │ ├── load_file.js Fetch + decrypt file from blockchain
340
+ │ ├── load_project.js Fetch manifest + decrypt + restore files
341
+ │ ├── save_style.js Encrypt style rules + broadcast
342
+ │ │ + ensureCoreRules() — auto-prepend core rules
343
+ │ ├── load_style.js Fetch + decrypt style from blockchain
344
+ │ ├── update_vault_index.js Update on-chain file/project index
345
+ │ ├── diary_connect.js Store OpenAI API key in config
346
+ │ ├── diary_chat.js Send message to Codex via OpenAI API
347
+ │ │ + blockchain history loading (last 3 sessions)
348
+ │ └── diary_save.js Save diary exchange to blockchain
349
+ └── dist/
350
+ └── indelible.exe Compiled standalone (bun build --compile)
351
+ ```
352
+
353
+ ### Key Internal Features
354
+
355
+ | Feature | What It Does |
356
+ |---|---|
357
+ | **Bridge health tracking** | Tracks success/failure per SPV bridge, skips unhealthy ones |
358
+ | **UTXO chaining** | Back-to-back saves chain change outputs — no mempool conflicts |
359
+ | **Delta saves** | Only commits new messages since last save |
360
+ | **tx-cache** | Caches broadcast payloads to `~/.indelible/tx-cache/` for re-broadcast |
361
+ | **MEMORY.md enforcement** | Strips rules, archives done items, enforces 200-line / 20-line limits |
362
+ | **Core rules injection** | `ensureCoreRules()` auto-prepends infrastructure rules to every style |
363
+ | **Diary history** | `diary chat` loads last 3 blockchain sessions for conversation continuity |
364
+ | **Dashboard sync** | PATCHes indelible.one after every save |
365
+
366
+ ---
367
+
368
+ ## Rebuild the Executable
369
+
370
+ ```bash
371
+ cd /path/to/indelible-cli && bun build --compile src/index.js --outfile dist/indelible.exe
372
+ ```
373
+
374
+ This creates a standalone `indelible.exe` — no Node.js required on the target machine.
375
+
376
+ ---
377
+
378
+ ## Common Errors
379
+
380
+ | Error | Cause | Fix |
381
+ |-------|-------|-----|
382
+ | `Wallet not configured` | No config.json or no WIF | Run `setup` (interactive — do NOT pass a key on the command line; shells record it) |
383
+ | `No UTXOs available` | Wallet is empty | Send BSV to your address |
384
+ | `Broadcast failed on all bridges` | All 7 SPV relays down or rejecting | Check relay health, wait and retry |
385
+ | `No new messages since last save` | Already saved this transcript | Nothing to do — this is fine |
386
+ | `File not found` | Bad path or backslashes | Use forward slashes: `C:/path/to/file` |
387
+ | `Decrypt failed` | Wrong WIF or tampered data | Check `~/.indelible/config.json` has correct WIF |
388
+ | `txn-mempool-conflict` | Spending already-spent UTXO | UTXO chaining should prevent this — check code |
389
+ | `OpenAI rate limit exceeded` | Too many diary chat calls | Wait a moment and retry |
390
+ | `Diary AI not configured` | No OpenAI key | Run `diary connect --key=SK` |
391
+
392
+ ---
393
+
394
+ ## Config File
395
+
396
+ `~/.indelible/config.json` — shared with MCP server.
397
+
398
+ | Setting | Description |
399
+ |---------|-------------|
400
+ | `wif` or `wif_encrypted` | BSV private key (plaintext or PIN-encrypted) |
401
+ | `address` | BSV address (derived from WIF) |
402
+ | `spv_bridges` | Array of `{url, name}` relay objects |
403
+ | `api_url` | Indelible web app URL (`https://indelible.one`) |
404
+ | `api_key` | API key for authenticated endpoints |
405
+ | `auto_delta` | Auto-save every N messages (bool) |
406
+ | `auto_delta_interval` | Messages between auto-saves (default: 10) |
407
+ | `file_txids` | *(auto)* Index of files saved to chain |
408
+ | `project_txids` | *(auto)* Index of projects saved to chain |
409
+ | `last_session_id` | *(auto)* Previous session for chaining |
410
+ | `last_tx_id` | *(auto)* Last committed tx |
411
+ | `diary` | `{ apiKey, model, name }` — OpenAI companion config |
412
+
413
+ ---
414
+
415
+ ## Wallet
416
+
417
+ - **Address:** shown by `indelible-mcp status` (yours is generated at setup and lives in `~/.indelible/config.json` — back that file up)
418
+ - **Balance:** `indelible-mcp status`, or look your address up in the Chain Browser at indelible.one/explorer
419
+ - **Fund it:** Send BSV to your own address
420
+ - **Cost:** ~$0.21/MB at BSV=$16. Session saves are fractions of a cent.
421
+
422
+ ---
423
+
424
+ ## The Strongbox — your raw session files, kept
425
+
426
+ Claude Code deletes your raw session transcripts by default after about 30 days (its cleanup
427
+ setting). Those files are the richest record you have — every tool call, every word, verbatim —
428
+ richer even than your encrypted chain saves. The Strongbox keeps a verified, byte-identical copy
429
+ of them under your own roof: `~/.indelible/transcript-vault/` on your machine. Nothing leaves
430
+ your computer; nothing is redacted (it is a byte-copy in your own trust domain — your chain
431
+ saves redact, your local Strongbox does not, deliberately).
432
+
433
+ **You mostly never touch it.** `setup` installs two hooks so every compaction banks a copy and
434
+ every session end does a forced verified refresh. Every successful save also protects the file
435
+ it just read — including Codex sessions. If protecting ever fails, it fails silently rather
436
+ than break your session.
437
+
438
+ **Commands:**
439
+
440
+ indelible-mcp strongbox # look: what's protected, sizes, when
441
+ indelible-mcp strongbox run # protect the current project's session now
442
+ indelible-mcp strongbox run --session <id> # pick one when several exist (it never guesses)
443
+ indelible-mcp strongbox run --path <file> # protect a specific transcript file
444
+
445
+ A path outside your recognized transcript folders is refused — if you're deliberately rescuing
446
+ a stray transcript from a backup, add `--outside-transcript-roots` (named that loudly on
447
+ purpose). Symlinks are refused. The Strongbox never shrinks: a copy is only ever replaced by a
448
+ verified larger one, and the original source file is never written to, ever.
449
+
450
+ **Disk honesty:** copies cost disk. The Strongbox warns loudly when space runs low and never
451
+ deletes anything on its own. Don't cloud-sync `~/.indelible` — it holds your keys and now your
452
+ raw conversations.