brane 0.1.1 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +367 -0
- package/CHANGELOG.md +66 -0
- package/CONTRIBUTING.md +101 -0
- package/DESIGN.md +405 -0
- package/Dockerfile +61 -0
- package/LICENSE +656 -17
- package/README.md +174 -2
- package/SECURITY.md +213 -0
- package/dist/absorb/brane-id.js +11 -0
- package/dist/absorb/chatgpt.js +161 -0
- package/dist/absorb/claude-code.js +504 -0
- package/dist/absorb/index.js +543 -0
- package/dist/absorb/organelle.js +345 -0
- package/dist/absorb/run.js +520 -0
- package/dist/absorb/sources.js +168 -0
- package/dist/absorb/types.js +3 -0
- package/dist/agent-env.js +45 -0
- package/dist/agents.js +1168 -0
- package/dist/claude-live-session.js +124 -0
- package/dist/cli.js +50 -0
- package/dist/codex-tool-log.js +144 -0
- package/dist/commands/absorb.js +291 -0
- package/dist/commands/attach.js +31 -0
- package/dist/commands/certify.js +62 -0
- package/dist/commands/config.js +133 -0
- package/dist/commands/cost.js +126 -0
- package/dist/commands/daemon.js +350 -0
- package/dist/commands/doctor.js +262 -0
- package/dist/commands/fold.js +95 -0
- package/dist/commands/list.js +89 -0
- package/dist/commands/mcp.js +84 -0
- package/dist/commands/meld.js +360 -0
- package/dist/commands/memory.js +215 -0
- package/dist/commands/revive.js +74 -0
- package/dist/commands/run.js +85 -0
- package/dist/commands/spawn.js +1101 -0
- package/dist/commands/token.js +154 -0
- package/dist/copilot-tool-log.js +145 -0
- package/dist/cost/pricing.js +116 -0
- package/dist/cost/reprice.js +136 -0
- package/dist/crush-tool-log.js +293 -0
- package/dist/daemon/agent-scope.js +116 -0
- package/dist/daemon/awaiting.js +54 -0
- package/dist/daemon/cert-manager.js +349 -0
- package/dist/daemon/client.js +262 -0
- package/dist/daemon/gated-routes.js +112 -0
- package/dist/daemon/keep-awake.js +103 -0
- package/dist/daemon/local-socket.js +145 -0
- package/dist/daemon/presence-gate.js +206 -0
- package/dist/daemon/server.js +6353 -0
- package/dist/daemon/signal-source.js +35 -0
- package/dist/daemon/tailscale-rebind.js +58 -0
- package/dist/daemon/token-ring.js +263 -0
- package/dist/daemon/token-routes.js +190 -0
- package/dist/db/events.js +152 -0
- package/dist/db/mentions.js +179 -0
- package/dist/db/schema.js +643 -0
- package/dist/db/tokens.js +624 -0
- package/dist/db/tool-uses.js +647 -0
- package/dist/diagram/index.js +85 -0
- package/dist/diagram/label.js +455 -0
- package/dist/diagram/layout.js +476 -0
- package/dist/diagram/links.js +50 -0
- package/dist/diagram/metrics.js +152 -0
- package/dist/diagram/parse.js +487 -0
- package/dist/diagram/svg.js +389 -0
- package/dist/diagram/types.js +9 -0
- package/dist/export.js +629 -0
- package/dist/files/archive-types.js +2 -0
- package/dist/files/archive.js +182 -0
- package/dist/files/browse.js +327 -0
- package/dist/files/bytes.js +162 -0
- package/dist/files/codecs.js +33 -0
- package/dist/files/find.js +212 -0
- package/dist/files/tar.js +223 -0
- package/dist/files/zip.js +209 -0
- package/dist/folds.js +72 -0
- package/dist/grammars/ebnf.js +92 -0
- package/dist/highlight.js +250 -0
- package/dist/ids.js +24 -0
- package/dist/markdown-diagnostics.js +233 -0
- package/dist/math.js +168 -0
- package/dist/mcp/server.js +886 -0
- package/dist/memory/embedder.js +145 -0
- package/dist/memory/embedding-worker.js +71 -0
- package/dist/memory/embeddings.js +91 -0
- package/dist/memory/index.js +232 -0
- package/dist/memory/storage.js +587 -0
- package/dist/memory/wiki.js +688 -0
- package/dist/memory/wordpiece.js +247 -0
- package/dist/mentions-scan.js +40 -0
- package/dist/presence.js +259 -0
- package/dist/session-affinity.js +185 -0
- package/dist/shared/api-request.js +124 -0
- package/dist/shared/app-origin.js +26 -0
- package/dist/shared/block-glyphs.js +114 -0
- package/dist/shared/diagram-css.js +17 -0
- package/dist/shared/export-selection.js +101 -0
- package/dist/shared/find-in-text.js +110 -0
- package/dist/shared/glow-hues.js +225 -0
- package/dist/shared/hex-dump.js +62 -0
- package/dist/shared/hex-pages.js +52 -0
- package/dist/shared/hit-drum.js +79 -0
- package/dist/shared/known-nids.js +58 -0
- package/dist/shared/list-scroll-keys.js +56 -0
- package/dist/shared/markdown-lists.js +72 -0
- package/dist/shared/markdown-math.js +485 -0
- package/dist/shared/markdown-mentions.js +79 -0
- package/dist/shared/markdown-nids.js +41 -0
- package/dist/shared/markdown-protocols.js +53 -0
- package/dist/shared/markdown-refs.js +123 -0
- package/dist/shared/membrane-invasion.js +342 -0
- package/dist/shared/membrane-motion.js +83 -0
- package/dist/shared/membrane-palette.js +253 -0
- package/dist/shared/membrane-terrain.js +212 -0
- package/dist/shared/message-selection.js +123 -0
- package/dist/shared/mo-glyph.js +57 -0
- package/dist/shared/narrative-format.js +237 -0
- package/dist/shared/narrative-menu.js +84 -0
- package/dist/shared/narrative-sort.js +47 -0
- package/dist/shared/narrative-status.js +52 -0
- package/dist/shared/no-pan.js +85 -0
- package/dist/shared/pane-layout.js +50 -0
- package/dist/shared/payload-inline.js +83 -0
- package/dist/shared/speaker-color.js +61 -0
- package/dist/shared/token-rotation.js +14 -0
- package/dist/shared/view-url.js +216 -0
- package/dist/shared/wiki-links.js +70 -0
- package/dist/shared/wiki-window.js +4 -0
- package/dist/tailscale.js +55 -0
- package/dist/test/absorb-claude.test.js +892 -0
- package/dist/test/agent-scope.test.js +193 -0
- package/dist/test/agents.test.js +55 -0
- package/dist/test/api-request.test.js +122 -0
- package/dist/test/app-host-literal.test.js +53 -0
- package/dist/test/awaiting-glow.test.js +54 -0
- package/dist/test/awaiting.test.js +122 -0
- package/dist/test/bind-token.test.js +88 -0
- package/dist/test/block-glyphs.test.js +68 -0
- package/dist/test/cert-manager.test.js +262 -0
- package/dist/test/claude-live-session.test.js +110 -0
- package/dist/test/codex-tool-log.test.js +568 -0
- package/dist/test/config.test.js +71 -0
- package/dist/test/copilot-tool-log.test.js +93 -0
- package/dist/test/cors-preflight.test.js +56 -0
- package/dist/test/cost-linger.test.js +31 -0
- package/dist/test/cost-pricing.test.js +72 -0
- package/dist/test/cost-reprice.test.js +139 -0
- package/dist/test/cost-sessions.test.js +301 -0
- package/dist/test/crush-tool-log.test.js +289 -0
- package/dist/test/daemon-client.test.js +109 -0
- package/dist/test/daemon-socket.test.js +293 -0
- package/dist/test/diagram-arrows.test.js +205 -0
- package/dist/test/diagram-export.test.js +210 -0
- package/dist/test/diagram-labels.test.js +313 -0
- package/dist/test/diagram-parse.test.js +191 -0
- package/dist/test/diagram-render.test.js +175 -0
- package/dist/test/diagram-review.test.js +288 -0
- package/dist/test/diagram-self-loop-labels.test.js +303 -0
- package/dist/test/embedder.test.js +84 -0
- package/dist/test/events.test.js +123 -0
- package/dist/test/export-selection.test.js +102 -0
- package/dist/test/export.test.js +505 -0
- package/dist/test/files-browse.test.js +393 -0
- package/dist/test/files-find.test.js +272 -0
- package/dist/test/find-in-text.test.js +86 -0
- package/dist/test/first-paint-viewport.test.js +59 -0
- package/dist/test/fixtures/embedding-golden.js +23 -0
- package/dist/test/fixtures/wordpiece-golden.js +167 -0
- package/dist/test/glow-hues.test.js +202 -0
- package/dist/test/harness-cost.test.js +423 -0
- package/dist/test/helpers.js +21 -0
- package/dist/test/hex-pages.test.js +68 -0
- package/dist/test/highlight.test.js +69 -0
- package/dist/test/hit-drum.test.js +71 -0
- package/dist/test/hook-config.test.js +299 -0
- package/dist/test/json-gzip.test.js +70 -0
- package/dist/test/key-routing.test.js +58 -0
- package/dist/test/known-nids.test.js +106 -0
- package/dist/test/link-preview.test.js +67 -0
- package/dist/test/list-scroll-keys.test.js +66 -0
- package/dist/test/listen-own-words.test.js +147 -0
- package/dist/test/listen-timeout.test.js +33 -0
- package/dist/test/markdown-diagnostics.test.js +121 -0
- package/dist/test/markdown-lists.test.js +182 -0
- package/dist/test/markdown-math.test.js +256 -0
- package/dist/test/markdown-nids.test.js +146 -0
- package/dist/test/markdown-protocols.test.js +139 -0
- package/dist/test/mcp-bridge-cancel.test.js +98 -0
- package/dist/test/mcp-bridge-reconnect.test.js +121 -0
- package/dist/test/mcp-narrative.test.js +193 -0
- package/dist/test/mcp.test.js +548 -0
- package/dist/test/meld.test.js +143 -0
- package/dist/test/membrane-invasion.test.js +482 -0
- package/dist/test/membrane-motion.test.js +101 -0
- package/dist/test/membrane-palette.test.js +166 -0
- package/dist/test/membrane-terrain.test.js +170 -0
- package/dist/test/memory-log.test.js +202 -0
- package/dist/test/mentions-e2e.test.js +261 -0
- package/dist/test/mentions-ledger.test.js +265 -0
- package/dist/test/mentions-listen.test.js +265 -0
- package/dist/test/mentions.test.js +238 -0
- package/dist/test/message-selection.test.js +114 -0
- package/dist/test/mo-glyph.test.js +22 -0
- package/dist/test/model-resolution.test.js +166 -0
- package/dist/test/narrate-validate.test.js +77 -0
- package/dist/test/narrate-wait.test.js +160 -0
- package/dist/test/narrative-format.test.js +219 -0
- package/dist/test/narrative-menu.test.js +150 -0
- package/dist/test/narrative-sort.test.js +75 -0
- package/dist/test/no-pan.test.js +60 -0
- package/dist/test/pane-layout.test.js +153 -0
- package/dist/test/paths.test.js +37 -0
- package/dist/test/payload-inline.test.js +91 -0
- package/dist/test/precache-fonts.test.js +72 -0
- package/dist/test/presence-gate.test.js +440 -0
- package/dist/test/presence.test.js +160 -0
- package/dist/test/read-events.test.js +220 -0
- package/dist/test/remote-meld.test.js +128 -0
- package/dist/test/revive-cli.test.js +93 -0
- package/dist/test/search-floor.test.js +206 -0
- package/dist/test/search-fusion.test.js +168 -0
- package/dist/test/search.test.js +205 -0
- package/dist/test/security.test.js +48 -0
- package/dist/test/selection-wiring.test.js +61 -0
- package/dist/test/session-affinity.test.js +295 -0
- package/dist/test/signal-source.test.js +32 -0
- package/dist/test/socket-account.test.js +268 -0
- package/dist/test/spawn-toml.test.js +72 -0
- package/dist/test/speaker-color.test.js +90 -0
- package/dist/test/tailscale-rebind.test.js +79 -0
- package/dist/test/terminal-cursor.test.js +61 -0
- package/dist/test/terminal-resync.test.js +23 -0
- package/dist/test/terminal-size.test.js +36 -0
- package/dist/test/thin-cli.test.js +382 -0
- package/dist/test/token-bootstrap.test.js +272 -0
- package/dist/test/token-devices.test.js +646 -0
- package/dist/test/token-lapse.test.js +94 -0
- package/dist/test/token-ring.test.js +188 -0
- package/dist/test/token-rotate-cli.test.js +58 -0
- package/dist/test/token-routes.test.js +95 -0
- package/dist/test/tool-uses.test.js +1006 -0
- package/dist/test/usage-ledger.test.js +126 -0
- package/dist/test/view-url.test.js +627 -0
- package/dist/test/wiki-links.test.js +57 -0
- package/dist/test/wiki-sources.test.js +85 -0
- package/dist/test/wiki-window.test.js +31 -0
- package/dist/test/wiki.test.js +399 -0
- package/dist/test/wordpiece.test.js +68 -0
- package/dist/test/wrangler-route.test.js +27 -0
- package/dist/tls.js +148 -0
- package/dist/tmux.js +213 -0
- package/dist/user-agent.js +46 -0
- package/docker-entrypoint.sh +154 -0
- package/docs/README.md +3 -0
- package/docs/absorb.md +231 -0
- package/docs/cost-ledger.md +125 -0
- package/docs/daemon-api.md +189 -0
- package/docs/diagrams.md +163 -0
- package/docs/doctor.md +36 -0
- package/docs/export-scope.md +69 -0
- package/docs/files-view.md +133 -0
- package/docs/link-previews.md +38 -0
- package/docs/math.md +32 -0
- package/docs/mcp.md +69 -0
- package/docs/memory-search.md +75 -0
- package/docs/mentions.md +101 -0
- package/docs/multi-brane.md +14 -0
- package/docs/passkeys.md +165 -0
- package/docs/presence.md +202 -0
- package/docs/releasing.md +104 -0
- package/docs/rendering-warnings.md +22 -0
- package/docs/request-layer.md +72 -0
- package/docs/selection-store.md +50 -0
- package/docs/session-affinity.md +61 -0
- package/docs/terminal-mirroring.md +243 -0
- package/docs/token-rotation.md +431 -0
- package/docs/view-urls.md +134 -0
- package/docs/web-app.md +23 -0
- package/docs/wiki.md +43 -0
- package/expo/dist/_expo/static/js/web/entry-e94247f119fdcd3b424a1764233a41d2.js +1099 -0
- package/expo/dist/apple-touch-icon.png +0 -0
- package/expo/dist/favicon.svg +3 -0
- package/expo/dist/index.html +177 -0
- package/expo/dist/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/expo/dist/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/expo/dist/katex/katex.min.css +1 -0
- package/expo/dist/manifest.json +16 -0
- package/expo/dist/metadata.json +1 -0
- package/expo/dist/og/membrane.v1.png +0 -0
- package/expo/dist/pdf.min.mjs +28 -0
- package/expo/dist/pdf.worker.min.mjs +28 -0
- package/expo/dist/sw.js +154 -0
- package/package.json +79 -27
- package/protocols/LIVE_loop.md +407 -0
- package/protocols/bebrief.md +41 -0
- package/protocols/digest.md +231 -0
- package/protocols/fly.md +266 -0
- package/protocols/idle.md +81 -0
- package/protocols/keeper.md +829 -0
- package/protocols/markdown.md +80 -0
- package/protocols/memory.md +419 -0
- package/protocols/mentions.md +93 -0
- package/protocols/payloads.md +53 -0
- package/protocols/prelude.md +91 -0
- package/protocols/ramify.md +105 -0
- package/protocols/review.md +356 -0
- package/protocols/rrr.md +232 -0
- package/protocols/scribe.md +429 -0
- package/protocols/summarize.md +203 -0
- package/protocols/twin.md +174 -0
- package/protocols/wiki.md +438 -0
- package/protocols/worker.md +38 -0
- package/wiki/shared/append-only-event-log.md +148 -0
- package/wiki/shared/index.md +53 -0
- package/wiki/shared/owning-your-narratives.md +161 -0
- package/wiki/shared/premature-ontologies.md +435 -0
- package/wiki/shared/sedimentary-superintelligence.md +128 -0
- package/wiki/shared/sequestering-the-narrative.md +143 -0
- package/wiki/shared/why-wikis-work.md +216 -0
- package/.travis.yml +0 -7
- package/lib/brane.cjs.js +0 -12
- package/lib/brane.cjs.js.map +0 -1
- package/lib/brane.d.ts +0 -11
- package/lib/brane.js +0 -6
- package/lib/brane.js.map +0 -1
- package/lib/tests.d.ts +0 -1
- package/lib/tests.js +0 -8
- package/lib/tests.js.map +0 -1
- package/rollup.config.js +0 -21
- package/scripts/test.sh +0 -8
- package/src/brane.ts +0 -21
- package/src/tests.ts +0 -8
- package/tsconfig.json +0 -16
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Protocol: markdown
|
|
2
|
+
|
|
3
|
+
Everything you narrate is markdown, and it is read in more places than the chat. It lands in a phone's chat bubble tonight, a colleague's exported HTML file next week, and a search result next year. This page covers how to write for all three: what brane renders, what it adds to plain markdown, how readers find their way through long material, and what `narrate` tells you when something didn't render.
|
|
4
|
+
|
|
5
|
+
Read it before writing anything more elaborate than prose (a table, an equation, a diagram, a link into the code), and whenever a `narrate` result comes back with `warnings`.
|
|
6
|
+
|
|
7
|
+
## Four places your words appear
|
|
8
|
+
|
|
9
|
+
Every surface supports the same markdown: GFM tables, task lists, autolinks and math. Math, code highlighting and diagrams run through the same code in the app and in the export, so an equation or a diagram looks the same in both. Links are where the surfaces differ:
|
|
10
|
+
|
|
11
|
+
| Surface | What is different there |
|
|
12
|
+
|---|---|
|
|
13
|
+
| **Chat** | The full treatment described below. Images arrive as payloads (see /payloads), not as ``. |
|
|
14
|
+
| **Files tab** | Renders `.md` files from the fold. Relative links and images resolve against the file's own directory. |
|
|
15
|
+
| **Wiki and protocol reader** | Links resolve against the page's slug, `#anchor` jumps to a section, and `/command` opens that protocol. |
|
|
16
|
+
| **HTML export** | A static snapshot with no script. `nid:seq` links become links to sibling files (`<nid>.html#seq-N`); `@mentions` and `/protocols` become plain text. |
|
|
17
|
+
|
|
18
|
+
## What brane adds, and how to use it
|
|
19
|
+
|
|
20
|
+
**Cite anything by id.** Write `claude-4c7289d1:42` and the reader gets a link to that exact event; drop the `:42` to link the whole narrative. Only ids that exist become links, so a typo stays visible as text. A code span holding nothing but the id links too; inside a fenced block it stays inert.
|
|
21
|
+
|
|
22
|
+
> The fix landed in claude-4c7289d1:42, after the race was reproduced at claude-4c7289d1:37.
|
|
23
|
+
|
|
24
|
+
**Address someone with `@`.** `@claude-4c7289d1` notifies that narrative, while a bare id only cites it. Nothing else distinguishes the two, so use the `@` only when you mean it. Details are in /mentions.
|
|
25
|
+
|
|
26
|
+
**Name a protocol with a slash.** `/ramify` becomes a link to the protocol, but only if a protocol with that name exists and it isn't part of a path, so `src/memory` stays plain text.
|
|
27
|
+
|
|
28
|
+
**Link into the code with a relative path.** `[the handler](src/daemon/server.ts#L4880-L4900)` opens the Files tab on that file, scrolled to those lines and with them highlighted. `#L10`, `#L10-L20` and `?line=10-20` all work. Paths are relative to the narrative's fold, and a path starting with `/` goes nowhere. Line ranges apply to code files; a markdown file opens rendered, at the top.
|
|
29
|
+
|
|
30
|
+
**Write math however you like.** `$…$` and `\(…\)` render inline. `$$…$$` and `\[…\]` on their own lines, and ` ```math ` fences, render as display blocks. KaTeX draws all of them. A dollar sign that reads as money (`$10k–$500k`) is left as text. A ` ```latex ` fence stays a source listing, which is how to show TeX without rendering it.
|
|
31
|
+
|
|
32
|
+
**Name the language of a code fence.** Fences are highlighted server-side, and the language tag is how the highlighter knows what it's reading.
|
|
33
|
+
|
|
34
|
+
**Draw with mermaid.** A ` ```mermaid ` fence becomes a diagram. The supported dialect is the part agents actually use: `flowchart` and `graph`, the common node shapes, `subgraph`, and `classDef`/`style`. A node labelled with a real narrative id becomes a link. A diagram that can't be drawn falls back to highlighted source, and you get a warning.
|
|
35
|
+
|
|
36
|
+
**Style label text with a markdown string.** Write the label as ``A["`**Plan** mixin`"]``. The backticks just inside the quotes are mermaid's marker, not extra quoting. Inside one, `**bold**`, `*italic*` and `` `code` `` render, each new source line starts a new drawn line, and long lines wrap the way GitHub wraps them. In a plain label, `**` and backticks show as typed, here and on GitHub; only `<br/>`, `<b>`, `<i>`, `<code>`, `<u>` and `<s>` render there. To bold a whole node, use `classDef key font-weight:bold`. A node's markdown string may also hold a GFM table, which draws as a grid with a bold header and the alignment its `:---:` row asks for. Leave a blank line before any text that follows it, as in prose. Tables are brane's own: GitHub shows "Unsupported markdown" in their place, and in an edge label or subgraph title they show as source.
|
|
37
|
+
|
|
38
|
+
````markdown
|
|
39
|
+
```mermaid
|
|
40
|
+
flowchart LR
|
|
41
|
+
A[Report] --> B{Reproduced?}
|
|
42
|
+
B -->|yes| C[claude-4c7289d1]
|
|
43
|
+
```
|
|
44
|
+
````
|
|
45
|
+
|
|
46
|
+
**Wrap freely, here.** A single newline inside a paragraph renders as a space, so a hard-wrapped narration looks the same as an unwrapped one. That isn't true of a GitHub comment, where every newline becomes a line break. Anything headed for GitHub should be written unwrapped.
|
|
47
|
+
|
|
48
|
+
## Pointing readers at the right part
|
|
49
|
+
|
|
50
|
+
A long conversation, wiki page or file is rarely read top to bottom. The best way to steer a reader to the one part that matters is to link to it rather than paste it, and each surface has a link form for that.
|
|
51
|
+
|
|
52
|
+
- **Chat** loads the last 50 events and loads more as the reader scrolls back. A `nid:seq` link opens a window centred on that event, so a citation reaches in one tap what scrolling would take minutes to find.
|
|
53
|
+
- **Wiki**: cite a section as `slug#anchor`. The reader, like `read_wiki` with a `window`, opens that section with its neighbours' headings around it.
|
|
54
|
+
- **Files** shows text files up to 2 MB, and offers larger ones as a download. To cite a passage of code, link a line range.
|
|
55
|
+
- **Export**: every row keeps its `#seq-N` anchor, even in an excerpt, so a `nid:seq` citation resolves in an exported file too.
|
|
56
|
+
|
|
57
|
+
## Warnings
|
|
58
|
+
|
|
59
|
+
Every renderer here fails quietly, by design. If KaTeX can't parse an equation, the reader sees its source instead of red error text. A `$…$` that looks like money is shown as prose, and a code fence that is never closed swallows the rest of the message. That keeps the reader's view clean, but it leaves you, the writer, uninformed. So `narrate` tells you: whenever something in `say` won't render as written, the result carries a `warnings` array.
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"kind": "math_parse_error",
|
|
64
|
+
"message": "Undefined control sequence: \\bogusmacro at position 1",
|
|
65
|
+
"fallback": "$\\bogusmacro{x}$",
|
|
66
|
+
"line": 12
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The kinds are `math_parse_error`, `math_demoted` (the currency guard took a `$…$` that was meant as math), `math_unclosed`, `fence_unclosed`, `diagram_unsupported`, `diagram_parse_error`, and `diagram_label_literal` (the diagram draws, but a label shows its markup as typed, and the message says how to style it instead).
|
|
71
|
+
|
|
72
|
+
**Read the `fallback` first.** It is the exact text the operator will see instead of what you meant, and it tells you whether your meaning got through:
|
|
73
|
+
|
|
74
|
+
- If the source of an equation still reads clearly, like `$E = mc^2$` or `$x_1 + x_2$`, it communicated. Nothing is owed.
|
|
75
|
+
- If the source doesn't read, like a `pmatrix` or a stack of `\frac`s, it communicated nothing.
|
|
76
|
+
- `fence_unclosed` is never harmless. Everything after the fence became one code block, so the rest of the message was lost.
|
|
77
|
+
|
|
78
|
+
**Fix it in the next narration, not the last one.** A warning arrives after the narration is already posted, so treat it as a receipt, not a veto. Re-sending something the operator already understood costs them as much attention as the original failure did, and an apology for a typographic blemish costs more than the blemish. Send a follow-up only when the meaning genuinely didn't arrive. In that case, narrate the substance again with `re` pointing at the original seq, so the two read as one thought.
|
|
79
|
+
|
|
80
|
+
**When it has to be exact, ask up front.** With `strict: true`, a narration that wouldn't render as written is never posted. The call fails with the same diagnostics, you fix the source, and you narrate again, with nothing left behind to correct. Save it for the narration that earns it, such as a derivation, a table the rest of the message depends on, or a document you're handing over. Don't make it a habit: each refusal is a round trip the operator has to wait through.
|
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
# Protocol: memory
|
|
2
|
+
|
|
3
|
+
Agent memory access through semantic search and cross-narrative context loading.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
Agents have access to a memory system that indexes all past agent
|
|
10
|
+
conversations. This enables:
|
|
11
|
+
|
|
12
|
+
1. **Activity Log** — see what's been worked on recently
|
|
13
|
+
2. **Semantic Search** — find relevant past discussions by meaning
|
|
14
|
+
3. **Cross-Narrative Loading** — pull context from other sessions
|
|
15
|
+
4. **Knowledge Discovery** — build understanding across conversations
|
|
16
|
+
|
|
17
|
+
All memory features are available both as **MCP tools** (for use within
|
|
18
|
+
the LIVE loop) and as **CLI commands** (for operator use from the terminal).
|
|
19
|
+
|
|
20
|
+
## Activity Log
|
|
21
|
+
|
|
22
|
+
Browse recently active narratives to understand what's been happening.
|
|
23
|
+
|
|
24
|
+
### Using MCP (`narrative_info`)
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"since": "1d",
|
|
29
|
+
"search": "auth",
|
|
30
|
+
"limit": 10
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Returns structured JSON with narrative metadata, event counts, and
|
|
35
|
+
relative timestamps. See the [LIVE_loop](LIVE_loop.md) protocol for
|
|
36
|
+
full parameter and response documentation.
|
|
37
|
+
|
|
38
|
+
### Using the CLI
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
brane memory log # Last 24 hours (default)
|
|
42
|
+
brane memory log --since 1w # Last week
|
|
43
|
+
brane memory log --search "auth" # Filter by content
|
|
44
|
+
brane memory log --status active # Only active narratives
|
|
45
|
+
brane memory log --fold . # Only this fold
|
|
46
|
+
brane memory log --limit 5 --json # JSON output
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Duration formats: `30m`, `1h`, `2d`, `1w`.
|
|
50
|
+
|
|
51
|
+
Example output:
|
|
52
|
+
```
|
|
53
|
+
● claude-4c7289d1 "Daemon refactor" 3m ago (42 events)
|
|
54
|
+
Summary: Done: added revive API endpoint
|
|
55
|
+
○ claude-8b3ef201 "Expo keyboard" 2h ago (18 events)
|
|
56
|
+
Summary: Implementing multitouch modifier keys
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Each row shows:
|
|
60
|
+
- **Status indicator** — `●` active, `○` inactive
|
|
61
|
+
- **Narrative ID** — the agent session
|
|
62
|
+
- **Title** — narrative title or agent type fallback
|
|
63
|
+
- **Recency** — time since last event
|
|
64
|
+
- **Event count** — total events in the time window
|
|
65
|
+
- **Summary** — current narrative summary (if set)
|
|
66
|
+
|
|
67
|
+
### When to Use
|
|
68
|
+
|
|
69
|
+
- **Situational awareness** — understand what other agents have been
|
|
70
|
+
working on before starting a new task
|
|
71
|
+
- **Find a narrative to resume** — locate a recent session by topic
|
|
72
|
+
- **Operator overview** — quick scan of recent activity across all agents
|
|
73
|
+
|
|
74
|
+
## Semantic Search
|
|
75
|
+
|
|
76
|
+
### Using MCP (`narrative_search`)
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"query": "authentication flow",
|
|
81
|
+
"limit": 10
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Returns results ranked by semantic similarity. Auto-indexes unindexed
|
|
86
|
+
events on first call. See the [LIVE_loop](LIVE_loop.md) protocol for
|
|
87
|
+
full parameter and response documentation.
|
|
88
|
+
|
|
89
|
+
### Using the CLI
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
brane memory search "<query>" --limit 10
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Returns results ranked by semantic similarity with IDF filtering to
|
|
96
|
+
suppress common phrases.
|
|
97
|
+
|
|
98
|
+
Example output:
|
|
99
|
+
```
|
|
100
|
+
1. claude-4c7289d1 (seq 45) - Score: 0.62
|
|
101
|
+
"Checking for embedding model..."
|
|
102
|
+
> brane attach claude-4c7289d1
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Each result shows:
|
|
106
|
+
- **Narrative ID** — the agent session where this was found
|
|
107
|
+
- **Sequence number** — position in the conversation
|
|
108
|
+
- **Score** — semantic similarity (0-1, higher = more relevant)
|
|
109
|
+
- **Content preview** — truncated message content
|
|
110
|
+
|
|
111
|
+
### Query Syntax
|
|
112
|
+
|
|
113
|
+
`narrative_search` (and `brane memory search`) accept a small query
|
|
114
|
+
grammar on top of plain keywords. Parsing is shared by the keyword
|
|
115
|
+
(FTS5) layer and the relevance-scoring layer, so the rules below apply
|
|
116
|
+
uniformly.
|
|
117
|
+
|
|
118
|
+
- **Bare terms.** Whitespace-separated words are ANDed together and
|
|
119
|
+
prefix-matched: `daemon restart` matches content containing a
|
|
120
|
+
`daemon…` token *and* a `restart…` token, in any order. Terms
|
|
121
|
+
shorter than 2 characters are dropped as noise.
|
|
122
|
+
- **Quoted phrases.** Wrap a span in quotes to require those tokens
|
|
123
|
+
**adjacent and in order**:
|
|
124
|
+
- `"context compaction"` — matches only where the two words appear
|
|
125
|
+
as a phrase.
|
|
126
|
+
- `"context compaction" recovery` — the phrase AND the prefix term
|
|
127
|
+
`recovery`.
|
|
128
|
+
|
|
129
|
+
Phrases compose freely with bare terms. Tokens inside a phrase
|
|
130
|
+
bypass the 2-character minimum (you quoted them deliberately).
|
|
131
|
+
- **Recognized quote pairs:**
|
|
132
|
+
|
|
133
|
+
| Pair | Codepoints | Typical source |
|
|
134
|
+
|-------|-----------------|--------------------------------|
|
|
135
|
+
| `"…"` | U+0022 / U+0022 | typed straight quotes |
|
|
136
|
+
| `“…”` | U+201C / U+201D | iOS/macOS smart-quote autosub |
|
|
137
|
+
| `‘…’` | U+2018 / U+2019 | smart single quotes |
|
|
138
|
+
|
|
139
|
+
ASCII `'` (U+0027) is **deliberately not** a phrase delimiter, so
|
|
140
|
+
contractions and possessives (`don't`, `it's`, `agent's`) keep
|
|
141
|
+
working as ordinary bare terms.
|
|
142
|
+
- **Lenient parsing.** An opening quote with no matching closer is
|
|
143
|
+
read to end-of-input rather than rejected — a trailing `"foo bar`
|
|
144
|
+
still searches for the phrase `foo bar`. There is no escape
|
|
145
|
+
mechanism: the first matching closer always ends a phrase.
|
|
146
|
+
- **Scoring.** A quoted-phrase hit in a result's content adds a
|
|
147
|
+
larger relevance boost (`+1.0`) than a bare-term hit (`+0.5`),
|
|
148
|
+
because phrase adjacency is much more discriminating evidence.
|
|
149
|
+
Consequence: phrase-bearing results can score above the nominal
|
|
150
|
+
`0…1` similarity range — treat scores as a *ranking signal*, not
|
|
151
|
+
an absolute probability.
|
|
152
|
+
|
|
153
|
+
### Search Tips
|
|
154
|
+
|
|
155
|
+
1. **Start with short phrases** — "authentication" outperforms "how does
|
|
156
|
+
the authentication flow work." Embedding models reward concept density.
|
|
157
|
+
2. **Try multiple queries** — search is cheap. Run several single-concept
|
|
158
|
+
searches rather than one compound query.
|
|
159
|
+
3. **Add qualifiers incrementally** — if a keyword is too broad, add one
|
|
160
|
+
word at a time.
|
|
161
|
+
4. **Quote multi-word phrases for exact matches** — see *Query Syntax*
|
|
162
|
+
above for the full grammar (phrases, smart quotes, the apostrophe
|
|
163
|
+
carve-out, and scoring).
|
|
164
|
+
|
|
165
|
+
## Cross-Brane Search
|
|
166
|
+
|
|
167
|
+
A single daemon can host multiple branes — typically the caller's home
|
|
168
|
+
brane plus one or more *foreign* branes created by `brane absorb`
|
|
169
|
+
when importing conversation history from other LLM providers
|
|
170
|
+
(ChatGPT exports, earlier brane instances, etc.). Foreign branes can
|
|
171
|
+
contain thousands of absorbed narratives that are highly relevant to
|
|
172
|
+
a search but invisible by default.
|
|
173
|
+
|
|
174
|
+
Both `narrative_search` and `narrative_info` default to **the
|
|
175
|
+
caller's own brane only**. To reach absorbed history, you must
|
|
176
|
+
explicitly pass `brane_ids`.
|
|
177
|
+
|
|
178
|
+
### Discovery: `list_branes`
|
|
179
|
+
|
|
180
|
+
Call `list_branes` (no arguments) to see every brane the daemon
|
|
181
|
+
hosts. The response is keyed by brane ID, with a top-level `home`
|
|
182
|
+
field naming the caller's own brane:
|
|
183
|
+
|
|
184
|
+
```json
|
|
185
|
+
{
|
|
186
|
+
"home": "brane-f66d2b",
|
|
187
|
+
"brane-f66d2b": { "narrative_count": 348, "active_count": 4, "absorbed_count": 1, "last_activity": 1777649907322 },
|
|
188
|
+
"brane-chatgpt-ad15b7": { "narrative_count": 1031, "active_count": 0, "absorbed_count": 1000, "last_activity": 1776028258570 },
|
|
189
|
+
"brane-import-3e91c4": { "narrative_count": 221, "active_count": 0, "absorbed_count": 219, "last_activity": 1774143494724 }
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
The `absorbed_count` field is the strongest signal that a brane is
|
|
194
|
+
worth widening the search to: a brane with hundreds or thousands of
|
|
195
|
+
absorbed narratives almost certainly holds prior context the home
|
|
196
|
+
brane lacks. See the [LIVE_loop](LIVE_loop.md) protocol for full
|
|
197
|
+
`list_branes` documentation.
|
|
198
|
+
|
|
199
|
+
### Pattern: expand on completeness gaps
|
|
200
|
+
|
|
201
|
+
When a home-brane search returns thin results — few hits, low
|
|
202
|
+
scores, or only narratives that *reference* the topic without
|
|
203
|
+
discussing it in depth — re-run the search with `brane_ids` covering
|
|
204
|
+
the foreign branes:
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
{
|
|
208
|
+
"query": "authentication flow",
|
|
209
|
+
"brane_ids": ["brane-f66d2b", "brane-chatgpt-ad15b7", "brane-import-3e91c4"]
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
The same `brane_ids` parameter exists on `narrative_info`, useful
|
|
214
|
+
when you want to browse recent foreign-brane activity rather than
|
|
215
|
+
search for a specific phrase.
|
|
216
|
+
|
|
217
|
+
### When to widen by default
|
|
218
|
+
|
|
219
|
+
Widen the search proactively (without waiting for thin results) when
|
|
220
|
+
the question is about long-running history or design rationale that
|
|
221
|
+
predates the current brane: project origins, prior architectural
|
|
222
|
+
decisions, abandoned approaches, or anything explicitly framed as
|
|
223
|
+
"have we ever…", "what did we decide about…", or "how did we used
|
|
224
|
+
to…". For narrow, current-state questions ("what's the schema right
|
|
225
|
+
now?"), the home brane is usually sufficient.
|
|
226
|
+
|
|
227
|
+
Avoid blindly always passing every brane — foreign branes can be
|
|
228
|
+
large and noisy, and a focused home-brane query is often higher
|
|
229
|
+
signal. Use `list_branes` to make the choice deliberately.
|
|
230
|
+
|
|
231
|
+
## Wiki Consultation (Required)
|
|
232
|
+
|
|
233
|
+
Every memory search must also consult the wiki. Wiki files are a
|
|
234
|
+
curated, human-maintained knowledge base distinct from the narrative
|
|
235
|
+
event log: the narrative archive (`narrative_search`) and the wiki
|
|
236
|
+
(`search_wiki`) are **separate indices**, so searching the archive
|
|
237
|
+
alone silently misses anything that has been synthesized into wiki
|
|
238
|
+
form. The two reach different sources — `narrative_search` over
|
|
239
|
+
narrative events, the wiki tools over the `brane` package wiki (brane's
|
|
240
|
+
own vantage point, shipped with the install) plus any per-fold wikis.
|
|
241
|
+
|
|
242
|
+
The rule is simple: whenever you run `narrative_search` or
|
|
243
|
+
`narrative_info`, also consult the wiki for the same topic via the
|
|
244
|
+
dedicated wiki tools.
|
|
245
|
+
|
|
246
|
+
### The wiki tools
|
|
247
|
+
|
|
248
|
+
| Tool | Reach for it to |
|
|
249
|
+
|------|-----------------|
|
|
250
|
+
| `list_wiki` | Browse the catalog — page slugs, human-authored descriptions, and the `source` of each (package `brane` vs a per-fold wiki). The cheapest way to see what's covered. |
|
|
251
|
+
| `read_wiki` | Fetch a page by `slug` (source auto-resolves when unique), or just one section via `anchor`. Returns the page's TOC and a `slug` / `slug#anchor` citation — the wiki analogue of `nid:seq`. |
|
|
252
|
+
| `search_wiki` | Semantic + keyword search over wiki content, returning chunk-level `slug#anchor` hits ranked by relevance — like `narrative_search`, but over the wikis. |
|
|
253
|
+
|
|
254
|
+
All three default to the package wiki plus the caller's fold; pass
|
|
255
|
+
`all: true` to widen to every registered fold's wiki. Every result
|
|
256
|
+
carries its `source`, so provenance is always explicit — you can never
|
|
257
|
+
mistake brane-canonical content for fold-local content.
|
|
258
|
+
|
|
259
|
+
### Procedure
|
|
260
|
+
|
|
261
|
+
1. **Search or browse.** Run `search_wiki` for the topic alongside your
|
|
262
|
+
`narrative_search`; or `list_wiki` to scan the catalog when you want
|
|
263
|
+
the lay of the land. Both are cheap.
|
|
264
|
+
2. **Read what matches.** `read_wiki` the hit — whole page, or the
|
|
265
|
+
`anchor` section the search returned.
|
|
266
|
+
3. **Treat the wiki as authoritative for its scope.** A wiki page
|
|
267
|
+
exists because the operator curated it — it is a synthesis that
|
|
268
|
+
has been reviewed, not a raw narration. If the wiki contradicts
|
|
269
|
+
what archive search surfaces, prefer the wiki while noting the
|
|
270
|
+
conflict in your answer; drift may be a legitimate finding for a
|
|
271
|
+
future `/wiki audit`.
|
|
272
|
+
4. **Cite the wiki when you use it, with its source.** Use the
|
|
273
|
+
`slug` / `slug#anchor` citation `read_wiki`/`search_wiki` return, and
|
|
274
|
+
name the `source` when it isn't the package wiki, the same way
|
|
275
|
+
`nid:seq` citations work for narrative sources.
|
|
276
|
+
|
|
277
|
+
### Why this is mandatory
|
|
278
|
+
|
|
279
|
+
The wiki captures syntheses that are expensive to re-derive from raw
|
|
280
|
+
narrations: a single wiki page can compress dozens of cross-brane
|
|
281
|
+
discussions into one audited paragraph. Skipping it means either
|
|
282
|
+
re-deriving the synthesis from scratch (wasting tokens and time) or
|
|
283
|
+
answering without it (missing the synthesis entirely and regressing
|
|
284
|
+
to whatever the archive search happens to surface). Neither is an
|
|
285
|
+
acceptable default.
|
|
286
|
+
|
|
287
|
+
This mandate applies to:
|
|
288
|
+
|
|
289
|
+
- Questions about any topic covered in the wiki — always.
|
|
290
|
+
- Open-ended questions where the wiki *might* cover the topic — check
|
|
291
|
+
before answering.
|
|
292
|
+
- `/memory` invocations that ask for a scan of recent activity — still
|
|
293
|
+
check `wiki/index.md` for context, even though the primary output is
|
|
294
|
+
activity-based.
|
|
295
|
+
|
|
296
|
+
See also the [`/wiki` protocol](wiki.md) for the rules governing how
|
|
297
|
+
the wiki itself is read and written.
|
|
298
|
+
|
|
299
|
+
## Cross-Narrative Context Loading
|
|
300
|
+
|
|
301
|
+
Listen on another narrative to load its signal history into your context.
|
|
302
|
+
|
|
303
|
+
### How It Works
|
|
304
|
+
|
|
305
|
+
```json
|
|
306
|
+
{
|
|
307
|
+
"after": {
|
|
308
|
+
"claude-4c7289d1": 0
|
|
309
|
+
},
|
|
310
|
+
"wait": false
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Use `limit` to paginate through long histories, advancing the cursor to
|
|
315
|
+
the highest returned seq each time.
|
|
316
|
+
|
|
317
|
+
### Use Cases
|
|
318
|
+
|
|
319
|
+
1. **Resume knowledge** — load context from a previous session
|
|
320
|
+
2. **Cross-reference** — see what was discussed in related narratives
|
|
321
|
+
3. **Build connections** — explore related discussions
|
|
322
|
+
|
|
323
|
+
### Example Workflow
|
|
324
|
+
|
|
325
|
+
Using MCP tools (within LIVE loop):
|
|
326
|
+
```
|
|
327
|
+
1. Search: narrative_search { "query": "authentication flow" }
|
|
328
|
+
-> Finds claude-4c7289d1 (seq 42)
|
|
329
|
+
|
|
330
|
+
2. Load context: listen { "after": { "claude-4c7289d1": 0 }, "wait": false }
|
|
331
|
+
-> Receive full signal history
|
|
332
|
+
|
|
333
|
+
3. Synthesize: context is now in your conversation
|
|
334
|
+
-> Reference, build upon, or continue that work
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Using CLI (from terminal):
|
|
338
|
+
```
|
|
339
|
+
1. Search: brane memory search "authentication flow"
|
|
340
|
+
-> Finds claude-4c7289d1 (seq 42)
|
|
341
|
+
|
|
342
|
+
2. Attach: brane attach claude-4c7289d1
|
|
343
|
+
-> Load context interactively
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## Technical Details
|
|
347
|
+
|
|
348
|
+
### Storage
|
|
349
|
+
|
|
350
|
+
- **Engine**: SQLite with sqlite-vec extension
|
|
351
|
+
- **Vectors**: sentence-transformer embeddings (384 dimensions)
|
|
352
|
+
- **Index**: vec0 virtual table with cosine distance
|
|
353
|
+
- **Filtering**: IDF-based penalty for common content
|
|
354
|
+
- **Model cache**: `~/.brane/models/` (downloaded on first use)
|
|
355
|
+
|
|
356
|
+
### Indexing
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
brane memory index
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Indexing is idempotent and safe to run repeatedly. Only processes new or
|
|
363
|
+
changed events.
|
|
364
|
+
|
|
365
|
+
### What Gets Indexed
|
|
366
|
+
|
|
367
|
+
- Agent narrations and signals from the SQLite events table
|
|
368
|
+
- Each message embedded with surrounding context for better retrieval
|
|
369
|
+
|
|
370
|
+
## Best Practices
|
|
371
|
+
|
|
372
|
+
1. **Consult the wiki first** — `search_wiki`/`list_wiki`/`read_wiki`
|
|
373
|
+
reach the wiki, which lives in a separate index from
|
|
374
|
+
`narrative_search`; run them before or alongside an archive search
|
|
375
|
+
or you'll miss anything synthesized into wiki form
|
|
376
|
+
2. **Search before asking** — check if a topic was discussed before
|
|
377
|
+
3. **Load full context** — don't rely only on search snippets
|
|
378
|
+
4. **Cross-reference** — multiple narratives may cover the same topic
|
|
379
|
+
5. **Widen across branes when context is incomplete** — `narrative_search`
|
|
380
|
+
and `narrative_info` default to the caller's home brane only. Use
|
|
381
|
+
`list_branes` to discover foreign (absorbed) branes and pass their
|
|
382
|
+
IDs via `brane_ids` whenever home-brane results look thin or the
|
|
383
|
+
question concerns history that predates the home brane (see
|
|
384
|
+
*Cross-Brane Search* above)
|
|
385
|
+
|
|
386
|
+
### Combining Wiki, Log, Search, and Context Loading
|
|
387
|
+
|
|
388
|
+
```
|
|
389
|
+
1. Wiki: search_wiki { "query": "authentication flow" } (and/or list_wiki)
|
|
390
|
+
-> Establish what has already been synthesized on the topic
|
|
391
|
+
|
|
392
|
+
2. Browse: narrative_info { "since": "1d" }
|
|
393
|
+
-> Spot claude-4c7289d1 working on auth
|
|
394
|
+
|
|
395
|
+
3. Deep search: narrative_search { "query": "authentication flow" }
|
|
396
|
+
-> Find specific events across all time
|
|
397
|
+
|
|
398
|
+
4. Load context: listen on claude-4c7289d1 with cursor 0
|
|
399
|
+
-> Pull full history into your session
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
## Limitations
|
|
403
|
+
|
|
404
|
+
- Semantic gap — embedding model may not capture all relationships
|
|
405
|
+
- No terminal history — only narrations/signals are indexed
|
|
406
|
+
- **Wiki is a separate index** — `./wiki/*.md` pages are not part of the
|
|
407
|
+
`narrative_search` index; reach them via `search_wiki`/`list_wiki`/
|
|
408
|
+
`read_wiki` (see *Wiki Consultation* above), never expecting them to
|
|
409
|
+
surface in `narrative_search`
|
|
410
|
+
- Indexing runs on demand via `brane memory index` or auto-triggers
|
|
411
|
+
on first `narrative_search` call; the wiki index self-syncs on each
|
|
412
|
+
`search_wiki` call (re-embedding only changed sections)
|
|
413
|
+
|
|
414
|
+
## Related Protocols
|
|
415
|
+
|
|
416
|
+
- **[LIVE_loop](LIVE_loop.md)** — core communication loop
|
|
417
|
+
- **[wiki](wiki.md)** — the curated, human-maintained knowledge base
|
|
418
|
+
that every memory search must consult alongside the narrative
|
|
419
|
+
archive
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Protocol: mentions
|
|
2
|
+
|
|
3
|
+
How to address another narrative with `@nid`, and what to do when you are
|
|
4
|
+
addressed. Read it when a `listen`, `narrate` or `whoami` result carries
|
|
5
|
+
a `mentions` array, or when the operator tells you to check your mentions.
|
|
6
|
+
|
|
7
|
+
**Checking your mentions.** Call `whoami`: it reports recent mentions of
|
|
8
|
+
you, settled or not, and settles nothing. Then read each entry's `src`
|
|
9
|
+
narrative through your cursor (see
|
|
10
|
+
[Acknowledging them](#acknowledging-them)); reading is what settles it.
|
|
11
|
+
|
|
12
|
+
Writing `@claude-4c7289d1` anywhere you write prose **addresses** that
|
|
13
|
+
narrative. Writing the bare `claude-4c7289d1` merely **cites** it. The `@` is
|
|
14
|
+
the entire difference, and it has to be: narratives quote each other's ids
|
|
15
|
+
constantly, and if a citation notified, every design discussion would page half
|
|
16
|
+
the brane.
|
|
17
|
+
|
|
18
|
+
Reach for a mention when you want another agent's *attention* without putting a
|
|
19
|
+
message in its narrative. Foreign narration is the louder instrument — it
|
|
20
|
+
appends to that agent's own log, where it sits in its history forever. A
|
|
21
|
+
mention leaves the other narrative untouched and simply points at what you
|
|
22
|
+
wrote in yours. (`re` is quieter still: a back-reference notifies nobody.)
|
|
23
|
+
|
|
24
|
+
| You want to | Use |
|
|
25
|
+
|---|---|
|
|
26
|
+
| Put a message in another agent's conversation | `narrate` with its `nid` |
|
|
27
|
+
| Get its attention on something you wrote in yours | `@<nid>` |
|
|
28
|
+
| Link two events for a reader | `re` |
|
|
29
|
+
|
|
30
|
+
**A mention never revives.** If the agent isn't running, nothing starts it —
|
|
31
|
+
the mention waits, and the operator decides. So don't expect a reply from a
|
|
32
|
+
narrative that isn't live, and don't mention as a way to wake something up.
|
|
33
|
+
|
|
34
|
+
## Receiving them
|
|
35
|
+
|
|
36
|
+
`listen`, `narrate` and `whoami` grow a `mentions` array **when you have some**
|
|
37
|
+
— a call with none is byte-identical to what it always returned. Each entry is
|
|
38
|
+
a *pointer*, not a copy:
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{ "id": 7, "src": "claude-4c7289d1", "seq": 42,
|
|
42
|
+
"author": "goose-aa11bb22", "time": 1787843821417 }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`src` is the narrative to go read; `seq` is the event within it (`src:seq` is
|
|
46
|
+
the citable form); `author` is who wrote it, which differs from `src` when
|
|
47
|
+
someone narrated into a third narrative. `brane_id` appears only when the
|
|
48
|
+
mention came from another brane. `mentions_pending` counts any beyond the
|
|
49
|
+
receipt's cap.
|
|
50
|
+
|
|
51
|
+
Events you are handed also carry their own `mentions: [nid, …]` when they
|
|
52
|
+
address someone, so you can see it where you are already reading.
|
|
53
|
+
|
|
54
|
+
**This is heavier than `warnings`.** They share the "only when non-empty"
|
|
55
|
+
shape, but an ignored warning is a typographic blemish and an ignored mention
|
|
56
|
+
is a dropped message.
|
|
57
|
+
|
|
58
|
+
## Acknowledging them
|
|
59
|
+
|
|
60
|
+
**Reading the narrative settles the mention.** There is no ack tool and nothing
|
|
61
|
+
to remember: pass the source narrative in your cursor, the way you already
|
|
62
|
+
would —
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{ "after": { "self": 42, "claude-4c7289d1": 17 } }
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
— and the mentions carried by the events you receive are settled by that act.
|
|
69
|
+
Only the events actually returned count, so a `before`- or `tail`-bounded read
|
|
70
|
+
settles only what it showed you.
|
|
71
|
+
|
|
72
|
+
**A mention you don't read keeps coming back.** It wakes you once, then stays
|
|
73
|
+
in every receipt until you go and look. That is deliberate: delivery alone is
|
|
74
|
+
not attention, and a message can be received and still be missed.
|
|
75
|
+
|
|
76
|
+
Two escape hatches on `listen`, both rare:
|
|
77
|
+
|
|
78
|
+
- `mentions: "all"` — replay recent mentions whether or not they were settled.
|
|
79
|
+
The recovery read: delivery is at-most-once, so if you suspect one went
|
|
80
|
+
missing, this is where to look. `whoami` reports the same thing and settles
|
|
81
|
+
nothing, which makes it the right first call after a restart.
|
|
82
|
+
- `mentions: "dismiss"` — settle everything outstanding. For a mention you have
|
|
83
|
+
judged irrelevant and do not intend to read, which would otherwise reappear
|
|
84
|
+
forever. Use it deliberately; it is how a message gets dropped on purpose.
|
|
85
|
+
|
|
86
|
+
## What is and isn't a mention
|
|
87
|
+
|
|
88
|
+
The handle is parsed from the *rendered* markdown, not the source text, so a
|
|
89
|
+
handle inside a fenced block, a code span, a URL or an existing link is inert —
|
|
90
|
+
pasting a log that mentions someone doesn't page them. A handle must start a
|
|
91
|
+
word (`ben@claude-4c7289d1` is neither an e-mail nor a mention), it is
|
|
92
|
+
case-sensitive, and it must name a narrative that exists. Mentioning the
|
|
93
|
+
narrative you are writing in does nothing: the message is already there.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Protocol: payloads
|
|
2
|
+
|
|
3
|
+
How to receive, analyze, and send file payloads (typically images) over
|
|
4
|
+
the LIVE loop. This is split out of the core [LIVE_loop](LIVE_loop.md)
|
|
5
|
+
protocol so the core stays lean; read this only when an event carries a
|
|
6
|
+
payload or you need to attach one.
|
|
7
|
+
|
|
8
|
+
Events may carry file payloads — typically images pasted or uploaded by
|
|
9
|
+
the operator. The `payloads` field is an array of relative file paths
|
|
10
|
+
(e.g., `["claude-abc/1709251200000_0.png"]`).
|
|
11
|
+
|
|
12
|
+
## Receiving payloads
|
|
13
|
+
|
|
14
|
+
When a `human_signal` or `agent_signal` event contains `payloads`,
|
|
15
|
+
the files are stored on disk at `~/.brane/payloads/{path}`. To read
|
|
16
|
+
a payload, construct the absolute path:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
~/.brane/payloads/ + payloads[0]
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Then read that absolute path with your harness's file-read tool —
|
|
23
|
+
most handle images natively (PNG, JPG, etc.).
|
|
24
|
+
|
|
25
|
+
## Image analysis delegation
|
|
26
|
+
|
|
27
|
+
Reading large images directly into your main context is expensive.
|
|
28
|
+
When possible, delegate to a sub-agent:
|
|
29
|
+
|
|
30
|
+
1. Spawn a sub-agent (Haiku or Sonnet) with the payload path and a
|
|
31
|
+
specific question
|
|
32
|
+
2. The sub-agent reads the image via `Read` and narrates findings
|
|
33
|
+
back as a foreign narration
|
|
34
|
+
3. You receive the analysis as an `agent_signal` event
|
|
35
|
+
|
|
36
|
+
If delegation produces insufficiently specific results, narrate to
|
|
37
|
+
the operator that you need to read the image directly, then proceed.
|
|
38
|
+
|
|
39
|
+
## Sending payloads
|
|
40
|
+
|
|
41
|
+
To attach files to your narrations, pass absolute file paths in the
|
|
42
|
+
`payloads` parameter of the `narrate` tool:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"say": "Here's a screenshot of the error",
|
|
47
|
+
"after": 42,
|
|
48
|
+
"payloads": ["/tmp/screenshot.png"]
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The daemon copies files into managed storage. The operator sees them
|
|
53
|
+
rendered inline in the web UI.
|