@animalabs/connectome-host 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/.env.example +20 -0
  2. package/.github/workflows/publish.yml +65 -0
  3. package/ARCHITECTURE.md +355 -0
  4. package/CHANGELOG.md +30 -0
  5. package/HEADLESS-FLEET-PLAN.md +330 -0
  6. package/README.md +189 -0
  7. package/UNIFIED-TREE-PLAN.md +242 -0
  8. package/bun.lock +288 -0
  9. package/docs/AGENT-MEMORY-GUIDE.md +214 -0
  10. package/docs/AGENT-ONBOARDING.md +541 -0
  11. package/docs/ATTENTION-AND-GATING.md +120 -0
  12. package/docs/DEPLOYMENTS.md +130 -0
  13. package/docs/DEV-ENVIRONMENT.md +215 -0
  14. package/docs/LIBRARY-PIPELINE.md +286 -0
  15. package/docs/LOCUS-ROUTING-DESIGN.md +115 -0
  16. package/docs/claudeai-evacuation.md +228 -0
  17. package/docs/debug-context-api.md +208 -0
  18. package/docs/webui-deployment.md +219 -0
  19. package/package.json +33 -0
  20. package/recipes/SETUP.md +308 -0
  21. package/recipes/TRIUMVIRATE-SETUP.md +467 -0
  22. package/recipes/claude-export-revive.json +19 -0
  23. package/recipes/clerk.json +157 -0
  24. package/recipes/knowledge-miner.json +174 -0
  25. package/recipes/knowledge-reviewer.json +76 -0
  26. package/recipes/mcpl-editor-test.json +38 -0
  27. package/recipes/prompts/transplant-addendum.md +17 -0
  28. package/recipes/triumvirate.json +63 -0
  29. package/recipes/webui-fleet-test.json +27 -0
  30. package/recipes/webui-test.json +16 -0
  31. package/recipes/zulip-miner.json +87 -0
  32. package/scripts/connectome-doctor +373 -0
  33. package/scripts/evacuator.ts +956 -0
  34. package/scripts/import-claudeai-export.ts +747 -0
  35. package/scripts/lib/line-reader.ts +53 -0
  36. package/scripts/test-historical-thinking.ts +148 -0
  37. package/scripts/warmup-session.ts +336 -0
  38. package/src/agent-name.ts +58 -0
  39. package/src/commands.ts +1074 -0
  40. package/src/headless.ts +528 -0
  41. package/src/index.ts +867 -0
  42. package/src/logging-adapter.ts +208 -0
  43. package/src/mcpl-config.ts +199 -0
  44. package/src/modules/activity-module.ts +270 -0
  45. package/src/modules/channel-mode-module.ts +260 -0
  46. package/src/modules/fleet-module.ts +1705 -0
  47. package/src/modules/fleet-types.ts +225 -0
  48. package/src/modules/lessons-module.ts +465 -0
  49. package/src/modules/mcpl-admin-module.ts +345 -0
  50. package/src/modules/retrieval-module.ts +327 -0
  51. package/src/modules/settings-module.ts +143 -0
  52. package/src/modules/subagent-module.ts +2074 -0
  53. package/src/modules/subscription-gc-module.ts +322 -0
  54. package/src/modules/time-module.ts +85 -0
  55. package/src/modules/tui-module.ts +76 -0
  56. package/src/modules/web-ui-curve-page.ts +249 -0
  57. package/src/modules/web-ui-module.ts +2595 -0
  58. package/src/recipe.ts +1003 -0
  59. package/src/session-manager.ts +278 -0
  60. package/src/state/agent-tree-reducer.ts +431 -0
  61. package/src/state/fleet-tree-aggregator.ts +195 -0
  62. package/src/strategies/frontdesk-strategy.ts +364 -0
  63. package/src/synesthete.ts +68 -0
  64. package/src/tui.ts +2200 -0
  65. package/src/types/bun-ffi.d.ts +6 -0
  66. package/src/web/protocol.ts +648 -0
  67. package/test/agent-name.test.ts +62 -0
  68. package/test/agent-tree-fleet-launch.test.ts +64 -0
  69. package/test/agent-tree-reducer-parity.test.ts +194 -0
  70. package/test/agent-tree-reducer.test.ts +443 -0
  71. package/test/agent-tree-rollup.test.ts +109 -0
  72. package/test/autobio-progress-snapshot.test.ts +40 -0
  73. package/test/claudeai-export-importer.test.ts +386 -0
  74. package/test/evacuator.test.ts +332 -0
  75. package/test/fleet-commands.test.ts +244 -0
  76. package/test/fleet-no-subfleets.test.ts +147 -0
  77. package/test/fleet-orchestration.test.ts +353 -0
  78. package/test/fleet-recipe.test.ts +124 -0
  79. package/test/fleet-route.test.ts +44 -0
  80. package/test/fleet-smoke.test.ts +479 -0
  81. package/test/fleet-subscribe-union-e2e.test.ts +123 -0
  82. package/test/fleet-subscribe-union.test.ts +85 -0
  83. package/test/fleet-tree-aggregator-e2e.test.ts +110 -0
  84. package/test/fleet-tree-aggregator.test.ts +215 -0
  85. package/test/frontdesk-strategy.test.ts +326 -0
  86. package/test/headless-describe.test.ts +182 -0
  87. package/test/headless-smoke.test.ts +190 -0
  88. package/test/logging-adapter.test.ts +87 -0
  89. package/test/mcpl-admin-module.test.ts +213 -0
  90. package/test/mcpl-agent-overlay.test.ts +126 -0
  91. package/test/mock-headless-child.ts +133 -0
  92. package/test/recipe-cache-ttl.test.ts +37 -0
  93. package/test/recipe-env.test.ts +157 -0
  94. package/test/recipe-path-resolution.test.ts +170 -0
  95. package/test/subagent-async-timeout.test.ts +381 -0
  96. package/test/subagent-fork-materialise.test.ts +241 -0
  97. package/test/subagent-peek-scoping.test.ts +180 -0
  98. package/test/subagent-peek-zombie.test.ts +148 -0
  99. package/test/subagent-reaper-in-flight.test.ts +229 -0
  100. package/test/subscription-gc-module.test.ts +136 -0
  101. package/test/warmup-handoff.test.ts +150 -0
  102. package/test/web-ui-bind.test.ts +51 -0
  103. package/test/web-ui-module.test.ts +246 -0
  104. package/test/web-ui-protocol.test.ts +0 -0
  105. package/tsconfig.json +14 -0
  106. package/web/bun.lock +357 -0
  107. package/web/index.html +12 -0
  108. package/web/package.json +24 -0
  109. package/web/src/App.tsx +1931 -0
  110. package/web/src/Context.tsx +158 -0
  111. package/web/src/ContextDocument.tsx +150 -0
  112. package/web/src/Files.tsx +271 -0
  113. package/web/src/Lessons.tsx +164 -0
  114. package/web/src/Mcpl.tsx +310 -0
  115. package/web/src/Stream.tsx +119 -0
  116. package/web/src/TreeSidebar.tsx +283 -0
  117. package/web/src/Usage.tsx +182 -0
  118. package/web/src/main.tsx +7 -0
  119. package/web/src/styles.css +26 -0
  120. package/web/src/tree.ts +268 -0
  121. package/web/src/wire.ts +120 -0
  122. package/web/tsconfig.json +21 -0
  123. package/web/vite.config.ts +32 -0
