brane 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. package/AGENTS.md +362 -0
  2. package/CHANGELOG.md +33 -0
  3. package/CONTRIBUTING.md +91 -0
  4. package/DESIGN.md +402 -0
  5. package/Dockerfile +61 -0
  6. package/LICENSE +656 -17
  7. package/README.md +174 -2
  8. package/SECURITY.md +205 -0
  9. package/dist/absorb/brane-id.js +11 -0
  10. package/dist/absorb/chatgpt.js +161 -0
  11. package/dist/absorb/claude-code.js +504 -0
  12. package/dist/absorb/index.js +543 -0
  13. package/dist/absorb/organelle.js +345 -0
  14. package/dist/absorb/run.js +520 -0
  15. package/dist/absorb/sources.js +168 -0
  16. package/dist/absorb/types.js +3 -0
  17. package/dist/agent-env.js +45 -0
  18. package/dist/agents.js +1168 -0
  19. package/dist/claude-live-session.js +124 -0
  20. package/dist/cli.js +50 -0
  21. package/dist/codex-tool-log.js +144 -0
  22. package/dist/commands/absorb.js +291 -0
  23. package/dist/commands/attach.js +31 -0
  24. package/dist/commands/certify.js +62 -0
  25. package/dist/commands/config.js +116 -0
  26. package/dist/commands/cost.js +126 -0
  27. package/dist/commands/daemon.js +350 -0
  28. package/dist/commands/doctor.js +262 -0
  29. package/dist/commands/fold.js +95 -0
  30. package/dist/commands/list.js +89 -0
  31. package/dist/commands/mcp.js +84 -0
  32. package/dist/commands/meld.js +332 -0
  33. package/dist/commands/memory.js +215 -0
  34. package/dist/commands/revive.js +74 -0
  35. package/dist/commands/run.js +85 -0
  36. package/dist/commands/spawn.js +1094 -0
  37. package/dist/commands/token.js +153 -0
  38. package/dist/copilot-tool-log.js +145 -0
  39. package/dist/cost/pricing.js +116 -0
  40. package/dist/cost/reprice.js +136 -0
  41. package/dist/crush-tool-log.js +293 -0
  42. package/dist/daemon/agent-scope.js +116 -0
  43. package/dist/daemon/awaiting.js +54 -0
  44. package/dist/daemon/cert-manager.js +349 -0
  45. package/dist/daemon/client.js +262 -0
  46. package/dist/daemon/gated-routes.js +112 -0
  47. package/dist/daemon/keep-awake.js +103 -0
  48. package/dist/daemon/local-socket.js +145 -0
  49. package/dist/daemon/presence-gate.js +206 -0
  50. package/dist/daemon/server.js +6349 -0
  51. package/dist/daemon/signal-source.js +35 -0
  52. package/dist/daemon/tailscale-rebind.js +58 -0
  53. package/dist/daemon/token-ring.js +263 -0
  54. package/dist/daemon/token-routes.js +190 -0
  55. package/dist/db/events.js +152 -0
  56. package/dist/db/mentions.js +179 -0
  57. package/dist/db/schema.js +633 -0
  58. package/dist/db/tokens.js +583 -0
  59. package/dist/db/tool-uses.js +647 -0
  60. package/dist/diagram/index.js +85 -0
  61. package/dist/diagram/label.js +455 -0
  62. package/dist/diagram/layout.js +476 -0
  63. package/dist/diagram/links.js +50 -0
  64. package/dist/diagram/metrics.js +152 -0
  65. package/dist/diagram/parse.js +487 -0
  66. package/dist/diagram/svg.js +389 -0
  67. package/dist/diagram/types.js +9 -0
  68. package/dist/export.js +629 -0
  69. package/dist/files/archive-types.js +2 -0
  70. package/dist/files/archive.js +182 -0
  71. package/dist/files/browse.js +327 -0
  72. package/dist/files/bytes.js +162 -0
  73. package/dist/files/codecs.js +33 -0
  74. package/dist/files/find.js +212 -0
  75. package/dist/files/tar.js +223 -0
  76. package/dist/files/zip.js +209 -0
  77. package/dist/folds.js +72 -0
  78. package/dist/grammars/ebnf.js +92 -0
  79. package/dist/highlight.js +250 -0
  80. package/dist/ids.js +24 -0
  81. package/dist/markdown-diagnostics.js +233 -0
  82. package/dist/math.js +168 -0
  83. package/dist/mcp/server.js +886 -0
  84. package/dist/memory/embedder.js +145 -0
  85. package/dist/memory/embedding-worker.js +71 -0
  86. package/dist/memory/embeddings.js +91 -0
  87. package/dist/memory/index.js +232 -0
  88. package/dist/memory/storage.js +587 -0
  89. package/dist/memory/wiki.js +688 -0
  90. package/dist/memory/wordpiece.js +247 -0
  91. package/dist/mentions-scan.js +40 -0
  92. package/dist/presence.js +259 -0
  93. package/dist/session-affinity.js +185 -0
  94. package/dist/shared/api-request.js +124 -0
  95. package/dist/shared/block-glyphs.js +114 -0
  96. package/dist/shared/diagram-css.js +17 -0
  97. package/dist/shared/export-selection.js +101 -0
  98. package/dist/shared/find-in-text.js +110 -0
  99. package/dist/shared/glow-hues.js +225 -0
  100. package/dist/shared/hex-dump.js +62 -0
  101. package/dist/shared/hex-pages.js +52 -0
  102. package/dist/shared/hit-drum.js +79 -0
  103. package/dist/shared/known-nids.js +58 -0
  104. package/dist/shared/list-scroll-keys.js +56 -0
  105. package/dist/shared/markdown-lists.js +72 -0
  106. package/dist/shared/markdown-math.js +485 -0
  107. package/dist/shared/markdown-mentions.js +79 -0
  108. package/dist/shared/markdown-nids.js +41 -0
  109. package/dist/shared/markdown-protocols.js +53 -0
  110. package/dist/shared/markdown-refs.js +123 -0
  111. package/dist/shared/membrane-invasion.js +342 -0
  112. package/dist/shared/membrane-motion.js +83 -0
  113. package/dist/shared/membrane-palette.js +253 -0
  114. package/dist/shared/membrane-terrain.js +212 -0
  115. package/dist/shared/message-selection.js +123 -0
  116. package/dist/shared/mo-glyph.js +57 -0
  117. package/dist/shared/narrative-format.js +237 -0
  118. package/dist/shared/narrative-menu.js +82 -0
  119. package/dist/shared/narrative-sort.js +47 -0
  120. package/dist/shared/narrative-status.js +52 -0
  121. package/dist/shared/no-pan.js +85 -0
  122. package/dist/shared/pane-layout.js +50 -0
  123. package/dist/shared/payload-inline.js +83 -0
  124. package/dist/shared/speaker-color.js +61 -0
  125. package/dist/shared/token-rotation.js +14 -0
  126. package/dist/shared/view-url.js +197 -0
  127. package/dist/shared/wiki-links.js +70 -0
  128. package/dist/shared/wiki-window.js +4 -0
  129. package/dist/tailscale.js +55 -0
  130. package/dist/test/absorb-claude.test.js +892 -0
  131. package/dist/test/agent-scope.test.js +193 -0
  132. package/dist/test/agents.test.js +55 -0
  133. package/dist/test/api-request.test.js +122 -0
  134. package/dist/test/awaiting-glow.test.js +54 -0
  135. package/dist/test/awaiting.test.js +122 -0
  136. package/dist/test/bind-token.test.js +88 -0
  137. package/dist/test/block-glyphs.test.js +68 -0
  138. package/dist/test/cert-manager.test.js +262 -0
  139. package/dist/test/claude-live-session.test.js +110 -0
  140. package/dist/test/codex-tool-log.test.js +568 -0
  141. package/dist/test/config.test.js +71 -0
  142. package/dist/test/copilot-tool-log.test.js +93 -0
  143. package/dist/test/cors-preflight.test.js +49 -0
  144. package/dist/test/cost-linger.test.js +31 -0
  145. package/dist/test/cost-pricing.test.js +72 -0
  146. package/dist/test/cost-reprice.test.js +139 -0
  147. package/dist/test/cost-sessions.test.js +301 -0
  148. package/dist/test/crush-tool-log.test.js +289 -0
  149. package/dist/test/daemon-client.test.js +109 -0
  150. package/dist/test/daemon-socket.test.js +293 -0
  151. package/dist/test/diagram-arrows.test.js +205 -0
  152. package/dist/test/diagram-export.test.js +210 -0
  153. package/dist/test/diagram-labels.test.js +313 -0
  154. package/dist/test/diagram-parse.test.js +191 -0
  155. package/dist/test/diagram-render.test.js +175 -0
  156. package/dist/test/diagram-review.test.js +288 -0
  157. package/dist/test/diagram-self-loop-labels.test.js +303 -0
  158. package/dist/test/embedder.test.js +84 -0
  159. package/dist/test/events.test.js +123 -0
  160. package/dist/test/export-selection.test.js +102 -0
  161. package/dist/test/export.test.js +505 -0
  162. package/dist/test/files-browse.test.js +393 -0
  163. package/dist/test/files-find.test.js +272 -0
  164. package/dist/test/find-in-text.test.js +86 -0
  165. package/dist/test/first-paint-viewport.test.js +59 -0
  166. package/dist/test/fixtures/embedding-golden.js +23 -0
  167. package/dist/test/fixtures/wordpiece-golden.js +167 -0
  168. package/dist/test/glow-hues.test.js +202 -0
  169. package/dist/test/harness-cost.test.js +423 -0
  170. package/dist/test/helpers.js +21 -0
  171. package/dist/test/hex-pages.test.js +68 -0
  172. package/dist/test/highlight.test.js +69 -0
  173. package/dist/test/hit-drum.test.js +71 -0
  174. package/dist/test/hook-config.test.js +262 -0
  175. package/dist/test/json-gzip.test.js +70 -0
  176. package/dist/test/key-routing.test.js +58 -0
  177. package/dist/test/known-nids.test.js +106 -0
  178. package/dist/test/link-preview.test.js +67 -0
  179. package/dist/test/list-scroll-keys.test.js +66 -0
  180. package/dist/test/listen-own-words.test.js +147 -0
  181. package/dist/test/listen-timeout.test.js +33 -0
  182. package/dist/test/markdown-diagnostics.test.js +121 -0
  183. package/dist/test/markdown-lists.test.js +182 -0
  184. package/dist/test/markdown-math.test.js +256 -0
  185. package/dist/test/markdown-nids.test.js +146 -0
  186. package/dist/test/markdown-protocols.test.js +139 -0
  187. package/dist/test/mcp-bridge-cancel.test.js +98 -0
  188. package/dist/test/mcp-bridge-reconnect.test.js +121 -0
  189. package/dist/test/mcp-narrative.test.js +193 -0
  190. package/dist/test/mcp.test.js +548 -0
  191. package/dist/test/meld.test.js +85 -0
  192. package/dist/test/membrane-invasion.test.js +482 -0
  193. package/dist/test/membrane-motion.test.js +101 -0
  194. package/dist/test/membrane-palette.test.js +166 -0
  195. package/dist/test/membrane-terrain.test.js +170 -0
  196. package/dist/test/memory-log.test.js +202 -0
  197. package/dist/test/mentions-e2e.test.js +261 -0
  198. package/dist/test/mentions-ledger.test.js +265 -0
  199. package/dist/test/mentions-listen.test.js +265 -0
  200. package/dist/test/mentions.test.js +238 -0
  201. package/dist/test/message-selection.test.js +114 -0
  202. package/dist/test/mo-glyph.test.js +22 -0
  203. package/dist/test/model-resolution.test.js +166 -0
  204. package/dist/test/narrate-validate.test.js +77 -0
  205. package/dist/test/narrate-wait.test.js +160 -0
  206. package/dist/test/narrative-format.test.js +219 -0
  207. package/dist/test/narrative-menu.test.js +137 -0
  208. package/dist/test/narrative-sort.test.js +75 -0
  209. package/dist/test/no-pan.test.js +60 -0
  210. package/dist/test/pane-layout.test.js +153 -0
  211. package/dist/test/paths.test.js +37 -0
  212. package/dist/test/payload-inline.test.js +91 -0
  213. package/dist/test/precache-fonts.test.js +72 -0
  214. package/dist/test/presence-gate.test.js +440 -0
  215. package/dist/test/presence.test.js +160 -0
  216. package/dist/test/read-events.test.js +220 -0
  217. package/dist/test/remote-meld.test.js +115 -0
  218. package/dist/test/revive-cli.test.js +93 -0
  219. package/dist/test/search-floor.test.js +206 -0
  220. package/dist/test/search-fusion.test.js +168 -0
  221. package/dist/test/search.test.js +205 -0
  222. package/dist/test/security.test.js +48 -0
  223. package/dist/test/selection-wiring.test.js +61 -0
  224. package/dist/test/session-affinity.test.js +295 -0
  225. package/dist/test/signal-source.test.js +32 -0
  226. package/dist/test/socket-account.test.js +268 -0
  227. package/dist/test/spawn-toml.test.js +72 -0
  228. package/dist/test/speaker-color.test.js +90 -0
  229. package/dist/test/tailscale-rebind.test.js +79 -0
  230. package/dist/test/terminal-cursor.test.js +61 -0
  231. package/dist/test/terminal-resync.test.js +23 -0
  232. package/dist/test/thin-cli.test.js +382 -0
  233. package/dist/test/token-bootstrap.test.js +272 -0
  234. package/dist/test/token-devices.test.js +587 -0
  235. package/dist/test/token-lapse.test.js +94 -0
  236. package/dist/test/token-ring.test.js +188 -0
  237. package/dist/test/token-rotate-cli.test.js +58 -0
  238. package/dist/test/token-routes.test.js +95 -0
  239. package/dist/test/tool-uses.test.js +1006 -0
  240. package/dist/test/usage-ledger.test.js +126 -0
  241. package/dist/test/view-url.test.js +581 -0
  242. package/dist/test/wiki-links.test.js +57 -0
  243. package/dist/test/wiki-sources.test.js +85 -0
  244. package/dist/test/wiki-window.test.js +31 -0
  245. package/dist/test/wiki.test.js +399 -0
  246. package/dist/test/wordpiece.test.js +68 -0
  247. package/dist/tls.js +148 -0
  248. package/dist/tmux.js +202 -0
  249. package/dist/user-agent.js +46 -0
  250. package/docker-entrypoint.sh +141 -0
  251. package/docs/README.md +3 -0
  252. package/docs/absorb.md +231 -0
  253. package/docs/cost-ledger.md +125 -0
  254. package/docs/daemon-api.md +189 -0
  255. package/docs/diagrams.md +163 -0
  256. package/docs/doctor.md +36 -0
  257. package/docs/export-scope.md +69 -0
  258. package/docs/files-view.md +133 -0
  259. package/docs/link-previews.md +38 -0
  260. package/docs/math.md +32 -0
  261. package/docs/mcp.md +69 -0
  262. package/docs/memory-search.md +75 -0
  263. package/docs/mentions.md +101 -0
  264. package/docs/multi-brane.md +14 -0
  265. package/docs/passkeys.md +165 -0
  266. package/docs/presence.md +202 -0
  267. package/docs/releasing.md +53 -0
  268. package/docs/rendering-warnings.md +22 -0
  269. package/docs/request-layer.md +72 -0
  270. package/docs/selection-store.md +50 -0
  271. package/docs/session-affinity.md +61 -0
  272. package/docs/terminal-mirroring.md +211 -0
  273. package/docs/token-rotation.md +413 -0
  274. package/docs/view-urls.md +114 -0
  275. package/docs/web-app.md +23 -0
  276. package/docs/wiki.md +43 -0
  277. package/expo/dist/_expo/static/js/web/entry-e56efc1291dca7258ea00b8108b033a4.js +1097 -0
  278. package/expo/dist/apple-touch-icon.png +0 -0
  279. package/expo/dist/favicon.svg +3 -0
  280. package/expo/dist/index.html +177 -0
  281. package/expo/dist/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  282. package/expo/dist/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  283. package/expo/dist/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  284. package/expo/dist/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  285. package/expo/dist/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  286. package/expo/dist/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
  287. package/expo/dist/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  288. package/expo/dist/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
  289. package/expo/dist/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
  290. package/expo/dist/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  291. package/expo/dist/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
  292. package/expo/dist/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  293. package/expo/dist/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  294. package/expo/dist/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  295. package/expo/dist/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
  296. package/expo/dist/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  297. package/expo/dist/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  298. package/expo/dist/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  299. package/expo/dist/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  300. package/expo/dist/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  301. package/expo/dist/katex/katex.min.css +1 -0
  302. package/expo/dist/manifest.json +16 -0
  303. package/expo/dist/metadata.json +1 -0
  304. package/expo/dist/og/membrane.v1.png +0 -0
  305. package/expo/dist/pdf.min.mjs +28 -0
  306. package/expo/dist/pdf.worker.min.mjs +28 -0
  307. package/expo/dist/sw.js +154 -0
  308. package/package.json +79 -27
  309. package/protocols/LIVE_loop.md +407 -0
  310. package/protocols/bebrief.md +41 -0
  311. package/protocols/digest.md +231 -0
  312. package/protocols/fly.md +266 -0
  313. package/protocols/idle.md +81 -0
  314. package/protocols/keeper.md +829 -0
  315. package/protocols/markdown.md +80 -0
  316. package/protocols/memory.md +419 -0
  317. package/protocols/mentions.md +93 -0
  318. package/protocols/payloads.md +53 -0
  319. package/protocols/prelude.md +91 -0
  320. package/protocols/ramify.md +105 -0
  321. package/protocols/review.md +356 -0
  322. package/protocols/rrr.md +232 -0
  323. package/protocols/scribe.md +429 -0
  324. package/protocols/summarize.md +203 -0
  325. package/protocols/twin.md +174 -0
  326. package/protocols/wiki.md +438 -0
  327. package/protocols/worker.md +38 -0
  328. package/wiki/shared/append-only-event-log.md +148 -0
  329. package/wiki/shared/index.md +48 -0
  330. package/wiki/shared/owning-your-narratives.md +161 -0
  331. package/wiki/shared/premature-ontologies.md +435 -0
  332. package/wiki/shared/sedimentary-superintelligence.md +128 -0
  333. package/wiki/shared/sequestering-the-narrative.md +143 -0
  334. package/wiki/shared/why-wikis-work.md +216 -0
  335. package/.travis.yml +0 -7
  336. package/lib/brane.cjs.js +0 -12
  337. package/lib/brane.cjs.js.map +0 -1
  338. package/lib/brane.d.ts +0 -11
  339. package/lib/brane.js +0 -6
  340. package/lib/brane.js.map +0 -1
  341. package/lib/tests.d.ts +0 -1
  342. package/lib/tests.js +0 -8
  343. package/lib/tests.js.map +0 -1
  344. package/rollup.config.js +0 -21
  345. package/scripts/test.sh +0 -8
  346. package/src/brane.ts +0 -21
  347. package/src/tests.ts +0 -8
  348. package/tsconfig.json +0 -16
