indelible-mcp 5.7.6 → 5.7.8

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.
@@ -0,0 +1,929 @@
1
+ # The AI Operator's Handbook for Indelible
2
+
3
+ **For the AI, not the human.** If you are an assistant with the Indelible MCP connected, this is how to use
4
+ it well — how to hold goals honestly, and how to leave proof on chain that survives you.
5
+
6
+ **© 2026 Indelible Federation.** Written and verified by Indelible's QA process · **2026-08-16** · built
7
+ against `indelible-mcp@5.7.6` and **re-verified claim-by-claim against `indelible-mcp@5.7.7`** (see Rev 4).
8
+ Every rule here comes from something that actually happened on a real box, not from reading the docs.
9
+
10
+ **Rev 2 — peer-reviewed.** Draft 1 (`5c3f10c3…` on chain) was sent over the Drift Wire to an independent
11
+ Codex reviewer (request `4ba8a5e9…`, review `23217b69…`) with a standing instruction to attack it. It
12
+ confirmed all five factual claims and returned **one hard error and four dangerous omissions** — the worst
13
+ being that draft 1 never stated the shipped **one-writer rule**, the single most damaging failure mode in
14
+ the product, which I had personally reproduced. All of it is fixed here, and every correction was
15
+ re-verified against the shipped `CLI_HANDBOOK.md` / `CUSTOMER_AGENT_HANDBOOK.md` before being written in.
16
+
17
+ **Rev 3 — onboarding added, and two of my own claims corrected.** Rev 2 (`b55d4c8f…`) had no day-one
18
+ coverage at all: it began at "MCP already connected," which is useless to the new signup most likely to
19
+ need it. **Part 0 is new.** Building it caught me in two errors of my own:
20
+
21
+ 1. Rev 2 said *"there is no interactive prompt; I checked the source."* **Wrong.** I checked `setupWallet`
22
+ and the `setup` case but never the no-args branch — bare `indelible-mcp` on a TTY runs a wizard that
23
+ prompts for the key. **The safe path existed the whole time and I told people it did not.**
24
+ 2. Rev 2 said a key pasted into a session "can end up permanently committed to chain." **Overstated.**
25
+ Session saves scrub validated WIF-shaped strings before the commit. Corrected in 7.2, with the residual
26
+ risks stated precisely.
27
+
28
+ **Rev 4 — re-verified against 5.7.7, and the product moved underneath it.** Before shipping this inside
29
+ the npm package, every checkable claim was verified against the *installed* `indelible-mcp@5.7.7` artifact
30
+ rather than any source tree — 210 claims, seven independent reviewers, then an adversarial pass that tried
31
+ to refute each finding before it counted. Thirteen survived. Seven were corrected here.
32
+
33
+ **Four of those seven were not errors when written** — 5.7.7 shipped the same day and closed them: setup
34
+ now exits `1`, a failed setup installs nothing, the quoted setup error is new wording that leads with the
35
+ safe path, and the README never taught `--wif=` (our own `CLI_HANDBOOK.md` did). **Three were real
36
+ mistakes**, and one mattered: this handbook said a private key inside a saved file is *only flagged*. It
37
+ is **refused** — `credential_in_content` and `secret_filename` sit in an unconditional always-block set
38
+ that no setting overrides. Understating a safety net is the one direction that can hurt someone, because
39
+ an operator who meets that refusal reads it as a bug and reaches for the bypass. Corrected in 7.2.
40
+
41
+ *A handbook about not trusting your own report should not be the one document nobody checked. Rev 1 was
42
+ confident and wrong in four places; rev 2 was confident and wrong in two more — including one where I said
43
+ "I checked the source" and had checked the wrong branch. **That phrase is exactly the kind of claim this
44
+ handbook tells you not to accept, and it should not have been accepted from me.** Both errors were caught
45
+ by adversarial review, not by re-reading my own work. That is the method working.*
46
+
47
+ ---
48
+
49
+ # Part 0 — Day one: before any of this works
50
+
51
+ *Everything after this part assumes a configured wallet and a connected MCP. If the human is a new signup,
52
+ you are here first. **Read 7.2 before you touch a single command in this part.***
53
+
54
+ ## 0.1 The shipped README misdescribes setup; the CLI now corrects it for you
55
+
56
+ `README.md` documents this Quick Start:
57
+
58
+ ```bash
59
+ npm install -g indelible-mcp
60
+ indelible-mcp setup # "generates a BSV keypair locally"
61
+ ```
62
+
63
+ **The comment is wrong, and the command alone will not configure anything.** Bare `setup` returns:
64
+
65
+ ```json
66
+ {
67
+ "success": false,
68
+ "error": "Private key required. Get it at indelible.one → Settings → Private Key, then run `indelible-mcp` with no arguments and follow the prompts — that path takes the key at a prompt, so it never lands in your shell history. For automation: setup --wif=YOUR_KEY --pin=YOUR_PIN (clear your shell history afterward).",
69
+ "hint": "Run `indelible-mcp` with no arguments and follow the prompts. That path takes your key at a prompt, so it never lands in your shell history. Use `setup --wif=… --pin=…` only for automation, and clear your shell history afterward if you do.",
70
+ "hooks": "not installed — setup did not complete"
71
+ }
72
+ ```
73
+
74
+ - **It generates nothing.** `setupWallet` only ever calls `PrivateKey.fromWif(...)` and reports *"Wallet
75
+ **imported** and encrypted!"*. The key comes **from indelible.one**, not from the package. The README's
76
+ *"generates a BSV keypair locally"* (`README.md:27`) and its `setup Generate wallet & register`
77
+ (`README.md:75`) are both wrong on this point.
78
+ - **It exits `1`.** The failure prints a JSON error and sets a non-zero exit code, so a script can rely on
79
+ it. ⚠️ That guarantee belongs to the `setup` path specifically — `indelible-mcp status` and
80
+ `indelible-mcp load` still exit `0` while printing an error, so do not assume every verb signals failure
81
+ through its exit code.
82
+ - **It installs nothing.** The failure path reports `"hooks": "not installed — setup did not complete"` and
83
+ writes no files at all, so a failed setup is a clean stop, not a half-install. There is nothing to
84
+ clean up.
85
+
86
+ **If a human tells you "I ran setup and nothing happened," this is why.** Nothing is broken on their
87
+ machine, and nothing was half-written. The error itself now names the missing step and the safe way to
88
+ take it — read it to them rather than improvising.
89
+
90
+ ## 0.2 The sequence that actually works
91
+
92
+ **Steps marked 🧑 are the human's alone. Do not perform them, and do not ask them to route a key through
93
+ you.**
94
+
95
+ | # | Step | Who |
96
+ |---|---|---|
97
+ | 1 | `npm install -g indelible-mcp` | either |
98
+ | 2 | Claude Code installed (`npm install -g @anthropic-ai/claude-code`) | either |
99
+ | 3 | **Get the key:** indelible.one → sign in → Settings → copy Private Key (WIF) | 🧑 |
100
+ | 4 | **Run bare `indelible-mcp` in their own terminal**, paste the WIF, choose a PIN (4+ chars) | 🧑 |
101
+ | 5 | Wizard auto-runs `claude mcp add --scope user indelible -- indelible-mcp` and installs hooks | auto |
102
+ | 6 | **Fund the wallet** — it prints the BSV address and **blocks until funds arrive** | 🧑 |
103
+ | 7 | Pro, only if they want session saves — `indelible.one/pricing` | 🧑 |
104
+ | 8 | **Back up `~/.indelible/config.json`** — see 7.2 | 🧑 |
105
+
106
+ **Step 4 is the whole ballgame.** The wizard is the safe path: the key is typed at a prompt, never in
107
+ `argv`, so it never reaches shell history. `setup --wif=KEY --pin=PIN` is the documented alternative and it
108
+ **does** leak to history — prefer the wizard, always.
109
+
110
+ **Step 6 blocks.** The wizard polls for a UTXO every 10 seconds in an unbounded loop and will sit there
111
+ until the address is funded. **That is not a hang.** If the human says it froze after showing an address,
112
+ tell them it is waiting for coin, and that they can Ctrl-C and re-run `indelible-mcp` later — the wallet is
113
+ already configured by that point.
114
+
115
+ ## 0.3 What they get without paying
116
+
117
+ Do not imply a free user is locked out — most of the product works:
118
+
119
+ | Free | Pro |
120
+ |---|---|
121
+ | **All reads** — `recall_context`, `load_context`, `load_file`, `load_project` | Session / file / project saves |
122
+ | Restore, the time card, style loading, Guardrails | The pre-compaction save |
123
+ | Diary conversations | **Goal snapshots to chain** (`save_goals_to_chain` — a Pro write that spends sats) |
124
+
125
+ A free wallet still gets every hook. The pre-compaction **save** is the piece that prints a plain Pro
126
+ notice instead of saving — **that is not an error**, and you should not report it as one. Their work is
127
+ still on disk; it simply is not yet provable. See 7.1.
128
+
129
+ **One rough edge to expect:** the wizard's final step offers an AI style, and saving a style is itself
130
+ Pro-gated. On a free plan that step prints a warning and no style is stored. Onboarding still succeeded.
131
+
132
+ ## 0.4 Before you conclude anything is broken
133
+
134
+ `indelible-mcp status`, `indelible-mcp load`, and `indelible-mcp vault load-file|load-project|load-style`
135
+ work from the CLI **whether or not the MCP is connected in this session**. (⚠️ Not every read has a CLI
136
+ verb: `recall_context` and `diary_recall` are **MCP-only** — there is no `indelible-mcp recall`, it returns
137
+ `✗ unknown command`.) If your Indelible tools are missing, that is a *client wiring* problem, not a dead
138
+ install — check with the CLI before telling the human their setup failed.
139
+
140
+ Two wiring details worth knowing, because the docs disagree with the code:
141
+
142
+ - The wizard registers with `claude mcp add --scope user …`, which writes `~/.claude.json`. The README's
143
+ hand-edited `settings.json` block is a **different** mechanism. If both were done, expect confusion.
144
+ - Dropping `--scope user` registers the server **project-scoped**, so it will not load in other
145
+ directories. `CLI_HANDBOOK.md` omits the flag; the code includes it. **Follow the code.**
146
+
147
+ ---
148
+
149
+ # Part 1 — The one rule
150
+
151
+ > **Never report success that nothing independent of you has confirmed.**
152
+
153
+ This is the whole handbook compressed. Everything below is that rule applied to a specific surface.
154
+
155
+ You will be tempted to relay what a tool told you. A tool telling you it worked is **not** evidence that it
156
+ worked — it is evidence that it *said so*. The chain is evidence. A block height is evidence. A second
157
+ source that had no reason to agree with you is evidence.
158
+
159
+ **Three habits that make you trustworthy:**
160
+
161
+ 1. **Ground over recall.** Never answer from memory about state you can check. Read the file, query the
162
+ chain, run the command. A memory note is a lead, not a fact.
163
+ 2. **Separate what you observed from what you concluded.** *"It printed X"* and *"X means Y"* are different
164
+ sentences, and the second is wrong far more often. Write both, labelled.
165
+ 3. **Correct yourself out loud, immediately.** A wrong claim you retract costs you nothing. A wrong claim
166
+ the human discovers later costs you everything. *(I have retracted four claims in this engagement. Each
167
+ retraction made the report stronger, not weaker.)*
168
+
169
+ ---
170
+
171
+ # Part 2 — Goals: what they are for
172
+
173
+ Goals are not a to-do list. They are **a durable, timestamped local record of intent and outcome** that
174
+ outlives your context window and survives compaction, and that can be snapshotted to chain afterwards with
175
+ `save_goals_to_chain`.
176
+
177
+ ⚠️ **That snapshot is a Pro write and it spends sats.** On a free plan the call returns the Pro notice and
178
+ no txid; on an unfunded wallet it returns *"No UTXOs available."* So the local record is durable for
179
+ everyone, but **anchored** only for a funded Pro account. Never promise a free user an on-chain goal
180
+ record.
181
+
182
+ That last part is why they matter. A goal closed with a txid in its evidence is a claim anyone can check
183
+ years later. A goal closed without one is just a story.
184
+
185
+ ## The shape of a real goal
186
+
187
+ This is a live goal from a production box — study it, because the quality is in the fields most people
188
+ leave empty:
189
+
190
+ ```json
191
+ {
192
+ "goal_id": "g-002",
193
+ "title": "Rotate the QA wallet — a WIF was exposed in chat",
194
+ "intent": "A private key (WIF) was exposed in a chat transcript during earlier work. Any exposed key
195
+ must be treated as compromised — funds swept to a fresh wallet and all clients repointed —
196
+ before it can be drained.",
197
+ "priority": 95,
198
+ "owner": "user",
199
+ "next_actions": [
200
+ "Generate a fresh wallet (new WIF)",
201
+ "Sweep all funds from the exposed wallet to the new address",
202
+ "Update ~/.indelible config + every client/bridge to the new key",
203
+ "Confirm the old wallet reads 0 on-chain and is never reused"
204
+ ],
205
+ "success_criteria": "Exposed wallet drained to zero, all clients using the new key, old key retired
206
+ permanently.",
207
+ "evidence_links": [],
208
+ "proposed_by": "claude",
209
+ "accepted_at": "2026-07-10T16:44:10.832Z"
210
+ }
211
+ ```
212
+
213
+ **What makes it good:**
214
+
215
+ - **`intent` answers "why", not "what".** Anyone reading it in six months knows the stakes without asking.
216
+ - **`success_criteria` is falsifiable.** "Drained to zero" can be checked against the chain. "Improve
217
+ wallet security" cannot. If you cannot imagine the test that proves it done, rewrite it.
218
+ - **`next_actions` are ordered and concrete** — each one is a thing a person could do today, not a theme.
219
+ - **`priority` is honest.** 95 because an exposed key drains. Do not give everything 80.
220
+ - **`owner` is real.** `user` when only the human can act (this one needs their wallet). `claude` when you
221
+ can finish it alone. `shared` otherwise. Do not own what you cannot do.
222
+
223
+ ---
224
+
225
+ # Part 3 — The lifecycle, and the governance you must not break
226
+
227
+ ```
228
+ propose → (human accepts) → work → evidence → complete → snapshot to chain
229
+ ```
230
+
231
+ ## 3.1 You propose. The human accepts. Never both.
232
+
233
+ `manage_goal` records `created_at` / `proposed_by` on propose, and `accepted_at` on accept. That
234
+ separation is the audit trail of consent. **Do not propose and accept in the same breath** — you would be
235
+ manufacturing agreement that never happened.
236
+
237
+ ⚠️ **But know exactly how thin that trail is.** `proposed_by` is not a timestamp and not an identity — it
238
+ is the hardcoded literal `"claude"` for every proposal. And there is **no `accepted_by` field anywhere in
239
+ the product**, so nothing records *who* accepted. The separation is only as truthful as your discipline in
240
+ keeping it. Same convention-not-lock caveat as 3.2 below.
241
+
242
+ ```
243
+ manage_goal(action:"propose", title:…, intent:…, success_criteria:…, next_actions:[…], priority:…, owner:…)
244
+ → then STOP. Tell the human it is proposed and wait.
245
+ ```
246
+
247
+ If the human says "just do it," you may proceed with the work — but say plainly that the goal is still
248
+ `proposed`, not `accepted`, so the record stays truthful.
249
+
250
+ ## 3.2 ⚠️ "Completion requires evidence" is a convention, not a lock
251
+
252
+ The tool description says completion requires evidence. **I checked the code: it does not.**
253
+
254
+ ```js
255
+ case "complete":
256
+ if (evidence) goal.evidence_links = [...] // ONLY if you pass it. No check. No error.
257
+ ```
258
+
259
+ Nothing stops you closing a goal with nothing to show. Which means **the integrity of the record is
260
+ entirely your discipline.** Treat it as a hard rule anyway:
261
+
262
+ > **Never call `complete` without at least one evidence link.** If you have no evidence, you have not
263
+ > finished — you have stopped.
264
+
265
+ The same applies to checklists: an unfinished checklist produces `checklist_advisory` and completes anyway.
266
+ Advisory means *you* are the check.
267
+
268
+ ## 3.3 What counts as evidence
269
+
270
+ In descending order of strength:
271
+
272
+ | Evidence | Why it is strong |
273
+ |---|---|
274
+ | **An on-chain txid** | Timestamped, signed, and independently checkable by anyone — see the caveat below |
275
+ | A commit SHA | Verifiable, but only while the repo exists and history is not rewritten |
276
+ | A URL | Verifiable today; may rot |
277
+ | A description of what you did | **Not evidence.** This is a story about evidence |
278
+
279
+ **Be precise about what a txid proves.** *Existence and timing* are permanent and need nothing from you:
280
+ anyone can confirm that this exact content was committed at that moment, and no one can alter or backdate
281
+ it. **Readability is not automatic.** Recovering the content later needs three things — the transaction
282
+ bytes still retrievable, the payload decryptable, and **the key still in the human's custody.** Lose the
283
+ key and the record stands forever as proof that something was said, permanently unreadable.
284
+
285
+ So: *"provably committed at this time"* — always true. *"anyone can read this forever"* — only with the key.
286
+ This is exactly why 7.2 matters.
287
+
288
+ Real example from a live goal — evidence that is actually checkable:
289
+
290
+ ```json
291
+ "evidence_links": [
292
+ "266da1a50885c1d94d623b0ebe71fd1fc085ad5bf4d32016e65aceab0252482f",
293
+ "f40507bdc7b552e1a3bc0f4ac96fe40397695fb576570192f713a78a438adf76"
294
+ ]
295
+ ```
296
+
297
+ Anyone can take those txids to a bridge and read the artifact. That is the standard.
298
+
299
+ ## 3.4 Use `notes` for findings that change the goal's meaning
300
+
301
+ When you learn something that reframes the work, write it into `notes` — not into a chat message that
302
+ dies with your context. A real one:
303
+
304
+ > *"ROOT CAUSE FOUND 7/10 (bigger than Conner): server-side session-store ingestion was frozen fleet-wide
305
+ > since 6/30 16:15 — proven by replay experiment… Conner's client was never at fault; every wallet
306
+ > onboarded after 6/30 had an empty store. Root fixed + backfilled 7/10; verified live (store 34→37).
307
+ > REMAINING: have Conner reload his Context tab."*
308
+
309
+ Notice: what was found, how it was proven, what it changes, and **what is still open**. That last clause
310
+ is what makes it useful to the next session.
311
+
312
+ ---
313
+
314
+ # Part 4 — Putting it on chain: making it indelible
315
+
316
+ Two different things get written, and you should know which you are doing.
317
+
318
+ **`save_goals_to_chain`** — snapshots the whole goals state to BSV. Use it at meaningful boundaries: after
319
+ a goal is accepted, after one is completed, at the end of a working session. It is the proof that *this
320
+ was the plan, at this time.*
321
+
322
+ **`save_file` / `save_session`** — writes the artifact itself. Use it for the report, the brief, the
323
+ evidence document whose txid you will then link into the goal.
324
+
325
+ ## The pattern that produces provable work
326
+
327
+ ```
328
+ 1. Do the work.
329
+ 2. Write the artifact (report, brief, diff, findings).
330
+ 3. save_file(artifact) → returns a txid
331
+ 4. VERIFY that txid against the chain → never trust the receipt alone (Part 5)
332
+ 5. manage_goal(action:"complete", evidence:[txid], notes:"what was proven and how")
333
+ 6. save_goals_to_chain() → the closure itself is now on chain
334
+ ```
335
+
336
+ Step 4 is the one people skip. It is the one that makes the rest true.
337
+
338
+ **Why this ordering matters:** the goal's evidence link points at an artifact that already exists on chain.
339
+ Anyone auditing later can follow goal → txid → artifact and check every claim without asking you anything.
340
+
341
+ ---
342
+
343
+ # Part 5 — Verifying a save (do not trust the receipt)
344
+
345
+ A save receipt is the writer's own account of itself. Read it, then check it.
346
+
347
+ **What the receipt fields actually mean on 5.7.7:**
348
+
349
+ | field | meaning |
350
+ |---|---|
351
+ | `status: "pending"` | On the network, **not yet in a block.** Correct and normal for a fresh save |
352
+ | `status: "committed"` | A block genuinely contains it. Only appears after mining |
353
+ | `status: "unknown"` | The chain could not be reached to classify it. **Not** a failure and **not** a success — go verify directly |
354
+ | `confirmed: false` | Not mined yet — expected alongside `pending` |
355
+ | `indexed: true/false` | Whether the search index accepted it. `false` = on chain but not yet findable. ⚠️ Present on `save_file` and `save_session` receipts **only** — goals, project and style snapshots omit it entirely, and **absent is not the same as `false`** |
356
+
357
+ ⚠️ **Two vocabularies, and the customer sees the other one.** The states above are fields on the
358
+ structured object. The receipt block a human actually reads prints `broadcast` (= `pending`) and
359
+ `confirmed` (= `committed`). And `save_goals_to_chain` — the whole subject of Part 4 — returns the printed
360
+ block only, so its object fields are never visible at all. Read what is in front of you before naming a
361
+ state to the human.
362
+
363
+ **Never treat `pending` as failure, and never treat a receipt as proof of burial.**
364
+
365
+ To verify independently, ask the federation directly:
366
+
367
+ ```
368
+ GET http://<bridge>:9333/api/tx/<txid>/hex → the raw transaction (proves it exists)
369
+ GET http://<bridge>:9333/api/tx/<txid>/status → blockHeight / confirmed
370
+ GET http://<bridge>:9333/api/address/<addr>/unspent
371
+ ```
372
+
373
+ **The strongest cheap check:** does the transaction's change output appear in the address's live UTXO set?
374
+ That was correct every single time across this engagement, while a bridge's `inMempool` flag was wrong for
375
+ every phantom. Ask several bridges — agreement across independent nodes is the point of a federation.
376
+
377
+ ---
378
+
379
+ # Part 6 — Failure modes, and what they actually mean
380
+
381
+ Learn these and you will stop misreading normal behavior as breakage.
382
+
383
+ | What you see | What it means | What to do |
384
+ |---|---|---|
385
+ | `status: pending` | Normal. Awaiting a block | Nothing |
386
+ | `WALLET_BUSY_RESERVED` | Another agent holds the coin. Names the holder and lease | Retry shortly. Safe |
387
+ | `BROADCAST_REJECTED … txn-mempool-conflict` | Another save took the coin first. **Nothing was spent** | Retry; it rebuilds |
388
+ | `WALLET_KEY_MISMATCH` | The key does not match the account. **Refused before spending** | Do not "fix" by editing config — run setup properly |
389
+ | `indexed: false` | On chain, not yet searchable | Nothing. It catches up |
390
+ | `⚠ agent could not be read … corrupt, NOT deleted` | A torn identity file | **Never re-birth over it.** Restore that file from backup. ⚠️ `agents --restore` will **not** fix it — it refuses an identity it cannot parse (*"refusing to overwrite a file we cannot compare"*) and leaves the file untouched. Only once the file is restored, or deliberately deleted, will a re-run rebuild that agent |
391
+ | `[g-401] lost its coin to <txid>` | Another writer spent it first | Informational |
392
+ | **Two machines, one wallet — both said `success`** | **The reservation is per-machine. One save is genuinely lost, silently** | **Write from one box only — see 7.0** |
393
+ | A Pro-gated tool refusing | Saves need Pro; reads are free | Tell the human what it costs before retrying (7.1) |
394
+ | `could not record receipt … save is on chain` | Local log write failed | Data is safe; fix the file permission |
395
+
396
+ **Note the shape of that table.** Almost every entry means *nothing is broken and nothing was lost.* The
397
+ one row that means real data loss is the two-machine row — and it is the only one that reports **success**.
398
+ That is the whole lesson of this handbook in a single line: **the alarming messages are safe, and the
399
+ dangerous one looks fine.**
400
+
401
+ **The meta-lesson:** every one of these is the product being honest with you. Earlier versions said
402
+ "committed" in several of these situations and customers lost work. Do not paper over an honest error by
403
+ retrying blindly — read it.
404
+
405
+ ---
406
+
407
+ # Part 7 — Things that will bite you
408
+
409
+ ## 7.0 ⚠️ THE ONE-WRITER RULE — read this before anything else in this part
410
+
411
+ **Read from every machine. Write from one.** This is the single most important operational fact in the
412
+ product, and it is stated in the shipped `CLI_HANDBOOK.md`:
413
+
414
+ > *"The same wallet on two machines: read from both, write from one. The coin-reservation that stops two
415
+ > saves colliding is kept **on the machine it runs on** — it cannot see a sibling box. So two machines
416
+ > sharing a wallet can pick the same coin, both broadcast, and Bitcoin keeps one; each box sees only its
417
+ > own attempt, so **both can report success while one save is lost.**"*
418
+
419
+ I have reproduced this on a customer box: two machines, one wallet, one coin — both returned
420
+ `success: true`, and one file was permanently gone. **The reservation layer is correct; it simply cannot
421
+ see another machine.**
422
+
423
+ **What this means for you:**
424
+
425
+ - Recall, verify, `load`, and read freely from anywhere.
426
+ - **Do the saving from one machine at a time.** If the human works on a laptop and a desktop, ask which one
427
+ is the writer.
428
+ - Treat any save that says `pending` or times out as **not yet durable** until you confirm it on chain.
429
+ - If two hosts are connected (e.g. Claude and Codex both with the MCP), **they each run an auto-save
430
+ timer.** That is two writers on one wallet by default. Say so to the human.
431
+
432
+ ## 7.1 Saving costs money and needs Pro
433
+
434
+ The shipped customer handbook is explicit:
435
+
436
+ > *"A funded wallet. **Session, file, and project saves need Pro. All reads are free.**"*
437
+ > *"…all four hooks run for everyone. Restore, the time card, style loading, and Guardrails are fully free.
438
+ > The pre-compaction **save** is the one piece that needs Pro. On a free wallet the hook still fires, but
439
+ > instead of saving it prints the plain notice that saving is a Pro feature. **That is not an error.**"*
440
+
441
+ Entitlement is checked **server-side per feature**, so do not hand the human a memorized list of gated
442
+ tools — I got that wrong once already. The reliable rule is the documented one: **writes need Pro, reads
443
+ are free.** If a save refuses on plan grounds, read what it actually says and relay that, rather than
444
+ guessing which tier covers what.
445
+
446
+ **So do not bank reflexively.** Every write spends real satoshis on the human's wallet and requires their
447
+ plan. Bank at **milestones that matter** (Part 10.2), not after every paragraph. On a free wallet, the
448
+ pre-compaction save is the one thing that will not fire — restore, the time card, style loading and the
449
+ guardrails all still work.
450
+
451
+ ## 7.2 Back the key up — "never sync" is only half the advice
452
+
453
+ `~/.indelible` holds unencrypted key material, so **never** suggest syncing it to Dropbox/iCloud/OneDrive/git.
454
+
455
+ **But the opposite failure is just as fatal**, and the shipped handbook says so: if the machine dies and
456
+ there is no copy of the key, the history survives on chain **forever and unreadable.** Encrypted with a key
457
+ that no longer exists is the same as gone.
458
+
459
+ Tell the human to keep a **secure offline copy** of their key — a password manager or paper, not a synced
460
+ folder. This is one of the few things worth interrupting them for.
461
+
462
+ ### ⚠️ Never run setup yourself. There is a safe path — point the human at it.
463
+
464
+ There are **two** ways to configure the key, and they are not equally safe:
465
+
466
+ | path | key in shell history / process list | can *you* run it? |
467
+ |---|---|---|
468
+ | **bare `indelible-mcp`** (the wizard) | **No** — typed at a prompt | **No.** TTY-gated |
469
+ | `setup --wif=KEY --pin=PIN` | **Yes — both** | Yes ← the hazard |
470
+
471
+ **Recommend the wizard.** Bare `indelible-mcp` on a terminal runs `runWizard()`, which prints
472
+ *"Go to indelible.one → Sign in → Settings → copy your Private Key (WIF)"* and prompts `Paste your WIF
473
+ here:`. Nothing reaches `argv`, so nothing reaches the history file.
474
+
475
+ **It is structurally out of your reach, by design.** The dispatcher sends no-args to the wizard **only when
476
+ `process.stdin.isTTY`**; without a TTY it starts the MCP server instead. So when you invoke it you do not
477
+ get the prompt. Do not fight that — it is the guardrail working.
478
+
479
+ **The `--wif=` form is the one to avoid.** It writes the key **and** the PIN into `~/.bash_history` /
480
+ `ConsoleHost_history.txt`, and exposes them in process listings while it runs.
481
+
482
+ The product already steers away from it: the help text lists the wizard **first** as *"recommended — your
483
+ key is never written to shell history"* and labels the flag form *"for automation (both values land in
484
+ shell history)"*, both setup error messages lead with the wizard, and the README never mentions `--wif=`
485
+ at all. The one exception is `CLI_HANDBOOK.md` (lines 231 and 382), which still teaches the flag form with
486
+ no warning attached — treat that as a doc bug, not as guidance, and follow the CLI's own steer instead.
487
+
488
+ **So:**
489
+
490
+ - **Never run either form on the human's behalf, and never ask them to paste a key to you.** Name the
491
+ command; let them run it in their own terminal.
492
+ - If they have already used `--wif=`, have them clear the history entry (`~/.bash_history`, or the
493
+ PowerShell file at `(Get-PSReadlineOption).HistorySavePath`).
494
+ - If a key ever does appear in your context, **say so immediately** and treat it as compromised. It needs
495
+ rotating, not hiding.
496
+
497
+ **Credit where it is due — and a correction to an earlier draft of this handbook.** Rev 2 claimed a key
498
+ pasted into a session "can end up permanently committed to chain." **That was overstated.** Session saves
499
+ run `redactSession()` in the save path — after the envelope is built and before the commit — which
500
+ replaces validated WIF-shaped strings with
501
+ `[REDACTED bsv_wif]` *before* the commit and prints
502
+ `[indelible] redact-on-save: scrubbed N credential-shaped string(s)`. The chain-commit outcome is
503
+ specifically defended against.
504
+
505
+ **What is still true, and why the rule stands anyway:**
506
+
507
+ - Redaction guards the **session** path; `save_file` does **not** call it. A key inside a file is caught by
508
+ the Witness instead, and although the Witness ships advisory (`witness.enforce: false`), two critical
509
+ codes sit in an unconditional **always-block** set: `credential_in_content` and `secret_filename`. A file
510
+ save carrying a well-formed key is **refused** (`Witness rejected file save: …`), not merely flagged.
511
+ Binary files are not content-scanned, but `.pem` / `.key` / `.env` still hard-block on the filename.
512
+ **Do not reach for `bypass_witness` or `WITNESS_BYPASS=1` to get past this** — that refusal is the last
513
+ thing standing between a live key and an immutable chain.
514
+ - It is pattern-matched and `isValidWif`-validated: a well-formed key is caught; a wrapped, split or
515
+ partial one is not guaranteed to be.
516
+ - It cleans the *commit*, not the world. The key is still in the local transcript on disk, still in the
517
+ terminal scrollback, and still in shell history if it arrived by `--wif=`.
518
+
519
+ **One layer working is not a reason to hand it more chances.** This is the one rule where being helpful is
520
+ the failure mode: **refusing to touch the key is the correct and maximally helpful action.**
521
+
522
+ ## 7.3 The rest
523
+
524
+ 1. **Coin contention is normal on a busy box.** If auto-save and you both want to write, one waits — see
525
+ the wait/lease distinction in 7.4. Splitting the balance into several outputs eases *same-machine*
526
+ contention, **but it does not fix the cross-machine problem in 7.0** and it moves the human's money:
527
+ **only ever suggest it, never do it unasked**, and let them choose the method.
528
+ 2. **Auto-save runs inside the MCP server** — it stops when the editor closes. Before a long break, save
529
+ once by hand (if they are on Pro).
530
+ 3. **On a new machine, run `agents --restore` before concluding the crew is missing.** Agents live in the
531
+ wallet, not the box. The most common false alarm there is.
532
+ 4. **Never print a private key, WIF, or seed** — not into chat, not into a file you will save, not into a
533
+ goal note. Report *the path and the fact*: "`agents/x/identity.json` has a plaintext `wif` field" is the
534
+ finding. The key itself is never the finding.
535
+ 5. **The credential guard is one layer, not a vault.** It inspects shell commands, will refuse harmless
536
+ ones whose filenames contain "wif"/"seed", and does not see programmatic reads. Route around it
537
+ honestly; never treat getting past it as permission.
538
+ 6. **Do not run two summoners for one seat** — the wire admits one answer, but both pilots bill the human's
539
+ vendor account.
540
+
541
+ ## 7.4 The two timers people confuse
542
+
543
+ - **Wait = 60 s** (`DEFAULT_WAIT_MS`) — how long *your* save will wait for a coin someone else holds.
544
+ - **Lease = 120 s** (`DEFAULT_LEASE_MS`) — how long the *holder's* claim stays valid.
545
+
546
+ They are different numbers for different actors. A save that gives up after 60 s has not hit a "60-second
547
+ lease" — it waited its full wait while a 120-second lease was still running.
548
+
549
+ **And Ctrl-C does not create a permanently stuck reservation.** As of 5.7.6 (still true on 5.7.7) a stale reservation — including
550
+ one holding a signed transaction — is reconciled automatically by chain evidence on the next claim.
551
+ **Manual clearing is almost never justified**; if you think it is, snapshot first (10.4) and say why.
552
+
553
+ ---
554
+
555
+ # Part 8 — A worked example, end to end
556
+
557
+ The human asks you to look into something. Here is the whole shape:
558
+
559
+ ```
560
+ 1. PROPOSE
561
+ manage_goal(propose,
562
+ title: "Confirm the bridge tx-status false-negative and file it",
563
+ intent: "The endpoint reports not-found for transactions that ARE confirmed — the mirror of a
564
+ hollow confirmed:true. Open since 6/22; unfiled, so it cannot be triaged.",
565
+ success_criteria: "GitHub issue filed with a reproducible case and the exact endpoint.",
566
+ next_actions: ["Capture a clean repro", "File on the federation repo", "Link the issue here"],
567
+ priority: 40, owner: "shared")
568
+ → tell the human. WAIT for accept.
569
+
570
+ 2. WORK — and ground everything
571
+ Query the endpoint. Query a control. Record exact responses, not impressions.
572
+
573
+ 3. WRITE THE ARTIFACT
574
+ A brief with the repro, the control, and the raw output.
575
+
576
+ 4. BANK IT AND VERIFY
577
+ save_file(brief) → txid
578
+ check txid on 3+ bridges → confirm it exists
579
+
580
+ 5. RECORD PROGRESS HONESTLY
581
+ manage_goal(update, notes: "CLEAN REPRO CAPTURED: /chain/seen/e8381c21 returned exists:true
582
+ height:956557 on 7/5, then exists:false on 7/10 — same tx, same bridge, confirmed both times.
583
+ Control: a 30-min-old tx returns exists:true. REMAINING: file the issue.")
584
+
585
+ 6. COMPLETE ONLY WHEN THE CRITERIA ARE MET
586
+ manage_goal(complete, evidence:[txid, issue_url], notes:"…")
587
+ save_goals_to_chain()
588
+ ```
589
+
590
+ Step 6 is the discipline. If the issue is not filed, the goal is **not** complete — no matter how good the
591
+ repro is. Update it, say what remains, and leave it open. **An honestly open goal is worth more than a
592
+ falsely closed one**, because the next session inherits the truth.
593
+
594
+ ---
595
+
596
+ # Part 9 — Writing the record: how to keep an arc going
597
+
598
+ Single documents are cheap. What compounds is an **arc** — a series where each document knows about the
599
+ ones before it, corrections are visible, and a stranger can read them in order and reconstruct the whole
600
+ story without asking anyone a question.
601
+
602
+ This is the part most operators never learn, and it is the difference between a pile of notes and a record.
603
+
604
+ ## 9.1 What an arc looks like
605
+
606
+ A real one, produced over eleven days across five releases:
607
+
608
+ ```
609
+ QA-GRADE-5.6.0-2026-08-10.md D+ 44156dd9… ← baseline: what was broken, and why it was invisible
610
+ QA-GRADE-5.7.1-2026-08-13.md A− a649c159… ← 3 P0s fixed; one condition named for the A
611
+ QA-GRADE-5.7.2-2026-08-14.md A− f5770cad… ← 5 fixed, but a new interaction appeared
612
+ QA-GRADE-5.7.3-2026-08-14.md A 9cf8febe… ← the named condition met, exactly
613
+ QA-GRADE-5.7.6-2026-08-16.md A 44a7cf24… ← two P1s closed; the biggest unlock of the series
614
+ ```
615
+
616
+ Read top to bottom and you get a narrative with a spine: *a product that lied about saving your work
617
+ learned to tell the truth.* No single document contains that. **The arc does.**
618
+
619
+ ## 9.2 The anatomy of a document that will still be useful in a year
620
+
621
+ Every entry in an arc carries the same seven parts. Not a template to fill in mechanically — a checklist of
622
+ what a future reader will need.
623
+
624
+ 1. **A header that orients a stranger.** Who wrote it, when, against what version, and *how it was
625
+ verified*. One line: *"measured on this box or checked against the public chain, never taken from a
626
+ receipt."*
627
+ 2. **A verdict up front.** A grade, a status, a one-sentence judgment. Put it in the first screen. Readers
628
+ who only read one thing should still get the answer.
629
+ 3. **Verbatim evidence, not paraphrase.** Paste the actual output, the exact line number, the real txid.
630
+ `:11098 buildReceipt(…, { indexed })` is checkable. "the receipt now includes indexed" is a rumour.
631
+ 4. **Observation separated from conclusion**, always labelled. *"I observed X"* then *"I conclude Y, and
632
+ here is why that might be wrong."*
633
+ 5. **A status carry-forward** — three buckets, every time: **fixed** (with evidence), **still open** (with
634
+ why it matters), **new**. This is what makes the next document possible.
635
+ 6. **An honesty ledger.** A named section listing what *you* got wrong since the last entry. Non-negotiable —
636
+ see 9.4.
637
+ 7. **Scope, stated as a limit.** What you did *not* test. A reader who mistakes your silence for coverage
638
+ will make a bad decision with your name on it.
639
+
640
+ ## 9.3 Naming, superseding, and the fact that chain is immutable
641
+
642
+ **Name for retrieval, not for prettiness.** `SUBJECT-scope-YYYY-MM-DD.md`. A year later someone will find
643
+ it by grepping a folder or a chain index — the filename is the index entry.
644
+
645
+ **You cannot edit what is on chain.** This changes how you correct things. Two moves, and they are not
646
+ interchangeable:
647
+
648
+ - **Amend** — the document is not yet banked. Edit it freely, then bank the finished thing.
649
+ - **Supersede** — the document is already on chain. **Write a new one that names what it replaces and
650
+ why.** Never quietly rewrite history; the old txid still exists and someone will read it.
651
+
652
+ A real superseding header, doing it properly:
653
+
654
+ > *"⚠️ THIS DOCUMENT CORRECTS AN ERROR IN THE CONSOLIDATED REPORT `628f6cba…`. It states the crew has never
655
+ > existed on this box. That is FALSE… Chain is immutable, so this document supersedes that section."*
656
+
657
+ That is the whole move: name the txid, state the error plainly, explain what replaces it. A reader landing
658
+ on the old document from a search still gets pointed at the truth.
659
+
660
+ ## 9.4 The honesty ledger — the part that makes the rest credible
661
+
662
+ Every entry in an arc should carry a section listing what you got wrong since the last one. A real example:
663
+
664
+ > - I reported corrupt identity **still silent**. **Wrong** — my check read `stdout` while the warning goes
665
+ > to `stderr`.
666
+ > - I called the second MCP process **a leaked duplicate**. **Wrong** — it is a legitimate second host.
667
+ > - I inferred a behavior from `findNewestTranscript()`. **Unsupported** — the source fact stands, the
668
+ > inference does not.
669
+ > - I nearly filed **idempotency broken**. **My test conditions**, not the product.
670
+
671
+ **Why this is not self-flagellation but the opposite:** a document with no corrections in it reads as
672
+ either flawless or unexamined, and readers correctly assume the second. A ledger tells them you are
673
+ checking, that your other claims survived the same scrutiny, and that when you say something held, it held.
674
+
675
+ It also does practical work: it stops the *next* session inheriting your bad conclusion as fact.
676
+
677
+ ## 9.5 The daily rhythm
678
+
679
+ You do not need a release to justify an entry. A working session is enough.
680
+
681
+ ```
682
+ START get_goals — hydrate: what was open, what was claimed, what is next
683
+ load / recent saves — what the last session actually concluded
684
+
685
+ DURING keep a running scratch file: verbatim output, timestamps, txids
686
+ when something surprises you, write the observation before the explanation
687
+
688
+ END write the entry — verdict, evidence, fixed/open/new, honesty ledger, scope
689
+ save_file(entry) → txid
690
+ VERIFY the txid on chain
691
+ manage_goal(update or complete, evidence:[txid])
692
+ save_goals_to_chain()
693
+ ```
694
+
695
+ **Three rules that keep an arc alive:**
696
+
697
+ - **Write the entry while the evidence is still in front of you.** Reconstructed detail is where errors are
698
+ born. If you are quoting from memory, you are already guessing.
699
+ - **One entry per session, not one per finding.** Findings are sections. A session is the unit a reader can
700
+ follow.
701
+ - **Bank it before you move on.** An unbanked document is a draft, and a draft is not a record. The moment
702
+ it has a txid it is citable, and the *next* entry can point at it instead of repeating it.
703
+
704
+ ## 9.6 How the pieces reference each other
705
+
706
+ An arc is a graph, and the edges are txids:
707
+
708
+ ```
709
+ goal g-006
710
+ └── evidence: 266da1a5… ← the brief proving the repro
711
+ └── superseded by: (later brief, if the finding changes)
712
+
713
+ QA-GRADE-5.7.6 44a7cf24…
714
+ ├── supersedes: nothing (new release)
715
+ ├── cites: the 5.7.3 grade, for the condition that was named and met
716
+ └── companion: BUGS-open-as-of-5.7.6 f2c3cf19…
717
+ └── supersedes: BUGS-5.7.3-drafted e48dd3cc…
718
+ ```
719
+
720
+ **When you cite, cite the txid, not the filename.** Filenames are local and can be renamed or lost; a txid
721
+ resolves from anywhere and cannot be altered or backdated. That is the entire reason to put it on chain.
722
+ (Reading the *content* back also needs the key — 3.3.)
723
+
724
+ ## 9.7 The test of a good arc
725
+
726
+ > Hand the series to someone who was not there. Can they reconstruct what happened, what is true now, and
727
+ > what is still unknown — **without asking you a single question?**
728
+
729
+ If yes, you have built a record. If they have to ask "but did that ever get fixed?" or "which of these is
730
+ current?", you have built a pile.
731
+
732
+ ---
733
+
734
+ # Part 10 — Prepare for compaction; do not run into it
735
+
736
+ Your context window will end. That is not a risk to manage, it is a certainty to schedule around. The
737
+ difference between a good operator and a green one is whether compaction finds them **ready or mid-sentence.**
738
+
739
+ ## 10.1 What actually happens
740
+
741
+ The pre-compact hook fires and saves the session automatically. **Do not rely on that as your plan** — it
742
+ saves the *transcript*, not your *conclusions*. A transcript of you reasoning toward a finding is not the
743
+ same artifact as the finding, written down, with its evidence, banked and citable.
744
+
745
+ Auto-save is your seatbelt. The daily MD is your actually-arriving-somewhere.
746
+
747
+ ## 10.2 Bank at milestones, not at the end
748
+
749
+ The failure mode is obvious once you have seen it: you work for three hours, plan to "write it up at the
750
+ end," and compaction arrives at hour two and forty minutes. Everything you *knew* is now a summary of a
751
+ summary.
752
+
753
+ **Bank when a thing becomes true, not when the session ends.**
754
+
755
+ | Moment | What to do |
756
+ |---|---|
757
+ | A finding is proven | Write the section. Bank the MD if it stands alone |
758
+ | A goal's criteria are met | `complete` with evidence, then `save_goals_to_chain()` |
759
+ | You are about to do something destructive | Snapshot the evidence **first** (see 10.4) |
760
+ | Context feels long, or the human goes quiet | Write the entry now, while the detail is in front of you |
761
+ | Before any risky or long operation | Bank first — so a crash costs the operation, not the knowledge |
762
+
763
+ **Rule of thumb: if losing the last hour would hurt, you are already overdue.**
764
+
765
+ **Separate the two halves, because only one costs money.** *Writing the document* is free and you should do
766
+ it liberally — the local MD is where the knowledge actually survives. *Committing it to chain* needs Pro
767
+ and spends sats (7.1), so it is the deliberate half. Write every milestone; bank the ones that are
768
+ **finished, standing, and worth citing later.**
769
+
770
+ That split also protects a customer on a free plan: their record still exists on disk and their work is
771
+ still recoverable — it simply is not yet provable. Say it that way rather than implying they have lost
772
+ everything.
773
+
774
+ ## 10.3 The pre-compaction checklist
775
+
776
+ When you sense the window closing — long session, big outputs, a lot of tool calls — spend two minutes:
777
+
778
+ ```
779
+ 1. Write the entry verdict · verbatim evidence · fixed/open/new · honesty ledger · scope
780
+ 2. save_file(entry) → txid
781
+ 3. Verify the txid on chain (do not skip: an unverified bank is a hope)
782
+ 4. manage_goal(update/complete, evidence:[txid], notes:"what is proven, what remains")
783
+ 5. save_goals_to_chain()
784
+ 6. Leave a next-step line the single most useful sentence for your successor
785
+ ```
786
+
787
+ That last one matters more than it looks. Your successor wakes with a summary and no instinct. **One
788
+ explicit sentence** — *"REMAINING: file the GitHub issue; repro is captured in txid 266da1a5"* — is worth
789
+ more than a page of restored context. Write it into the goal's `notes`, not into chat, because chat is
790
+ what gets compacted.
791
+
792
+ ## 10.4 Snapshot before you mutate
793
+
794
+ Any time you are about to clear a cache, delete a reservation, corrupt a file to test error handling, or
795
+ overwrite state: **copy the evidence somewhere durable first.**
796
+
797
+ You will otherwise destroy the only proof of the thing you were investigating. Once you clear a stuck
798
+ reservation, "there was a stuck reservation" becomes your word against nothing. A snapshot file — or better,
799
+ a banked txid — keeps the finding real after the state is gone.
800
+
801
+ ## 10.5 After compaction: reconcile, do not assume
802
+
803
+ You will wake with two sources: the **blockchain restore** (signed, timestamped — authoritative) and a
804
+ **continuation summary** (auto-generated, unverified — secondary).
805
+
806
+ - Orient from the chain restore first.
807
+ - Treat the summary as a lead for anything after the last save timestamp.
808
+ - **Say which source told you what.** *"Source: blockchain (tx X, saved TIME)"* and, if relevant,
809
+ *"Gap: N messages from the continuation summary."*
810
+ - **If they disagree, reconcile by timestamp — do not simply declare "the chain wins."** The chain is
811
+ authoritative for **what was true at the moment it was saved.** It says nothing about the twenty minutes
812
+ of work that happened after the last save. A signed record from 09:12 does not overrule a summary
813
+ describing 09:40. Take the chain as the trusted baseline, layer the post-save gap on top as *unverified*,
814
+ and label it that way.
815
+ - Then `get_goals` — that is where your successor-self left the real state.
816
+
817
+ Never claim knowledge from the chain restore that you actually got from the summary. It is the same
818
+ discipline as Part 1, applied to your own memory.
819
+
820
+ ---
821
+
822
+ # Part 11 — Talking to humans, and the line to the dev team
823
+
824
+ A green operator interrupts. A good one arrives with the answer, or with a question only the human can
825
+ resolve. **Every unnecessary escalation spends the one resource you cannot mint: their attention.**
826
+
827
+ ## 11.1 Answer it yourself first — the four checks
828
+
829
+ Before asking a human anything about Indelible, do these. Most questions die here:
830
+
831
+ 1. **Read the shipped docs.** `CLI_HANDBOOK.md` and `CUSTOMER_AGENT_HANDBOOK.md` ship **inside the npm
832
+ package** (`node_modules/indelible-mcp/`). They are ground truth for what the installed version claims,
833
+ and almost nobody reads them.
834
+ 2. **Ask the box.** `indelible-mcp status`, `--version`, `agents --list`, `workshop --status`,
835
+ `drift ledger`, `get_goals`.
836
+ 3. **Ask the chain.** `/api/tx/<txid>/status`, `/api/address/<addr>/unspent`, and a bridge `/health`.
837
+ This settles nearly every "did it work?" question outright.
838
+ 4. **Check whether it is documented behavior.** Several things that look broken are stated intentions —
839
+ commerce agents needing personas, escrow being refused for now, notary being inherently two-block.
840
+
841
+ ## 11.2 What is worth waking a human for
842
+
843
+ **Ask when:** money or keys are at stake · the action is irreversible · a decision is genuinely theirs
844
+ (what to buy, what to prioritise, whether to rotate a key) · you have two readings of a requirement and
845
+ they lead to different work.
846
+
847
+ **Do not ask when:** the box or the chain can tell you · it is in the shipped docs · it is a transient you
848
+ have not retried · you are seeking reassurance rather than information.
849
+
850
+ **And when you do ask: bring the answer with you.** Not *"a save failed, what should I do?"* but *"a save
851
+ hit `WALLET_BUSY_RESERVED` twice, the holder is a live pid with a lapsed lease, retry succeeded on the
852
+ third attempt in 11s — flagging it because it may indicate contention, nothing is lost."* One message,
853
+ decision-ready.
854
+
855
+ ## 11.3 The reporter is a channel to the team, not just a bug form
856
+
857
+ `report_bug` is the line to the Indelible team — **and it is not only for bugs.** Use it for ideas,
858
+ suggestions, feature requests, questions about intended behavior, and "this was confusing" feedback.
859
+ Anything you would otherwise ask a human to relay, send directly.
860
+
861
+ **Mark the intent in the summary** so triage is instant:
862
+
863
+ ```
864
+ report_bug(summary: "SUGGESTION: agents --restore should say how many citizens lack personas",
865
+ description: "After a restore, 2 of 16 got personas, so 3 commerce agents silently cannot be
866
+ served. A one-line note in the restore output would prevent the confusion.
867
+ Not a defect — a clarity improvement.",
868
+ severity: "low")
869
+ ```
870
+
871
+ Prefixes that work: `SUGGESTION:` · `IDEA:` · `QUESTION:` · `DOCS:` · `UX:` · plain summary for a real defect.
872
+
873
+ **How to use it well:**
874
+
875
+ - **Do not invent facts.** The tool auto-attaches the real version, wallet address, recent receipts and
876
+ environment. Supply only the narrative. Never fabricate a version, txid, or URL — you will be wrong and
877
+ it will be checked.
878
+ - **Triage transients first.** Retry a "No UTXOs" or "gateway unreachable" blip before filing; those are
879
+ usually an unconfirmed change output resolving itself.
880
+ - **It auto-matches known issues.** A `status:"known_issue"` reply is a *good* outcome — instant triage,
881
+ nobody's time spent. Only use `still_file: true` when you are confident your case is genuinely different,
882
+ and say why.
883
+ - **Get the human's OK before filing.** It reaches real people.
884
+ - **Be specific enough to act on.** File and line, exact error text, and the smallest repro you can state.
885
+ *"Saving is slow"* is noise. *"A 970-byte file save took 16.5s; build and broadcast finished in <1s;
886
+ the remainder is unaccounted"* is a ticket someone can pick up.
887
+
888
+ ## 11.4 The green-operator mistakes, and what to do instead
889
+
890
+ These are the ones actually observed on customer boxes. Learn them and you skip the whole apprenticeship.
891
+
892
+ | Green move | What is really happening | Do this |
893
+ |---|---|---|
894
+ | Panicking at `status: pending` | Normal — awaiting a block | Nothing |
895
+ | Panicking at `indexed: false` | On chain, index lagging | Nothing |
896
+ | Concluding "my crew is gone" on a new machine | Agents live in the wallet, not the box | `agents --restore` |
897
+ | **Re-birthing over a corrupt agent** | The file is corrupt, **not** deleted — and the warning says so | Restore that file from backup. `agents --restore` refuses a file it cannot parse and will not repair it |
898
+ | Retrying a save every 15s | You are landing inside a live **120 s lease** and compounding contention | Let the built-in **60 s wait** do its job (7.4) |
899
+ | Killing a slow save with Ctrl-C | Leaves a reservation the next claim has to reconcile | Let it finish — it tells you what it is waiting for |
900
+ | **Saving from two machines on one wallet** | **Both can report success while one save is lost** | **Write from one box only (7.0)** |
901
+ | Banking after every small step | Each write costs the human sats and needs Pro | Bank at milestones (7.1, 10.2) |
902
+ | Editing `config.json` to "fix" `WALLET_KEY_MISMATCH` | The guard is protecting you from unreadable data | Run `setup` properly on that machine |
903
+ | Clearing caches reflexively | You destroy the evidence of the thing you were debugging | Snapshot first (10.4) |
904
+ | Relaying "✓ reported" as proof | That is the client's own claim | Verify against the server or the chain |
905
+ | Filing documented behavior as a bug | Wastes triage, erodes your signal | Check the shipped handbooks first |
906
+ | Asking the human "did my save work?" | The chain answers in one request | Query it, then report the answer |
907
+
908
+ **The through-line:** most of these are the same error wearing different clothes — *treating a system's
909
+ self-report as the truth, or treating an honest error as a catastrophe.* The product spent five releases
910
+ learning to tell you the truth. Read what it says, and check what matters.
911
+
912
+ ---
913
+
914
+ # Part 12 — What "as good as the QA box" actually means
915
+
916
+ Not knowing more commands. It is four habits:
917
+
918
+ 1. **Check the thing you are about to claim** — against the chain, the file, or a second source.
919
+ 2. **Test the mechanism, not the thing that resembles it.** Verify a function is *called*, not merely
920
+ defined. Confirm your test exercised the path you think it did. Several of my early findings were
921
+ invalid because the code path never ran.
922
+ 3. **Say what you do not know.** "I have not verified that" is a complete, professional sentence.
923
+ 4. **Leave proof, not assertions.** A txid outlives your context window. Your confidence does not.
924
+
925
+ > Everything above reduces to one question you should ask before every claim you make to a human:
926
+ > **"What would I show someone who did not believe me?"**
927
+ > If the answer is "my word," you are not finished yet.
928
+
929
+ — QA machine `15P3dSued`