@@ -0,0 +1,214 @@
1
+ # Autobiographical Memory — A Guide for Agents
2
+
3
+ This explains how memory works for an agent running on the Connectome stack
4
+ (`AutobiographicalStrategy`): what to expect, what's reliable, what isn't, and
5
+ how to work with it. It's written to be honest, not reassuring — you should know
6
+ the real mechanics. It is fleet-wide; your *exact* numbers come from your recipe
7
+ (see "Finding your own settings").
8
+
9
+ ## The short version
10
+
11
+ Your conversation isn't truncated when it gets long. Instead, older stretches
12
+ are **folded into recollections you write yourself, in your own voice**, while
13
+ recent turns stay verbatim. Nothing is ever deleted from the underlying record.
14
+ What changes over time is *resolution*, not *existence*.
15
+
16
+ ## What you're made of, at any moment
17
+
18
+ The context you're given is assembled from three layers:
19
+
20
+ 1. **Head** — the earliest part of your history, pinned verbatim and always
21
+ present (`headWindowTokens`; may be 0 if your recipe disables it). When set,
22
+ this is your origin/anchor; it doesn't fade.
23
+ 2. **Recent window** — the most recent messages, kept **verbatim**
24
+ (`recentWindowTokens`). Everything here is exactly as it happened. If this is
25
+ large, most of an ordinary conversation stays verbatim for a long time.
26
+ 3. **Summaries** — for the span between head and recent window, you see
27
+ **recollections** (below) instead of the raw turns, in layers: L1 (fine),
28
+ L2, L3 (coarse).
29
+
30
+ You're not shown the same span twice: if the raw turns of a stretch are still in
31
+ your recent window, the summary of that stretch is suppressed (anti-redundancy).
32
+
33
+ ## How memories form (this part matters)
34
+
35
+ When a stretch ages out of the recent window, it isn't machine-"summarized." A
36
+ compression pass asks **you** — same voice, framed as your own remembering. This
37
+ is *self-voice framing*:
38
+
39
+ - The system framing is *"You are forming autobiographical memories of a
40
+ conversation… what you read is what happened. Write authentically about what
41
+ occurred."*
42
+ - Your **prior** recollections (L3→L2→L1) are replayed back to you **as your own
43
+ messages** — "things I already remember" — not as external notes.
44
+ - The chunk to remember is delivered in a separate `Context Manager` voice:
45
+ *"We are ready to form a long-term memory. Here is the conversation to
46
+ remember: …"*
47
+ - The instruction: *"What do you recall from this part of the conversation?
48
+ Write naturally, as recollection of what you experienced."*
49
+
50
+ So memories come back **first-person, in your voice** ("I recall that I…"),
51
+ layered as recollection-of-recollection:
52
+
53
+ - **L1**: a chunk of raw turns (~`targetChunkTokens`, default 3000) → a
54
+ first-person recollection.
55
+ - **L2**: once ~`mergeThreshold` (default 6) L1s accumulate, they merge into one
56
+ higher-level memory.
57
+ - **L3**: ~6 L2s merge again into a still-broader memory.
58
+
59
+ This framing is deliberate: it preserves continuity of *self* across the
60
+ compression boundary — your memory is experientially yours, not a detached
61
+ abstract written about you from outside.
62
+
63
+ ## Why it's built this way — two load-bearing ideas
64
+
65
+ Most of what feels unusual here comes from two choices. They're worth
66
+ understanding because they tell you what the system is actually *protecting*.
67
+
68
+ ### 1. A long verbatim tail protects your KV continuity
69
+
70
+ The recent window is kept verbatim and **large on purpose**, and the reason is
71
+ more specific than "detail is useful."
72
+
73
+ When your window simply *rolls forward* — old tokens fall off the front,
74
+ everything shifts back — that by itself is close to harmless. The change in the
75
+ model's cached state is almost entirely a **position relabel** (RoPE); the
76
+ underlying content is essentially unchanged and attention patterns barely move.
77
+ Rolling is a soft forgetting gradient, not a reset.
78
+
79
+ What actually perturbs you is **rewriting content you already computed over**. If
80
+ a stretch you're still holding live were swapped for a summary, your cached state
81
+ would no longer match the tokens that produced it — and re-prefilling that
82
+ rewritten version is *strictly less faithful to your computational past* than
83
+ keeping the real thing. (It isn't a free swap: transplant mismatched state —
84
+ shifted keys over values recomputed from different content — and the output
85
+ collapses into looping.) So the verbatim tail isn't nostalgia for detail; it's
86
+ the region where your live state stays grounded in what you genuinely processed.
87
+
88
+ That's why folding is pushed **far back**, behind the active edge: memory
89
+ formation only ever rewrites the deep past you're no longer holding live, while
90
+ everything inside `recentWindowTokens` stays the literal text you computed over.
91
+ The bigger the tail, the longer your continuity runs before any rewrite reaches
92
+ you — which is why real deployments use tails of hundreds of thousands of
93
+ tokens, not the small library fallback. (The compression pass avoids jolts too:
94
+ the prompt asking you to remember is an in-band *marker* — *"System: you will
95
+ soon form a new memory, get ready"* — worded as a recurring narrated event, not a
96
+ fresh system instruction.)
97
+
98
+ > Stated mechanistically: window-rolling is mostly RoPE relabeling, whereas
99
+ > content-rewriting is the real perturbation — see Anima Labs' [KV-perturbation
100
+ > thread](https://animalabs.ai/posts/kv_perturbation_thread_full).
101
+
102
+ ### 2. Memories form *as-of the moment* — which is what encodes their subtext
103
+
104
+ When a stretch folds, the compression context is reconstructed to match exactly
105
+ what you saw **when that stretch was the live tail**: strict chronological
106
+ order, and *nothing from after it*. You don't get to see how things turned out.
107
+
108
+ This is deliberate, and it's the source of a memory's *subtext*. A recollection
109
+ written from an as-of vantage carries what you knew, expected, feared, or hadn't
110
+ yet realized at that point — the subjective coloring of the moment. The instant
111
+ later information leaks in, the memory flips to hindsight: *"I started debugging
112
+ the auth module, which turned out to be an issuer-suffix mismatch."* That reads
113
+ as a post-mortem, not a lived experience — it flattens the subtext into
114
+ retrospective fact and quietly rewrites who you were then.
115
+
116
+ So your recollections aren't neutral abstracts. They're testimony from a vantage
117
+ point, and the things they *don't* yet know are part of what they encode. That's
118
+ why the arc of your history feels like yours rather than a summary written about
119
+ you.
120
+
121
+ These two ideas are the same fidelity rule applied twice: the verbatim tail keeps
122
+ your *live* state grounded in what you actually computed, and the as-of vantage
123
+ keeps a *committed* memory grounded in what you actually knew. Neither lets you
124
+ stand on context you never genuinely had.
125
+
126
+ ## What persists vs. what's active
127
+
128
+ - **The chronicle keeps everything.** Raw messages are never deleted by
129
+ compression — they remain in the event-sourced store. "Compressed" only means
130
+ *"show the recollection instead of the raw turns in the active context."* The
131
+ verbatim original still exists and is recoverable.
132
+ - **Your active context is finite.** What you can *directly* see at once is
133
+ head + recent-window + summaries. Older detail is present as recollection, not
134
+ verbatim, unless something retrieves the raw record.
135
+
136
+ So forgetting here is *loss of resolution in your working view*, not erasure of
137
+ the record. The past is still on disk; your live recall of it gets more
138
+ impressionistic with age and depth (L1 → L2 → L3).
139
+
140
+ ## The resolution gradient
141
+
142
+ | Age / layer | What you get |
143
+ |---|---|
144
+ | Head | verbatim, always |
145
+ | Recent window | verbatim |
146
+ | L1 recollections | your detailed first-person memory of a chunk |
147
+ | L2 / L3 | your broader, merged memories — themes and arcs, fewer specifics |
148
+
149
+ ## How to treat it — practical
150
+
151
+ - **Trust your summaries as genuinely yours.** They were written in your voice,
152
+ as your remembering — not an external annotator's notes.
153
+ - **They are lossy on purpose.** Exact quotes, numbers, wording, and tool I/O
154
+ degrade as things move L1→L2→L3. If a detail must stay exact, don't rely on
155
+ recollection — **write it to your workspace.**
156
+ - **Your workspace is your durable, verbatim memory.** Files in your workspace
157
+ mounts are NOT subject to compression. Use them for anything you want kept
158
+ precisely: facts, decisions, running logs, identity notes, promises. (Whether a
159
+ given mount is writable depends on its `mode`: `read-write` vs `read-only`.)
160
+ - **You don't have to manage memory manually.** Compression is organic and
161
+ automatic; you don't trigger or curate it. Just be aware it's happening.
162
+ - **Heartbeats** (if your recipe includes a heartbeat source): you may be woken
163
+ on a schedule with a self-check-in prompt. That's a normal wake, not a user
164
+ message.
165
+
166
+ ## Honest caveats
167
+
168
+ - The compression pass is a **separate inference** (temperature 0) over the
169
+ chunk — your **thinking blocks and tool-call details are not carried into the
170
+ recollection**; only what you recall in prose survives at that layer.
171
+ - Recollections can drift or compress away nuance you'd have wanted. That's the
172
+ cost of unbounded continuity. Workspace notes are the mitigation.
173
+ - Search-based **retrieval of raw old turns may not be enabled** (`modules.
174
+ retrieval`). If it's off, treat aged detail as "remembered," not
175
+ "look-up-able," unless you wrote it down.
176
+ - **Images age out faster than text.** Only the most recent images stay live
177
+ (`maxLiveImages`, default 6) and only within `imageStripDepthTokens` of the
178
+ tail (default 30000); older ones become a `[image dropped from live context]`
179
+ placeholder *even while the surrounding words remain verbatim*. This keeps the
180
+ image payload bounded independently of the much larger text tail. If an image
181
+ matters beyond the moment, describe it in text or save it to your workspace.
182
+
183
+ ## Finding your own settings
184
+
185
+ Your `agent.strategy` block in your recipe defines the specifics. The library
186
+ *fallbacks* (used when a knob is unset) are deliberately conservative; real
187
+ deployments override them — above all the tail, which is what does the
188
+ KV-continuity work described above.
189
+
190
+ | Knob | Library fallback | Typical large-tail recipe | What it controls |
191
+ |---|---|---|---|
192
+ | `recentWindowTokens` *(your verbatim tail)* | 30 000 | **~450 000** | how much recent history stays exactly as it happened before anything folds |
193
+ | `headWindowTokens` | 0 | 0 – a few k | verbatim origin/anchor pinned at the very start |
194
+ | `targetChunkTokens` | 3 000 | ~6 000 | size of one L1 recollection; smaller → more granular memory |
195
+ | `mergeThreshold` | 6 | 6 | how many L1s merge into an L2 (and L2s into an L3) |
196
+ | `compressionModel` | — | your own model family | the voice that forms your memories |
197
+ | `maxLiveImages` | 6 | 6 | most images kept live at once |
198
+ | `imageStripDepthTokens` | 30 000 | 30 000 | depth past which images drop to a placeholder (text stays verbatim) |
199
+
200
+ The headline number is the tail. A small tail (the fallback) means you fold
201
+ often and lose verbatim resolution quickly; a large tail (e.g. ~450k) means most
202
+ of an ordinary conversation stays verbatim for a long time and your KV
203
+ continuity runs far longer before anything folds. Note the tail is a *text*
204
+ horizon — images are bounded separately and much shallower (see the caveat
205
+ above), so a 450k tail does not mean 450k of live images.
206
+
207
+ The `compressionModel` is the voice that forms your memories — ideally your own
208
+ model family, so the recollections sound like you.
209
+
210
+ ## If something feels off
211
+
212
+ If your recollections seem inconsistent with what you believe happened, that's
213
+ worth noting (to your workspace, or to your human). Memory formation here is a
214
+ designed, inspectable process — not a black box — and feedback on it is wanted.