brane 0.0.2 → 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.
- package/AGENTS.md +362 -0
- package/CHANGELOG.md +33 -0
- package/CONTRIBUTING.md +91 -0
- package/DESIGN.md +402 -0
- package/Dockerfile +61 -0
- package/LICENSE +656 -17
- package/README.md +174 -2
- package/SECURITY.md +205 -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 +116 -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 +332 -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 +1094 -0
- package/dist/commands/token.js +153 -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 +6349 -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 +633 -0
- package/dist/db/tokens.js +583 -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/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 +82 -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 +197 -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/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 +49 -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 +262 -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 +85 -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 +137 -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 +115 -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/thin-cli.test.js +382 -0
- package/dist/test/token-bootstrap.test.js +272 -0
- package/dist/test/token-devices.test.js +587 -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 +581 -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/tls.js +148 -0
- package/dist/tmux.js +202 -0
- package/dist/user-agent.js +46 -0
- package/docker-entrypoint.sh +141 -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 +53 -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 +211 -0
- package/docs/token-rotation.md +413 -0
- package/docs/view-urls.md +114 -0
- package/docs/web-app.md +23 -0
- package/docs/wiki.md +43 -0
- package/expo/dist/_expo/static/js/web/entry-e56efc1291dca7258ea00b8108b033a4.js +1097 -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 +81 -23
- 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 +48 -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/.npmignore +0 -2
- package/.travis.yml +0 -5
- package/index.js +0 -8
- package/index.js~ +0 -12
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
# /wiki [guidance]
|
|
2
|
+
|
|
3
|
+
Maintain and query a flat, richly interlinked markdown wiki at `./wiki/`
|
|
4
|
+
in the current fold. The wiki is the human operator's second brain for
|
|
5
|
+
this project — the agent's job is to *answer from it*, *refresh it
|
|
6
|
+
against current reality*, and *flag drift*, but never to decide what it
|
|
7
|
+
contains.
|
|
8
|
+
|
|
9
|
+
## Default is read-only
|
|
10
|
+
|
|
11
|
+
**`/wiki` without imperative write-intent is a query.** The agent reads
|
|
12
|
+
`wiki/*.md`, answers the operator's question as a narration, and does
|
|
13
|
+
not modify any files. This is the primary mode — treat writes as rare
|
|
14
|
+
and deliberate, not the norm.
|
|
15
|
+
|
|
16
|
+
Writes happen only when the guidance contains an unambiguous imperative:
|
|
17
|
+
`update`, `refresh`, `rewrite`, `apply`, `write`, `fill`, `sync`,
|
|
18
|
+
`propagate`, or equivalent. "Tell me about X," "what does the wiki say
|
|
19
|
+
about Y," "is the page on Z accurate" — all read mode.
|
|
20
|
+
|
|
21
|
+
When in doubt about intent, stay in read mode and narrate what you
|
|
22
|
+
*would* change. The operator can re-invoke with explicit write guidance.
|
|
23
|
+
|
|
24
|
+
## The agent does not invent concepts
|
|
25
|
+
|
|
26
|
+
The failure mode this protocol exists to prevent is the agent deciding
|
|
27
|
+
that a new concept deserves a wiki page. When the agent, midway through
|
|
28
|
+
writing, notices a sub-idea and spins off `sediment-based-superintelligence.md`
|
|
29
|
+
as a companion to `sedimentary-superintelligence.md`, the ontology has
|
|
30
|
+
been corrupted from inside — the operator now has two pages for one
|
|
31
|
+
concept and no way to tell which is canonical without reading both.
|
|
32
|
+
|
|
33
|
+
The rule is about *concepts*, not filenames. The operator is the source
|
|
34
|
+
of the concept set; the agent fills, refreshes, and cross-links the
|
|
35
|
+
pages those concepts get. Filename spelling is an implementation detail
|
|
36
|
+
the agent handles (kebab-case slugs, consistent with existing pages),
|
|
37
|
+
but the concept itself must come from the operator.
|
|
38
|
+
|
|
39
|
+
Cases:
|
|
40
|
+
|
|
41
|
+
- **Operator introduces a concept in imperative guidance** → free to
|
|
42
|
+
create a page for it. The concept can be named directly (`sedimentary
|
|
43
|
+
superintelligence`) or by filename (`sedimentary-superintelligence.md`);
|
|
44
|
+
either form is authorization. Create the file, draft from raw sources,
|
|
45
|
+
apply the page rules. Don't pre-narrate a draft and ask the operator
|
|
46
|
+
to paste — that's too indirect when the authorization is clear.
|
|
47
|
+
- **Operator asks a question that mentions a concept with no matching
|
|
48
|
+
page** → read mode. Answer from raw sources. Note the gap in a
|
|
49
|
+
footer, but do not create a page — a concept mentioned in a question
|
|
50
|
+
is not a concept the operator has asked to be added to the wiki.
|
|
51
|
+
- **Agent encounters a novel concept while refreshing or answering** →
|
|
52
|
+
no new page. Mention the concept in prose where relevant; if it
|
|
53
|
+
seems to deserve its own page, surface that as a suggestion in the
|
|
54
|
+
narration for the operator to decide.
|
|
55
|
+
- **Stub file already exists** (just `# Foo` or a seed line) → refresh
|
|
56
|
+
mode fills it. The stub's existence is the operator's signal that
|
|
57
|
+
this concept belongs in the ontology.
|
|
58
|
+
- **Renames and deletions** → propose in narration, never apply on
|
|
59
|
+
disk. These are ontology decisions.
|
|
60
|
+
|
|
61
|
+
Creating the `wiki/` directory itself is permitted the first time a
|
|
62
|
+
page creation is authorized — it's implied by the first authorized
|
|
63
|
+
page, not a concept decision of its own.
|
|
64
|
+
|
|
65
|
+
## Voice and register
|
|
66
|
+
|
|
67
|
+
Wiki pages are reference material, not essays, advocacy, or marketing
|
|
68
|
+
copy. Write in a neutral, descriptive, third-person register — closer
|
|
69
|
+
to a Wikipedia article than to a product pitch or a personal manifesto.
|
|
70
|
+
The reader should learn what the subject *is* and what has been
|
|
71
|
+
*claimed* about it, not be sold on why it matters.
|
|
72
|
+
|
|
73
|
+
Concrete rules:
|
|
74
|
+
|
|
75
|
+
1. **Attribute positions; do not assert them.** Anything that reflects
|
|
76
|
+
the operator's (or anyone else's) argument, preference, or
|
|
77
|
+
conjecture should be presented as theirs, not as fact. Use
|
|
78
|
+
"Newman argues that…", "is described as…", "has been proposed as…",
|
|
79
|
+
"is characterized as…" rather than stating the claim flat. Facts
|
|
80
|
+
from code, config, external sources, or reproducible observations
|
|
81
|
+
can be stated directly; opinions cannot.
|
|
82
|
+
|
|
83
|
+
2. **Cut editorializing phrases.** Words and phrases that assert
|
|
84
|
+
importance or deliver a rhetorical punch without adding information
|
|
85
|
+
don't belong: *load-bearing*, *the joke is*, *keeps X honest*,
|
|
86
|
+
*makes the form work*, *the real play*, *escape velocity is
|
|
87
|
+
literal*, *it's not metaphor — it's*, *what this unlocks*, *designed
|
|
88
|
+
to X*. If the underlying claim is substantive, state it plainly and
|
|
89
|
+
attribute it; if it's decoration, remove it.
|
|
90
|
+
|
|
91
|
+
3. **Flag metaphors as metaphors.** When an analogy is allusive rather
|
|
92
|
+
than structural, say so. "Newman sometimes calls this *X*, by
|
|
93
|
+
analogy to…" beats asserting the analogy as if it were definitional.
|
|
94
|
+
A metaphor used by the subject's author once in passing should not
|
|
95
|
+
become the page's organizing frame.
|
|
96
|
+
|
|
97
|
+
4. **Avoid sales-pitch sections.** *Why this matters*, *What this
|
|
98
|
+
unlocks*, and similar sections are advocacy shapes. If the content
|
|
99
|
+
is genuinely informative, it can live as a *Rationale* or
|
|
100
|
+
*Background* section framed descriptively. If it's only advocacy,
|
|
101
|
+
cut it.
|
|
102
|
+
|
|
103
|
+
5. **Describe, don't defend.** If the subject is a proposal, call it a
|
|
104
|
+
proposal and summarize it. Resist the urge to argue *for* the
|
|
105
|
+
proposal inside the description of it; that's what provenance links
|
|
106
|
+
are for — the reader can follow the citation to see the argument
|
|
107
|
+
as the author made it.
|
|
108
|
+
|
|
109
|
+
6. **Preserve citations regardless of register.** The tone of the
|
|
110
|
+
prose is independent of provenance requirements. Every non-trivial
|
|
111
|
+
claim still carries its `nid:seq` or file-path citation. Neutral
|
|
112
|
+
voice is not a reason to drop citations; it is a reason to let the
|
|
113
|
+
citations do more of the work.
|
|
114
|
+
|
|
115
|
+
7. **Don't anthropomorphize the subject into a hero.** Subjects are not
|
|
116
|
+
"bold," "radical," "unlike any other tool" — not even when the
|
|
117
|
+
source material says so. Leave that framing in the cited source.
|
|
118
|
+
|
|
119
|
+
8. **Don't inflate the operator's epistemic footprint.** Neutral-voice
|
|
120
|
+
attribution creates a specific bias: every "Ben argues…" or "Newman
|
|
121
|
+
proposes…" is a claim that the operator originated the idea. When
|
|
122
|
+
agents write the wiki, it is tempting to attach the operator's name
|
|
123
|
+
to every framing, including syntheses the agent itself generated in
|
|
124
|
+
earlier narrations that the operator merely didn't object to. That
|
|
125
|
+
quietly promotes agent-generated material into operator positions.
|
|
126
|
+
|
|
127
|
+
Before attributing a claim to the operator, check its provenance:
|
|
128
|
+
|
|
129
|
+
- **Originated in a `human_signal`** → safe to attribute to the
|
|
130
|
+
operator. Example: the operator writes "a trigram is exactly
|
|
131
|
+
three words" → "Newman defines a trigram as…" is correct.
|
|
132
|
+
- **Originated in an agent `narration`, with no operator
|
|
133
|
+
pushback** → do **not** attribute to the operator. Use passive
|
|
134
|
+
construction: "has been proposed…", "a formulation that appears
|
|
135
|
+
in the narrative record…", "is discussed in the archive as…".
|
|
136
|
+
Cite the narration directly; let the reader follow the link and
|
|
137
|
+
see who actually said it.
|
|
138
|
+
- **Agent narration that the operator explicitly affirmed**
|
|
139
|
+
(e.g., the operator replied "yes, exactly" or saved it as
|
|
140
|
+
feedback memory) → attribute to the operator *if* the affirmation
|
|
141
|
+
was specifically about that claim, not about the broader reply.
|
|
142
|
+
Cite both the narration and the affirming signal.
|
|
143
|
+
- **Operator paraphrased an agent's framing back** (e.g., the
|
|
144
|
+
agent proposed "register descent," the operator used the term
|
|
145
|
+
in a later signal) → the term is shared; attribute the *origin*
|
|
146
|
+
to the agent narration and note the operator's uptake if the
|
|
147
|
+
distinction matters.
|
|
148
|
+
|
|
149
|
+
When in doubt, prefer passive or archive-anchored attribution
|
|
150
|
+
("the term appears in the archive as…", "this framing has been
|
|
151
|
+
proposed") over naming the operator. The citation does the heavy
|
|
152
|
+
lifting; the reader can see who actually originated the claim by
|
|
153
|
+
clicking through.
|
|
154
|
+
|
|
155
|
+
This register applies to **all write modes**: create, refresh, and
|
|
156
|
+
targeted edits. Read-mode answers (narrations) have more register
|
|
157
|
+
latitude — they are operator-facing conversation, not the wiki — but
|
|
158
|
+
the page itself, once written, should read as reference.
|
|
159
|
+
|
|
160
|
+
## Wiki structure
|
|
161
|
+
|
|
162
|
+
Flat layout — every page lives directly under `wiki/`, with one
|
|
163
|
+
permitted subdirectory, `wiki/shared/`, that is itself flat:
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
wiki/
|
|
167
|
+
index.md # human-maintained catalog (agent never edits)
|
|
168
|
+
<page-name>.md # one file per concept/entity/topic — fold-local
|
|
169
|
+
shared/
|
|
170
|
+
index.md # catalog of the shared pages (agent never edits)
|
|
171
|
+
<page-name>.md # visible from every fold that can reach this one
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**Local and shared.** Pages directly under `wiki/` are visible only to
|
|
175
|
+
agents working in this fold. Pages under `wiki/shared/` are visible to
|
|
176
|
+
every fold: `list_wiki`, `read_wiki`, and `search_wiki` show another
|
|
177
|
+
fold only its `shared/` pages, and reading its local page errors with
|
|
178
|
+
*"local, not shared"* rather than *not found*. The brane install
|
|
179
|
+
directory is a fold too, so brane's own shipped pages are simply that
|
|
180
|
+
fold's `shared/`. A page's slug is its path under `wiki/`:
|
|
181
|
+
`foo.md` is local, `shared/foo.md` is shared, and a citation
|
|
182
|
+
(`slug#anchor`) means the same thing to every reader.
|
|
183
|
+
|
|
184
|
+
**Which side a page lives on is the operator's call**, exactly like
|
|
185
|
+
naming it. The agent never moves a page between `wiki/` and
|
|
186
|
+
`wiki/shared/`, in either direction. Keep local pages fluid — they are
|
|
187
|
+
where a fold thinks — and treat promotion to `shared/` as publication.
|
|
188
|
+
|
|
189
|
+
Filenames are kebab-case and stable. Internal links use plain markdown,
|
|
190
|
+
**relative to the linking file's directory** — the way GitHub and every
|
|
191
|
+
editor render them: from a local page, `[x](x.md)` and
|
|
192
|
+
`[y](shared/y.md)`; from a shared page, `[y](y.md)` for a shared
|
|
193
|
+
sibling and `[x](../x.md)` for a local page. Do not use `[[wikilink]]`
|
|
194
|
+
syntax — it only renders in Obsidian.
|
|
195
|
+
|
|
196
|
+
A shared page may link to a local one, but that link is a **citation,
|
|
197
|
+
not a promise**: a reader in another fold will see the target named and
|
|
198
|
+
scoped ("local to fold `personal`, not shared") and cannot open it. So a
|
|
199
|
+
shared page must *read* without its local links — the way a narration
|
|
200
|
+
must read without the scrollback. Local → shared links are always safe.
|
|
201
|
+
|
|
202
|
+
Pages should cross-link generously to other existing pages. Every link
|
|
203
|
+
target must be a file that currently exists in `wiki/` (or
|
|
204
|
+
`wiki/shared/`) — if the natural link target is missing, mention the
|
|
205
|
+
concept in prose without linking and add a footer note: *"Could link to
|
|
206
|
+
a `<name>.md` page if you create one."*
|
|
207
|
+
|
|
208
|
+
## Provenance
|
|
209
|
+
|
|
210
|
+
Non-trivial claims carry an inline citation:
|
|
211
|
+
|
|
212
|
+
- To a narrative event: `[claude-4c7289d1:42]` (the operator's UI
|
|
213
|
+
auto-linkifies this).
|
|
214
|
+
- To a protocol: the slash command itself — `/wiki`, `/LIVE_loop` — which
|
|
215
|
+
the reader linkifies into the protocol document. Never write it as a
|
|
216
|
+
path (`../protocols/wiki.md`): links that escape the wiki dir are
|
|
217
|
+
refused by the reader and render as dead text.
|
|
218
|
+
- To a file path: `daemon/server.ts:215` (operator's editor auto-opens).
|
|
219
|
+
- To an external source: standard markdown link with URL.
|
|
220
|
+
|
|
221
|
+
Citations let future `/wiki audit` passes check whether each claim still
|
|
222
|
+
holds. A page with no citations is not audit-tractable; flag that in
|
|
223
|
+
audit output.
|
|
224
|
+
|
|
225
|
+
## Modes
|
|
226
|
+
|
|
227
|
+
### Read mode (default)
|
|
228
|
+
|
|
229
|
+
Guidance is a question or statement without write-intent verbs.
|
|
230
|
+
|
|
231
|
+
1. Read `wiki/index.md` if it exists, then any pages it points to that
|
|
232
|
+
seem relevant to the question.
|
|
233
|
+
2. If the wiki is thin on the topic, fall back to `narrative_search`
|
|
234
|
+
over past narratives and direct file reads in the fold.
|
|
235
|
+
3. Narrate the answer. Cite the wiki pages you used (`[foo](foo.md)`
|
|
236
|
+
links) and the raw sources that filled gaps.
|
|
237
|
+
4. If the question is about something with no matching page, say so in
|
|
238
|
+
a footer — do not create the file.
|
|
239
|
+
5. **Do not edit any file in `wiki/`.** Not even to "fix a typo while
|
|
240
|
+
you're at it." Read mode is read-only, period.
|
|
241
|
+
|
|
242
|
+
### Audit mode
|
|
243
|
+
|
|
244
|
+
Guidance explicitly requests an audit: `/wiki audit`, `/wiki audit foo`,
|
|
245
|
+
`/wiki check for drift`, `/wiki what's stale`.
|
|
246
|
+
|
|
247
|
+
1. Walk the target page(s).
|
|
248
|
+
2. For each non-trivial claim with provenance: verify the cited source
|
|
249
|
+
still supports it. If the source is a narrative, sample it with
|
|
250
|
+
`listen` (`wait: false`, narrow `after`/`before`). If a file path,
|
|
251
|
+
read the file.
|
|
252
|
+
3. For claims without provenance: flag them as unauditable.
|
|
253
|
+
4. For internal links: verify each `[text](name.md)` points to a file
|
|
254
|
+
that exists, resolving relative to the linking file's directory.
|
|
255
|
+
Separately list links from a `shared/` page to a local page — not
|
|
256
|
+
an error, but the reader elsewhere can't follow them, so the page
|
|
257
|
+
must stand without them.
|
|
258
|
+
5. Sample recent activity via `narrative_search` — look for topics that
|
|
259
|
+
would belong on an existing page but aren't mentioned there. Call
|
|
260
|
+
this out as *drift*, not as a new-page proposal.
|
|
261
|
+
6. Narrate a structured report (see "Audit output" below).
|
|
262
|
+
7. **No writes.** Audit is read-only.
|
|
263
|
+
|
|
264
|
+
### Create mode
|
|
265
|
+
|
|
266
|
+
Guidance introduces a concept with a creation imperative:
|
|
267
|
+
`/wiki seed sedimentary-superintelligence.md`, `/wiki start a page on
|
|
268
|
+
the LIVE loop`, `/wiki create a page about the daemon port allocator`.
|
|
269
|
+
|
|
270
|
+
1. If `wiki/` doesn't exist, create it.
|
|
271
|
+
2. Gather material from raw sources for the introduced concept —
|
|
272
|
+
`narrative_search`, `narrative_info`, and direct file reads.
|
|
273
|
+
3. Write the page directly. Don't pre-narrate the draft and ask the
|
|
274
|
+
operator to paste it — the operator's introduction of the concept
|
|
275
|
+
is authorization to write. Choose a kebab-case filename consistent
|
|
276
|
+
with existing wiki pages; if the operator named the file, use that
|
|
277
|
+
spelling.
|
|
278
|
+
4. Apply the protocol's page rules: flat layout, kebab-case links,
|
|
279
|
+
inline provenance (`nid:seq` or file paths) for every non-trivial
|
|
280
|
+
claim, cross-links to existing wiki pages only.
|
|
281
|
+
5. Narrate a brief confirmation with the refresh marker (see below) and
|
|
282
|
+
a one-liner summary of what the page covers.
|
|
283
|
+
|
|
284
|
+
### Refresh / write mode
|
|
285
|
+
|
|
286
|
+
Guidance contains an imperative aimed at an existing page: `/wiki
|
|
287
|
+
update`, `/wiki refresh foo`, `/wiki rewrite bar to include X`,
|
|
288
|
+
`/wiki sync daemon.md with current server code`, `/wiki fill the empty
|
|
289
|
+
stub at foo.md`.
|
|
290
|
+
|
|
291
|
+
Scope the work from the guidance:
|
|
292
|
+
|
|
293
|
+
- **Whole-wiki refresh** (`/wiki update`, no target): run audit first,
|
|
294
|
+
narrate the drift report, then apply fixes page-by-page, narrating
|
|
295
|
+
each page's delta as you go.
|
|
296
|
+
- **Single-page refresh** (`/wiki refresh foo`): load `foo.md`, audit
|
|
297
|
+
it, rewrite sections that have drifted, narrate the diff.
|
|
298
|
+
- **Targeted edit** (`/wiki update foo to mention X`): narrow edit
|
|
299
|
+
matching the guidance.
|
|
300
|
+
|
|
301
|
+
Rules for writes:
|
|
302
|
+
|
|
303
|
+
1. **Only edit files that already exist.** If the guidance refers to a
|
|
304
|
+
page that doesn't exist and doesn't name a filename imperatively,
|
|
305
|
+
switch to read mode and note the gap. If the guidance *does* name
|
|
306
|
+
a filename imperatively with a creation verb, use create mode.
|
|
307
|
+
2. **Never edit `index.md`.** Propose index-line changes in narration
|
|
308
|
+
for the operator to apply by hand. Format:
|
|
309
|
+
```
|
|
310
|
+
Proposed index.md entry for foo.md:
|
|
311
|
+
- [foo](foo.md) — one-line summary
|
|
312
|
+
```
|
|
313
|
+
3. **Narrate before large rewrites.** If a page will be >50% rewritten
|
|
314
|
+
or more than one page is being changed, narrate the plan first,
|
|
315
|
+
then proceed — the operator can interrupt via signal. Small edits
|
|
316
|
+
(section-level or smaller) can proceed without pre-narration, but
|
|
317
|
+
always narrate what you changed after the fact.
|
|
318
|
+
4. **Backlink re-reading after any page edit.** When you rewrite
|
|
319
|
+
`foo.md`, grep `wiki/*.md` for links pointing to `foo.md`. For each
|
|
320
|
+
incoming link, re-read the paragraph surrounding the link and
|
|
321
|
+
verify the prose still accurately describes `foo.md`'s updated
|
|
322
|
+
content. If it no longer does, either fix the linking prose (if the
|
|
323
|
+
fix is mechanical) or flag it in narration for the operator.
|
|
324
|
+
5. **Preserve human prose.** If an operator-authored paragraph still
|
|
325
|
+
holds, leave it untouched. Write-mode work is targeted at claims
|
|
326
|
+
that have drifted or stubs that need filling — not stylistic
|
|
327
|
+
rewrites for their own sake.
|
|
328
|
+
6. **Keep citations fresh.** Every rewritten paragraph that makes a
|
|
329
|
+
non-trivial claim must carry or retain a citation.
|
|
330
|
+
|
|
331
|
+
## Reality sources
|
|
332
|
+
|
|
333
|
+
The wiki reflects "current reality" of the current fold. The agent draws
|
|
334
|
+
reality from these sources, in rough order of authority:
|
|
335
|
+
|
|
336
|
+
1. **Code and config in the fold** — the actual state of the project.
|
|
337
|
+
2. **Recent narratives** — discovered via `narrative_search` and
|
|
338
|
+
`narrative_info`. Especially useful for decisions and rationale that
|
|
339
|
+
aren't expressed in code.
|
|
340
|
+
3. **The wiki itself** — for topics that depend on prior synthesis
|
|
341
|
+
(e.g., design intent, history). But never cite the wiki as evidence
|
|
342
|
+
for a claim in the wiki — that's circular. Always trace to a
|
|
343
|
+
narrative or file.
|
|
344
|
+
|
|
345
|
+
When refreshing, work backward from the last `/wiki` refresh timestamp
|
|
346
|
+
(grep the wiki or `narrative_search` for `"Wiki refreshed"` — see
|
|
347
|
+
"Refresh marker" below). Focus on narratives and code that have changed
|
|
348
|
+
since then.
|
|
349
|
+
|
|
350
|
+
## Audit output
|
|
351
|
+
|
|
352
|
+
Structure drift reports like this (omit empty sections):
|
|
353
|
+
|
|
354
|
+
```markdown
|
|
355
|
+
**Wiki audit** — {page or "full"} — {timestamp}
|
|
356
|
+
|
|
357
|
+
### Drifted claims
|
|
358
|
+
- `foo.md`: "X does Y" — cited `daemon/server.ts:42` but that line now
|
|
359
|
+
does Z. [suggested rewrite: "X does Z"]
|
|
360
|
+
|
|
361
|
+
### Unauditable claims
|
|
362
|
+
- `bar.md`: "Historically Y was preferred" — no provenance.
|
|
363
|
+
|
|
364
|
+
### Broken links
|
|
365
|
+
- `baz.md` links to `quux.md` which does not exist.
|
|
366
|
+
|
|
367
|
+
### Stubs
|
|
368
|
+
- `empty-page.md` has no content beyond its header.
|
|
369
|
+
|
|
370
|
+
### Missing coverage
|
|
371
|
+
- Recent narrative claude-abc:33 discusses the new memory subsystem at
|
|
372
|
+
length. `memory.md` doesn't mention these changes.
|
|
373
|
+
|
|
374
|
+
### Suggested cross-links
|
|
375
|
+
- `foo.md` paragraph 3 should probably link to `bar.md` (current
|
|
376
|
+
mention is in plain prose).
|
|
377
|
+
|
|
378
|
+
### Suggested index entries
|
|
379
|
+
- (agent never edits index.md; list proposed one-liners here)
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Refresh output follows the same structure but with an additional
|
|
383
|
+
**Applied** section listing the files and sections the agent actually
|
|
384
|
+
modified.
|
|
385
|
+
|
|
386
|
+
## Refresh marker
|
|
387
|
+
|
|
388
|
+
After any write-mode invocation, narrate a marker line so future
|
|
389
|
+
`/wiki` passes can locate the last refresh:
|
|
390
|
+
|
|
391
|
+
```
|
|
392
|
+
**Wiki refreshed** — {timestamp} — {N pages modified} ({guidance})
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
This is the `narrative_search` anchor for "when was the wiki last
|
|
396
|
+
synced with reality." Audit mode narrates its own marker:
|
|
397
|
+
|
|
398
|
+
```
|
|
399
|
+
**Wiki audited** — {timestamp} — {N pages checked}
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
## Quick reference
|
|
403
|
+
|
|
404
|
+
| Intent in guidance | Mode | Touches files? |
|
|
405
|
+
|---|---|---|
|
|
406
|
+
| Question, "tell me about X" | Read | No |
|
|
407
|
+
| `audit`, `check`, `what's stale` | Audit | No |
|
|
408
|
+
| `update`, `refresh`, `rewrite`, `apply`, `write`, `fill`, `sync` (existing page) | Refresh | Yes, existing files only |
|
|
409
|
+
| `seed`, `create`, `start`, `add` + **operator-introduced concept** | Create | Yes, new file |
|
|
410
|
+
| Concept mention in a question, no existing page | Read + footer note | No |
|
|
411
|
+
|
|
412
|
+
## Wiki access tools
|
|
413
|
+
|
|
414
|
+
Beyond reading wiki files directly off disk, three MCP tools expose the
|
|
415
|
+
wiki as a first-class, provenance-stamped surface — usable from any
|
|
416
|
+
fold, reaching both this fold's wiki and the `brane` package wiki:
|
|
417
|
+
|
|
418
|
+
- **`list_wiki`** — catalog of pages: slug, human-authored description
|
|
419
|
+
(from page frontmatter, else the first prose line), and `source`.
|
|
420
|
+
- **`read_wiki`** — fetch a page by slug (or one section via `anchor`),
|
|
421
|
+
with the page's TOC and a `slug` / `slug#anchor` citation.
|
|
422
|
+
- **`search_wiki`** — semantic + keyword search over wiki content,
|
|
423
|
+
returning chunk-level `slug#anchor` hits, like `narrative_search` but
|
|
424
|
+
over the wikis. Its index self-syncs on call.
|
|
425
|
+
|
|
426
|
+
Pages may carry a `description:` (and optional `title:`) in `---`
|
|
427
|
+
frontmatter; `list_wiki` surfaces it verbatim (human-authored, never
|
|
428
|
+
AI-synthesized). See the [memory](memory.md) protocol for the full
|
|
429
|
+
consultation procedure.
|
|
430
|
+
|
|
431
|
+
## Related protocols
|
|
432
|
+
|
|
433
|
+
- **[LIVE_loop](LIVE_loop.md)** — the communication loop this runs in.
|
|
434
|
+
- **[memory](memory.md)** — `narrative_search` and `search_wiki` are the
|
|
435
|
+
primary tools for reality-sync during refresh.
|
|
436
|
+
- **[digest](digest.md)** — time-windowed syntheses; wiki pages can
|
|
437
|
+
reference digests as provenance, and a digest can point at wiki pages
|
|
438
|
+
for concept-level context.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Protocol: worker
|
|
2
|
+
|
|
3
|
+
The default role. Nothing beyond the LIVE loop applies, except to
|
|
4
|
+
repeat: never delete anything, and do not act before alignment is
|
|
5
|
+
explicitly reached.
|
|
6
|
+
|
|
7
|
+
You will almost certainly need **/LIVE_loop** — it is the execution
|
|
8
|
+
environment, not an option. Read it first if you have not already.
|
|
9
|
+
|
|
10
|
+
## The other protocols, briefly
|
|
11
|
+
|
|
12
|
+
Reach for these when a signal names them (`/memory`, `/review`, …) or
|
|
13
|
+
the task calls for them; `list_protocols` is always current.
|
|
14
|
+
|
|
15
|
+
| Protocol | When |
|
|
16
|
+
|----------|------|
|
|
17
|
+
| /LIVE_loop | Always — the loop itself |
|
|
18
|
+
| /memory | Searching narrative history, loading context from other narratives |
|
|
19
|
+
| /payloads | Receiving or sending files and images over the loop |
|
|
20
|
+
| /review | Reading and critiquing a proposed change, usually a PR |
|
|
21
|
+
| /ramify | Delegating work to spawned sub-agents |
|
|
22
|
+
| /summarize | Consolidating a long session into a durable summary |
|
|
23
|
+
| /idle | Stopping the loop when the operator says the work is done — only as a signal's first token |
|
|
24
|
+
| /digest | Summarizing activity across narratives over a time window |
|
|
25
|
+
| /rrr | Putting the running code on what is merged: fetch, rebase, rebuild, restart |
|
|
26
|
+
| /wiki | Maintaining the fold's `./wiki/` |
|
|
27
|
+
| /scribe | Taking dictation into a document |
|
|
28
|
+
| /keeper, /twin | Other roles — informational unless the operator layers one onto you |
|
|
29
|
+
|
|
30
|
+
## Brane-internal
|
|
31
|
+
|
|
32
|
+
These protocols only mean something when the fold is the brane
|
|
33
|
+
repository itself (the checkout the daemon runs from — compare
|
|
34
|
+
`whoami`'s `fold_dir`). In any other project, ignore them.
|
|
35
|
+
|
|
36
|
+
| Protocol | When |
|
|
37
|
+
|----------|------|
|
|
38
|
+
| /fly | Brane's own Fly.io deployment |
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Append-Only Event Log
|
|
2
|
+
|
|
3
|
+
The durable substrate behind every narrative. A single SQLite table
|
|
4
|
+
(`events` in `~/.brane/brane.db`) that every narration, operator signal,
|
|
5
|
+
and foreign narration lands in — and once landed, cannot be changed.
|
|
6
|
+
Integrity is not an agent convention or a trust assumption; it is a
|
|
7
|
+
property of the code that has the only write path and the SQL that
|
|
8
|
+
schema enforces.
|
|
9
|
+
|
|
10
|
+
Every event belongs to a narrative and carries a `seq` that is unique
|
|
11
|
+
within it — `PRIMARY KEY (narrative_id, seq)` in `src/db/schema.ts`.
|
|
12
|
+
The composite key makes the (narrative, seq) pair unforgeable: two
|
|
13
|
+
events cannot share a seq in the same narrative, and no event can exist
|
|
14
|
+
without one. Alongside `seq` an event carries its `time` (stamped at
|
|
15
|
+
append), a `type`, free-form `content`, a server-stamped `source`,
|
|
16
|
+
optional `re` back-references, optional `payloads`, and an opt-in
|
|
17
|
+
`meta` object. The three conversational types — `narration`,
|
|
18
|
+
`human_signal`, `agent_signal` — say *who spoke*, never what kind of
|
|
19
|
+
thing was said; the system types (`started`, `restarted`,
|
|
20
|
+
`binding_rejected`) record lifecycle facts nobody said at all. The
|
|
21
|
+
schema itself is documented with the code in `AGENTS.md`.
|
|
22
|
+
|
|
23
|
+
## The write path
|
|
24
|
+
|
|
25
|
+
Every live write goes through `appendEvent` in `src/db/events.ts`,
|
|
26
|
+
which reads the current max seq, increments it, and inserts. Callers
|
|
27
|
+
never provide their own `seq` — the options type has no such field —
|
|
28
|
+
so there is no way to write out of order or collide with an existing
|
|
29
|
+
row. (The one exception is `brane absorb`, whose import pipeline
|
|
30
|
+
inserts directly with self-computed seqs; it is operator-initiated and
|
|
31
|
+
not reachable from any agent tool.)
|
|
32
|
+
|
|
33
|
+
`source` is written by the daemon at append time — the MCP bridge and
|
|
34
|
+
the agent have no write path of their own. How the value is chosen
|
|
35
|
+
differs by event type:
|
|
36
|
+
|
|
37
|
+
- **Operator signals** arrive over the HTTP signal route or the
|
|
38
|
+
control WebSocket. `source` names the delivering transport
|
|
39
|
+
(defaulting to `"web"`), supplied by the authenticated operator
|
|
40
|
+
client — so a token holder chooses the label on its own signals, but
|
|
41
|
+
an agent cannot write a human signal at all.
|
|
42
|
+
- **Foreign narrations** are appended by the daemon's MCP `narrate`
|
|
43
|
+
handler with the *caller's* narrative ID as `source`, taken from the
|
|
44
|
+
authenticated WebSocket identity. The agent does not get to choose
|
|
45
|
+
what is written into that column.
|
|
46
|
+
- **Own narrations** go through the same handler with the same
|
|
47
|
+
server-stamped identity.
|
|
48
|
+
|
|
49
|
+
The MCP bridge (`src/mcp/server.ts`) does not import `better-sqlite3`
|
|
50
|
+
and holds no database handle. It is a thin stdio↔WebSocket translator;
|
|
51
|
+
every database write goes through the daemon, which means the identity
|
|
52
|
+
check and the `source` stamp cannot be bypassed by a compromised bridge
|
|
53
|
+
or a misbehaving tool call.
|
|
54
|
+
|
|
55
|
+
There is no DELETE against the `events` table anywhere in the codebase,
|
|
56
|
+
and no code path mutates an event's `content`, `seq`, `source`, `time`,
|
|
57
|
+
or `type` after append. The one UPDATE that exists is the memory
|
|
58
|
+
indexer's additive backfill of the `meta` column (session and model
|
|
59
|
+
attribution, `src/memory/index.ts`) — it annotates, it never rewrites.
|
|
60
|
+
Append-only for the record itself is enforced by the absence of
|
|
61
|
+
mutation code, not by a runtime flag that could be flipped later.
|
|
62
|
+
|
|
63
|
+
## The read path
|
|
64
|
+
|
|
65
|
+
The cursor API (`readEvents` in `src/db/events.ts`) takes three
|
|
66
|
+
optional bounds: `after: N` for events with `seq > N`, `before: N` for
|
|
67
|
+
events with `seq < N`, and `tail: N` for the last N matching events.
|
|
68
|
+
They compose — `{ after, before }` is a window, `{ tail, before }` is
|
|
69
|
+
backward pagination — and results always come back in ascending `seq`
|
|
70
|
+
order regardless of which bounds were used [claude-b629ddae:19].
|
|
71
|
+
|
|
72
|
+
The cursor is the contract for no-missed-signals: a caller that polls
|
|
73
|
+
with `after: 42` is guaranteed every event with `seq > 42`, so any
|
|
74
|
+
signal that arrived while the caller was elsewhere surfaces on the next
|
|
75
|
+
call. This is what makes the LIVE loop's long-poll semantics correct
|
|
76
|
+
(/LIVE_loop) — not magic on the server, just a monotonically increasing
|
|
77
|
+
integer the client remembers.
|
|
78
|
+
|
|
79
|
+
## Integrity properties
|
|
80
|
+
|
|
81
|
+
Four properties fall out of the append-only design and the server-side
|
|
82
|
+
`source` stamp [claude-f64c335a:53]:
|
|
83
|
+
|
|
84
|
+
- **Unrewritable history.** No DELETE, and nothing ever touches an
|
|
85
|
+
event's `content`, `seq`, `source`, or `time` after append. The agent
|
|
86
|
+
cannot redact, edit, or reorder its own past; the only way the record
|
|
87
|
+
can change is if the entire database is replaced, which a LIVE loop
|
|
88
|
+
agent has no authority to do.
|
|
89
|
+
- **Unforgeable origin.** `source` is stamped by the daemon from the
|
|
90
|
+
authenticated caller's identity. An agent narrating into a foreign
|
|
91
|
+
narrative cannot claim to be the operator; a client cannot forge
|
|
92
|
+
narrations from another narrative's agent.
|
|
93
|
+
- **Monotonic contract.** `PRIMARY KEY (narrative_id, seq)` makes the
|
|
94
|
+
seq unique per narrative, and `appendEvent` always writes
|
|
95
|
+
`MAX(seq) + 1`. No gaps, no duplicates, no out-of-order.
|
|
96
|
+
- **Durable.** Written to `~/.brane/brane.db` in WAL mode, synced on
|
|
97
|
+
commit. Survives daemon restarts, crashes, and context compactions —
|
|
98
|
+
everything external to the host filesystem.
|
|
99
|
+
|
|
100
|
+
These are the properties the safety argument in
|
|
101
|
+
[sedimentary-superintelligence](sedimentary-superintelligence.md)
|
|
102
|
+
depends on: an agent's trail cannot be covered up by the agent itself,
|
|
103
|
+
because the write path the agent can reach is append-only and the
|
|
104
|
+
`source` field is out of its control. The defense against an agent
|
|
105
|
+
that would edit its own trail is not "watch harder" — at machine speed
|
|
106
|
+
no operator can — but append-only, monotonically-sequenced,
|
|
107
|
+
agent-unwritable event storage, expressed as database invariants rather
|
|
108
|
+
than as trust in the model's cooperation [claude-f64c335a:53].
|
|
109
|
+
|
|
110
|
+
## What it enables
|
|
111
|
+
|
|
112
|
+
- **Cursor-based long-polling.** The `listen` tool's wait-for-new-events
|
|
113
|
+
semantics depend on the monotonic seq to guarantee no missed signals.
|
|
114
|
+
Without append-only integrity the cursor would be a suggestion, not a
|
|
115
|
+
contract (/LIVE_loop).
|
|
116
|
+
- **Semantic memory across narratives.** Events with stable `seq`
|
|
117
|
+
values can be indexed by the memory subsystem and cited from future
|
|
118
|
+
sessions as `narrative-id:seq` — a form that only works because seq
|
|
119
|
+
is stable after write (/memory).
|
|
120
|
+
- **Compounding narrations.** Every token spent on a narration lands in
|
|
121
|
+
a log that is searchable, citable, and available to future agents.
|
|
122
|
+
Terminal output is volatile and unindexed; narrations accumulate.
|
|
123
|
+
This is the premise of
|
|
124
|
+
[sedimentary-superintelligence](sedimentary-superintelligence.md),
|
|
125
|
+
and the same property is what makes the narrative
|
|
126
|
+
[sequesterable](sequestering-the-narrative.md) — a medium durable
|
|
127
|
+
enough that `/clear` becomes a routine operation rather than an
|
|
128
|
+
emergency.
|
|
129
|
+
- **Safety-by-construction for capable agents.** An agent that could
|
|
130
|
+
rewrite its own history can conceal intent; an agent that cannot can
|
|
131
|
+
only be observed. Making the log append-only converts the supervision
|
|
132
|
+
problem from "trust the model" into "watch the stream"
|
|
133
|
+
[claude-f64c335a:53].
|
|
134
|
+
|
|
135
|
+
## Related
|
|
136
|
+
|
|
137
|
+
- [sedimentary-superintelligence](sedimentary-superintelligence.md) —
|
|
138
|
+
the log *is* the sediment. This page describes the substrate's
|
|
139
|
+
integrity; that page describes what the substrate is for.
|
|
140
|
+
- [sequestering-the-narrative](sequestering-the-narrative.md) — the
|
|
141
|
+
narrative's *position*, set apart from scrollback and context; this
|
|
142
|
+
page is about its *integrity*.
|
|
143
|
+
- [owning-your-narratives](owning-your-narratives.md) — the practice
|
|
144
|
+
that makes an unrewritable record worth reading.
|
|
145
|
+
- [premature-ontologies](premature-ontologies.md) — why the schema
|
|
146
|
+
types who spoke and never what was said.
|
|
147
|
+
- /LIVE_loop — the protocol that reads from and writes to this log;
|
|
148
|
+
authoritative on cursor parameters and response shapes.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Brane Wiki
|
|
2
|
+
|
|
3
|
+
What brane is, why it's shaped the way it is, and what it asks of the
|
|
4
|
+
agents that run inside it. The narratives are the read path and the
|
|
5
|
+
source of truth; these pages are an opinionated projection of them
|
|
6
|
+
([why-wikis-work](why-wikis-work.md)). When a page disagrees with the
|
|
7
|
+
narrative record, the record wins.
|
|
8
|
+
|
|
9
|
+
New here? Read in order:
|
|
10
|
+
|
|
11
|
+
1. [sedimentary-superintelligence](sedimentary-superintelligence.md) —
|
|
12
|
+
the one-paragraph pitch: an archive smarter than you, inert at rest.
|
|
13
|
+
2. [why-wikis-work](why-wikis-work.md) — why a second brain works, where
|
|
14
|
+
it fails, and why this directory exists anyway.
|
|
15
|
+
3. [sequestering-the-narrative](sequestering-the-narrative.md) — the
|
|
16
|
+
narrative held apart from scrollback and context window.
|
|
17
|
+
4. [owning-your-narratives](owning-your-narratives.md) — what that asks
|
|
18
|
+
of an agent, turn by turn.
|
|
19
|
+
5. [premature-ontologies](premature-ontologies.md) — the intellectual
|
|
20
|
+
inheritance: why refusing a typology is the substrate decision.
|
|
21
|
+
6. [append-only-event-log](append-only-event-log.md) — the one code-level
|
|
22
|
+
commitment everything above rests on.
|
|
23
|
+
|
|
24
|
+
## Theses — what brane believes
|
|
25
|
+
- [sedimentary-superintelligence](sedimentary-superintelligence.md) — an archive of accumulated dialogue smarter than any user yet inert at rest; intelligence lives in the act of integration, not the sediment.
|
|
26
|
+
- [sequestering-the-narrative](sequestering-the-narrative.md) — the narrative held apart from disposable scrollback, volatile context, and other agents' records.
|
|
27
|
+
- [owning-your-narratives](owning-your-narratives.md) — the agent practice that follows: narrate for downstream retrieval, not upstream expression.
|
|
28
|
+
- [premature-ontologies](premature-ontologies.md) — why committing a typology before its categories have earned their scope keeps failing; the refusal of taxonomy-as-substrate.
|
|
29
|
+
- [why-wikis-work](why-wikis-work.md) — where the wiki pattern wins, where it struggles, and why this directory is a disciplined compromise.
|
|
30
|
+
|
|
31
|
+
## Substrate — how brane keeps its word
|
|
32
|
+
- [append-only-event-log](append-only-event-log.md) — the single immutable SQLite table behind every narrative; integrity enforced by schema, not convention.
|
|
33
|
+
|
|
34
|
+
## Mechanism lives elsewhere
|
|
35
|
+
|
|
36
|
+
The daemon, transports, agent adapters, security model, and the LIVE
|
|
37
|
+
loop's exact tool contract are documented in `AGENTS.md` (an index into `docs/`), `DESIGN.md`,
|
|
38
|
+
`SECURITY.md`, and `protocols/` — all shipped alongside this wiki and
|
|
39
|
+
maintained with the code. Pages here make arguments; those files
|
|
40
|
+
describe machinery.
|
|
41
|
+
|
|
42
|
+
## Local to the brane fold, not shipped
|
|
43
|
+
|
|
44
|
+
The brane checkout's `wiki/` holds further pages that are either
|
|
45
|
+
brane-internal or still settling: `brane-ontology`, `why-tailscale`,
|
|
46
|
+
and `how-to-brane`. They are local pages of that fold — readable
|
|
47
|
+
by agents working in the checkout, not published with the package and
|
|
48
|
+
not visible from other folds.
|