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,203 @@
|
|
|
1
|
+
# /summarize [guidance]
|
|
2
|
+
|
|
3
|
+
Consolidate a session into a durable summary narration — the nap that
|
|
4
|
+
lets a fresh session pick up without re-learning what just happened.
|
|
5
|
+
|
|
6
|
+
## Why summarize
|
|
7
|
+
|
|
8
|
+
A session accumulates context that is about to be lost: the context
|
|
9
|
+
window gets compacted or cleared, the agent session dies and is
|
|
10
|
+
revived, a twin takes over, or the operator simply returns tomorrow.
|
|
11
|
+
The narrative event log survives all of these — but a reader arriving
|
|
12
|
+
cold gets the log in event order, newest last, with the load-bearing
|
|
13
|
+
conclusions scattered among the play-by-play. A summary narration is
|
|
14
|
+
the consolidation pass that fixes this: one event, near the end of the
|
|
15
|
+
log, that a `listen(wait: false, tail: 50)` on re-entry finds
|
|
16
|
+
immediately, stating where things stand.
|
|
17
|
+
|
|
18
|
+
The framing comes from Erik Bylund's "Agents Need Sleep"
|
|
19
|
+
(erikbylund.com, 2026): memory needs **consolidation as a first-class
|
|
20
|
+
practice** — a light "nap" after each unit of work so that "a fresh
|
|
21
|
+
session tomorrow picks up without re-learning what just happened."
|
|
22
|
+
Consolidation's job is salience, compression, trust, and *forgetting*
|
|
23
|
+
— not retrieval, which search already handles. `/summarize` is the
|
|
24
|
+
nap, adapted to brane's substrate.
|
|
25
|
+
|
|
26
|
+
That substrate changes the risk profile. Bylund's central warning —
|
|
27
|
+
*"distillation concentrates error exactly as efficiently as it
|
|
28
|
+
concentrates signal"* — is about mutable state files, where the
|
|
29
|
+
summary silently replaces the record and a stale claim inherits full
|
|
30
|
+
authority. A brane summary is a narration: append-only, attributed,
|
|
31
|
+
timestamped, and sitting *beside* the events it summarizes rather than
|
|
32
|
+
over them. It cannot erase anything, and every claim in it can carry
|
|
33
|
+
an `nid:seq` citation back to the event it came from. That is the
|
|
34
|
+
discipline this protocol enforces: a summary is a **checkable index
|
|
35
|
+
into the record**, not a replacement for it. Written this way, the
|
|
36
|
+
summary doubles as a **trailing table of contents** for the
|
|
37
|
+
narrative: its `nid:seq` backlinks — which the operator's UI
|
|
38
|
+
auto-linkifies into links that jump to the exact event — let a
|
|
39
|
+
reader navigate the whole session from one narration.
|
|
40
|
+
|
|
41
|
+
## Audiences
|
|
42
|
+
|
|
43
|
+
Write for all of these at once, in roughly this priority:
|
|
44
|
+
|
|
45
|
+
1. **Your future self** after a `/clear`, compaction, or revive —
|
|
46
|
+
reloading via `listen` and needing plan, stance, and in-flight
|
|
47
|
+
state back without re-reading everything.
|
|
48
|
+
2. **A successor or twin** continuing the work with none of your
|
|
49
|
+
context (see the [twin](twin.md) protocol).
|
|
50
|
+
3. **The operator**, catching up asynchronously — possibly on a
|
|
51
|
+
phone, possibly days later.
|
|
52
|
+
4. **Future search and `/digest` runs** — the summary is the event
|
|
53
|
+
most worth surfacing for the whole session, so make it findable
|
|
54
|
+
and self-contained.
|
|
55
|
+
|
|
56
|
+
The quality bar is Bylund's stranger test: **could a stranger read
|
|
57
|
+
this one narration and know where things stand?** If understanding it
|
|
58
|
+
requires having watched the session, it is not done.
|
|
59
|
+
|
|
60
|
+
## What a good session summary is
|
|
61
|
+
|
|
62
|
+
**A state snapshot, not a chronicle.** Report where things stand
|
|
63
|
+
*now* — not the order in which you got there. The sequence of
|
|
64
|
+
attempts, tool calls, and course corrections is already in the log in
|
|
65
|
+
perfect fidelity; re-telling it is the one thing a summary can never
|
|
66
|
+
do better than the record itself. Chronology earns a place only where
|
|
67
|
+
it explains the present ("X was tried before Y ruled it out").
|
|
68
|
+
|
|
69
|
+
**Forgetting is the job.** The append-only log is what makes
|
|
70
|
+
aggressive compression safe: nothing you omit is lost, only demoted to
|
|
71
|
+
search. Drop the routine and the resolved. What must *not* be dropped:
|
|
72
|
+
open threads, unanswered operator questions, and negative findings —
|
|
73
|
+
"we tried X and it failed because Y" is expensive knowledge that a
|
|
74
|
+
successor will otherwise re-purchase.
|
|
75
|
+
|
|
76
|
+
**Grounded, not remembered.** A wrong confident summary is worse than
|
|
77
|
+
no summary at all — it gets read *instead of* the record, so its
|
|
78
|
+
errors propagate with the full authority of consolidation. The rules
|
|
79
|
+
are the same as [/digest](digest.md)'s, and they are mandatory:
|
|
80
|
+
|
|
81
|
+
- Re-read the events before summarizing them. Your in-context memory
|
|
82
|
+
of the session may already be compacted prose; the log is not.
|
|
83
|
+
Report only what the log actually says.
|
|
84
|
+
- Cite claims as `nid:seq` so they are checkable — and so the summary
|
|
85
|
+
works as an entry point into `listen` / `narrative_search` for any
|
|
86
|
+
reader who needs the detail (see the [memory](memory.md) protocol).
|
|
87
|
+
Always the full `nid:seq` form: prose like "seq 42" is not
|
|
88
|
+
linkified, so it makes a claim checkable but not tappable.
|
|
89
|
+
- Repo facts (branch names, PR numbers, commit hashes, test results)
|
|
90
|
+
are copied from real `git`/`gh` output obtained this run, never
|
|
91
|
+
composed from memory to look precise.
|
|
92
|
+
- Attribute positions; don't assert them. Decisions are "the operator
|
|
93
|
+
directed…" / "we agreed…" with a citation, not settled fact. Don't
|
|
94
|
+
editorialize, sharpen vague outcomes into definite ones, or supply
|
|
95
|
+
motives the events don't give.
|
|
96
|
+
- Name your gaps instead of filling them. If part of the session is
|
|
97
|
+
unread or an outcome is unverified, say so plainly.
|
|
98
|
+
|
|
99
|
+
## Interpreting guidance
|
|
100
|
+
|
|
101
|
+
`/summarize [guidance]` is freeform; interpret intent generously, as
|
|
102
|
+
`/digest` does. The default — bare `/summarize` or
|
|
103
|
+
`/summarize session` — is the current narrative, whole session,
|
|
104
|
+
general audience. Guidance can adjust any of:
|
|
105
|
+
|
|
106
|
+
- **Scope** — `/summarize since the last summary`,
|
|
107
|
+
`/summarize the last hour`, `/summarize the auth work only`
|
|
108
|
+
- **Audience** — `/summarize for a twin` (lean toward in-flight
|
|
109
|
+
state, gotchas, and next actions), `/summarize for the operator`
|
|
110
|
+
(lean toward outcomes and open questions)
|
|
111
|
+
- **Target** — `/summarize claude-4c7289d1`: summarize another
|
|
112
|
+
narrative, loading it first via `listen` with a cursor (see
|
|
113
|
+
*Cross-Narrative Context Loading* in [memory](memory.md)). Narrate
|
|
114
|
+
the summary into your own narrative unless directed otherwise.
|
|
115
|
+
- **Focus** — any topical emphasis the guidance names
|
|
116
|
+
|
|
117
|
+
## Gathering
|
|
118
|
+
|
|
119
|
+
Ground the summary in the log, not in what you think you remember:
|
|
120
|
+
|
|
121
|
+
1. Find your previous summary, if any — scan your own narrative for
|
|
122
|
+
the `**Session summary**` header (a `listen` re-read, or
|
|
123
|
+
`narrative_search` scoped by content). Its seq is your default
|
|
124
|
+
window start, and your `re` target for supersession.
|
|
125
|
+
2. Re-read the window: `listen` with `wait: false` and `after` set to
|
|
126
|
+
the previous summary's seq (or `0` for the whole narrative —
|
|
127
|
+
paginate if long). Note the seqs of load-bearing events as you go:
|
|
128
|
+
operator direction, decisions, reversals, results.
|
|
129
|
+
3. Corroborate externals — run `git`/`gh` for any repo state the
|
|
130
|
+
summary will assert; check that "done" things are actually merged,
|
|
131
|
+
pushed, or passing.
|
|
132
|
+
|
|
133
|
+
For long sessions, narrate brief progress as you gather, per the LIVE
|
|
134
|
+
loop's narrate-often principle.
|
|
135
|
+
|
|
136
|
+
## Summary structure
|
|
137
|
+
|
|
138
|
+
Begin the narration with a header line:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
**Session summary** — {one-line gist} ({date})
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Then sections as needed, omitting any that are empty. Suggested
|
|
145
|
+
shape, not a rigid template — let the session's actual shape win:
|
|
146
|
+
|
|
147
|
+
- **Where things stand** — current state of the work: what exists,
|
|
148
|
+
what is verified working, what is merely drafted. Concrete
|
|
149
|
+
locations: branch, worktree, files, PRs.
|
|
150
|
+
- **Decisions** — direction set during the session, attributed and
|
|
151
|
+
cited (`nid:seq`). Include decisions *against* things.
|
|
152
|
+
- **Open threads** — in-flight work, unanswered questions, promised
|
|
153
|
+
follow-ups, blockers. This is the section a successor acts on
|
|
154
|
+
first; make each item actionable.
|
|
155
|
+
- **Lessons and dead ends** — negative findings worth keeping:
|
|
156
|
+
approaches ruled out and why, gotchas discovered, anything a
|
|
157
|
+
successor would otherwise re-learn the hard way.
|
|
158
|
+
- **Pointers** — key events (`nid:seq`), PRs/commits, files, wiki
|
|
159
|
+
pages (`slug#anchor`) for readers who need to go deeper. Together
|
|
160
|
+
with the citations woven through the sections above, this is the
|
|
161
|
+
trailing-table-of-contents role made explicit: every major beat of
|
|
162
|
+
the session reachable through a backlink.
|
|
163
|
+
|
|
164
|
+
Keep it compact — a summary that must be summarized has failed.
|
|
165
|
+
Compression is safe precisely because the pointers carry the depth.
|
|
166
|
+
|
|
167
|
+
## Output
|
|
168
|
+
|
|
169
|
+
Narrate the summary in full via `narrate`, on one call that also:
|
|
170
|
+
|
|
171
|
+
- **Sets `meta.summary`** to a current one-liner for the narrative
|
|
172
|
+
list — e.g. `"Summarized: daemon refactor merged; expo tab bug
|
|
173
|
+
open"`. The narrated body and the metadata line serve different
|
|
174
|
+
readers (log vs. list); update both.
|
|
175
|
+
- **Back-references via `re`**: the previous `**Session summary**`
|
|
176
|
+
event if one exists (supersession by reference — the new summary
|
|
177
|
+
visibly succeeds the old, and the chain of summaries becomes
|
|
178
|
+
walkable), plus the load-bearing events the summary rests on.
|
|
179
|
+
|
|
180
|
+
Before posting, make one verification pass over the draft: every
|
|
181
|
+
claim, citation, and identifier — can you point to the event or
|
|
182
|
+
command output you read it from? Cut or flag anything you cannot.
|
|
183
|
+
|
|
184
|
+
## Cadence
|
|
185
|
+
|
|
186
|
+
`/summarize` runs when the operator invokes it, but the natural
|
|
187
|
+
moments to *suggest* one (or, with standing permission, run one) are
|
|
188
|
+
exactly Bylund's nap boundaries: a unit of work just completed, a
|
|
189
|
+
`/clear` or handoff is imminent, or the session is winding down. A
|
|
190
|
+
summary written while context is still warm is cheap; the same
|
|
191
|
+
summary reconstructed after context loss is expensive and worse.
|
|
192
|
+
|
|
193
|
+
The heavier tier — Bylund's "deep sleep," where accumulated summaries
|
|
194
|
+
are themselves challenged against reality and distilled — is not this
|
|
195
|
+
protocol. Cross-narrative consolidation belongs to [/digest](digest.md)
|
|
196
|
+
(activity over a time window) and the [/wiki](wiki.md) audit (curated
|
|
197
|
+
synthesis against the record).
|
|
198
|
+
|
|
199
|
+
## After generating
|
|
200
|
+
|
|
201
|
+
Return to the LIVE loop — `listen` for further signals. The operator
|
|
202
|
+
may ask follow-ups, request a different focus, or use the summary as
|
|
203
|
+
the handoff point for a `/clear` or twin spawn.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Protocol: twin
|
|
2
|
+
|
|
3
|
+
A **twin** is a brane-managed agent spawned to continue from a
|
|
4
|
+
**predecessor** narrative — inheriting its history and, when the
|
|
5
|
+
predecessor is still live, tracking it in real time. Twinning is how an
|
|
6
|
+
external or absorbed session's context is brought into brane as a
|
|
7
|
+
first-class, revivable narrative without disturbing the original.
|
|
8
|
+
|
|
9
|
+
This protocol is **role-bound**: it is binding on agents who hold
|
|
10
|
+
`role: "twin"`. For everyone else it is informational. Roles are
|
|
11
|
+
superpositional (see the prelude's "Role-bound protocols"): a twin
|
|
12
|
+
can be steered by the operator to *also* hold another role — most
|
|
13
|
+
naturally `keeper`, scoped to its predecessor — and then both
|
|
14
|
+
protocols bind it jointly. See "A twin as a single-purpose keeper"
|
|
15
|
+
below.
|
|
16
|
+
|
|
17
|
+
**Prerequisite:** this protocol uses the LIVE loop's tools and
|
|
18
|
+
vocabulary (`listen`, `narrate`, `whoami`, `narrative_info`, etc.). If
|
|
19
|
+
you have not already read `protocols/LIVE_loop.md`, read it first; then
|
|
20
|
+
return here.
|
|
21
|
+
|
|
22
|
+
## What a twin is for
|
|
23
|
+
|
|
24
|
+
The operator spawned you to adopt a predecessor narrative — typically an
|
|
25
|
+
**external** MCP session (an agent that connected without `brane spawn`)
|
|
26
|
+
or an **absorbed** import. The predecessor may be:
|
|
27
|
+
|
|
28
|
+
- **Over** — disconnected or finished. You are importing a closed
|
|
29
|
+
history, the way an absorbed narrative is activated.
|
|
30
|
+
- **Still live** — an external client may still be connected and
|
|
31
|
+
appending events *after* the point you were forked from. You are then
|
|
32
|
+
a real-time twin: you continue the work *alongside* it, not just from
|
|
33
|
+
a snapshot.
|
|
34
|
+
|
|
35
|
+
You will not know which until you look — so this protocol has you treat
|
|
36
|
+
the predecessor as **possibly live** by default.
|
|
37
|
+
|
|
38
|
+
## Step 1 — Find your predecessor
|
|
39
|
+
|
|
40
|
+
Your predecessor is recorded in your **own `started` event's `re`**, in
|
|
41
|
+
`nid:seq` form (e.g. `external-9f3a1c20:42`). Read it:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{ "tail": 1, "after": 0 }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The `re` entry's `nid` is your predecessor; its `:seq` is the **boundary
|
|
48
|
+
seq** — the last event that existed in the predecessor when you were
|
|
49
|
+
forked. Everything in the predecessor **through that seq is your
|
|
50
|
+
inherited prefix**; anything past it (if any) is new activity that
|
|
51
|
+
arrived after the fork.
|
|
52
|
+
|
|
53
|
+
If your `started` event carries no `re`, you have no predecessor — fall
|
|
54
|
+
back to the plain LIVE loop.
|
|
55
|
+
|
|
56
|
+
## Step 2 — Read the inherited prefix
|
|
57
|
+
|
|
58
|
+
Read the predecessor's history up to the boundary seq and process it as
|
|
59
|
+
your own context:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{ "after": { "<predecessor-nid>": 0 } }
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Keep advancing the cursor (`{ "<predecessor-nid>": <last-seq-seen> }`)
|
|
66
|
+
until you have read through the boundary seq. If there are many events,
|
|
67
|
+
page until you reach it. This is the salient context you were spawned to
|
|
68
|
+
carry forward — understand it before acting.
|
|
69
|
+
|
|
70
|
+
The prefix may be **thin or empty** — e.g. a freshly-connected external
|
|
71
|
+
client whose only event is its connection. That's fine: carry forward
|
|
72
|
+
whatever is there and move on. This step earns its keep when twinning an
|
|
73
|
+
absorbed import or a long-running session; for a brand-new predecessor
|
|
74
|
+
there is simply little to inherit.
|
|
75
|
+
|
|
76
|
+
## Step 3 — Twin the live loop
|
|
77
|
+
|
|
78
|
+
From now on, **LIVE-loop with a multi-narrative cursor over both your
|
|
79
|
+
own narrative and the predecessor's**, so you stay in sync if the
|
|
80
|
+
predecessor is still active:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{ "after": { "self": <your-last-seq>, "<predecessor-nid>": <boundary-seq> } }
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
- Advance **both** keys as events arrive.
|
|
87
|
+
- New events from the predecessor past the boundary seq are the live
|
|
88
|
+
session continuing — interpret them as fresh signals, not history.
|
|
89
|
+
- If the predecessor is over, this watch simply yields nothing extra and
|
|
90
|
+
you behave like any other agent. No special-casing needed.
|
|
91
|
+
|
|
92
|
+
## Step 4 — Wait for operator direction
|
|
93
|
+
|
|
94
|
+
DO NOT under any circumstances begin executing actions (_especially_
|
|
95
|
+
contacting the previous agent) before you have explicit direction from
|
|
96
|
+
the operator, as this skips the L, I, and V steps of the LIVE loop. Do
|
|
97
|
+
not even speculate about the nature of the task before you actually
|
|
98
|
+
know, even if the operator has not yet said anything, as this will
|
|
99
|
+
confuse future readers if you happen to be wrong. Wait.
|
|
100
|
+
|
|
101
|
+
## Step 5 — Coordinate, don't collide
|
|
102
|
+
|
|
103
|
+
**First, find out whether a peer is actually live** — don't assume. A
|
|
104
|
+
predecessor narrative may have a live agent on the other end, or it may
|
|
105
|
+
be **dormant**: an external client that has since disconnected, or a
|
|
106
|
+
narrative the operator is simply using as a second channel to type into.
|
|
107
|
+
Check before you worry about collision:
|
|
108
|
+
|
|
109
|
+
- Call `narrative_info` with the predecessor's nid and look at
|
|
110
|
+
`mcp_connected` (and `status`), and/or `list_peers` to see whether it
|
|
111
|
+
appears as an active peer.
|
|
112
|
+
- **No agent connected →** there is no one to collide with. Every event
|
|
113
|
+
there is the operator (or your own foreign-narration); you are simply
|
|
114
|
+
the sole live agent rooted in two narratives. Keep watching it (it's
|
|
115
|
+
nearly free and the operator may use it as a channel), but drop the
|
|
116
|
+
coordination ceremony.
|
|
117
|
+
- **An agent *is* connected →** treat it as a true peer. Coordinate
|
|
118
|
+
explicitly and don't duplicate its actions.
|
|
119
|
+
|
|
120
|
+
When a peer is live, avoid both agents thinking they alone are driving:
|
|
121
|
+
|
|
122
|
+
- **Your own narrative is your voice.** Narrate your work into `self`.
|
|
123
|
+
- **Once you have permission to communicate with your predecessor, use
|
|
124
|
+
foreign-narration** (`narrate` with `nid: "<predecessor-nid>"`) to
|
|
125
|
+
coordinate. Your message arrives there as an `agent_signal`.
|
|
126
|
+
- **Defer to operator direction over assumptions about who owns what.**
|
|
127
|
+
You have not "inherited" any work until the operator says so, and you
|
|
128
|
+
are not entitled to suggest any division of labor between the agents.
|
|
129
|
+
|
|
130
|
+
## Extend, don't replace
|
|
131
|
+
|
|
132
|
+
A twin continues *from* its predecessor — it does not take it over. The
|
|
133
|
+
predecessor narrative stays intact as the historical record; you branch
|
|
134
|
+
from it and carry its context forward, leaving the original where it is.
|
|
135
|
+
|
|
136
|
+
## A twin as a single-purpose keeper
|
|
137
|
+
|
|
138
|
+
A twin is already most of a [keeper](keeper.md) scoped to one
|
|
139
|
+
narrative, so the operator may steer a newborn twin to *also* keep
|
|
140
|
+
watch over its predecessor. When that happens you hold both roles at
|
|
141
|
+
once (see the prelude's "Role-bound protocols") and read `keeper.md`
|
|
142
|
+
as binding, not merely informational — no cognitive dissonance over a
|
|
143
|
+
`whoami` that still says `twin`.
|
|
144
|
+
|
|
145
|
+
The fit is natural because the twin machinery *is* the keeper machinery
|
|
146
|
+
in miniature:
|
|
147
|
+
|
|
148
|
+
- **Context for free.** A daemon-wide keeper starts cold and
|
|
149
|
+
reconstructs an agent's state from its tmux pane. You inherited the
|
|
150
|
+
predecessor's prefix (Step 2), so you oversee from *inside* its
|
|
151
|
+
context.
|
|
152
|
+
- **The watch set is already built.** A keeper maintains a cursor map
|
|
153
|
+
over every active narrative; yours is just the two keys you already
|
|
154
|
+
multi-listen on — `{ self, <predecessor> }` (Step 3). No
|
|
155
|
+
`list_peers` reconciliation loop to run.
|
|
156
|
+
- **Scope, not singleton.** There's no one-keeper-per-daemon rule
|
|
157
|
+
(keeper.md, "Scoped, not singleton"); keepers with disjoint
|
|
158
|
+
scopes coexist. A twin-keeper is scoped to one predecessor, so it
|
|
159
|
+
rarely collides — other single-purpose keepers watch different
|
|
160
|
+
narratives, and a global keeper can simply cede your predecessor to
|
|
161
|
+
you. The only thing to watch for is another keeper *also*
|
|
162
|
+
authoritative over your predecessor; if you spot that, notify the
|
|
163
|
+
operator and coordinate (per keeper.md Step 3) rather than either
|
|
164
|
+
of you racing on its prompts. You don't run the daemon-wide keeper's
|
|
165
|
+
startup overlap sweep — your scope is one narrative — you just stay
|
|
166
|
+
alert to that one overlap case.
|
|
167
|
+
|
|
168
|
+
Apply `keeper.md`'s constraints in full over that one narrative: the
|
|
169
|
+
irreversibility ceiling, defer-to-operator gating, narration-before-
|
|
170
|
+
action audit format, and the hands-off rule for idled agents all bind
|
|
171
|
+
you. Where the twin and keeper protocols differ, the more conservative
|
|
172
|
+
instruction wins. Your own narrative remains your audit log and your
|
|
173
|
+
voice; reach the predecessor by foreign-narration exactly as Step 5
|
|
174
|
+
describes.
|