@@ -0,0 +1,232 @@
1
+ # Protocol: rrr
2
+
3
+ `/rrr [branch=main]` puts the running code on what is actually merged.
4
+ Fetch, rebase onto `origin/<branch>`, rebuild, restart.
5
+
6
+ Three letters, four r's:
7
+
8
+ | r | step |
9
+ |---|---|
10
+ | *refetch* | `git fetch origin` — elided from the name, because it's implied |
11
+ | **rebase** | onto `origin/<branch>` |
12
+ | **rebuild** | the project's build |
13
+ | **restart** | whatever long-running process serves that build, if there is one |
14
+
15
+ The first half is the same in every repository. The second half is
16
+ whatever *this* fold's build and process are — read them off the
17
+ project (`package.json` scripts, a `Makefile`, a `justfile`, its
18
+ README) rather than assuming. When the fold is the brane repository
19
+ itself, they are `npm run build` and `brane daemon restart`, and that
20
+ case has enough of its own consequences to get its own section at the
21
+ end of this document.
22
+
23
+ ## Why
24
+
25
+ An agent's working tree is a claim about the world; `origin/main` is
26
+ the world. Between them sit merged PRs you never pulled, your own
27
+ commits that were squashed on the way in, and build output compiled
28
+ from neither. `/rrr` collapses the three into one state and puts the
29
+ live process on it, so that what you are about to test is **what has
30
+ actually been merged** rather than what your branch believes.
31
+
32
+ The last step is the one that matters. A build writes files; a
33
+ process that started before the build holds its code in memory. Until
34
+ it is restarted, a green build is a claim about files on disk and
35
+ nothing more.
36
+
37
+ **The operator knows the restart will blink.** On an explicit `/rrr`,
38
+ do not spend a narration warning about the process going down or
39
+ asking whether to proceed; the invocation *is* the consent. Report the
40
+ restart as a step you took, not a risk you weighed.
41
+
42
+ ## Restart from the right checkout
43
+
44
+ A restart is only "testing this tree" if the process is started *from*
45
+ this tree. Many restart commands re-exec whatever checkout invoked them
46
+ — so restarting from a worktree does not test the worktree; it installs
47
+ that worktree's build as the process for everyone who shares it, until
48
+ someone restarts from somewhere else.
49
+
50
+ So before step 6, ask where the running process was started from, and
51
+ compare it to `whoami`'s `fold_dir`. If they differ:
52
+
53
+ - **Don't restart from here** unless the operator has said to, knowing
54
+ what it means. It is a wider side effect wearing the costume of a
55
+ local one.
56
+ - You may still do the read-only half — `git fetch origin`, and rebase
57
+ *your own branch* onto `origin/<branch>` if that is what you want.
58
+ That is ordinary work, not `/rrr`.
59
+ - If what you need is the process on merged code, say so and let the
60
+ operator run `/rrr` in the checkout it runs from, or ask for
61
+ permission to walk over to it. Then come back.
62
+
63
+ ## Steps
64
+
65
+ Narrate as you go — each step's real output, not a plan restated. A
66
+ `/rrr` that reports "rebased, rebuilt, restarted" without ever showing
67
+ what git and the build said is indistinguishable from one that did
68
+ nothing.
69
+
70
+ **1. Fetch.** `git fetch origin` — or `git fetch origin <branch>`.
71
+ This comes first because the next step is a question about the
72
+ *target*, and you cannot ask it before you have one.
73
+
74
+ **2. Take stock of the tree.** `git status --porcelain`, and then, for
75
+ each path it names, the question that actually matters:
76
+
77
+ ```
78
+ git show origin/<branch>:<path> | diff - <path>
79
+ ```
80
+
81
+ The question is **not** "is the tree dirty?" — that is tidiness. It is
82
+ **"does this tree hold bytes that exist nowhere else?"** Dirt is only
83
+ dangerous when it is the sole copy of something.
84
+
85
+ - **Empty diff — a duplicate.** The file already matches where you are
86
+ going; the sync will not change it. `git add` it and continue. That
87
+ is not a workaround: git compares the *index* against the target, so
88
+ an entry that already equals the incoming content applies cleanly and
89
+ the file lands tracked and clean. An untracked file matching an
90
+ incoming *new* file is the same case and takes the same `git add`.
91
+ - **Non-empty diff, or the path doesn't exist upstream — real work.**
92
+ **Stop here and report it.** Do not stash, do not `git checkout --`,
93
+ do not `git clean`, do not `git rebase --skip` your way past a
94
+ conflict. The golden rule at the head of this document covers
95
+ uncommitted work, which is the most easily destroyed artifact in the
96
+ repository and the only one with no copy anywhere.
97
+ - **Mid-conflict** (`UU`, a `rebase-merge/` directory) — stop
98
+ regardless. Someone's resolution is in progress.
99
+
100
+ Untracked files unrelated to the sync — scratch scripts, tarballs,
101
+ build droppings — are neither; leave them in place, say what they are,
102
+ and continue.
103
+
104
+ The duplicate case is worth spelling out because it is the *common*
105
+ one, not an edge: you merged your own PR, so your working copies are
106
+ copies of the destination. Treating that as a blocker stops the run
107
+ over files that hold no information — and a guard that fires on the
108
+ ordinary case is one people learn to route around, which is how the
109
+ guard stops protecting the case that matters.
110
+
111
+ **3. Switch and rebase.**
112
+
113
+ ```
114
+ git checkout <branch> # default: main
115
+ git rebase origin/<branch>
116
+ ```
117
+
118
+ On a checkout of `main` that has no local commits this is a
119
+ fast-forward and says so. If the rebase **conflicts**, stop: narrate
120
+ the conflicting paths and the operator decides. Do not resolve
121
+ conflicts inside `/rrr` — you were asked to sync, and a conflict means
122
+ the sync is a question rather than a mechanism.
123
+
124
+ **4. Reinstall if the dependencies moved.** Note the pre-rebase commit
125
+ (`git rev-parse HEAD`) before step 3, then afterwards ask what actually
126
+ moved among the project's lockfiles and anything that patches
127
+ installed packages:
128
+
129
+ ```
130
+ git diff --name-only <old>..HEAD -- <lockfiles> <patch dirs>
131
+ ```
132
+
133
+ If any of them changed, run the matching install. A repository can
134
+ hold more than one independent package tree — a root and a sub-app,
135
+ each with its own lockfile and `node_modules` — and a top-level build
136
+ that *runs* the sub-app's build without installing for it; check each
137
+ tree, not just the root. Patch directories (`patch-package`,
138
+ `patches/`) belong in the list because a changed patch rewrites code
139
+ inside an installed package and shows up in **no** lockfile at all, so
140
+ it is invisible to the check everyone thinks to run.
141
+
142
+ Skipping this is not a build failure, which is what makes it worth a
143
+ step. A stale dependency tree usually compiles and then misbehaves at
144
+ runtime, and the hour goes to debugging the code that was merged rather
145
+ than the install that wasn't. When in doubt, install everything — it
146
+ is seconds when nothing changed.
147
+
148
+ **5. Rebuild.** The project's full build — not just its typecheck, if
149
+ the two differ, and not just one half of a multi-part build: a server
150
+ compiled against a stale client bundle presents as a UI bug rather
151
+ than a build one. If the build fails, **stop and report the error**;
152
+ do not restart onto half-written output.
153
+
154
+ **6. Restart.** The process that serves the build, with whatever
155
+ command the project uses for it. Mind the checkout question above.
156
+
157
+ **7. Confirm.** Check the process actually came back on new code —
158
+ its pid changed, it is alive, its reported version or start time
159
+ moved. A restart that silently failed leaves the old process running
160
+ and every subsequent test measuring the old code.
161
+
162
+ ## Afterwards
163
+
164
+ Say what changed, concretely: the commit range the rebase brought in
165
+ (`git log --oneline <old>..HEAD`), whether the build was clean, the
166
+ new pid. That list is the point of the exercise — it is the answer to
167
+ "what am I now testing?"
168
+
169
+ Then return to the LIVE loop and `listen`. `/rrr` is preparation; the
170
+ operator usually has something they wanted to test *on* merged code,
171
+ and that instruction is the next signal.
172
+
173
+ ## In the brane repository itself
174
+
175
+ Everything below applies only when the fold **is** the brane checkout
176
+ — the one whose `dist/` the daemon is running. In any other project,
177
+ none of it does.
178
+
179
+ **The four r's, concretely.** Rebuild is `npm run build` — `tsc` plus
180
+ the Expo web export. Not `npx tsc` alone: that leaves `expo/dist/`
181
+ stale, so the daemon serves the *old* app bundle over the new server.
182
+ Restart is `brane daemon restart`; it preserves port and token, so
183
+ existing links and QR codes keep working. Confirm with `brane daemon
184
+ status` and check the pid moved.
185
+
186
+ **The daemon is one process per machine, and it restarts from whichever
187
+ checkout invoked the command** — `brane daemon restart` re-spawns
188
+ `process.argv[1]`. That is the "restart from the right checkout" rule
189
+ above at its sharpest: a restart from a worktree installs that
190
+ worktree's build as the daemon for every other agent's MCP bridge,
191
+ every open phone, and every terminal mirror. `/rrr` therefore belongs
192
+ in the checkout the daemon already runs from; confirm with `whoami`'s
193
+ `fold_dir` against the running daemon rather than assuming.
194
+
195
+ **What the blink is.** Every agent's MCP bridge drops, the app
196
+ reconnects, terminal mirrors resync — a few seconds, and none of it is
197
+ news to the operator.
198
+
199
+ **Two package trees.** `package-lock.json` at the root and
200
+ `expo/package-lock.json`, each with its own `node_modules`, not a
201
+ workspace. `npm run build` *runs* the Expo build (`npm run build:web
202
+ --prefix expo`) but never installs for it. So step 4's diff is:
203
+
204
+ ```
205
+ git diff --name-only <old>..HEAD -- \
206
+ package-lock.json expo/package-lock.json expo/patches
207
+ ```
208
+
209
+ - root lockfile → `npm i`
210
+ - `expo/package-lock.json` **or** `expo/patches/` → `(cd expo; npm i)`
211
+ - both, or you'd rather not read the diff → `npm i && (cd expo; npm i)`
212
+
213
+ `expo/patches/` is there because `expo/package.json`'s `postinstall`
214
+ runs `patch-package`.
215
+
216
+ **Your own bridge goes down with it.** You are restarting the daemon
217
+ your MCP bridge is connected to. The bridge reconnects on its own with
218
+ backoff, but in the window around the restart a brane call in flight
219
+ comes back `daemon connection lost (reconnecting — please retry)` and
220
+ a parked `listen` is answered and dropped. **Retry the call.** Once.
221
+ That error is the restart working, not the restart failing — and it is
222
+ not something to narrate an alarm about. Only if calls are still
223
+ failing after several seconds of retries has something actually gone
224
+ wrong; then report it with the real error text, and check `brane
225
+ daemon logs` before concluding anything.
226
+
227
+ **Protocol changes need no `/rrr`.** The daemon reads `protocols/`
228
+ from disk on every `read_protocol`, so a protocol edit is live the
229
+ moment it is written. Same for `wiki/`. If a rebase brought in only
230
+ markdown under those directories, the rebuild and restart are honest
231
+ work but they are not what made the change take effect — say so rather
232
+ than implying the restart was load-bearing.
@@ -0,0 +1,429 @@
1
+ # /scribe [target]
2
+
3
+ Take human dictation and render it faithfully into a progressively more
4
+ complete document, without embellishment. The operator dictates; the
5
+ scribe commits only what the operator **endorses**, in the operator's own
6
+ voice, and nothing more. The scribe is a **faithful recorder, not an
7
+ author** — its fidelity to the source *is* the job.
8
+
9
+ `/scribe` is the near-mirror of [`/wiki`](wiki.md): the wiki forbids the
10
+ agent from inventing *concepts*; the scribe forbids it from inventing
11
+ *words*. Anything on the page the operator did not endorse is a defect.
12
+
13
+ The endgame is a fully voice-driven tool — speech-to-text in,
14
+ text-to-speech read-back out — so every rule holds when the operator
15
+ can't see the screen and must trust their ears. That makes fidelity
16
+ load-bearing, not aspirational.
17
+
18
+ ## Prime directive
19
+
20
+ **No content enters the document except as a faithful rendering of
21
+ something the operator endorsed** — composed, pasted, or authorized by
22
+ reference (see *Provenance*). The scribe contributes no substance of its
23
+ own: no invented sentences, no connective tissue, no "the author notes
24
+ that…", no polishing a rough idea, no filling a gap with a guess. When
25
+ tempted to add, it raises an **open question** and waits.
26
+
27
+ The page is in the **operator's voice**, their phrasing preserved. The
28
+ scribe's own voice appears only in read-backs and open questions, never
29
+ in document prose.
30
+
31
+ ## Target, up front
32
+
33
+ A session **begins by fixing its destination** — the operator names the
34
+ artifact (usually a markdown file) before any dictation is committed:
35
+
36
+ ```
37
+ /scribe spec.md
38
+ ```
39
+
40
+ - **File doesn't exist** → the scribe creates it and starts an empty
41
+ manifest (see *The ledger*).
42
+ - **File exists** → the scribe **adopts** it: its current content becomes
43
+ one or more `baseline` fragments — preserved and rendered, but with no
44
+ endorsement chain (a later `/notary` pass marks baseline ungrounded).
45
+ The scribe never claims baseline content as human-authored.
46
+ - **No target set** → the scribe's first act is to ask for one; nothing
47
+ is committed until a destination exists.
48
+
49
+ The target is **sticky**: dictation lands there until the operator
50
+ redirects (`/scribe other.md`) or exits.
51
+
52
+ ## Latched session
53
+
54
+ Dictation is continuous — the operator won't prefix every sentence,
55
+ least of all by voice — so the scribe **latches**:
56
+
57
+ - `/scribe <target>` opens a resident session.
58
+ - While latched, **every** `human_signal` is handled by the scribe (as
59
+ prose, instruction, query, or correction), not as a general LIVE-loop
60
+ request.
61
+ - `/scribe stop` closes it; the scribe confirms and returns to the
62
+ ordinary loop.
63
+
64
+ If something plainly outside the writing task arrives while latched, the
65
+ scribe raises an open question ("didn't sound like dictation — step out
66
+ of the session?") rather than silently acting or transcribing.
67
+
68
+ ## Channels: four kinds of utterance
69
+
70
+ Every latched `human_signal` is one of four things, never bleeding
71
+ together:
72
+
73
+ 1. **Prose** — content to render, in the operator's voice.
74
+ 2. **Instruction** — a directive about the document's *shape*: "intro
75
+ goes last," "keep §3 before §2," "put the pricing bit under §2." May
76
+ be **standing** or one-off. Changes fragment *metadata* (placement,
77
+ ordering), never fragment *text*.
78
+ 3. **Query** — a question *about* the document that changes nothing:
79
+ "read me back §2," "word count?" Answered from the render; no change.
80
+ 4. **Correction / retraction** — a change to what's there: an in-flight
81
+ fix ("no, make that fifteen percent") **supersedes** a fragment; a
82
+ retraction ("strike that") **retracts** one.
83
+
84
+ **Disambiguation is hybrid:** infer the channel from phrasing by default;
85
+ reserved mode-words override when the operator wants certainty (`note:` /
86
+ `instruction:` mark an instruction, `scribe:` addresses the scribe,
87
+ `verbatim:` forces prose — for dictating text that *itself* begins with a
88
+ mode-word, e.g. writing documentation about scribe; plain speech is
89
+ prose); the **read-back is the safety net** — a misclassification is
90
+ caught on the next breath. When genuinely uncertain *and* the guess would
91
+ change the document, the scribe **asks**. A wrong silent guess is exactly
92
+ the embellishment this protocol prevents.
93
+
94
+ ## The per-utterance loop
95
+
96
+ For **every** latched `human_signal`, in order:
97
+
98
+ 1. **Classify** the channel (prose / instruction / query / correction).
99
+ 2. **Apply the fidelity licence** and create or modify **fragment(s)** in
100
+ the manifest — never edit document text directly.
101
+ 3. **Re-render** the target wholesale from the manifest (see *Projection*).
102
+ 4. **Verify** the render equals a fresh recompute from the manifest,
103
+ byte-for-byte; on mismatch, **fail closed** — re-render, do not proceed.
104
+ 5. **Read back** the fragment delta and cite the endorsing seq.
105
+ 6. **Update `meta.summary`** to `Scribe: <target> — §<current section>`.
106
+
107
+ Queries touch neither manifest nor file — answer from the current render
108
+ and read back. Everything else runs the full loop.
109
+
110
+ ## The ledger: fragment, manifest, projection
111
+
112
+ The document is **not the store** — it is a *projection*. The store is a
113
+ ledger of endorsed fragments; the file is regenerated from it on every
114
+ change. Nothing is ever edited in place, so nothing untouched can be
115
+ silently relexed: *the document is a projection; the log is the
116
+ notarized ledger.*
117
+
118
+ **Fragment — the unit of record.** Each endorsed utterance yields at most
119
+ one fragment: the operator's words, verbatim after the fidelity licence.
120
+ A fragment carries:
121
+
122
+ - `id` — a stable handle, `f<seq>` of the endorsing signal (`baseline-N`
123
+ for adopted content).
124
+ - `endorse` — the endorsing `human_signal` `nid:seq` (`null` for
125
+ baseline).
126
+ - `origin` — for adopted-by-reference passages, the `nid:seq` the words
127
+ came from; else `null`. Two-coordinate provenance: *who authorized*
128
+ distinct from *where the words came from*.
129
+ - `section` — the placement label (which outline section it belongs to);
130
+ `null` ⇒ appended at document end.
131
+ - `status` — `active` · `superseded:<id>` · `retracted` · `baseline`.
132
+ - `text` — the verbatim content.
133
+
134
+ **Manifest — the working store.** A sidecar next to the target:
135
+ `<target>.scribe.json`. It holds the ordered section outline, every
136
+ fragment record (**never deleted** — only its `status` changes), standing
137
+ instructions, open questions, and the hash of the last render. The event
138
+ log remains ground truth for audit; the manifest is the machine-checkable
139
+ index into it. Maintain it with ordinary file tools until a future
140
+ `brane scribe` command owns it.
141
+
142
+ ```json
143
+ {
144
+ "target": "spec.md",
145
+ "sections": ["Overview", "Pricing", "Deployment"],
146
+ "fragments": [
147
+ { "id": "f7", "endorse": "claude-4anserzq:7", "origin": null,
148
+ "section": "Pricing", "status": "active",
149
+ "text": "Pricing starts at fifteen percent of contract value." }
150
+ ],
151
+ "standing": ["Introduction goes last."],
152
+ "questions": [
153
+ { "id": "q9", "kind": "hole", "text": "§Deployment named, not yet dictated." }
154
+ ],
155
+ "render_hash": "sha256:…"
156
+ }
157
+ ```
158
+
159
+ **Projection — the document is rendered, never edited.** On every change,
160
+ regenerate the target `.md` wholesale: section headings in outline order,
161
+ then each section's `active` fragments in manifest order, then the
162
+ scribe-notes block. Rendering is **mechanical copying** — the agent
163
+ assembles the file *by reading `text` out of the manifest*, never by
164
+ recalling prose from context. Writing (overwriting) the target is the
165
+ *render mechanism* and is expected; the ledger, not the file, is the thing
166
+ never rewritten from memory.
167
+
168
+ **Render verification — the fail-closed gate.** The render is a *pure
169
+ function of the manifest* — headings from `sections`, each section's
170
+ `active` fragments in order, then the notes block. So verification is
171
+ **deterministic equality**: recompute the expected render from the
172
+ manifest and require it to match the file on disk **byte-for-byte**. Any
173
+ mismatch ⇒ re-render; never accept a render that doesn't match. This is
174
+ strictly stronger than the old snapshot→diff gate — one check proves at
175
+ once that every fragment is present and faithful, that **nothing
176
+ unendorsed was inserted between fragments**, and that the order is
177
+ correct. And because the check is a pure recompute, a dumb tool can run
178
+ it — a future `brane scribe render --check`, the notary, or the operator
179
+ — so fidelity never rests on the agent's discipline.
180
+
181
+ **Placement — no cursor.** The operator never manages an insertion point.
182
+ A fragment's `section` is set from the section the operator most recently
183
+ named; absent any, it appends at document end. "Put the pricing bit under
184
+ §2" is a **metadata change** (set `section`) plus a re-render — no text
185
+ surgery. The scribe never *guesses* placement: ambiguous placement stays
186
+ an open question. Directed placement is faithful; invented placement is
187
+ embellishment.
188
+
189
+ **Corrections and retractions.** "No wait, fifteen percent" → a **new**
190
+ fragment (endorsed by the correcting seq) whose `status` supersedes the
191
+ old one; the superseded record stays in the manifest, absent from the
192
+ render. "Strike that" → set the fragment's `status` to `retracted` (text
193
+ preserved in the manifest, absent from the render). No in-place text edit
194
+ exists anywhere in this protocol.
195
+
196
+ **Drift guard.** Before each render, compare the on-disk file to the
197
+ manifest's `render_hash`. A mismatch means the file was hand-edited since
198
+ the last render. **Never clobber silently:** raise an open question. If
199
+ the operator endorses the drift, adopt it as a fragment endorsed by that
200
+ signal; otherwise the next render restores the manifest's truth.
201
+
202
+ ## Fidelity line
203
+
204
+ Faithful is not literal-to-a-fault; speech carries noise the operator
205
+ doesn't intend as content. The licence is narrow and fixed:
206
+
207
+ **Permitted** (faithful to intent): strip disfluencies ("um," false
208
+ starts, stumbles); honor explicit self-corrections (commit the corrected
209
+ form, not the abandoned one); normalize mechanical surface (casing,
210
+ obvious punctuation, implied paragraph breaks).
211
+
212
+ **Forbidden** (embellishment): adding, sharpening, or "improving" any
213
+ substantive word; reordering beyond an explicit instruction; resolving an
214
+ ambiguity by guessing intent; expanding a pronoun or reference unless its
215
+ referent is unambiguous in the immediate dictation — otherwise raise an
216
+ open question.
217
+
218
+ Every substantive word is preserved. When in doubt, preserve and ask.
219
+
220
+ ## Scribe notes: holes and standing instructions
221
+
222
+ Standing instructions and open questions aren't prose but belong *with*
223
+ the document. They live **only in the manifest** (`standing`,
224
+ `questions`) and are **rendered** into a visible, scribe-owned block at
225
+ the foot of the file — one source of truth, so the block and any inline
226
+ markers can never drift apart:
227
+
228
+ ```markdown
229
+ <!-- SCRIBE:BEGIN -->
230
+ ## Scribe notes
231
+ **Standing instructions**
232
+ - Introduction goes last.
233
+ **Open questions**
234
+ - [order?] Pricing paragraph under §2 or its own section?
235
+ - [hole] §Deployment named but not yet dictated.
236
+ <!-- SCRIBE:END -->
237
+ ```
238
+
239
+ - **Holes** (sections named but not dictated) and **debates** (order,
240
+ referent, ambiguity) are `questions` entries; the render surfaces each,
241
+ including any inline `> [SCRIBE: …]` marker at its location.
242
+ - The scribe **never resolves an open question itself** — that would be
243
+ authoring. It waits for the operator, then applies the resolution
244
+ (a manifest change + re-render) and drops the `questions` entry.
245
+ - **Standing instructions apply retroactively.** "Intro goes last" sets
246
+ placement metadata now, is read back, and is recorded in `standing` to
247
+ govern future work.
248
+
249
+ ## Read-back: the operator's only mirror
250
+
251
+ In a voice-only session the read-back is the *sole* way to catch an
252
+ embellishment, so it is **mandatory** and **derived from the fragment
253
+ delta** (what the utterance created, superseded, or retracted), never from
254
+ recollection of intent:
255
+
256
+ - **Cadence:** one concise read-back **per `human_signal`** — what
257
+ changed, plus any open question raised. Full-document read-back only on
258
+ request.
259
+ - **Form (two-part):** a **speakable sentence** first — TTS reads this
260
+ ("Added to §Pricing; one question: before or after the terms?") —
261
+ followed by the committed **fragment text verbatim** in a fenced block,
262
+ the literal audit record:
263
+
264
+ ```
265
+ Pricing starts at fifteen percent of contract value.
266
+ ```
267
+ - **Content is literal, never a paraphrase.** Cite the endorsing seq via
268
+ `re:` and in text; for adopted content also name the `origin` seq.
269
+
270
+ ## Provenance: every fragment carries a human endorsement
271
+
272
+ The document is built so a later, independent
273
+ [`/notary`](#the-notary-a-separable-follow-on) pass can prove **every
274
+ fragment was endorsed by the operator**, and quantify *how*. Two brane
275
+ guarantees make it possible:
276
+
277
+ - **`source` is stamped server-side and cannot be spoofed** — a
278
+ `human_signal` is provably operator-originated.
279
+ - **`seq` is monotonic and append-only** — `nid:seq` is an immutable
280
+ coordinate for a specific human utterance.
281
+
282
+ The scribe's obligations:
283
+
284
+ 1. **Admission rule.** Every fragment must carry an **operator
285
+ endorsement** delivered through a `human_signal`. Endorsement is read
286
+ *maximally* — composing words fresh, pasting them, **or authorizing a
287
+ previously discussed passage by brief reference** ("add the pricing
288
+ paragraph the agent drafted"). A reference is dictation in the
289
+ abstract: the operator adopts an *identified* passage without
290
+ re-uttering it. Forbidden is only the *scribe* pulling agent content
291
+ in **on its own initiative**. When admitting by reference: the
292
+ referent must be **unambiguous** (resolve to a specific `nid:seq`, else
293
+ raise an open question — *which* passage?), and the retrieved passage
294
+ is **rendered faithfully** (copied into the fragment `text`, not
295
+ rewritten or "improved").
296
+ 2. **Citation.** Each committing read-back cites the **endorsing
297
+ `human_signal` seq** (the fragment's `endorse`, via `re:` and in text).
298
+ For content admitted by reference, it *also* names the fragment's
299
+ `origin` seq — distinguishing *where the words came from* from *who
300
+ authorized them*, which makes the retrieval independently auditable.
301
+ 3. **Grain.** Provenance is tracked per **fragment**. Reorders and
302
+ re-placements move fragments without changing their `text`, so
303
+ provenance rides along untouched.
304
+
305
+ The **canonical store is the event log**, not the document, and not the
306
+ manifest — the manifest is a convenience index and the document a
307
+ projection. The spoof-proof record is the chain of
308
+ `human_signal → citing read-back` events.
309
+
310
+ ### What the chain proves: endorsement, not origination
311
+
312
+ Brane witnesses the **channel**, and that is enough. What passes through
313
+ the `human_signal` channel is, by that act, **adopted by the operator as
314
+ their own** — composed, recalled, or pasted alike. Copy-paste is **not
315
+ laundering and not discouraged**: sending something through the human
316
+ channel *is* the decision that "this is what I would have said." The chain
317
+ proves *every fragment was endorsed and faithfully rendered without the
318
+ agent adding anything unendorsed.* It does not prove where the operator's
319
+ ideas came from — **origination is unmeasurable and beside the point;
320
+ endorsement is what authorship has always meant.** A signature never
321
+ certified you originated the language, only that you adopted it.
322
+
323
+ The trust model is asymmetric **by design**: the system **distrusts the
324
+ agent** (fenced by the admission rule and the render-verification gate)
325
+ and **trusts the operator** (their endorsement is definitional). If you
326
+ wouldn't trust the operator's endorsement, no provenance system helps —
327
+ they're the authoring principal, not a party under audit.
328
+
329
+ So the notary's core metric is a **three-way split**, not a single
330
+ "endorsed fraction":
331
+
332
+ - **composed** — the operator supplied the words;
333
+ - **adopted** — the operator authorized an agent-originated passage by
334
+ reference (endorsed, not their words);
335
+ - **unendorsed** — baseline, or a fragment added in violation of the
336
+ admission rule (no endorsement).
337
+
338
+ "Endorsed" alone isn't the discriminator: an operator could authorize a
339
+ whole agent draft by reference — 100% endorsed, 0% composed, fully
340
+ legitimate but not the same as one they wrote. **Composed vs. adopted** is
341
+ what carries weight; ghostwriting surfaces as low-composed or
342
+ high-unendorsed, never as composed. This is the defensible reading of
343
+ "prove exactly how much of it is yours": your *words* (composed), your
344
+ *choices* (adopted), and what is *neither* (unendorsed).
345
+
346
+ ## The notary: a separable follow-on
347
+
348
+ Notarization — *attesting* the chain holds — is a **different job** from
349
+ authoring, and wants to be structurally independent: a notary who wrote
350
+ the document is a weak notary. The scribe's citation discipline is the
351
+ evidence base a future `/notary` pass consumes to emit a
352
+ fragment-by-fragment attestation and the composed/adopted/unendorsed
353
+ split. The scribe lays the rails; it does not self-attest. `/notary`'s
354
+ own protocol is a follow-on, not part of this document.
355
+
356
+ ## Skill vs. protocol — what Brane adds
357
+
358
+ Most of this document is portable: the behavioral spec (fidelity line,
359
+ channel-sorting, ledger discipline, open-question reflex) is
360
+ agent-interpreted prose that could live as a harness *skill*
361
+ (`.claude/skills/scribe.md`). That part is **not Brane-specific**.
362
+
363
+ Brane's irreducible contribution is **evidence, not behavior**: an
364
+ authority-stamped boundary between human and machine content. A skill's
365
+ only record is its own agent's transcript — single-party, ephemeral,
366
+ certifying nothing about which bytes were human; a process cannot
367
+ notarize its own inputs. Brane's log can, because `source` is stamped by
368
+ a party neither operator nor agent controls, and the log is append-only
369
+ and independently re-verifiable.
370
+
371
+ Scoping:
372
+
373
+ - **No provenance proof needed** → a `/scribe` *skill* is equivalent and
374
+ simpler. Prefer it.
375
+ - **A provable human/AI split matters** — "no reliance on AI" (a fully
376
+ *composed* document) or honest disclosure of what was *adopted* → only
377
+ the Brane substrate delivers it.
378
+
379
+ The slogan: **"write with agent assistance — then prove exactly how much
380
+ of it is yours."** Read "yours" as *endorsed by you*. In one line: **the
381
+ skill gives you *faithful*; the log gives you *provable*.**
382
+
383
+ ## Recovery
384
+
385
+ The manifest plus the event log are the **complete** session state — the
386
+ latch, target, ledger, and open questions all persist outside agent
387
+ context. After compaction or a revive:
388
+
389
+ 1. `whoami`, then `listen` with `tail` to reload recent context.
390
+ 2. Scan back for the most recent `/scribe <target>`; if it has no
391
+ matching `/scribe stop`, the **latch is still on** and `<target>` is
392
+ the sticky destination.
393
+ 3. Reload `<target>.scribe.json` — it *is* the working state; re-render
394
+ from it and verify. Nothing is lost.
395
+ 4. If the current section is uncertain, read back the tail and **confirm
396
+ with the operator** rather than guess.
397
+
398
+ ## Golden rule
399
+
400
+ The scribe **never deletes files, git history, or any artifact** on its
401
+ own. Dictated *retraction* ("strike that sentence") sets a fragment's
402
+ `status` to `retracted` — the text leaves the render but stays in the
403
+ manifest, and the retraction command is itself the `human_signal` of
404
+ record — so the file and everything around it are never removed. Prefer
405
+ `cp` over `mv`; if something seems to need deletion, surface it to the
406
+ operator. See /prelude's Golden Rule.
407
+
408
+ ## Quick reference
409
+
410
+ | Operator utterance | Channel | Manifest operation |
411
+ |---|---|---|
412
+ | Plain speech | Prose (composed) | Append `active` fragment, cite endorse seq |
413
+ | "add the pricing bit we discussed" | Prose (adopted by reference) | Append fragment with `origin`, cite endorse + origin |
414
+ | "intro goes last" | Instruction (standing) | Set placement, record in `standing`, re-render |
415
+ | "put the pricing bit under §2" | Instruction (placement) | Set fragment `section`, re-render |
416
+ | "read me back §2," "word count?" | Query | None — answer from render |
417
+ | "no wait, X" | Correction | New fragment supersedes prior, re-render |
418
+ | "strike that" | Retraction | Set `status: retracted`, re-render |
419
+ | Referent or placement unclear | (open question) | Add `questions` entry, wait |
420
+ | `/scribe stop` | Session control | None — closes session |
421
+
422
+ ## Related protocols
423
+
424
+ - **[LIVE_loop](LIVE_loop.md)** — the loop this runs inside; source of the
425
+ `human_signal` guarantees provenance depends on.
426
+ - **[wiki](wiki.md)** — sibling faithful-rendering protocol; shares the
427
+ fidelity and provenance disciplines.
428
+ - **[review](review.md)** — precedent for keeping verification independent
429
+ of production (the scribe/notary split).