@animalabs/agent-framework 0.23.2 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (338) hide show
  1. package/README.md +212 -42
  2. package/dist/src/agent.d.ts +60 -9
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +92 -12
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/api/server.d.ts.map +1 -1
  7. package/dist/src/api/server.js +14 -12
  8. package/dist/src/api/server.js.map +1 -1
  9. package/dist/src/code-execution/engine.d.ts +177 -0
  10. package/dist/src/code-execution/engine.d.ts.map +1 -0
  11. package/dist/src/code-execution/engine.js +494 -0
  12. package/dist/src/code-execution/engine.js.map +1 -0
  13. package/dist/src/code-execution/index.d.ts +5 -10
  14. package/dist/src/code-execution/index.d.ts.map +1 -1
  15. package/dist/src/code-execution/index.js +5 -9
  16. package/dist/src/code-execution/index.js.map +1 -1
  17. package/dist/src/code-execution/isolate/calls.d.ts +114 -0
  18. package/dist/src/code-execution/isolate/calls.d.ts.map +1 -0
  19. package/dist/src/code-execution/isolate/calls.js +145 -0
  20. package/dist/src/code-execution/isolate/calls.js.map +1 -0
  21. package/dist/src/code-execution/isolate/child-entry.d.ts +2 -0
  22. package/dist/src/code-execution/isolate/child-entry.d.ts.map +1 -0
  23. package/dist/src/code-execution/isolate/child-entry.js +5 -0
  24. package/dist/src/code-execution/isolate/child-entry.js.map +1 -0
  25. package/dist/src/code-execution/isolate/child-main.d.ts +26 -0
  26. package/dist/src/code-execution/isolate/child-main.d.ts.map +1 -0
  27. package/dist/src/code-execution/isolate/child-main.js +132 -0
  28. package/dist/src/code-execution/isolate/child-main.js.map +1 -0
  29. package/dist/src/code-execution/isolate/child.d.ts +44 -0
  30. package/dist/src/code-execution/isolate/child.d.ts.map +1 -0
  31. package/dist/src/code-execution/isolate/child.js +315 -0
  32. package/dist/src/code-execution/isolate/child.js.map +1 -0
  33. package/dist/src/code-execution/isolate/frames.d.ts +80 -0
  34. package/dist/src/code-execution/isolate/frames.d.ts.map +1 -0
  35. package/dist/src/code-execution/isolate/frames.js +210 -0
  36. package/dist/src/code-execution/isolate/frames.js.map +1 -0
  37. package/dist/src/code-execution/isolate/output.d.ts +68 -0
  38. package/dist/src/code-execution/isolate/output.d.ts.map +1 -0
  39. package/dist/src/code-execution/isolate/output.js +143 -0
  40. package/dist/src/code-execution/isolate/output.js.map +1 -0
  41. package/dist/src/code-execution/isolate/prelude.d.ts +109 -0
  42. package/dist/src/code-execution/isolate/prelude.d.ts.map +1 -0
  43. package/dist/src/code-execution/isolate/prelude.js +401 -0
  44. package/dist/src/code-execution/isolate/prelude.js.map +1 -0
  45. package/dist/src/code-execution/isolate/protocol.d.ts +151 -0
  46. package/dist/src/code-execution/isolate/protocol.d.ts.map +1 -0
  47. package/dist/src/code-execution/isolate/protocol.js +150 -0
  48. package/dist/src/code-execution/isolate/protocol.js.map +1 -0
  49. package/dist/src/code-execution/isolate/render.d.ts +57 -0
  50. package/dist/src/code-execution/isolate/render.d.ts.map +1 -0
  51. package/dist/src/code-execution/isolate/render.js +214 -0
  52. package/dist/src/code-execution/isolate/render.js.map +1 -0
  53. package/dist/src/code-execution/isolate/runner.d.ts +250 -0
  54. package/dist/src/code-execution/isolate/runner.d.ts.map +1 -0
  55. package/dist/src/code-execution/isolate/runner.js +854 -0
  56. package/dist/src/code-execution/isolate/runner.js.map +1 -0
  57. package/dist/src/code-execution/isolate/scripts.d.ts +175 -0
  58. package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -0
  59. package/dist/src/code-execution/isolate/scripts.js +357 -0
  60. package/dist/src/code-execution/isolate/scripts.js.map +1 -0
  61. package/dist/src/code-execution/quickjs.wasm +0 -0
  62. package/dist/src/code-execution/tool-definition.d.ts +93 -43
  63. package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
  64. package/dist/src/code-execution/tool-definition.js +176 -142
  65. package/dist/src/code-execution/tool-definition.js.map +1 -1
  66. package/dist/src/deadline-timer.d.ts +3 -0
  67. package/dist/src/deadline-timer.d.ts.map +1 -1
  68. package/dist/src/deadline-timer.js +1 -1
  69. package/dist/src/deadline-timer.js.map +1 -1
  70. package/dist/src/framework.d.ts +1027 -440
  71. package/dist/src/framework.d.ts.map +1 -1
  72. package/dist/src/framework.js +4093 -2238
  73. package/dist/src/framework.js.map +1 -1
  74. package/dist/src/gate/event-gate.d.ts +28 -1
  75. package/dist/src/gate/event-gate.d.ts.map +1 -1
  76. package/dist/src/gate/event-gate.js +88 -10
  77. package/dist/src/gate/event-gate.js.map +1 -1
  78. package/dist/src/held-writes.d.ts +16 -3
  79. package/dist/src/held-writes.d.ts.map +1 -1
  80. package/dist/src/held-writes.js +16 -3
  81. package/dist/src/held-writes.js.map +1 -1
  82. package/dist/src/index.d.ts +6 -6
  83. package/dist/src/index.d.ts.map +1 -1
  84. package/dist/src/index.js +9 -8
  85. package/dist/src/index.js.map +1 -1
  86. package/dist/src/mcpl/channel-registry.d.ts +471 -75
  87. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  88. package/dist/src/mcpl/channel-registry.js +1673 -337
  89. package/dist/src/mcpl/channel-registry.js.map +1 -1
  90. package/dist/src/mcpl/conversation-router.d.ts +12 -7
  91. package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
  92. package/dist/src/mcpl/conversation-router.js +12 -7
  93. package/dist/src/mcpl/conversation-router.js.map +1 -1
  94. package/dist/src/mcpl/convert-block.d.ts.map +1 -1
  95. package/dist/src/mcpl/convert-block.js +9 -5
  96. package/dist/src/mcpl/convert-block.js.map +1 -1
  97. package/dist/src/mcpl/inbound-source.d.ts +50 -0
  98. package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
  99. package/dist/src/mcpl/inbound-source.js +130 -0
  100. package/dist/src/mcpl/inbound-source.js.map +1 -1
  101. package/dist/src/mcpl/index.d.ts +2 -1
  102. package/dist/src/mcpl/index.d.ts.map +1 -1
  103. package/dist/src/mcpl/index.js +3 -2
  104. package/dist/src/mcpl/index.js.map +1 -1
  105. package/dist/src/mcpl/log-value.d.ts +6 -0
  106. package/dist/src/mcpl/log-value.d.ts.map +1 -1
  107. package/dist/src/mcpl/log-value.js +8 -0
  108. package/dist/src/mcpl/log-value.js.map +1 -1
  109. package/dist/src/mcpl/modern-connection.d.ts +15 -6
  110. package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
  111. package/dist/src/mcpl/modern-connection.js +168 -53
  112. package/dist/src/mcpl/modern-connection.js.map +1 -1
  113. package/dist/src/mcpl/prose-grammar.d.ts +4 -5
  114. package/dist/src/mcpl/prose-grammar.d.ts.map +1 -1
  115. package/dist/src/mcpl/prose-grammar.js +4 -5
  116. package/dist/src/mcpl/prose-grammar.js.map +1 -1
  117. package/dist/src/mcpl/protocol-family.d.ts +97 -10
  118. package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
  119. package/dist/src/mcpl/protocol-family.js +173 -16
  120. package/dist/src/mcpl/protocol-family.js.map +1 -1
  121. package/dist/src/mcpl/push-coalescer.d.ts +132 -14
  122. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  123. package/dist/src/mcpl/push-coalescer.js +227 -50
  124. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  125. package/dist/src/mcpl/push-handler.d.ts +6 -1
  126. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  127. package/dist/src/mcpl/push-handler.js +4 -1
  128. package/dist/src/mcpl/push-handler.js.map +1 -1
  129. package/dist/src/mcpl/reference-fetcher.d.ts +2 -2
  130. package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
  131. package/dist/src/mcpl/reference-fetcher.js +4 -4
  132. package/dist/src/mcpl/reference-fetcher.js.map +1 -1
  133. package/dist/src/mcpl/server-connection.d.ts +50 -21
  134. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  135. package/dist/src/mcpl/server-connection.js +158 -74
  136. package/dist/src/mcpl/server-connection.js.map +1 -1
  137. package/dist/src/mcpl/tags.d.ts +24 -0
  138. package/dist/src/mcpl/tags.d.ts.map +1 -1
  139. package/dist/src/mcpl/tags.js +33 -0
  140. package/dist/src/mcpl/tags.js.map +1 -1
  141. package/dist/src/mcpl/tool-result-normalize.d.ts +2 -1
  142. package/dist/src/mcpl/tool-result-normalize.d.ts.map +1 -1
  143. package/dist/src/mcpl/tool-result-normalize.js.map +1 -1
  144. package/dist/src/mcpl/transport.d.ts +55 -7
  145. package/dist/src/mcpl/transport.d.ts.map +1 -1
  146. package/dist/src/mcpl/transport.js +163 -34
  147. package/dist/src/mcpl/transport.js.map +1 -1
  148. package/dist/src/mcpl/types.d.ts +22 -6
  149. package/dist/src/mcpl/types.d.ts.map +1 -1
  150. package/dist/src/mcpl/types.js.map +1 -1
  151. package/dist/src/module-registry.d.ts +4 -2
  152. package/dist/src/module-registry.d.ts.map +1 -1
  153. package/dist/src/module-registry.js +100 -13
  154. package/dist/src/module-registry.js.map +1 -1
  155. package/dist/src/modules/discord/index.d.ts.map +1 -1
  156. package/dist/src/modules/discord/index.js +8 -13
  157. package/dist/src/modules/discord/index.js.map +1 -1
  158. package/dist/src/modules/history/index.d.ts.map +1 -1
  159. package/dist/src/modules/history/index.js +27 -4
  160. package/dist/src/modules/history/index.js.map +1 -1
  161. package/dist/src/modules/history/semantic.d.ts +15 -3
  162. package/dist/src/modules/history/semantic.d.ts.map +1 -1
  163. package/dist/src/modules/history/semantic.js +27 -5
  164. package/dist/src/modules/history/semantic.js.map +1 -1
  165. package/dist/src/modules/index.d.ts +1 -1
  166. package/dist/src/modules/index.d.ts.map +1 -1
  167. package/dist/src/modules/index.js.map +1 -1
  168. package/dist/src/modules/unknown-tool.d.ts +4 -1
  169. package/dist/src/modules/unknown-tool.d.ts.map +1 -1
  170. package/dist/src/modules/unknown-tool.js +4 -1
  171. package/dist/src/modules/unknown-tool.js.map +1 -1
  172. package/dist/src/modules/workspace/branch-intent.d.ts +3 -1
  173. package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
  174. package/dist/src/modules/workspace/branch-intent.js +3 -1
  175. package/dist/src/modules/workspace/branch-intent.js.map +1 -1
  176. package/dist/src/modules/workspace/edit-plan.d.ts +265 -0
  177. package/dist/src/modules/workspace/edit-plan.d.ts.map +1 -0
  178. package/dist/src/modules/workspace/edit-plan.js +794 -0
  179. package/dist/src/modules/workspace/edit-plan.js.map +1 -0
  180. package/dist/src/modules/workspace/edit-text.d.ts +117 -0
  181. package/dist/src/modules/workspace/edit-text.d.ts.map +1 -0
  182. package/dist/src/modules/workspace/edit-text.js +584 -0
  183. package/dist/src/modules/workspace/edit-text.js.map +1 -0
  184. package/dist/src/modules/workspace/effects.d.ts +5 -4
  185. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  186. package/dist/src/modules/workspace/effects.js +78 -25
  187. package/dist/src/modules/workspace/effects.js.map +1 -1
  188. package/dist/src/modules/workspace/index.d.ts +484 -61
  189. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  190. package/dist/src/modules/workspace/index.js +2173 -645
  191. package/dist/src/modules/workspace/index.js.map +1 -1
  192. package/dist/src/modules/workspace/observe.d.ts +213 -38
  193. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  194. package/dist/src/modules/workspace/observe.js +416 -36
  195. package/dist/src/modules/workspace/observe.js.map +1 -1
  196. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  197. package/dist/src/modules/workspace/reconcile.js +15 -8
  198. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  199. package/dist/src/modules/workspace/text.d.ts +32 -0
  200. package/dist/src/modules/workspace/text.d.ts.map +1 -0
  201. package/dist/src/modules/workspace/text.js +67 -0
  202. package/dist/src/modules/workspace/text.js.map +1 -0
  203. package/dist/src/modules/workspace/types.d.ts +210 -6
  204. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  205. package/dist/src/modules/workspace/types.js.map +1 -1
  206. package/dist/src/modules/workspace/watcher.d.ts +3 -2
  207. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  208. package/dist/src/modules/workspace/watcher.js.map +1 -1
  209. package/dist/src/operator-log.d.ts +52 -24
  210. package/dist/src/operator-log.d.ts.map +1 -1
  211. package/dist/src/operator-log.js.map +1 -1
  212. package/dist/src/recovery/discord-awareness-outbox.d.ts +496 -72
  213. package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
  214. package/dist/src/recovery/discord-awareness-outbox.js +1196 -289
  215. package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
  216. package/dist/src/recovery/offline-branch.d.ts +26 -1
  217. package/dist/src/recovery/offline-branch.d.ts.map +1 -1
  218. package/dist/src/recovery/offline-branch.js +164 -39
  219. package/dist/src/recovery/offline-branch.js.map +1 -1
  220. package/dist/src/recovery/recover-cli.js +23 -4
  221. package/dist/src/recovery/recover-cli.js.map +1 -1
  222. package/dist/src/send-tools.d.ts +11 -0
  223. package/dist/src/send-tools.d.ts.map +1 -0
  224. package/dist/src/send-tools.js +11 -0
  225. package/dist/src/send-tools.js.map +1 -0
  226. package/dist/src/tool-result-guard.d.ts +4 -3
  227. package/dist/src/tool-result-guard.d.ts.map +1 -1
  228. package/dist/src/tool-result-guard.js +5 -4
  229. package/dist/src/tool-result-guard.js.map +1 -1
  230. package/dist/src/tool-result-history.d.ts +1 -1
  231. package/dist/src/tool-result-history.js +1 -1
  232. package/dist/src/tune-out/coordinator.d.ts +21 -0
  233. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  234. package/dist/src/tune-out/coordinator.js +139 -37
  235. package/dist/src/tune-out/coordinator.js.map +1 -1
  236. package/dist/src/types/agent.d.ts +4 -0
  237. package/dist/src/types/agent.d.ts.map +1 -1
  238. package/dist/src/types/events.d.ts +62 -9
  239. package/dist/src/types/events.d.ts.map +1 -1
  240. package/dist/src/types/framework.d.ts +62 -58
  241. package/dist/src/types/framework.d.ts.map +1 -1
  242. package/dist/src/types/module.d.ts +40 -8
  243. package/dist/src/types/module.d.ts.map +1 -1
  244. package/dist/src/types/trace.d.ts +111 -10
  245. package/dist/src/types/trace.d.ts.map +1 -1
  246. package/dist/src/usage/types.d.ts +16 -0
  247. package/dist/src/usage/types.d.ts.map +1 -1
  248. package/dist/src/usage/usage-tracker.d.ts +14 -1
  249. package/dist/src/usage/usage-tracker.d.ts.map +1 -1
  250. package/dist/src/usage/usage-tracker.js +81 -41
  251. package/dist/src/usage/usage-tracker.js.map +1 -1
  252. package/package.json +6 -5
  253. package/src/agent.ts +93 -12
  254. package/src/api/server.ts +14 -12
  255. package/src/code-execution/engine.ts +595 -0
  256. package/src/code-execution/index.ts +5 -17
  257. package/src/code-execution/isolate/calls.ts +199 -0
  258. package/src/code-execution/isolate/child-entry.ts +5 -0
  259. package/src/code-execution/isolate/child-main.ts +132 -0
  260. package/src/code-execution/isolate/child.ts +327 -0
  261. package/src/code-execution/isolate/frames.ts +209 -0
  262. package/src/code-execution/isolate/output.ts +161 -0
  263. package/src/code-execution/isolate/prelude.ts +409 -0
  264. package/src/code-execution/isolate/protocol.ts +240 -0
  265. package/src/code-execution/isolate/render.ts +230 -0
  266. package/src/code-execution/isolate/runner.ts +911 -0
  267. package/src/code-execution/isolate/scripts.ts +479 -0
  268. package/src/code-execution/quickjs.wasm +0 -0
  269. package/src/code-execution/quickjs.wasm.LICENSES +149 -0
  270. package/src/code-execution/tool-definition.ts +236 -167
  271. package/src/deadline-timer.ts +1 -1
  272. package/src/framework.ts +4468 -2418
  273. package/src/gate/event-gate.ts +78 -11
  274. package/src/held-writes.ts +17 -3
  275. package/src/index.ts +30 -22
  276. package/src/mcpl/channel-registry.ts +1825 -368
  277. package/src/mcpl/conversation-router.ts +12 -7
  278. package/src/mcpl/convert-block.ts +9 -5
  279. package/src/mcpl/inbound-source.ts +131 -0
  280. package/src/mcpl/index.ts +4 -2
  281. package/src/mcpl/log-value.ts +9 -0
  282. package/src/mcpl/modern-connection.ts +162 -53
  283. package/src/mcpl/prose-grammar.ts +4 -5
  284. package/src/mcpl/protocol-family.ts +199 -21
  285. package/src/mcpl/push-coalescer.ts +306 -62
  286. package/src/mcpl/push-handler.ts +10 -2
  287. package/src/mcpl/reference-fetcher.ts +4 -4
  288. package/src/mcpl/server-connection.ts +180 -79
  289. package/src/mcpl/tags.ts +36 -0
  290. package/src/mcpl/tool-result-normalize.ts +2 -1
  291. package/src/mcpl/transport.ts +162 -33
  292. package/src/mcpl/types.ts +23 -6
  293. package/src/module-registry.ts +92 -13
  294. package/src/modules/discord/index.ts +8 -13
  295. package/src/modules/history/index.ts +25 -3
  296. package/src/modules/history/semantic.ts +29 -6
  297. package/src/modules/index.ts +1 -0
  298. package/src/modules/unknown-tool.ts +4 -1
  299. package/src/modules/workspace/branch-intent.ts +3 -1
  300. package/src/modules/workspace/edit-plan.ts +954 -0
  301. package/src/modules/workspace/edit-text.ts +618 -0
  302. package/src/modules/workspace/effects.ts +70 -19
  303. package/src/modules/workspace/index.ts +2247 -642
  304. package/src/modules/workspace/observe.ts +465 -56
  305. package/src/modules/workspace/reconcile.ts +14 -7
  306. package/src/modules/workspace/text.ts +68 -0
  307. package/src/modules/workspace/types.ts +211 -6
  308. package/src/modules/workspace/watcher.ts +3 -2
  309. package/src/operator-log.ts +47 -19
  310. package/src/recovery/discord-awareness-outbox.ts +1500 -356
  311. package/src/recovery/offline-branch.ts +189 -55
  312. package/src/recovery/recover-cli.ts +25 -4
  313. package/src/send-tools.ts +11 -0
  314. package/src/tool-result-guard.ts +6 -5
  315. package/src/tool-result-history.ts +1 -1
  316. package/src/tune-out/coordinator.ts +163 -42
  317. package/src/types/agent.ts +4 -0
  318. package/src/types/events.ts +62 -9
  319. package/src/types/framework.ts +62 -58
  320. package/src/types/module.ts +40 -8
  321. package/src/types/trace.ts +121 -15
  322. package/src/usage/types.ts +16 -0
  323. package/src/usage/usage-tracker.ts +86 -43
  324. package/dist/src/code-execution/py-runner.d.ts +0 -191
  325. package/dist/src/code-execution/py-runner.d.ts.map +0 -1
  326. package/dist/src/code-execution/py-runner.js +0 -655
  327. package/dist/src/code-execution/py-runner.js.map +0 -1
  328. package/dist/src/code-execution/runtime-py.d.ts +0 -50
  329. package/dist/src/code-execution/runtime-py.d.ts.map +0 -1
  330. package/dist/src/code-execution/runtime-py.js +0 -677
  331. package/dist/src/code-execution/runtime-py.js.map +0 -1
  332. package/dist/src/mcpl/prose-stream-router.d.ts +0 -88
  333. package/dist/src/mcpl/prose-stream-router.d.ts.map +0 -1
  334. package/dist/src/mcpl/prose-stream-router.js +0 -291
  335. package/dist/src/mcpl/prose-stream-router.js.map +0 -1
  336. package/src/code-execution/py-runner.ts +0 -791
  337. package/src/code-execution/runtime-py.ts +0 -677
  338. package/src/mcpl/prose-stream-router.ts +0 -268
@@ -9,7 +9,8 @@ import { type ToolClass, type ToolClassSource } from './mcpl/tool-classes.js';
9
9
  import { ChannelRegistry } from './mcpl/channel-registry.js';
10
10
  import { ConversationRouter } from './mcpl/conversation-router.js';
11
11
  import type { SessionUsageSnapshot } from './usage/types.js';
12
- import { type SurgeryMarkerReceipt, type OperatorLogEntry, type OperatorLogInput, type OperatorRequester } from './operator-log.js';
12
+ import { type DiscordAwarenessView, type DiscordAwarenessCancelReceipt, type DiscordAwarenessMarks, type DiscordAwarenessRetractReceipt } from './recovery/discord-awareness-outbox.js';
13
+ import { type SurgeryMarkerReceipt, type SurgeryMarksPreview, type OperatorLogEntry, type OperatorLogInput, type OperatorRequester } from './operator-log.js';
13
14
  /**
14
15
  * Feasibility verdict for a runtime-settings patch, derived through the SAME
15
16
  * settings→config mapping the live apply path uses (`Agent.planRuntimeSettings`
@@ -76,9 +77,10 @@ export interface HostModeStatus {
76
77
  * scheduler's next pass consumes them). Continuations of a held turn
77
78
  * (budget restart, tool results) are never counted. */
78
79
  gatedRequests: number;
79
- /** Background code-execution scripts still running. Quiesce does NOT stop
80
- * them — they hold no turn token, so drain doesn't wait for them. Reported
81
- * so the operator sees what is still acting during the window. */
80
+ /** code_execution scripts still running that no call is waiting on: left
81
+ * running after a yield, outside any turn. Quiesce does NOT stop them —
82
+ * they hold no turn token, so drain doesn't wait for them. Reported so the
83
+ * operator sees what is still acting during the window. */
82
84
  backgroundScripts: number;
83
85
  /** Context writes (module events, api message.send) withheld because the
84
86
  * host is quiesced. Persisted while quiesced and flushed by resume(). */
@@ -177,8 +179,8 @@ interface InferenceToolSnapshot {
177
179
  * adapter files every status it doesn't list (404, 405, 409, 410, 413,
178
180
  * 415, 422 …) as invalid_request, so it alone produces an invalid_request
179
181
  * at 413 or 422, and no 0.5.86 adapter produces a context_length at 413.
180
- * - From membrane 0.5.87 (membrane #56 and #107), this package's floor, every
181
- * adapter sends an HTTP failure through one status table
182
+ * - From membrane 0.5.87 (membrane #56 and #107), below this package's
183
+ * floor, every adapter sends an HTTP failure through one status table
182
184
  * (errorFromProviderStatus). On a 400 or 422, auth codes and reasons and
183
185
  * the two account refusals it recognizes by their text (a balance too low,
184
186
  * usage limits reached) are auth, and a context overflow, by its code or
@@ -301,10 +303,13 @@ export declare class AgentFramework {
301
303
  * framework, and tests set it by cast. */
302
304
  private inboundAcceptanceObserver?;
303
305
  private streamBoundaryEnds;
304
- /** A tool boundary injected fresh CONVERSATIONAL input (a real message —
305
- * not a reaction or a system marker) into the live stream. Tells
306
- * driveStream to clear sticky explicit-send suppression before handling
307
- * the next model round. Never affects routing: the turn locus is frozen. */
306
+ /** A tool boundary injected fresh CONVERSATIONAL input (a real message,
307
+ * or an edit the coalescer marks as the agent's first view; not a system
308
+ * marker or a reaction, reaction removal, edit or deletion marker) into
309
+ * the live stream. Tells driveStream to clear sticky explicit-send
310
+ * suppression before handling the next model round. The signal itself
311
+ * never moves routing: the boundary re-pins the turn's locus by its own
312
+ * rule (repinChannel). */
308
313
  private midTurnInputSignals;
309
314
  /** Last outbound locus announced to each agent as a durable `[routing]`
310
315
  * window message. Announce-on-change only: steady state emits nothing
@@ -319,13 +324,13 @@ export declare class AgentFramework {
319
324
  /**
320
325
  * Each agent's routing state for its current logical turn (TurnRouting):
321
326
  * its trigger channel, locus and engaged channels, the sticky destination,
322
- * the turn's destination, hybrid's hold, a ` !` continuation and receipt
323
- * tallies. The start that opens a turn makes a
324
- * new object instead of clearing the old one, and every later stream of
325
- * the turn shares it (openLogical). A queued delivery holds the object of
326
- * the turn that queued it, so prose a turn leaves queued when it ends (a
327
- * skip_reply ends it before its posts have run) still follows that turn's
328
- * destination, and its late writes can't reach the next turn.
327
+ * hybrid's hold, a ` !` continuation and receipt tallies. The start that
328
+ * opens a turn makes a new object instead of clearing the old one, and
329
+ * every later stream of the turn shares it (openLogical). A queued delivery
330
+ * holds the object of the turn that queued it, so prose a turn leaves
331
+ * queued when it ends (a skip_reply ends it before its posts have run)
332
+ * still follows that turn's routing, and its late writes can't reach the
333
+ * next turn.
329
334
  */
330
335
  private turnRouting;
331
336
  /**
@@ -334,6 +339,15 @@ export declare class AgentFramework {
334
339
  * posts go out in the order they were written, across streams and turns.
335
340
  */
336
341
  private proseSpeechChains;
342
+ /**
343
+ * Each stream whose `channels/outgoing/complete` hasn't gone yet, from
344
+ * its start: an ended one's waits for the deliveries it queued
345
+ * (driveStream's finally), and one the framework no longer tracks, such
346
+ * as a disposed ephemeral's, may still be running. stop() sends them at
347
+ * once, before it clears the channel registry and closes the MCPL
348
+ * connections.
349
+ */
350
+ private pendingOutgoingCompletes;
337
351
  /**
338
352
  * Each agent's open logical turn: its routing state and receipt tallies
339
353
  * (TurnRouting). It stays open from the start that opens it until the
@@ -379,6 +393,11 @@ export declare class AgentFramework {
379
393
  private usedEphemeralAgentNames;
380
394
  /** One-shot generation tickets minted by createEphemeralAgent. */
381
395
  private ephemeralCandidates;
396
+ /** Every agent createEphemeralAgent made, for as long as the object lives:
397
+ * its usage counts in the usage record's one shared ephemeral entry. Kept
398
+ * by the object, not the run's record (ephemeralRuns), which its cleanup
399
+ * drops before a cancelled stream may count its last usage. */
400
+ private ephemeralAgents;
382
401
  /** Warn only once per Agent instance after utilities are registered. */
383
402
  private emptyUtilityPermissionWarnings;
384
403
  /** Physical ephemeral frames deliberately disposed by their run watchdog/caller.
@@ -487,6 +506,16 @@ export declare class AgentFramework {
487
506
  private deferredScanFrom;
488
507
  private deferredMessages;
489
508
  private activeTurnTokens;
509
+ /** Each turn whose settle has ended it (settleAgent, endDroppedTurn), for
510
+ * its agent's scripts: its start's teardown can still hold the agent's
511
+ * token, and a turn that has ended isn't live (liveTurns). A later start
512
+ * that runs on the same routing, as a resume can, takes it out again
513
+ * (beginAgentTurn). */
514
+ private settledTurns;
515
+ /** Agents whose fresh turn's coalescing assembly is running
516
+ * (beginAgentTurn): the window in which addMessage honours a write's
517
+ * bypassDeferralFor naming that agent. */
518
+ private readonly assembling;
490
519
  /**
491
520
  * The InferenceRequest that started each agent's turn in progress — set and
492
521
  * cleared exactly where the turn token is. Read-only outside: the host
@@ -569,7 +598,10 @@ export declare class AgentFramework {
569
598
  */
570
599
  private readonly sharedSlotAgents;
571
600
  /** The windows of forks and runs deregistered while the host was quiesced,
572
- * by agent name; resume() releases them (releaseWindowNowOrAfterResume). */
601
+ * by agent name (releaseWindowNowOrAfterResume); resume() releases them
602
+ * (runReleasesAfterResume), or stop() passes on what they left, unread or
603
+ * queued, and clears them. While a name is here, no other flush drains
604
+ * its queue (drainDeferredFor). */
573
605
  private readonly releasesAfterResume;
574
606
  /** The coalescing commit in flight, if any (see commitCoalescingDurable). */
575
607
  private coalescingCommit;
@@ -594,25 +626,20 @@ export declare class AgentFramework {
594
626
  /** Forks whose TTL closure turn has been queued — disposed (removed from
595
627
  * agents/agentConfigs/conversationAgentHomes) when their stream ends. */
596
628
  private closingConversationAgents;
597
- private codeExecutionConfig;
598
- private codeExecutionRunners;
629
+ private codeExecution;
599
630
  private scriptToolWaiters;
600
- /** Per agent, the foreground script now running. An endTurn-carrying inner
601
- * result marks the script that made the call, and is applied to that
602
- * script's code_execution result instead of cancelling the stream
603
- * mid-script (which would wedge the turn). A stopped script's late result
604
- * marks only that script, never the agent's next one. Its `turnId` is the
605
- * turn of the code_execution call running it, which its calls carry. */
606
- private scriptDeferredEndTurn;
607
- /** RFC-007: per agent, the origin of the foreground script its runner is
608
- * executing, handed to that script's inner calls (scripts run one at a
609
- * time per runner). Background runners capture theirs in the closure. */
610
- private foregroundScriptOrigins;
611
- /** Background (daemon) scripts: model-authored watchers that outlive their
612
- * spawning turn. Each gets a DEDICATED PyRunner; wake_agent() injects a
613
- * provenance envelope + payload and requests inference. Keyed by script id. */
614
- private backgroundScripts;
615
- private backgroundScriptCounter;
631
+ /** Per agent, a round that called code_execution and waits for those calls'
632
+ * results before its prose is routed (ScriptRound). */
633
+ private scriptRounds;
634
+ /** Each code_execution result, by the round that dispatched its call: it
635
+ * settles only that round, even if a newer round reuses its call id. */
636
+ private scriptRoundOfResult;
637
+ /** Each code_execution call of a round that waits, by its watch, whether
638
+ * the round waits on that call or not, a stop's included, though no call
639
+ * a script makes once its stop is asked reaches a tool, since the runner
640
+ * refuses it: its script's calls that reach the host while that call
641
+ * watches it, which the round counts (ScriptRound.scripts). */
642
+ private scriptRoundCalls;
616
643
  /** Resident-set per-agent tool-result inline cap (chars), via
617
644
  * agent_settings `tool_result_inline_max_chars`. DURABLE: persisted in
618
645
  * framework state like the core runtime settings and restored at create
@@ -662,7 +689,7 @@ export declare class AgentFramework {
662
689
  /** Modern-MCP (2026-07-28) servers, by id; read through modernServers().
663
690
  * They are kept apart from the MCPL registry on purpose: they have no
664
691
  * grant, planes or server→host traffic, so the MCPL machinery (quiesce's
665
- * plane pauses, awareness gates, policy) never sees them. They take part
692
+ * plane pauses, policy) never sees them. They take part
666
693
  * only through the tool paths, and their list changes reach agents
667
694
  * through ordinary admission. */
668
695
  private modernMcpConnections;
@@ -687,8 +714,9 @@ export declare class AgentFramework {
687
714
  * subsystem can be lazily initialized by connectMcplServer when the
688
715
  * framework started with zero configured servers. */
689
716
  private mcplInferenceRoutingConfig;
690
- /** Durable, non-Chronicle projection queue for messages removed by a branch. */
691
- private discordAwarenessOutbox;
717
+ /** The awareness ledger; null for a framework with neither storePath nor
718
+ * discordAwarenessOutboxPath, which refuses a marks choice. */
719
+ private readonly discordAwarenessOutbox;
692
720
  private discordAwarenessEmoji;
693
721
  private discordAwarenessDeadlineMs;
694
722
  /** Durable JSONL record of operator-initiated mutations (see operator-log.ts). */
@@ -703,9 +731,10 @@ export declare class AgentFramework {
703
731
  private surgeryHold;
704
732
  /** Serialize per-server drains so reconnect and an online undo cannot race. */
705
733
  private discordAwarenessDrains;
706
- /** Framework-global inference gate; older generations cannot release it. */
707
- private discordAwarenessBarrier;
708
- private discordAwarenessBarrierGeneration;
734
+ /** The servers whose running pass a later trigger joined
735
+ * (drainDiscordAwarenessOutbox): before it leaves, that pass tries once
736
+ * more what it had already tried. */
737
+ private discordAwarenessDrainsJoined;
709
738
  private eventGate;
710
739
  private usageTracker;
711
740
  /** Explicit-send or private suppression carried into a tool-result-guard retry. */
@@ -719,9 +748,9 @@ export declare class AgentFramework {
719
748
  * try again in the same process: the framework it had begun is stopped, as
720
749
  * stop() stops one, but giving up after 30 s on each of stop()'s cleanup
721
750
  * waits, for an operator's operations already running, then for its
722
- * modules and MCPL servers, and then for awareness drains a failed startup
723
- * barrier left running, and a store it opened is closed. A store the
724
- * caller passed in is left open.
751
+ * modules and MCPL servers, and then for awareness drains still running,
752
+ * such as its startup's delivery, and a store it opened is closed. A store
753
+ * the caller passed in is left open.
725
754
  */
726
755
  static create(config: FrameworkConfig): Promise<AgentFramework>;
727
756
  /**
@@ -814,6 +843,14 @@ export declare class AgentFramework {
814
843
  * iteration.
815
844
  * - a later stop() waits again, within its own budget, for any stream or
816
845
  * loop this one left running, so the store never closes under it.
846
+ *
847
+ * Each conversation fork still live ends, as a closing fork's end does,
848
+ * whatever its stream is doing, as each run does: its channel unbinds, and
849
+ * its window's release passes on to the primary the notices it left that
850
+ * the primary takes in its place, unread in its window, or still queued
851
+ * for it unless it read the copy that landed there. Its end settles a
852
+ * tool-result batch its stream still held and removes the stream's
853
+ * entries, and once it has left, its stream's late events are dropped.
817
854
  */
818
855
  stop(teardownTimeoutMs?: number | undefined): Promise<void>;
819
856
  /** What start() and addModule() pass before either begins work of a
@@ -872,6 +909,10 @@ export declare class AgentFramework {
872
909
  private acquirePrimaryProviderGate;
873
910
  private releasePrimaryProviderGate;
874
911
  private flushAuxiliaryAdmission;
912
+ /** A provider hold's released requests start no turn (the scheduler drops
913
+ * them): the primary turn the release left pending won't run, so the
914
+ * recovery ends and auxiliary admission reopens. */
915
+ private endPendingPrimary;
875
916
  private waitForAuxiliaryIdle;
876
917
  private withAuxiliaryAdmission;
877
918
  /**
@@ -913,6 +954,12 @@ export declare class AgentFramework {
913
954
  * and the cap applies only to AF's own default. A negative stated wait is
914
955
  * a stated 0, as in ProviderWaits: the 1 s floor, plus jitter. */
915
956
  private accelerationCooldownMs;
957
+ /** Whether two requests are one wake, for a provider hold's dedup: the
958
+ * same agent, reason, source, time and channel, and the same coalescing
959
+ * marks: a batch wake's subject, a batch-only merge's subjects (it has no
960
+ * single subject), and the write a wake reads. A wake with any of them
961
+ * can be withdrawn or dropped on its own, and must not stand for one
962
+ * without. (coalescingBatch is set only beside one of the first two.) */
916
963
  private sameInferenceRequest;
917
964
  private consultProviderHold;
918
965
  /** A host hold whose slice expired: ask the host again before spending an
@@ -977,9 +1024,8 @@ export declare class AgentFramework {
977
1024
  /**
978
1025
  * Refuse an auxiliary call to a model the provider asked this agent to wait
979
1026
  * on, without calling it. The refusal is a retryable rate limit carrying
980
- * the remaining wait, so a caller that paces (context-manager's compression
981
- * lane, from its corrective round #138 on) waits it out instead of spending
982
- * a call. It is marked
1027
+ * the remaining wait, so a caller that paces waits it out instead of
1028
+ * spending a call. It is marked
983
1029
  * `providerAdmission: 'deferred'`: no call was made, so a caller can keep
984
1030
  * the wait without counting a failed call (room-225 #47927).
985
1031
  */
@@ -1165,7 +1211,7 @@ export declare class AgentFramework {
1165
1211
  /** The registered workspace module, if any (used by save_image). */
1166
1212
  private getWorkspaceModule;
1167
1213
  /** RFC-005 host-mediated reference fetcher (lazy; needs server configs +
1168
- * a writable workspace mount for storage). */
1214
+ * a read-write workspace mount without an include for storage). */
1169
1215
  private referenceFetcherInstance?;
1170
1216
  private getReferenceFetcher;
1171
1217
  /** Register every RFC-005 reference in an MCPL peer's tool-result content
@@ -1354,14 +1400,16 @@ export declare class AgentFramework {
1354
1400
  * acknowledged once: the chronicle is synced, then the persisted queue is
1355
1401
  * rewritten without the batch (ackDeferredWrites). Until then the batch
1356
1402
  * stays in the durable queue, so a crash mid-flush replays it at the next
1357
- * boot, which skips each entry that already landed, by its deferredWriteId
1358
- * — no loss, no duplicates. The batch is stored in queue order, whatever
1359
- * its targets (writeDrainedInOrder). A write the store rejects stays
1360
- * queued, logged, with what is queued behind it for its target, so the
1361
- * flush never stores that target's later entries ahead of it, and other
1362
- * targets' entries go on. (A write that isn't deferred can still land
1363
- * ahead of it, such as one for an idle agent once the host has resumed.)
1364
- * A boot that meets it again logs it and goes on.
1403
+ * boot, which skips each entry that already landed, by its deferredWriteId —
1404
+ * no loss, no duplicates. The batch is stored in queue order, whatever its
1405
+ * targets (writeDrainedInOrder). A write the store rejects stays queued,
1406
+ * logged, with what is queued behind it for its target, so the flush never
1407
+ * stores that target's later entries ahead of it, and other targets' entries
1408
+ * go on. One the store refuses as malformed, which it would at every flush,
1409
+ * is logged and dropped instead, and what is behind it goes on. (A write
1410
+ * that isn't deferred can still land ahead of it, such as one for an idle
1411
+ * agent once the host has resumed.) A boot that meets it again logs it and
1412
+ * goes on.
1365
1413
  *
1366
1414
  * Per-target: an agent whose turn is still alive keeps ITS messages
1367
1415
  * deferred for its own turn boundary; everyone else's flush now.
@@ -1434,8 +1482,8 @@ export declare class AgentFramework {
1434
1482
  * memory-only: they land within the turn, at a tool boundary or at its
1435
1483
  * end, and a crash before then loses them. That window runs to the turn's
1436
1484
  * end for a message held there and what is queued behind it, and, on a
1437
- * stream that can't carry injected messages, for every message deferred
1438
- * during the turn.
1485
+ * stream that declares it can't carry injected messages (membrane's XML
1486
+ * prefill path, from 0.6.0), for every message deferred during the turn.
1439
1487
  *
1440
1488
  * A write that fails, or a queue over the cap, which writes nothing,
1441
1489
  * leaves the record as it last held it, except that store only, a write
@@ -1662,7 +1710,17 @@ export declare class AgentFramework {
1662
1710
  *
1663
1711
  * This is create()'s first read of framework/state, so it also refuses a
1664
1712
  * framework/state that isn't an object: every reader of that state would
1665
- * take it as holding nothing, and its first write would replace it. */
1713
+ * take it as holding nothing, and its first write would replace it.
1714
+ *
1715
+ * A stored entry restores into the shared ephemeral entry, rather than
1716
+ * under its own name, when it is marked as the shared entry, when it was an
1717
+ * ephemeral agent's from before they shared one entry, its name having an
1718
+ * ephemeral agent's namespace in the store (subagent/<name>, as
1719
+ * createEphemeralAgent opens it), or when it is the shared entry an earlier
1720
+ * framework wrote back without its mark. A name a persistent agent has keeps
1721
+ * an unmarked entry either way: one in `configured`, or one with a
1722
+ * resident's or a conversation agent's namespace (agents/<name>,
1723
+ * conversations/<name>). */
1666
1724
  private restoreUsageState;
1667
1725
  private persistUsageState;
1668
1726
  /** An agent's persisted record, or null when it has none. Throws the
@@ -1858,9 +1916,12 @@ export declare class AgentFramework {
1858
1916
  /**
1859
1917
  * Mark an inference refusal visibly: react on the message that holds the
1860
1918
  * refused agent's conversational locus (the most recent incoming channel
1861
- * message; an ephemeral run has none, so a subagent's refusal marks no
1862
- * message) with a category-specific emoji. Best-effort — failures are
1863
- * logged, never thrown, and non-Discord loci are silently skipped.
1919
+ * message that isn't a reaction, reaction removal, edit or deletion
1920
+ * marker, apart from an edit the coalescer delivers on acceptance as the
1921
+ * agent's first view; an ephemeral run has none, so a subagent's refusal
1922
+ * marks no message) with a category-specific emoji. Best-effort —
1923
+ * failures are logged, never thrown, and non-Discord loci are silently
1924
+ * skipped.
1864
1925
  */
1865
1926
  private reactToRefusal;
1866
1927
  /**
@@ -1949,7 +2010,7 @@ export declare class AgentFramework {
1949
2010
  * advancing merges during a quiesce window.
1950
2011
  *
1951
2012
  * host-status — report the quiesce state (drained / parked wakes /
1952
- * running background scripts).
2013
+ * scripts left running).
1953
2014
  *
1954
2015
  * release-provider-wait — end an agent's provider wait (a provider's
1955
2016
  * stated retry-after, kept across restarts) for one `model` or all, as an
@@ -1989,14 +2050,14 @@ export declare class AgentFramework {
1989
2050
  */
1990
2051
  tailProcessLogs(count?: number, eventType?: string): ProcessLogEntryWithId[];
1991
2052
  /**
1992
- * Switch the store to an existing branch, start the delivery of the
1993
- * Discord awareness marks the move changes (startDiscordAwarenessDelivery),
1994
- * and re-materialize the config mount from it. Resolves once the mount has
1995
- * run; if it fails, it rejects with the store already moved. The marks'
1996
- * delivery isn't awaited, and its failure doesn't fail the switch. The
1997
- * store has moved by the time the call returns, before its promise
1998
- * settles, and a refusal moves nothing. An operator's operation: refused
1999
- * once stop() has begun, and waited for by stop() while it runs.
2053
+ * Switch the store to an existing branch and re-materialize the config
2054
+ * mount from it. A switch adds or removes no Discord awareness marks: they
2055
+ * are one-shot, a surgery's or an operator's explicit choice. Resolves once
2056
+ * the mount has run; if it fails, it rejects with the store already moved.
2057
+ * It moves the store once any maintenance already running has finished, so
2058
+ * the move can come after the call returns, and a refusal moves nothing.
2059
+ * An operator's operation: refused once stop() has begun, and waited for
2060
+ * by stop() while it runs.
2000
2061
  *
2001
2062
  * The branch moves under every agent sharing the store, so the switch
2002
2063
  * reserves the store as a surgery does: every agent must be idle, or it is
@@ -2072,6 +2133,29 @@ export declare class AgentFramework {
2072
2133
  * does. Always release in `finally`: a token nobody clears wedges the fleet.
2073
2134
  */
2074
2135
  private reserveStoreForSurgery;
2136
+ /**
2137
+ * A surgery's marker batch, recorded before its body change. If it can't
2138
+ * be recorded, the surgery doesn't start, and the error says what the
2139
+ * ledger may hold (DiscordAwarenessOutbox.prepare). Without a ledger there
2140
+ * is none: a marks choice was refused before this (refuseMarksWithoutLedger),
2141
+ * and a suppression runs with no record to resume it from.
2142
+ */
2143
+ private prepareMarkerBatch;
2144
+ /**
2145
+ * A marks choice needs a ledger to keep it: a framework that has none
2146
+ * refuses one before anything is planned or changed.
2147
+ */
2148
+ private refuseMarksWithoutLedger;
2149
+ /**
2150
+ * After a failed surgery has put the source back: retire its prepared
2151
+ * awareness batch, but only when the store is confirmed on the source. If
2152
+ * it isn't, the batch stays prepared as the evidence of an unfinished body
2153
+ * (a start on its target finishes a suppression's removals). Either way
2154
+ * none of its marks is ever sent: a start retires what this can't.
2155
+ * Never throws: the caller is already reporting the surgery's failure;
2156
+ * returns a clause to append to it.
2157
+ */
2158
+ private retireAfterRestore;
2075
2159
  /**
2076
2160
  * After a failed switch or redaction: put the store back on `sourceBranch`
2077
2161
  * if it moved, and return a sentence saying what actually happened. Never
@@ -2082,14 +2166,17 @@ export declare class AgentFramework {
2082
2166
  * Roll the active branch back so `messageId` becomes its tail: fork the
2083
2167
  * chronicle at that message (origin-sequence time-travel branch) and switch
2084
2168
  * to the fork. Everything after the message stays on the source branch.
2085
- * Discord messages that left the live context get awareness markers via the
2086
- * durable outbox, exactly as message-granular `undo` does.
2169
+ *
2170
+ * The rollback is local to the resident. Marking removed Discord messages
2171
+ * with an awareness reaction is a separate, explicit publication choice
2172
+ * (`marks`, default `none`); `previewSurgeryMarks` shows what each scope
2173
+ * would cover, and passing its `refs` binds the choice to exactly that set.
2087
2174
  *
2088
2175
  * Returns once the switch has landed: the body is applied, with a
2089
2176
  * marker-scheduling receipt (`markers`). It does not wait for Discord to
2090
- * accept the reactions: delivery is started, behind the MCPL data-plane
2091
- * gate, and continues without the caller or the store reservation waiting
2092
- * on it; its per-message outcomes stay in the outbox ledger.
2177
+ * accept the reactions: delivery is started and continues without the
2178
+ * caller, the store reservation or MCPL traffic waiting on it; what
2179
+ * Discord answers is kept in the awareness ledger.
2093
2180
  *
2094
2181
  * Throws `OperatorActionError` (`agent-busy`, `unknown-message`, …) — the
2095
2182
  * agent must be idle; nothing is queued.
@@ -2100,6 +2187,8 @@ export declare class AgentFramework {
2100
2187
  note?: string;
2101
2188
  /** Branch name for the fork (default `rollback/<agent>/<ts>`, or with `-2`, `-3`, … appended when the store already holds that name). */
2102
2189
  branchName?: string;
2190
+ /** Publication choice for awareness marks; default `none`. */
2191
+ marks?: DiscordAwarenessMarks;
2103
2192
  }): Promise<{
2104
2193
  agentName: string;
2105
2194
  sourceBranch: string;
@@ -2127,9 +2216,10 @@ export declare class AgentFramework {
2127
2216
  * source branch: fork at the current head (by default `suppress/<agent>/<ts>`,
2128
2217
  * numbered `-2`, `-3`, … when the store already holds that name), redact
2129
2218
  * the messages on the fork, switch to it. Shards of a body group are always
2130
- * removed together. Discord originals get awareness markers via the outbox;
2131
- * the batch is `explicit`-activated only after every removal succeeded, and
2132
- * a crash mid-way is finished at next boot (resumePreparedDiscordSuppressions).
2219
+ * removed together. With a marks choice, the Discord originals get awareness
2220
+ * marks through the ledger: the batch is activated only after every removal
2221
+ * succeeded, and a crash mid-way is finished at next boot
2222
+ * (resumePreparedDiscordSuppressions), its marks retired unsent.
2133
2223
  * Like rollbackToMessage, it returns once the body change has landed, with
2134
2224
  * a marker-scheduling receipt (`markers`); delivery continues without the
2135
2225
  * caller waiting on it.
@@ -2144,6 +2234,8 @@ export declare class AgentFramework {
2144
2234
  note?: string;
2145
2235
  /** Branch name for the fork (default `suppress/<agent>/<ts>`, or with `-2`, `-3`, … appended when the store already holds that name). */
2146
2236
  branchName?: string;
2237
+ /** Publication choice for awareness marks; default `none`. */
2238
+ marks?: DiscordAwarenessMarks;
2147
2239
  }): Promise<{
2148
2240
  agentName: string;
2149
2241
  sourceBranch: string;
@@ -2163,66 +2255,94 @@ export declare class AgentFramework {
2163
2255
  preview?: string;
2164
2256
  } | null;
2165
2257
  }>;
2258
+ /**
2259
+ * The messages a rollback to `messageId` would remove, validated, without
2260
+ * changing anything. Never bisects a body group: chronicle refuses that
2261
+ * for removals and branchAt has no such guard, so the target snaps to the
2262
+ * group's last shard.
2263
+ */
2264
+ private planRollback;
2265
+ /**
2266
+ * The removal intervals a suppression of `requestedIds` would apply
2267
+ * (index-ordered, newest first), validated, without changing anything. A
2268
+ * shard expands to its whole body group (chronicle refuses to bisect one),
2269
+ * and a group interval is always removed as a range.
2270
+ */
2271
+ private planSuppression;
2272
+ /**
2273
+ * What a rollback or suppression would remove, and which Discord messages
2274
+ * each publication scope would mark, without changing anything or reading
2275
+ * message content. A surface shows this before an operator chooses
2276
+ * `marks`; passing a scope's `refs` back as `marks.refs` binds the choice
2277
+ * to exactly that set, so a later application never widens it.
2278
+ */
2279
+ previewSurgeryMarks(agentName: string, target: {
2280
+ rollbackTo: string;
2281
+ } | {
2282
+ suppress: string[];
2283
+ }): SurgeryMarksPreview;
2284
+ /** The awareness ledger's batches and retract requests, for operator surfaces. */
2285
+ listDiscordAwareness(): DiscordAwarenessView[];
2286
+ /**
2287
+ * Stop all further sends and retries of a batch's marks, or of a retract
2288
+ * request's removals (by its request id). Never removes a reaction and
2289
+ * never undoes one: requests already on the wire, or whose outcome is
2290
+ * unknown, are reported and may still land.
2291
+ */
2292
+ cancelDiscordAwareness(target: string, opts?: {
2293
+ requester?: OperatorRequester;
2294
+ note?: string;
2295
+ }): Promise<DiscordAwarenessCancelReceipt>;
2296
+ /**
2297
+ * Remove this bot's awareness mark, through each ref's configured MCPL
2298
+ * route, from a batch's refs, or (`all`) from every ref of every batch not
2299
+ * retired and every reaction the ledger holds. The receipt says how many
2300
+ * removals were queued and on how many of those reactions an earlier add
2301
+ * may land afterwards.
2302
+ */
2303
+ retractDiscordAwareness(target: string | 'all', opts?: {
2304
+ requester?: OperatorRequester;
2305
+ note?: string;
2306
+ }): Promise<DiscordAwarenessRetractReceipt>;
2307
+ private awarenessOperatorAction;
2166
2308
  /**
2167
2309
  * Record a surgery's prepared marker batch as active once its body change
2168
2310
  * has landed, and say what happened. Never throws: the body is already
2169
2311
  * applied, so a ledger failure here is reported in the receipt rather than
2170
2312
  * as a failed surgery an operator might retry. A batch that could not be
2171
- * activated is retired, so no later reconciliation can deliver it behind a
2172
- * receipt saying it was not scheduled (`not-scheduled`). If retiring fails
2173
- * too, the receipt says only that the outcome is `unresolved`: the batch is
2174
- * retained, and it may still be delivered. A rollback's batch
2175
- * (activated by target branch) may be promoted by the very next
2176
- * reconciliation, the one the delivery it starts runs; a suppression's
2177
- * (activated explicitly) waits for the next start.
2313
+ * activated is retired, so no later start can deliver it behind a receipt
2314
+ * saying it was not scheduled (`not-scheduled`). If retiring fails too, it
2315
+ * stays prepared, and a start retires it, unsent: the receipt is
2316
+ * `not-scheduled` either way.
2178
2317
  *
2179
- * A batch with no refs (a suppression journal with nothing addressable) is
2180
- * still activated, which closes its resume journal. It schedules no marks,
2181
- * so it reports `none` whatever the ledger does. If it can be neither
2182
- * activated nor retired, its journal is left prepared and closes at the
2183
- * next start: every interval it names has already committed, so the resume
2184
- * skips them all and activates it.
2318
+ * A batch with no refs (a suppression's resume record, with nothing
2319
+ * addressable) is still activated, which closes it. It schedules no marks,
2320
+ * so it reports `none` whatever the ledger does, and a failure is logged.
2321
+ * If it can be neither activated nor retired, it stays prepared, and
2322
+ * closes at the next start on its branch: every interval it names has
2323
+ * already committed, so the resume skips them all and retires it.
2185
2324
  */
2186
2325
  private activateSurgeryMarkers;
2187
2326
  /**
2188
- * Start awareness delivery after a branch move (a surgery, a switch, an
2189
- * undo or redo) without the caller awaiting it. No operator response waits
2190
- * for Discord to accept marks: the MCPL data-plane gate alone holds channel
2191
- * traffic that arrives after it until they are attempted.
2192
- * The sync's body installs that gate synchronously, before its first
2193
- * await, so calling this while a surgery still holds the store puts the
2194
- * gate up before the store is released. With no drain running, the
2195
- * drain starts in the same synchronous run (the first reaction request can
2196
- * be written before this returns); with one running, this generation's pass
2197
- * follows it (drainForGeneration). Either way delivery continues
2198
- * independently: the caller's response and any store reservation stop
2199
- * waiting on remote reactions. A turn may run during delivery when its wake
2200
- * carries no channel traffic (a scheduler timer, a provider admission), and
2201
- * also when its channel traffic was admitted before the gate went up
2202
- * (queued when a surgery began, or arriving during its switch or fork): the
2203
- * surgery's store reservation, which used to hold such a turn through the
2204
- * drain, now ends once the gate is up. A failure is accounted by the gate
2205
- * itself: the current generation's failure recycles the connections (or,
2206
- * once the host is stopping, releases the gate instead), and a superseded
2207
- * one leaves that to the newer generation, whose own pass meets the same
2208
- * ledger. Here it is logged and raised as an ops alert, and the next sync,
2209
- * reconnect or start delivers what is still pending.
2210
- *
2211
- * Like a server's drain, the delivery runs apart from the operation that
2212
- * started it: it isn't an operator's operation. A drain already running
2213
- * when stop() begins sends nothing more, and stop() waits for it to record
2214
- * the call it had in flight, which closing the connections ends; what it
2215
- * hasn't sent stays pending in the durable outbox, unrecorded. Once stop()
2216
- * has begun, none is started, since there's no point opening a drain that
2217
- * the teardown is about to cut off: the marks stay pending, and the next
2218
- * start's barrier reconciles the outbox with the branch and delivers them.
2219
- *
2220
- * @param after What moved the branch, for the log and the alert
2221
- * ("rollback", "branch switch", "undo" …).
2222
- * @param agentName The agent the move was for, or "framework" for a
2223
- * branch switch that names none.
2224
- */
2225
- startDiscordAwarenessDelivery(after: string, agentName?: string): void;
2327
+ * The receipt for a batch whose body change has landed, from what the
2328
+ * ledger settled. Anything short of `queued` is logged and raised as an
2329
+ * ops alert: the body stands either way.
2330
+ */
2331
+ private settledMarkerReceipt;
2332
+ /**
2333
+ * Start awareness delivery without the caller awaiting it. The drain starts
2334
+ * now and continues independently. Delivery never gates MCPL traffic or
2335
+ * turns; a failure is logged and raised as an ops alert, and the queued
2336
+ * work stays in the ledger for the next pass. It isn't an
2337
+ * operator's operation, as syncDiscordAwarenessMarkers is: stop() waits
2338
+ * for running drains only once it has closed their servers, within its
2339
+ * budget, and once stop() has begun none is started, since the teardown
2340
+ * would cut it off. The next start delivers what is due. A quiesce doesn't
2341
+ * hold it, as it holds turns and what servers send: a delivery starts no
2342
+ * turn, and the answers to the host's own requests are never held, so a
2343
+ * surgery made during a quiesce has its marks sent then.
2344
+ */
2345
+ private deliverDiscordAwarenessInBackground;
2226
2346
  /** Start config file IO without holding the caller or a surgery's store
2227
2347
  * reservation. The gate picks it up by mtime; stop() still waits for it. */
2228
2348
  private materializeConfigMountAfterBranchSwitch;
@@ -2324,10 +2444,10 @@ export declare class AgentFramework {
2324
2444
  /**
2325
2445
  * Spawn a persistent per-channel conversation agent ("fork") from the
2326
2446
  * template agent: own ContextManager under `conversations/{name}`, seeded
2327
- * with the template's compiled context without its thinking or its unpaired
2328
- * tool blocks (the SubagentModule wholesale-copy pattern; see the seeding
2329
- * comment below), registered in the event loop like any agent — but never
2330
- * primary.
2447
+ * with the template's compiled context without its thinking, its channel
2448
+ * and by-name notices, or its unpaired tool blocks (the SubagentModule
2449
+ * wholesale-copy pattern; see the seeding comment below), registered in the
2450
+ * event loop like any agent — but never primary.
2331
2451
  */
2332
2452
  private createConversationAgent;
2333
2453
  /**
@@ -2360,6 +2480,15 @@ export declare class AgentFramework {
2360
2480
  * in flight for the channel, and only this spawn's settlement removes it,
2361
2481
  * so the entry it removes is its own. It's removed before anyone waiting
2362
2482
  * on it resumes, so a waiter that decides again doesn't find it.
2483
+ *
2484
+ * It binds only while the fork it created is still the agent registered
2485
+ * under its name. stop() ends each live fork and unbinds the channels
2486
+ * bound to them, so a fork it ends while this spawn waits for the creation
2487
+ * to return has no binding yet, and binding it then would route the
2488
+ * channel to a name that's gone. The spawn rejects instead, as a failed
2489
+ * spawn does. Its fork's name stays used, so the router's counter for the
2490
+ * channel first moves to the spawn's generation, which the store already
2491
+ * holds, and the channel's next qualifying message spawns the next one.
2363
2492
  */
2364
2493
  private spawnConversationAgent;
2365
2494
  /**
@@ -2378,17 +2507,27 @@ export declare class AgentFramework {
2378
2507
  */
2379
2508
  private storeConversationGeneration;
2380
2509
  /**
2381
- * Remove a closed conversation fork from the framework: its closure turn
2382
- * has finished, so the home mapping has served its purpose and keeping the
2383
- * agent registered would just grow every agent scan and broadcast filter
2384
- * forever. The fork's context stays in Chronicle for investigation.
2510
+ * Remove a conversation fork from the framework, once its closure turn has
2511
+ * finished or when stop() ends it: the home mapping has served its purpose,
2512
+ * and keeping the agent registered would just grow every agent scan and
2513
+ * broadcast filter forever. Its window is released now, or, while the host
2514
+ * is quiesced, at resume (releaseWindowNowOrAfterResume); when stop() ends
2515
+ * it then, stop()'s pass for postponed releases passes on the failed
2516
+ * replies it left unread instead. No binding names it
2517
+ * by then: the idle sweep unbinds its channel as the closure begins,
2518
+ * stop() unbinds it just before it ends the fork, and a spawn whose fork
2519
+ * stop() has ended binds nothing (spawnConversationAgent). The fork's
2520
+ * context stays in Chronicle for investigation.
2385
2521
  */
2386
2522
  private disposeConversationAgent;
2387
2523
  /**
2388
2524
  * Scope MCPL context injections for a conversation-bound agent: drop
2389
- * injections that are another open channel's context (injection namespace
2390
- * = channelId by adapter convention), keep its own channel and anything
2391
- * that isn't channel context.
2525
+ * injections that are another registered channel's context (injection
2526
+ * namespace = channelId by adapter convention), keep its own channel and
2527
+ * anything that isn't channel context. A channel's context is its own
2528
+ * whether or not it's open: one the agent closed, or one whose server's
2529
+ * transport closed and that isn't confirmed again yet, still belongs to
2530
+ * its own fork.
2392
2531
  */
2393
2532
  private scopeInjectionsForAgent;
2394
2533
  /**
@@ -2466,6 +2605,20 @@ export declare class AgentFramework {
2466
2605
  * stamped (a direct framework caller), which is the closest observation.
2467
2606
  */
2468
2607
  private channelSource;
2608
+ /**
2609
+ * An inbound item's metadata with its stored copy's own digest
2610
+ * (`storedBodyDigest`): the delivered-body digest's function over exactly
2611
+ * the blocks handed to storage here — every decoration included, before
2612
+ * storage shards them. That function hashes blocks as the store keeps them
2613
+ * (inline media re-encoded and relabeled from its bytes), so an unsharded
2614
+ * copy read back hashes to this too. A body the store shards (adaptive
2615
+ * ingress chunking) carries this on every shard, with its metadata, and no
2616
+ * shard hashes to it. Taken at each storage site, never earlier, because
2617
+ * a path can still decorate the body after ingestion stamped it (the
2618
+ * closed-channel invitation; room-220 #48282). An edit through
2619
+ * editMessage keeps metadata but not this hash.
2620
+ */
2621
+ private static withStoredDigest;
2469
2622
  /** Source envelope of a channels/incoming event (lane facts as given). */
2470
2623
  private channelEventSource;
2471
2624
  /** Source envelope of a push event: its derived channel, else unscoped. */
@@ -2517,7 +2670,7 @@ export declare class AgentFramework {
2517
2670
  /** Queue a wake for each agent of the batch's audience, when its latest
2518
2671
  * occurrence triggers inference. `plain`: an ordinary push wake, without
2519
2672
  * the subject a withdrawal of the batch's wakes goes by, for a render
2520
- * placed in its agent's deferred queue (wakeToRead). */
2673
+ * placed in its agent's deferred queue (wakeToRead), at `readsDeferredWrite`. */
2521
2674
  private queueCoalescedWakes;
2522
2675
  /** Withdraw unstarted wakes whose sole cause is this subject (§4.2). */
2523
2676
  private cancelCoalescedWakes;
@@ -2527,11 +2680,18 @@ export declare class AgentFramework {
2527
2680
  * scanning the unread tail (above the watermark) — never below it.
2528
2681
  */
2529
2682
  private resolvePlacement;
2683
+ /** Unread (the coalescer's isUnread) by the consumed watermark, or, by the
2684
+ * shown watermark, never possibly shown (its isUnshown). A placement still
2685
+ * in the deferred queue is both, once settled (settleUnknownLandings): one
2686
+ * whose write may already be stored, its store unsearchable, is a doubt,
2687
+ * which counts as read and as shown. */
2530
2688
  private isUnreadPlacement;
2531
2689
  /**
2532
2690
  * Unread = stored, above the agent's consumed watermark on the current
2533
2691
  * branch, not a body-group shard (immutable), and not folded into any
2534
2692
  * summary (compression is consumption, §3.3). Conservative on every doubt.
2693
+ * By the shown watermark (Agent.getShownWatermark), the same test says the
2694
+ * message may never have been shown.
2535
2695
  */
2536
2696
  private isUnreadStoredMessage;
2537
2697
  private removePlacement;
@@ -2586,7 +2746,7 @@ export declare class AgentFramework {
2586
2746
  * (Named for its first use, the silent tick.)
2587
2747
  */
2588
2748
  private silentTurnRowMetadata;
2589
- /** Record plain-prose segments this turn suppressed without drafts (proseRouting=disabled). */
2749
+ /** Record plain-prose segments this turn suppressed without drafts (proseRouting=disabled, or a round withheld before its scripts returned). */
2590
2750
  private recordProseSuppression;
2591
2751
  /**
2592
2752
  * Silenced plain speech: an explicit send holds it as resendable drafts; a
@@ -2722,10 +2882,12 @@ export declare class AgentFramework {
2722
2882
  private announceLocusIfChanged;
2723
2883
  /**
2724
2884
  * The channel a message moves its turn's locus to, by the addressed
2725
- * re-pin rule (2026-07-31, n=6 and n=7): a conversational message (not a
2726
- * reaction or a system marker) that addressed the agent, or that follows
2727
- * up in a channel the turn sent into (TurnRouting.engaged). Undefined for
2728
- * any other message. A tool boundary weighs the messages it injects by it,
2885
+ * re-pin rule (2026-07-31, n=6 and n=7): a conversational message (by
2886
+ * isConversationalInjection: not a system marker, nor a reaction, reaction
2887
+ * removal, edit or deletion marker, apart from an edit the coalescer marks
2888
+ * as the agent's first view) that addressed the agent, or that follows up
2889
+ * in a channel the turn sent into (TurnRouting.engaged). Undefined for any
2890
+ * other message. A tool boundary weighs the messages it injects by it,
2729
2891
  * and noteArrival the ones no boundary of the turn weighs.
2730
2892
  */
2731
2893
  private repinChannel;
@@ -2751,6 +2913,12 @@ export declare class AgentFramework {
2751
2913
  * its own agent, so no boundary of another resident's turn weighs it.
2752
2914
  */
2753
2915
  private noteForOtherResidents;
2916
+ /**
2917
+ * Show the turn's typing indicator in `channelId`, stopping the one it last
2918
+ * showed elsewhere: this stream's, or one an earlier stream of the turn
2919
+ * left running when it handed the turn on.
2920
+ */
2921
+ private showTurnTyping;
2754
2922
  /**
2755
2923
  * The channel of the turn's newest arrival whose message is still in the
2756
2924
  * agent's store (TurnRouting.arrivals). A message removed since it was
@@ -2776,15 +2944,155 @@ export declare class AgentFramework {
2776
2944
  /**
2777
2945
  * Durable window notice for a channel the agent did not ask to open: a
2778
2946
  * subscription-policy admission, announced as the decision before its
2779
- * transport RPC (a failed open keeps the decision, and channel_list shows
2780
- * transport state), or an open that the agent's own delivery or reply
2781
- * caused (`opened-by-delivery`, `opened-by-reply`), once its transport is
2782
- * confirmed. Either way it names `channel_close` as the opt-out (their
2783
- * decision outranks policy). What an open channel delivers is its server's
2784
- * to say (#406), so the notice doesn't promise its traffic. System message:
2785
- * never triggers inference, never conversational, never locus-eligible.
2947
+ * transport RPC (a failed open keeps the decision, and the host tries again
2948
+ * when the server next registers the channel), or an open that the agent's
2949
+ * own delivery or reply caused (`opened-by-delivery`, `opened-by-reply`),
2950
+ * once its transport is confirmed. It names `channel_close` as the opt-out
2951
+ * (neither the subscription policy nor the server's default reopens a
2952
+ * channel the agent closed) only where the agent it's addressed to can
2953
+ * call it for every channel it names (canCloseChannels): a conversation
2954
+ * fork may close only its home channel, and an agent's allowedTools can leave
2955
+ * channel_close out. The other residents can read it too, where several
2956
+ * share one slot (#291); a fork's seed leaves it out (primaryNoticeTexts).
2957
+ * Where an
2958
+ * agent's own send opened a channel it can't close, the primary is told by
2959
+ * name too, if it's registered and can close it, and the agent is told
2960
+ * that it was. What an open channel delivers is its server's to say (#406),
2961
+ * so the notice says how servers differ rather than promising its traffic,
2962
+ * and says that only to an agent whose window holds the channel's traffic
2963
+ * (holdsChannelTraffic).
2964
+ * System message: never triggers inference, never conversational, never
2965
+ * locus-eligible.
2786
2966
  */
2787
2967
  private recordChannelAutoOpenNotice;
2968
+ /**
2969
+ * Write a builder's channel notices in order, each on its own: one that
2970
+ * can't be written is logged, and the rest are still written. A reader's
2971
+ * notice that says the primary was told comes after the primary's, and is
2972
+ * written in its `untold` words where the primary's write failed, so it
2973
+ * never says the primary was told of a notice that wasn't written. A write
2974
+ * addMessage defers to the primary's next boundary, as it does any write
2975
+ * to an agent mid-turn, counts as written: a memory-only queue loses it at
2976
+ * exit, as it loses any deferred write. Through
2977
+ * framework.addMessage for mid-turn safety (deferral + hear-while-acting
2978
+ * injection): an open a delivery forces happens inside a live turn, and a
2979
+ * direct context-manager append there would store the notice out of order.
2980
+ */
2981
+ private writeChannelNotices;
2982
+ /**
2983
+ * The notices recordChannelAutoOpenNotice writes, in order: the primary's
2984
+ * by name where the reader can't close the channels, then the reader's,
2985
+ * which then says the primary was told (`untold`: its words where that
2986
+ * didn't land). None, logged, for an agent that has ended when there's no
2987
+ * primary to tell.
2988
+ * The reader's carries its inputs (`passOn`), the channels' server among
2989
+ * them, where it's addressed to the agent whose send opened the channels
2990
+ * and that agent was told it can close them, so a release that finds it
2991
+ * unread can tell the primary in its place (channelNoticeForPrimary), which
2992
+ * calls this again for the agent then gone. A policy admission's goes where
2993
+ * addMessage delivers it, to no agent of its own, and carries none.
2994
+ */
2995
+ private channelOpenedNotices;
2996
+ /**
2997
+ * Whether `who` can call channel_close for every one of `channelIds` here:
2998
+ * its allowedTools hold it (canAgentUseTool), and a conversation fork,
2999
+ * whose channel_close dispatchChannelToolCall refuses for any channel but
3000
+ * its home, only for its home.
3001
+ */
3002
+ private canCloseChannels;
3003
+ /**
3004
+ * Whether `who` holds the traffic of every one of `channelIds`, so that
3005
+ * what an open channel delivers is in its window. Where conversations are
3006
+ * routed, an incoming message goes to the fork its channel is bound to, or
3007
+ * nowhere, and never to the primary (handleMcplChannelIncoming), so a fork
3008
+ * holds only its home's, and only while the router binds its home to it.
3009
+ * An idle expiry's sweep unbinds the home before the fork's closure turn
3010
+ * (ConversationRouter.expired), and from then the closing fork holds none;
3011
+ * a newer fork the home is bound to holds it instead. Elsewhere an
3012
+ * incoming message is stored with no forAgent, in deliveryAgent()'s store,
3013
+ * and where that's the residents' shared slot, every agent that reads the
3014
+ * slot holds it (sharedSlotAgents: the ordinary residents, and the
3015
+ * subconscious through its merged view); a run's store is its own. (A push
3016
+ * names its channel and lands in the primary's window either way, but it
3017
+ * comes whether or not the channel is open, so it isn't what opening one
3018
+ * delivers.)
3019
+ */
3020
+ private holdsChannelTraffic;
3021
+ /**
3022
+ * Whether `who`'s window holds the traffic of the channels it may open or close, for the words its channel_open and
3023
+ * channel_close carry. A conversation fork does for its home, the one
3024
+ * channel it may close, decided by the home rather than the binding, so a fork whose binding expired keeps its words
3025
+ * through its closure turn: changing them then would send its whole window uncached, for a sentence false for that
3026
+ * turn only. Otherwise as holdsChannelTraffic has it: on a host that routes conversations, the trunk holds none, and
3027
+ * otherwise the delivery agent and the readers of the residents' shared slot do. An ephemeral run holds none.
3028
+ */
3029
+ private holdsChannelTrafficForTools;
3030
+ /** Whether `who` is the delivery agent, or reads the residents' shared slot it stores into. */
3031
+ private residentHoldsTraffic;
3032
+ /**
3033
+ * How a notice to the primary names `agentName`: a conversation fork by the
3034
+ * channel it's bound to, as notices name channels, with its own name once,
3035
+ * after "named", and as "that fork" after that ("your fork" where the
3036
+ * primary is the template forks are made from); any other agent by its
3037
+ * name. `first` is said mid-sentence, so a fork's ends with a comma. A
3038
+ * fork's home is known while it's registered and through its release; a
3039
+ * notice passed on later, at resume or at boot, names it by its name.
3040
+ */
3041
+ private agentForPrimary;
3042
+ /**
3043
+ * How a notice to `reader` names the primary it says was told: "Your
3044
+ * primary" to a conversation fork made from the primary, whose
3045
+ * configuration is the primary's with only its name changed, so its prompt
3046
+ * may give the primary's name as its own; the primary's name to any other
3047
+ * agent, a fork made from another template included.
3048
+ */
3049
+ private primaryForReader;
3050
+ /** Whether `agentName` is a conversation fork made from the primary: the
3051
+ * router's template is the primary (connectome-host's is). */
3052
+ private forkOfPrimary;
3053
+ /**
3054
+ * Window notice for a reply whose channel couldn't be opened: the reply
3055
+ * went out through its send tool, but the open that engaging the channel
3056
+ * asks for failed. Without it the agent would wait for a conversation it
3057
+ * won't see. It goes to the agent whose reply it was, or, when no agent
3058
+ * is named, where addMessage delivers an unrouted message (deliveryAgent:
3059
+ * the primary, else the first registered agent), as the opened notice
3060
+ * does, and its advice is judged for that agent. Where the channel stays
3061
+ * closed, an agent that has ended is told nothing, and nor is anyone in
3062
+ * its place: nothing follows from the failure. Where it's selected for
3063
+ * opening, the primary is told by name in its place, if one is registered,
3064
+ * as the opened notice tells it of an open by an agent that has ended, so
3065
+ * an agent that could close the channel hears it may open. It names
3066
+ * channel_open as the way to try again only where the agent it's addressed
3067
+ * to can call it: a conversation fork's channel_open is refused outright
3068
+ * (dispatchChannelToolCall), and an agent's allowedTools can leave it out.
3069
+ * The other residents can read it too, where several share one slot
3070
+ * (#291); a fork's seed leaves it out (primaryNoticeTexts).
3071
+ * Where the channel is selected for opening, it says so and why, as
3072
+ * speech's failure does, and what that means: where the host couldn't
3073
+ * record putting the channel's decision back, a later delivery or
3074
+ * reconnect tries again; where the
3075
+ * server's latest announcement or the subscription policy lifted the
3076
+ * default put back, the host tries again itself, so channel_open isn't
3077
+ * named. Either way channel_close withdraws that, named only to an agent
3078
+ * that can call it here (a fork may close only its home channel). Where
3079
+ * the reader can't, the primary is told by name too, if it's registered
3080
+ * and can close it, and the reader is told that it was. System message, as
3081
+ * the opened notice is.
3082
+ */
3083
+ private recordReplyOpenFailedNotice;
3084
+ /**
3085
+ * The notices recordReplyOpenFailedNotice writes, in order: the primary's
3086
+ * by name where the reader can't close a channel selected for opening,
3087
+ * then the reader's, which then says the primary was told (`untold`: its
3088
+ * words where that didn't land). None, logged, where the agent has ended and the channel
3089
+ * stays closed, or there's no primary to tell. The reader's carries its
3090
+ * inputs (`passOn`), the channel's server among them, where it's addressed
3091
+ * to the agent whose reply it was, the channel is selected for opening and
3092
+ * that agent was told it can close it, so a release that finds it unread
3093
+ * can tell the primary in its place (channelNoticeForPrimary).
3094
+ */
3095
+ private replyOpenFailedNotices;
2788
3096
  /**
2789
3097
  * A `!` continuation the turn asked for (`>>#x !`, `>>>#x !`): start another
2790
3098
  * turn now instead of pausing until the next external event. It reads the
@@ -2798,19 +3106,20 @@ export declare class AgentFramework {
2798
3106
  /** The agent's routing state for its current turn, made when it has none. */
2799
3107
  private routingOf;
2800
3108
  /**
2801
- * Explicit-prose-routing delivery gateway (docs/explicit-prose-routing.md).
2802
- * Every prose segment of an `explicit`-mode agent flows through here:
2803
- * parse the `>>` prefix, resolve the target, deliver — or bounce to the
2804
- * held bounce draft with a resend notice. Misdelivery is structurally impossible:
2805
- * nothing is ever sent to a destination the model did not name (directly
2806
- * or via the turn's sticky target).
3109
+ * Explicit-prose-routing delivery gateway (docs/explicit-prose-routing.md),
3110
+ * entered directly: parse the `>>` prefix, resolve the target, deliver, or
3111
+ * bounce to the held bounce draft with a resend notice. Misdelivery is
3112
+ * structurally impossible: nothing is ever sent to a destination the model
3113
+ * did not name (directly or via the turn's sticky target). A stream's own
3114
+ * deliveries go through deliverAdmittedProse with its outgoing stream
3115
+ * (onPublished); this entry has no stream, and only tests call it.
2807
3116
  */
2808
3117
  private deliverProse;
2809
3118
  /**
2810
3119
  * Explicit prose's envelopes, each `>>` target resolved now, once. A live
2811
- * round is admitted at its boundary: its turn's destination is decided from
2812
- * these resolutions (roundDestination), and its queued delivery posts to
2813
- * them, however the registry's names change before it runs.
3120
+ * round is admitted as it ends, at its tool-calls event, and its queued
3121
+ * delivery posts to these resolutions, however the registry's names change
3122
+ * before it runs.
2814
3123
  */
2815
3124
  private admitProse;
2816
3125
  private deliverAdmittedProse;
@@ -2835,13 +3144,6 @@ export declare class AgentFramework {
2835
3144
  /** A draft's state as the journal reads it now: after a write that failed
2836
3145
  * and was reconciled, whatever reached the journal counts. */
2837
3146
  private draftStateNow;
2838
- /**
2839
- * Where a delivered round leaves its turn's sticky destination, as the
2840
- * explicit gateway sets it once the round's envelopes run: each `>>`
2841
- * envelope whose target resolved becomes the destination. One that didn't
2842
- * resolve bounces and leaves it, as do `>>skip_reply` and unprefixed text.
2843
- */
2844
- private roundDestination;
2845
3147
  /** Locus-preserving explicit publication. Source remains byte-identical in Chronicle. */
2846
3148
  private deliverHybridProse;
2847
3149
  /** `>>skip_reply {{unsent}}` and its hybrid form: set the latest bounce
@@ -2942,8 +3244,9 @@ export declare class AgentFramework {
2942
3244
  executeToolCall(call: ToolCall): Promise<ToolResult>;
2943
3245
  /**
2944
3246
  * Admin puppet: execute ONE tool call AS an agent and persist the
2945
- * tool_use + tool_result pair in that agent's window exactly as a
2946
- * model-initiated call is stored.
3247
+ * tool_use + tool_result pair in that agent's window as a
3248
+ * model-initiated call is stored, but under the inline cap its call
3249
+ * carried, whereas a model's call takes the cap at the store.
2947
3250
  *
2948
3251
  * Born from the princess exemplar surgery (2026-08-23). Her folded
2949
3252
  * narrative said "I have no tools"; every past tool_use/tool_result pair
@@ -2988,51 +3291,67 @@ export declare class AgentFramework {
2988
3291
  /** Event-pushing wrapper for the model-driven dispatch path. */
2989
3292
  private dispatchCodeExecutionToolCall;
2990
3293
  /**
2991
- * Run one code_execution script for an agent. Never rejects.
3294
+ * A model-issued tool's result has arrived. When it answers the last of
3295
+ * the code_execution calls a round waits on (ScriptRound), the round's
3296
+ * prose is routed now, its scripts' calls counted.
3297
+ */
3298
+ private settleScriptRound;
3299
+ /**
3300
+ * Whether a code_execution call watches a script that can change its
3301
+ * round's routing, so the round waits for the call (ScriptRound): a run's
3302
+ * script, or the script a wait names by its script_id, as it would watch
3303
+ * it. Its code must name a tool whose call can change the round's routing
3304
+ * in the turn's mode, under its same-round policy (routingToolsNamed,
3305
+ * changesRouting). The reading is coarse, so a comment or a string naming
3306
+ * such a tool holds the round as well, for no longer than the call's yield,
3307
+ * and a name built at runtime isn't seen: its round is routed at once, as a
3308
+ * round was before scripts counted. A stop's watch counts what reaches the
3309
+ * host as any call's does (scriptRoundCalls), but nothing a script makes
3310
+ * once its stop is asked reaches a tool, since the runner refuses it, so a
3311
+ * stop holds no round, and a list returns at once.
3312
+ * Without code execution, or for an agent whose allowedTools doesn't name
3313
+ * code_execution, no script runs, and the call's answer settles no round,
3314
+ * so a round waiting for it would be withheld when its stream ended.
3315
+ */
3316
+ private scriptMayRoute;
3317
+ /**
3318
+ * One code_execution call: run a script, or wait for, stop or list the
3319
+ * agent's scripts. Never rejects.
2992
3320
  *
2993
- * The script runs in the agent's persistent python interpreter with every
2994
- * tool on the agent's CURRENT surface injected (minus code_execution
2995
- * itself). Inner tool calls are dispatched through dispatchToolCall — the
2996
- * exact model path, including MCPL state/checkpoint handling, channel
2997
- * routing, and traces — and resolved via scriptToolWaiters, so their
2998
- * results reach the running script and never the model context.
3321
+ * A script runs in a process of its own, on the engine, with every tool on
3322
+ * the agent's CURRENT surface (minus code_execution itself). Its calls come
3323
+ * back through dispatchToolCall as the agent's — the exact model path,
3324
+ * including MCPL state/checkpoint handling, channel routing, and traces —
3325
+ * and are resolved via scriptToolWaiters, so their results reach the script
3326
+ * and never the model context (scriptToolCall). The return says how the
3327
+ * script ended, or that it's still running, first; then its calls, its
3328
+ * value and its output since the last return (renderReturn). `roundCalls`,
3329
+ * when a round waits on this call (ScriptRound), takes the script's calls
3330
+ * that reach the host while this call watches it.
2999
3331
  */
3000
3332
  private runCodeExecution;
3001
- /** Background scripts are the primary agent's, or any agent's when no primary agent is named. */
3002
- private runsBackgroundScripts;
3003
- /** How many background scripts an agent may have running at once. */
3004
- private maxBackgroundScripts;
3005
- /** How many of this agent's background scripts are running now. */
3006
- private runningBackgroundScripts;
3007
- /**
3008
- * Start a background script: dedicated interpreter, output journaled to a
3009
- * workspace file, wake_agent() available in-script. The tool result
3010
- * returns immediately; the script runs until it ends, hits the lifetime
3011
- * ceiling, or is cancelled. Scripts DIE WITH THE HOST PROCESS — that
3012
- * limitation is stated in the tool description so agents can calibrate
3013
- * how much to rely on an armed wake.
3014
- */
3015
- private startBackgroundScript;
3016
- /** First read-write mount name, or null. */
3017
- private firstWritableMountName;
3333
+ /** code_execution's settings and every agent's scripts, made once code execution is on. */
3334
+ private makeCodeExecution;
3335
+ /** The tools a script of this agent may call now: the agent's own surface, without code_execution. */
3336
+ private scriptTools;
3018
3337
  /**
3019
- * wake_agent() from a background script: enforce the per-script wake cap
3020
- * and rate floor (delay, not drop — the script awaits the ack), then
3021
- * inject the provenance envelope + payload and request inference.
3022
- * Resolves null on delivery; an error string refuses the wake (raises
3023
- * RuntimeError inside the script).
3338
+ * The first read-write mount without an include, or null. The framework
3339
+ * keeps its own files there (`tool-results/`, `refs/`). A mount with an
3340
+ * include holds only the files it names, so it would refuse them, and a
3341
+ * setup whose only writable mount has one is treated as having none.
3024
3342
  */
3025
- private handleScriptWake;
3026
- /** Background script ended (clean, crash, deadline, cancel/dispose). */
3027
- private settleBackgroundScript;
3343
+ private firstWritableMountName;
3028
3344
  /**
3029
- * Deliver a background-script event: provenance envelope into the agent's
3030
- * context + an inference request. Deliberately does NOT consult the event
3345
+ * A script's word to its agent: a wake_agent() payload, or the ending of a
3346
+ * left script that failed, crashed or was stopped at its limit. It enters
3347
+ * the agent's context, spilled to the workspace past the agent's inline
3348
+ * cap, with an inference request. Deliberately does NOT consult the event
3031
3349
  * gate — the agent armed this wake themselves (wake-through-sleep
3032
3350
  * authority); it enters tagged so gate policies could be taught about it
3033
- * later if that ever needs revisiting.
3351
+ * later if that ever needs revisiting. Throws when it can't be delivered,
3352
+ * so the script's wake_agent() says so.
3034
3353
  */
3035
- private injectScriptWake;
3354
+ private scriptWake;
3036
3355
  /**
3037
3356
  * Oversized content policy (antra, 2026-07-31; completed for issue #89):
3038
3357
  * never hit the agent in the face with a huge blob, never silently destroy
@@ -3040,7 +3359,7 @@ export declare class AgentFramework {
3040
3359
  * file (readable with the agent's own tools — deterministic name, kept
3041
3360
  * until the workspace owner deletes it) and replaced by a truncated head +
3042
3361
  * a trailing file reference. Falls back to EXPLICIT plain truncation when
3043
- * there is no writable workspace. Cap resolution lives in
3362
+ * there is no read-write mount without an include. Cap resolution lives in
3044
3363
  * resolveToolResultInlineCap; callers pass the resolved cap.
3045
3364
  */
3046
3365
  /**
@@ -3069,8 +3388,8 @@ export declare class AgentFramework {
3069
3388
  */
3070
3389
  private storedToolResultText;
3071
3390
  /** Where a tool result labelled `label` is written: `<first writable
3072
- * mount>/tool-results/<label>.txt`, or null when there is no writable
3073
- * workspace. */
3391
+ * mount without an include>/tool-results/<label>.txt` (see
3392
+ * firstWritableMountName), or null when there is no such mount. */
3074
3393
  private toolResultFilePlace;
3075
3394
  /**
3076
3395
  * A withheld original uses the remaining time in its batch's deadline.
@@ -3087,54 +3406,39 @@ export declare class AgentFramework {
3087
3406
  /**
3088
3407
  * Write one tool result's text to its tool-results file (see
3089
3408
  * toolResultFilePlace): the one place both the inline cap's spill and the
3090
- * guard's withheld originals go. null when there is no writable workspace.
3409
+ * guard's withheld originals go. null when there is no writable mount
3410
+ * without an include.
3091
3411
  * A failed write is reported, traced and logged here, never thrown. With a
3092
3412
  * branch, the file lands on that branch or isn't written (see writeBinary).
3093
3413
  */
3094
3414
  private writeToolResultFile;
3415
+ /** How to read a tool result's file back a page at a time, with each page
3416
+ * sized to come back within `cap`. */
3417
+ private spillPageAdvice;
3095
3418
  private spillOrTruncate;
3096
- private getOrCreateScriptRunner;
3097
3419
  /**
3098
- * Resolve one script-inner tool call to the string the script's tool
3099
- * function returns, and whether that result is an error (the script's
3100
- * `.is_error`). Never rejects: a failure without structured content becomes
3101
- * an "Error: ..." string, matching the managed PTC runtime ("Claude's code
3102
- * receives this error"), and a structured one its JSON object.
3103
- *
3104
- * A result without structured content is serialized with the HISTORY
3105
- * serializer: images become placeholders, since a script variable holding
3106
- * megabytes of base64 helps nobody. A result with structured content is
3107
- * one JSON object holding both of the server's views
3108
- * (scriptStructuredResult), so its content blocks reach the script as the
3109
- * dispatch gave them, images and payloads included. A module's result that
3110
- * can't be stored or sent, such as a cyclic object or a BigInt, is already
3111
- * an error naming the tool when the dispatch returns it (storableToolResult),
3112
- * so a script reads that error's text.
3113
- */
3114
- private handleScriptToolCall;
3115
- /** The 5MB protocol safety cap on what a script receives. */
3116
- private static readonly SCRIPT_RESULT_MAX_CHARS;
3117
- /**
3118
- * A structured MCP result as a script receives it: one JSON object holding
3119
- * both of the server's views, `{ content, structuredContent, isError }`,
3120
- * plus `error` (the text) on a tool error. `content` is the content array
3121
- * the dispatch gave this call (the direct reading): the server's blocks as
3122
- * sent, so payloads and images survive, except that an MCPL peer's blocks
3123
- * get the treatment RFC-005 gives them on every lane the model reads
3124
- * (referenceBlockForScript). `structuredContent` is the tool's own JSON, as
3125
- * sent. Past the size cap the result stays valid JSON: the whole object is
3126
- * saved to the workspace, and the script gets
3127
- * `{ isError, oversized: { chars, savedTo } }`. If it can't be saved, the
3128
- * script gets a failure to materialize the result, saying the tool may
3129
- * already have completed, never a success missing its result. A result
3130
- * that can't be converted to JSON (a cyclic object, a BigInt), which the
3131
- * dispatch's own check makes unlikely here, gets the same object empty,
3132
- * `{ content: [], structuredContent: null, isError: true, error }`, the
3133
- * error naming the tool. In every form, the script's `.is_error` is the
3134
- * `isError` of the object its string holds, and its `.structured` is read
3135
- * from that string.
3136
- */
3137
- private scriptStructuredResult;
3420
+ * The bridge: one of a script's calls, as its agent's, through the ordinary
3421
+ * dispatcher, so the agent's allowlist and every gate apply as they do to
3422
+ * its own call: the bridge's half of adding nothing to what the agent's
3423
+ * tools allow. Never rejects. A call the dispatcher refused before it
3424
+ * opened (ToolResult.refused) reaches the script as a ToolRefused Error with
3425
+ * the refusal's text; any other result, a failure included, reaches it in
3426
+ * the one shape every tool answers (scriptResultAnswer).
3427
+ */
3428
+ private scriptToolCall;
3429
+ /**
3430
+ * A dispatched result as a script receives it: `{ content, structuredContent,
3431
+ * isError }`, one shape for every tool. `content` is
3432
+ * what the model would read: a structured result's blocks as the dispatch
3433
+ * gave them (the direct reading, with RFC-005's treatment of an MCPL peer's
3434
+ * blocks), and otherwise one text block of the model's text, which for a
3435
+ * failure is its error. `structuredContent` is the tool's own structured
3436
+ * content where it sent one, `false`, `0` and `null` included, else null.
3437
+ * A result that can't be converted to JSON (a cyclic object, a BigInt),
3438
+ * which the dispatch's own check makes unlikely here, is a failure naming
3439
+ * the tool and saying the call itself completed.
3440
+ */
3441
+ private scriptResultAnswer;
3138
3442
  /**
3139
3443
  * Dispatch a script-inner tool call through the NORMAL dispatch path and
3140
3444
  * resolve with its result. The waiter intercept in handleProcessEvent
@@ -3147,8 +3451,25 @@ export declare class AgentFramework {
3147
3451
  * `turnId` is the turn the call was made in (dispatchToolCall).
3148
3452
  */
3149
3453
  private dispatchScriptToolCall;
3150
- /** Abort the agent's script, running or still starting, when the turn it belongs to ends or is reset to run again. */
3151
- private abortAgentScript;
3454
+ /**
3455
+ * A stream's turn ended without its calls' answers, or is reset to run
3456
+ * again (a stream cancelled, failed or waiting on its provider): the
3457
+ * agent's scripts take it as an abandoned end of that stream's turn
3458
+ * (AgentScripts.turnEnded). A quiesce abandons its stream's own turn (or
3459
+ * every turn, when it has none to name), and the host stopping every turn
3460
+ * of the agent's (`'every'`).
3461
+ */
3462
+ private abandonAgentScripts;
3463
+ /**
3464
+ * The agent's turns still live, for its scripts (AgentScripts.turnEnded):
3465
+ * its open logical turn, and the turn of its start in progress, unless
3466
+ * that's `ending`'s or has settled. A start is in progress while it holds
3467
+ * the agent's turn token, from its dequeue through its hooks, compile,
3468
+ * stream and restarts to its settled teardown (activeTurnTokens); its turn
3469
+ * ends at its settle, and the teardown after it, such as its speech's
3470
+ * delivery, is no longer the turn's (settledTurns).
3471
+ */
3472
+ private liveTurns;
3152
3473
  private toMembraneToolResult;
3153
3474
  /**
3154
3475
  * If `data` is an MCP tool-result content array carrying at least one image,
@@ -3174,6 +3495,15 @@ export declare class AgentFramework {
3174
3495
  * result is the spill file, not an over-bound blob in live context).
3175
3496
  */
3176
3497
  private resolveToolResultInlineCap;
3498
+ /**
3499
+ * A tool call's resultMaxChars: how long its result may be and still reach
3500
+ * its caller whole. A call from a running script resolves to the script,
3501
+ * which takes any result that fits its memory (scriptResultMaxChars). Any
3502
+ * other call's result is stored in its agent's context under the agent's
3503
+ * inline cap, and a call for an agent the framework doesn't hold gets the
3504
+ * house default.
3505
+ */
3506
+ private resultMaxCharsFor;
3177
3507
  private approximateDecodedBase64Bytes;
3178
3508
  private sanitizeProcessLogValue;
3179
3509
  /** Writes one inference-log entry. A stream's entries go through its
@@ -3234,25 +3564,44 @@ export declare class AgentFramework {
3234
3564
  * while unregistered. Genuine legacy caller names retain their surface. */
3235
3565
  private canAgentUseTool;
3236
3566
  private agentToolPermissionFailure;
3567
+ /**
3568
+ * A dispatched call answered without running its tool. RFC-007's lifecycle
3569
+ * forgets it, and its result says it was refused (`ToolResult.refused`), both
3570
+ * from here, so the two can't disagree.
3571
+ */
3572
+ private refusedResult;
3237
3573
  /**
3238
3574
  * Why this host refuses a skip_reply call, as the model will read it, or
3239
3575
  * undefined when it doesn't (skipReplyWakeRefusal): without an EventGate,
3240
3576
  * any wake_in_seconds; with one, a wake_in_seconds that isn't a number of
3241
3577
  * seconds. Only when the channel registry handles skip_reply. The dispatch
3242
3578
  * that refuses the call reads it here, and so does the turn's bookkeeping of
3243
- * a refused round, for the model's own calls: the silence before it, which
3244
- * comes back after its round, and in XML mode which round's prose stays
3245
- * private. A skip_reply round's own prose stays private by the tool's name,
3246
- * refused or not.
3579
+ * a refused round (roundCallOf), for the model's calls and a script's calls
3580
+ * that reach the host while a call of the round watches it: the silence
3581
+ * before it, which comes back after its round, and in XML mode which round's
3582
+ * prose stays private. A skip_reply round's own prose stays private by the
3583
+ * tool's name, refused or not.
3247
3584
  */
3248
3585
  private skipReplyRefusal;
3249
3586
  private refusesSelfWake;
3587
+ /**
3588
+ * A call as its round's routing counts it, made directly, or by a script
3589
+ * and reaching the host while a run or wait call of the round watches it
3590
+ * (ScriptRound). A skip_reply refused, because the agent's allowedTools
3591
+ * doesn't name it or because this host can't set the wake it asks for, is
3592
+ * marked refused: it keeps its own round private and silences nothing after
3593
+ * it. A refusal withholds the call's effect, not the model's choice to keep
3594
+ * its words private. Any other call the list refuses posted nothing, so it
3595
+ * gives no cause. A script's call the bridge refuses before dispatch
3596
+ * (`refusedHere`) counts as one the list refuses.
3597
+ */
3598
+ private roundCallOf;
3250
3599
  /**
3251
3600
  * Dispatch a call the agent made. `turnId` is the turn it was made in
3252
3601
  * (TurnRouting.turnId), as its caller knows it: a model's call, the turn
3253
- * whose stream made it; a foreground script's inner call, the turn of the
3254
- * code_execution call whose script is running when the call arrives. A
3255
- * background script's call has none.
3602
+ * whose stream made it; a script's call, the turn of the code_execution
3603
+ * call watching the script when the call reaches the host. A call of a
3604
+ * script left running, which no call watches, has none.
3256
3605
  */
3257
3606
  private dispatchToolCall;
3258
3607
  private dispatchToolCallEvent;
@@ -3291,18 +3640,53 @@ export declare class AgentFramework {
3291
3640
  *
3292
3641
  * So none of a target's entries lands ahead of an earlier one, and a queued
3293
3642
  * tool_use that can't be stored keeps the tool_result queued behind it from
3294
- * being stored alone. (A tool_use that is stored, followed by a tool_result
3295
- * that can't be, stays stored without it until the tool_result lands at a
3296
- * later flush. The only queued pair is puppetToolCall's defensive one,
3297
- * which no path reaches today.) An entry that keeps failing is logged by
3298
- * id at each flush, and holds its target's later queued writes rather than
3299
- * letting them land out of order.
3643
+ * being stored alone, unless context-manager refused it as malformed
3644
+ * (below). (A tool_use that is stored, followed by a tool_result that
3645
+ * can't be, stays stored without it until the tool_result lands at a later
3646
+ * flush, or for good when the store refuses the tool_result as malformed.
3647
+ * The only queued pair is puppetToolCall's, queued only when its turn's
3648
+ * token is no longer its own once the pair is built, which its comment
3649
+ * calls defensive.) An entry that keeps failing is logged by id at each
3650
+ * flush, and holds its target's later queued writes rather than letting
3651
+ * them land out of order.
3652
+ *
3653
+ * An entry context-manager refuses as malformed (MalformedContentError) is
3654
+ * the exception for the store's own validation: context-manager checks
3655
+ * content and every shard before writing. A custom synchronous strategy
3656
+ * hook can throw the same class after append (context-manager #288);
3657
+ * unreadable landing in that callback escape remains a limitation until
3658
+ * the CM follow-up lands. A copy actually found still counts first. Other
3659
+ * ambiguous errors remain queued for ID reconciliation before retry. A
3660
+ * malformed refusal would fail every flush and hold its target's later
3661
+ * writes for good, so it's logged and dropped instead, and its
3662
+ * target isn't cut: left in the un-acked set, the next ack drops it from
3663
+ * the durable queue. A tool_use dropped this way leaves a tool_result
3664
+ * queued behind it to be stored alone. context-manager mends a tool_use
3665
+ * whose input isn't an object, so it refuses one only when that input has
3666
+ * no JSON form or the block itself is malformed. addMessage refuses such
3667
+ * content before it's queued, so an entry meets this here from a queue an
3668
+ * earlier process persisted, as puppetToolCall's pair, which it queues
3669
+ * itself, or when the strategy's chunking splits well-formed content into a
3670
+ * shard the store refuses, which the store's error names.
3300
3671
  *
3301
- * The hold is the queue's alone. A write that isn't deferred is stored at
3302
- * once and can land ahead of a held entry: a fresh tool_result, whatever
3303
- * its agent's state, and any write while its agent's turn, stream and tool
3304
- * cycle are all idle and the host isn't quiesced. So an entry that keeps
3305
- * failing holds only what is deferred behind it.
3672
+ * From a fresh turn's start to the end of its coalescing assembly, before
3673
+ * its checkpoint, every write deferred for its agent lands in that
3674
+ * request, in arrival order, up to one that can't be stored and unless the
3675
+ * host is quiesced (flushForStart). The turn-start flush writes the queue;
3676
+ * while the assembly runs, each write it makes into the agent's own window
3677
+ * (addMessage's bypassDeferralFor) first writes what was deferred since;
3678
+ * and what was deferred during the assembly is written once it ends. A
3679
+ * write the assembly makes while an entry is held waits behind it in the
3680
+ * queue, so the hold covers the assembly's writes too, and so does one
3681
+ * made while the host is quiesced with anything queued for the agent: a
3682
+ * quiesce that begins while an assembly awaits a render lets that turn
3683
+ * drain, and what is queued waits for resume(). Outside that window the
3684
+ * hold is the queue's alone: a write that isn't deferred is stored at once
3685
+ * and can land ahead of a held entry, as a fresh tool_result does whatever
3686
+ * its agent's state, and any write does while its agent's turn, stream and
3687
+ * tool cycle are all idle and the host isn't quiesced. So an entry that
3688
+ * keeps failing holds what is deferred behind it and the assembly's writes
3689
+ * for its agent.
3306
3690
  *
3307
3691
  * A write can throw after its message is stored: a store listener, the
3308
3692
  * strategy's handling of the add, or a later shard of a sharded body can
@@ -3312,24 +3696,28 @@ export declare class AgentFramework {
3312
3696
  * written, at most once: the entry isn't requeued and stored a second
3313
3697
  * time, and what landed, as later compiles render it (asCompiled), is what
3314
3698
  * it returns as the entry's content. For a sharded body, that can be its
3315
- * first shards alone, since the append loop stops at the throw; the rest
3316
- * of the body isn't stored. (Requeued, the
3699
+ * first shards alone if rollback could not remove them; context-manager
3700
+ * from 0.15 otherwise removes shards from a failed append. (Requeued, the
3317
3701
  * landed shards would be stored twice, and only the rest could not be
3318
3702
  * appended later without splitting the body.) Boot's scan for landed
3319
3703
  * writes counts a landed shard the same way. When the store can't be read
3320
- * back (storedCopiesOf logs it), nothing is found, and the entry is put
3321
- * back as one that couldn't be stored: if it had landed, a later flush
3322
- * stores it again.
3704
+ * back (storedCopiesOf logs it), or couldn't say how many messages it held
3705
+ * before the write, whether the entry landed is unknown: it's put back
3706
+ * marked so (`landing`), and before it's written again the store is
3707
+ * searched for its id (landedCopiesById). Found, it counts as written, as
3708
+ * above, at the flush that finds it; not found, it's written; and while
3709
+ * the store can't be searched, it stays queued, holding what's behind it.
3323
3710
  *
3324
3711
  * Returns what was written (stored, or deferred again by addMessage, whose
3325
- * id is then empty), in queue order: for one target, a prefix of its
3326
- * entries. Each comes with its content: as given, unless the store took it
3327
- * as more than one message (a sharded body) and can be read back, when its
3328
- * copies are returned joined, as later compiles render them (asCompiled),
3329
- * or its write threw after storing it (above). `onLanded` hears an entry
3330
- * whose write threw after storing it, with the id it landed under, as soon
3331
- * as it's found: before the writes after it, so whatever it records keeps
3332
- * their order.
3712
+ * id is then empty), in queue order: for one target, its entries up to the
3713
+ * first that couldn't be stored, less entries refused as malformed and dropped. Each comes
3714
+ * with its content: as given, unless the store took it as more than one
3715
+ * message (a sharded body) and can be read back, when its copies are
3716
+ * returned joined, as later compiles render them (asCompiled), or its write
3717
+ * threw after storing it (above). `onLanded` hears an entry whose write
3718
+ * threw after storing it, with the id it landed under, as soon as it's
3719
+ * found: before the writes after it, so whatever it records keeps their
3720
+ * order.
3333
3721
  */
3334
3722
  private writeDrainedInOrder;
3335
3723
  /** How many messages the agent's store holds: undefined when its store
@@ -3338,26 +3726,63 @@ export declare class AgentFramework {
3338
3726
  /** The messages carrying `deferredWriteId` among those the agent's store
3339
3727
  * gained from position `from` on, in store order, with their blobs
3340
3728
  * resolved, as a request carries them. A sharded body's carry its
3341
- * `bodyGroupId`. */
3729
+ * `bodyGroupId`. Undefined when the store can't be read back, which is
3730
+ * logged: not the same as nothing found. */
3342
3731
  private storedCopiesOf;
3732
+ /** The messages carrying `deferredWriteId` anywhere in the agent's store,
3733
+ * found by their id (queryMessages, as landedRow finds a held write's),
3734
+ * so no position is needed. Undefined when the store can't be searched,
3735
+ * which is logged. */
3736
+ private landedCopiesById;
3343
3737
  /** The line naming a drained write that threw: one that couldn't be stored,
3344
- * which is already back in the queue, or, with `landed`, one stored before
3345
- * the throw (for a sharded body, how many of its shards). Logging mustn't
3346
- * fail the flush that met it, so a thrown value that has no text is named
3347
- * as such. */
3738
+ * which is already back in the queue; with 'dropped', a malformed refusal
3739
+ * from the store's pre-write validation (see the CM #288 caveat above);
3740
+ * with a count, one stored before the
3741
+ * throw (for a sharded body, how many of its shards), or, with
3742
+ * `foundLater`, one an earlier write of which landed and was found by its
3743
+ * id; with `'unknown'`, one whose store couldn't be read to tell
3744
+ * whether it landed, back in the queue to be looked up first; and with
3745
+ * `'still-unknown'`, one that still can't be looked up. Logging mustn't
3746
+ * fail the flush that met it, so a thrown value that has no text is
3747
+ * named as such. */
3348
3748
  private logDeferredWriteError;
3749
+ /**
3750
+ * Write what is queued for `agent` into its window past its deferral, in
3751
+ * queue order and cut at a write that fails, though one the store refuses
3752
+ * as malformed is dropped and what follows goes on (writeDrainedInOrder),
3753
+ * between a fresh turn's start and its checkpoint, where what is stored is
3754
+ * the turn's input: at the start, before each write the coalescing
3755
+ * assembly makes for the agent, and once the assembly ends, the last two
3756
+ * not while the host is quiesced, when what is queued waits for resume().
3757
+ * What is stored is weighed for the start now beginning and for every
3758
+ * other resident's open turn. Returns whether anything is still queued for
3759
+ * the agent.
3760
+ */
3761
+ private flushForStart;
3762
+ /** Whether anything is queued for `agentName`, by drainDeferredFor's
3763
+ * target rule. */
3764
+ private queuedFor;
3349
3765
  /** Re-add drained entries through addMessage, which stores each or defers
3350
3766
  * it again, in queue order and cut per target (writeDrainedInOrder). With
3351
3767
  * `bypassDeferral`, each is stored past its target's deferral (stop()). A
3352
3768
  * write that threw after storing missed the notes addMessage takes after a
3353
3769
  * store, so they're taken for what landed as soon as it's found, before
3354
3770
  * the writes after it: an open turn's arrivals keep the order the writes
3355
- * landed in, and its newest stays the newest (remainingArrival). */
3771
+ * landed in, and its newest stays the newest (remainingArrival).
3772
+ *
3773
+ * A target no longer registered (a fork or a run that has ended, here or
3774
+ * before a crash) has no window to land in: a failed reply queued for it,
3775
+ * or a channel notice it could have acted on, becomes the primary's
3776
+ * by-name notice, under the entry's own id and place in the queue
3777
+ * (queuedNoticeForPrimary), and is written with the rest; any other write
3778
+ * is dropped, logged, by addMessage. Nothing here reads the gone agent's
3779
+ * window, so such a notice an earlier write of which landed there, and
3780
+ * which the agent read, goes on too. */
3356
3781
  private readdDrained;
3357
3782
  /**
3358
3783
  * Where a notice about an agent's own action belongs: its failed reply, its
3359
- * bounced prose (beside its `{{unsent}}` clipboard), its background script's
3360
- * wake, the notices about its drafts. Every registered agent's notice is
3784
+ * bounced prose (beside its `{{unsent}}` clipboard), its script's wake, the
3785
+ * notices about its drafts. Every registered agent's notice is
3361
3786
  * addressed to that agent, so it lands in the window that agent reads and
3362
3787
  * waits on that agent's own turn, stream and tool cycle: a conversation
3363
3788
  * fork or an ephemeral run reads only its isolated slot, and a resident's
@@ -3368,9 +3793,10 @@ export declare class AgentFramework {
3368
3793
  * null when the agent is no longer registered (a fork or a run already
3369
3794
  * released): there is no window to write, so the caller writes nothing,
3370
3795
  * traces nothing and requests no wake. The drop is logged here, once. A
3371
- * failed reply is passed on by name instead (passFailedReplyToPrimary). The
3372
- * notice of a channel an agent's own send opened follows the same rule in
3373
- * recordChannelAutoOpenNotice, which passes it on by name too.
3796
+ * failed reply is passed on by name instead (passNoticeToPrimary). The
3797
+ * notices of a channel an agent's own send opened, or a reply couldn't
3798
+ * open, follow the same rule in their builders (channelOpenedNotices,
3799
+ * replyOpenFailedNotices), which pass them on by name too.
3374
3800
  */
3375
3801
  private noticeTargetFor;
3376
3802
  /**
@@ -3379,33 +3805,77 @@ export declare class AgentFramework {
3379
3805
  * (releaseWindowNowOrAfterResume), since a write could land mid-surgery.
3380
3806
  *
3381
3807
  * The agent never reads its window again, so every failed-reply notice it
3382
- * never read is passed to the primary, by name, once: each one stored in
3383
- * its window above its consumed watermark (flushed there at its turn's end,
3384
- * or stored while it was idle) and not heard at a tool boundary, and each
3385
- * one still queued for it. Writes still
3386
- * queued would wait for a boundary it never reaches, and the flush that
3387
- * finds it gone would drop them, so they land in its own window now, which
3388
- * Chronicle keeps for investigation. Its stream is over or cancelled, so it
3389
- * compiles nothing more. One path still stores after these writes: a
3390
- * `complete` that arrived while the agent still waited for tools awaits
3391
- * the spill of its last tool results, and stores them once that resolves,
3392
- * even if a watchdog has ended the run meanwhile. A tool boundary stores
3393
- * nothing for a round whose turn was stopped while its results were
3808
+ * never read, and every channel notice it could act on and never read, is
3809
+ * passed to the primary, by name, once (passesToPrimary,
3810
+ * passOnFromReleasedWindow): each one stored in its window above its
3811
+ * consumed watermark (flushed there at its turn's end, or stored while it
3812
+ * was idle) and not heard at a tool boundary, and each one still queued
3813
+ * for it, pending or un-acked. One with an entry still in the durable
3814
+ * queue goes on only as that entry, under its own id and seq, so a crash
3815
+ * before the ack below replays it once; a copy of it in the window decides
3816
+ * only whether the agent read it. Writes still queued would wait for a
3817
+ * boundary it never reaches, and a flush that finds it gone would drop all
3818
+ * but the notices it passes on, so they land in its own window now, which
3819
+ * Chronicle keeps for investigation. One whose earlier write may have
3820
+ * landed (`landing` unknown) is looked up there by its id first, or, where
3821
+ * the store can't be searched, in the window's own read: found, it isn't
3822
+ * stored again; where neither can see the store, it's stored anyway, with
3823
+ * a line saying it may now be stored twice, or, where storing it fails
3824
+ * too, that it may be stored once, twice or not at all. Its stream is over
3825
+ * or cancelled, or, when stop() ends it, may still run past its cancel, and
3826
+ * then drops each event that comes after the agent has left (driveStream);
3827
+ * a turn of its still assembling or compiling, as when stop() ends it,
3828
+ * drops before it sends anything. One path still stores after these
3829
+ * writes: a `complete` that arrived while the agent still waited for tools
3830
+ * awaits the spill of its last tool results, and stores them once that
3831
+ * resolves, even if a watchdog has ended the run meanwhile. A tool boundary
3832
+ * stores nothing for a round whose turn was stopped while its results were
3394
3833
  * prepared.
3395
3834
  */
3396
3835
  private releaseWindow;
3397
3836
  /**
3398
- * The failed-reply notices stored in `agent`'s window that it never read:
3399
- * those above the lower of its consumed watermark and the point where the
3400
- * watermark's branch and the current one part (branchesPartAt), or every
3401
- * one, when it never compiled. The watermark moves at a compile, and at a
3402
- * tool boundary whose
3403
- * stream declares it carries the messages injected there
3404
- * (markContextConsumed), so a notice the live stream heard is under it, and
3405
- * one a boundary stored without sending (a turn a tool ended, a budget
3406
- * restart, a stream that may drop injections) is above it.
3407
- */
3408
- private unreadFailedReplies;
3837
+ * The part of a released agent's pass to the primary that its release and
3838
+ * stop() share (stop() runs it for a release the quiesce postponed). Each
3839
+ * notice stored in its window that it never read and the primary takes in
3840
+ * its place (passesToPrimary: a failed reply, or a channel notice its
3841
+ * reader could act on) goes on as stored, by name (passNoticeToPrimary),
3842
+ * except a copy of an entry for it still in the durable queue, pending or
3843
+ * un-acked: that entry is the notice's one identity until its ack, the one
3844
+ * boot's check for landed writes knows, so it's the entry that goes on, as
3845
+ * the primary's by-name notice under its own id and seq (`passOn`,
3846
+ * queuedNoticeForPrimary), and a crash before the ack replays it once, not
3847
+ * twice. A queued notice goes on unless the agent read a copy of it that
3848
+ * landed in its window; where the window can't be read, it goes on, since
3849
+ * telling the primary of a notice the agent may have read costs less than
3850
+ * telling no one. Both callers run this before their drain, which hands
3851
+ * pending entries to the un-acked set, so the un-acked entries for the
3852
+ * agent here have all landed (their write went through, or a lookup found
3853
+ * it: settleFound), and they go on here; the pending ones are the
3854
+ * caller's. Returns the window's read, `passOn`, what it has queued so far
3855
+ * for the primary, and how many un-acked entries the agent had.
3856
+ */
3857
+ private passOnFromReleasedWindow;
3858
+ /**
3859
+ * What a released agent's window holds that its pass to the primary reads
3860
+ * (passOnFromReleasedWindow): `unread`, the notices stored there that it
3861
+ * never read and the primary takes in its place (passesToPrimary: its
3862
+ * failed replies, and the channel notices it was told it could act on),
3863
+ * other than copies of the entries `held` names; and `held`, for each of
3864
+ * those entries with a copy there, its copies and whether any of them is
3865
+ * unread. A notice is read below the lower of its consumed watermark and
3866
+ * the point where the watermark's branch and the current one part
3867
+ * (branchesPartAt), and unread everywhere when it has no watermark. The
3868
+ * watermark is set when the agent is created, and moves at a compile, and
3869
+ * at a tool boundary whose stream declares it carries the messages
3870
+ * injected there (markContextConsumed). So a notice such a stream carried
3871
+ * is under it. One a boundary stored without sending (a turn a tool ended,
3872
+ * a budget restart) is above it, and so is one injected into a stream that
3873
+ * doesn't declare it carries injections, which may have dropped it:
3874
+ * counted as unread, it goes to the primary even if the agent heard it,
3875
+ * rather than to no one where the stream dropped it. null when the window
3876
+ * can't be read, which is logged.
3877
+ */
3878
+ private releasedWindow;
3409
3879
  /**
3410
3880
  * The last sequence two branches' histories share: Infinity for one branch,
3411
3881
  * and for two, the point where they part. A branch's records are numbered
@@ -3424,39 +3894,71 @@ export declare class AgentFramework {
3424
3894
  * deregistered, so its stream can't dispatch anything more and resume
3425
3895
  * doesn't weigh its context, and a write addressed to it meanwhile is
3426
3896
  * treated as for any agent no longer registered (dropped, or passed to the
3427
- * primary if it's a failed reply).
3897
+ * primary if it's a failed reply, or a channel notice its reader could act
3898
+ * on).
3428
3899
  */
3429
3900
  private releaseWindowNowOrAfterResume;
3430
3901
  /** resume(): the windows whose release the quiesce window postponed, each on its own. */
3431
3902
  private runReleasesAfterResume;
3432
3903
  /**
3433
- * A fork or an ephemeral run ended before reading that its reply's delivery
3434
- * to a channel failed: it was released with the notice stored in its window
3435
- * unread, or its delivery failed after release. (A notice still queued for
3436
- * it, at release or restored at boot, goes on as the queue entry itself:
3437
- * queuedFailedReplyForPrimary.) Tell the primary instead, naming the
3438
- * speaker, so an agent who can still act learns of it and can tell the
3439
- * human. It gives the reply's length, not its words, which stay in the
3440
- * speaker's window. Its wording follows the speaker's own notice
3441
- * (onRouteFailure): a delivery that wasn't confirmed may have been posted,
3442
- * and neither text says no one saw the reply, since only this channel's
3443
- * routing failed. Only for a delivery to a channel; a reply that had no
3444
- * channel to go to (no locus) had no human waiting for it. Never throws:
3445
- * it runs inside a release, which must complete whatever this write meets.
3446
- */
3447
- private passFailedReplyToPrimary;
3448
- /**
3449
- * A queued failed-reply entry for `speaker`, who is gone, as the primary's
3450
- * by-name notice (passFailedReplyToPrimary's words): the same entry, under
3451
- * its own id and seq, now addressed to the primary. Written through the
3452
- * drain, it lands stamped with that id, or waits in the queue under it, so
3453
- * boot's exactly-once holds for it: a crash before the original's ack
3454
- * replays one entry, never the original and a separate notice. null when no
3455
- * one is told (logged): a reply that had no channel to reach, or no primary.
3456
- */
3457
- private queuedFailedReplyForPrimary;
3904
+ * A fork or an ephemeral run ended before reading a notice the primary
3905
+ * takes in its place (passesToPrimary): it was released with the notice
3906
+ * stored in its window unread, or, for a failed reply, its delivery failed
3907
+ * after release. (A notice still queued for it, at release or restored at
3908
+ * boot, goes on as the queue entry itself: queuedNoticeForPrimary.) Tell
3909
+ * the primary instead, naming the speaker, so an agent who can still act
3910
+ * learns of it (noticeForPrimary). Never throws: it runs inside a release,
3911
+ * which must complete whatever this write meets.
3912
+ */
3913
+ private passNoticeToPrimary;
3914
+ /**
3915
+ * A queued entry for `speaker`, who is gone, that the primary takes in its
3916
+ * place, as the primary's by-name notice (noticeForPrimary): the same
3917
+ * entry, under its own id and seq, now addressed to the primary. Written
3918
+ * through the drain, it lands stamped with that id, or waits in the queue
3919
+ * under it, so boot's exactly-once holds for it: a crash before the
3920
+ * original's ack replays one entry, never the original and a separate
3921
+ * notice. An entry marked as one whose earlier write may have landed
3922
+ * (`landing`) keeps the mark, so before it's written it's looked up by its
3923
+ * id in the primary's window, where it would land now
3924
+ * (writeDrainedInOrder). A release has looked in the speaker's own window
3925
+ * first (releaseWindow). null when no one is told (logged where it's
3926
+ * decided).
3927
+ */
3928
+ private queuedNoticeForPrimary;
3929
+ /**
3930
+ * The primary's by-name notice in place of one `speaker` never read, and
3931
+ * what it's about, as a log line says it: a failed reply's
3932
+ * (failedReplyNoticeForPrimary) or a channel notice's
3933
+ * (channelNoticeForPrimary). null when no one is told, which is logged
3934
+ * where it's decided.
3935
+ */
3936
+ private noticeForPrimary;
3937
+ /**
3938
+ * The primary's by-name notice in place of a channel notice `speaker` was
3939
+ * told it could act on and never read: its builder, called again now that
3940
+ * `speaker` has ended, gives the words it gives an agent that has ended,
3941
+ * judged for the primary, or nothing, logged, with no primary to tell.
3942
+ * They speak of the open or the failure as it was, as the notice did, a
3943
+ * failed one's reason for its selection included, which an agent's
3944
+ * channel_open since replaces in the record and not in the words, and
3945
+ * only of what still holds by each channel's durable decision on its own
3946
+ * server: the registry's (getDesiredState), or before there is one, as at
3947
+ * a serving boot's flush, the lifecycle log's (desiredStateInLog). An
3948
+ * opened channel is kept while it's decided open or tuned out, whatever its
3949
+ * transport is doing at that moment: the decision is what channel_close
3950
+ * changes and what the host carries out once the transport is back, and at
3951
+ * a serving boot no transport is up yet. A failed one is kept only while
3952
+ * it's still decided open and its transport isn't open, since "Not open"
3953
+ * would misstate an open one. One tuned out since is left out too: the
3954
+ * tune-out is a newer decision, by an agent that knows the channel, and
3955
+ * the notice's reason and its channel_open advice, which a tuned-out
3956
+ * channel refuses, would misstate it. With nothing left, no one is told,
3957
+ * logged here.
3958
+ */
3959
+ private channelNoticeForPrimary;
3458
3960
  /** The primary's by-name notice of `speaker`'s failed reply, or null when no
3459
- * one is told, which is logged here (see passFailedReplyToPrimary). */
3961
+ * one is told, which is logged here (see passNoticeToPrimary). */
3460
3962
  private failedReplyNoticeForPrimary;
3461
3963
  /**
3462
3964
  * A channel as a notice names it: the label when the registry has one, since
@@ -3479,17 +3981,18 @@ export declare class AgentFramework {
3479
3981
  * slot (sharedSlotAgents). A write whose target is gone isn't among them:
3480
3982
  * no module reads that agent's store, and the write waits for its window's
3481
3983
  * release (drainDeferredFor) or, at its flush, is dropped (addMessage), a
3482
- * failed reply passing to the primary as its notice
3483
- * (queuedFailedReplyForPrimary).
3984
+ * failed reply, or a channel notice its reader could act on, passing to the
3985
+ * primary as its notice (queuedNoticeForPrimary).
3484
3986
  */
3485
3987
  private heldWritesFor;
3486
3988
  /**
3487
3989
  * The writes held for `reader`'s store (heldWritesFor) as the rows a
3488
- * module's context reads: each under its handle, marked `held`, with the
3489
- * participant, content and metadata it was written with, the time it was
3490
- * first held as its timestamp, and a sequence after every row the store
3491
- * holds, in queue order. The sequence and timestamp are provisional: the
3492
- * stored row has the store's own.
3990
+ * module's context reads: each under its handle, marked `held`, and
3991
+ * `heldFromResidents` too when its metadata carries a tune-out's stamp
3992
+ * (asModuleRow), with the participant, content and metadata it was
3993
+ * written with, the time it was first held as its timestamp, and a
3994
+ * sequence after every row the store holds, in queue order. The sequence
3995
+ * and timestamp are provisional: the stored row has the store's own.
3493
3996
  */
3494
3997
  private heldRows;
3495
3998
  /** The row a held write landed as, found by the id it's stored with
@@ -3497,6 +4000,54 @@ export declare class AgentFramework {
3497
4000
  * as addMessage answers a stored write. Null when it hasn't landed, or is
3498
4001
  * no longer in the store. */
3499
4002
  private landedRow;
4003
+ /**
4004
+ * Settle held writes whose landing is unknown (DeferredWrite.landing),
4005
+ * among those `which` picks, before a path reads or changes held writes:
4006
+ * each is looked up by its id in its target's store (landedCopiesById).
4007
+ * Found, the write landed (settleFound). Not found, the mark goes, and
4008
+ * it's an ordinary held write, which is persisted as an edit is. Where the
4009
+ * store can't be searched, it stays marked, a doubt each path reads by its
4010
+ * own rule.
4011
+ */
4012
+ private settleUnknownLandings;
4013
+ /**
4014
+ * A marked held write found to have landed, as `stored`: it leaves the
4015
+ * pending queue for the un-acked set, as a drained write does, so it stays
4016
+ * in the durable queue until the next ack has synced the store that holds
4017
+ * it, and it's a stored write from then on, so the paths for a landed
4018
+ * write apply to it. It takes the notes a store takes (noteStored), which
4019
+ * its first write missed when it threw, as a flush that finds such a write
4020
+ * takes them (readdDrained), and is logged by its id. It isn't carried
4021
+ * into a turn, as a flush that finds it carries it: the agent reads it at
4022
+ * its next compile, where the store holds it.
4023
+ */
4024
+ private settleFound;
4025
+ /**
4026
+ * A stored row a module names by its id: where it carries the
4027
+ * deferredWriteId of a marked held write the reader's store holds, it's
4028
+ * that write's copy, so the write landed, and it's settled as found
4029
+ * (settleFound) before the row is read or changed. A lookup by the id
4030
+ * can't be needed then, so this holds where the store can't be searched
4031
+ * too.
4032
+ */
4033
+ private settleByCopy;
4034
+ /** A held write whose landing stays unknown after settling, its store
4035
+ * unsearchable, can't be edited or removed: it may already be stored, and
4036
+ * changing only the queued entry could leave its stored copy as it was.
4037
+ * Throws with nothing changed. */
4038
+ private refuseUnsettled;
4039
+ /** Whether the agent has nothing left to read of a deferred write, on
4040
+ * evidence only: the row it landed as is at or below the agent's consumed
4041
+ * watermark on its current branch, or it's in neither the queue (drained
4042
+ * entries not yet stored included) nor the store's current branch:
4043
+ * removed, or left on a branch the agent has switched from, where a turn
4044
+ * now would find nothing of it (switching back brings it back unread,
4045
+ * with no wake, as main's wake spent on this branch leaves it). Any doubt
4046
+ * reads as unread, such as a watermark that a branch switch or an undo
4047
+ * left on another branch, or a store that can't be read: a turn that
4048
+ * finds nothing new costs less than a write no wake brings the agent to
4049
+ * read. */
4050
+ private deferredWriteReadOrGone;
3500
4051
  private editMessage;
3501
4052
  private removeMessage;
3502
4053
  private getMessage;
@@ -3654,80 +4205,132 @@ export declare class AgentFramework {
3654
4205
  * closeAll does. `timeoutMs` bounds the wait without cancelling cleanup. */
3655
4206
  private closeModernMcpConnections;
3656
4207
  /**
3657
- * Reconcile the durable ledger with Chronicle, then deliver every server's
3658
- * work. A drain still running is waited for and then followed by a fresh
3659
- * pass (drainForGeneration). Like the other operator entry points, it's
3660
- * refused once stop() has begun, and stop() waits for one already running.
3661
- * The framework's own branch moves start their delivery without awaiting
3662
- * it (startDiscordAwarenessDelivery).
4208
+ * Deliver every server's queued awareness operations now (or only
4209
+ * `onlyServerId`'s) and wait for this pass, and for a pass already under
4210
+ * way on a server, whose last request may still be on the wire with
4211
+ * nothing left due. Like the other operator entry points, it's refused
4212
+ * once stop() has begun, and stop() waits for one already running.
4213
+ * Delivery never gates MCPL traffic or turns: the framework's own
4214
+ * deliveries run in the background (deliverDiscordAwarenessInBackground).
4215
+ * A server that is not connected is skipped (its work stays queued until
4216
+ * it connects).
3663
4217
  */
3664
4218
  syncDiscordAwarenessMarkers(onlyServerId?: string): Promise<void>;
3665
- /** The sync's work. It installs the MCPL data-plane gate before its first
3666
- * await, so a caller that starts it while holding the store puts the gate
3667
- * up before releasing the store. */
4219
+ /** One delivery pass over every server with due work, or only `onlyServerId`'s. */
3668
4220
  private runDiscordAwarenessSync;
4221
+ /**
4222
+ * Finish the removals of every suppression pending on the active branch
4223
+ * (an interrupted surgery's, or a version 2 ledger's that 0.22.x never
4224
+ * activated). Its batch is then retired, none of its marks sent, and
4225
+ * reported with the redo that applies them (reportRetiredAwareness): a
4226
+ * start never activates a surgery's marks. An interval whose messages are
4227
+ * only partly present can't be finished safely, and stops the start.
4228
+ */
3669
4229
  private resumePreparedDiscordSuppressions;
3670
4230
  /**
3671
- * Deliver every due ref independently. Permanent Discord failures are kept
3672
- * in the ledger for audit but do not block later operations; retryable
3673
- * failures remain pending for the next reconnect/list-change attempt.
3674
- * Once stop() has begun, a drain sends nothing more and records nothing
3675
- * for what it hasn't sent: that stays pending, as it was, for the next
3676
- * start's barrier. stop() closes the connections and then waits for each
3677
- * drain still running to record the call it had in flight.
4231
+ * The start's reconciliation of the awareness ledger, before any
4232
+ * delivery. It derives nothing from branch ancestry and activates nothing
4233
+ * (recoverAtStartup): a batch an interrupted surgery left is retired, none
4234
+ * of its marks sent, except a suppression whose removals are pending, which
4235
+ * a start on its branch finishes (resumePreparedDiscordSuppressions); a
4236
+ * request the previous process left on the wire is recorded unanswered. No
4237
+ * content is read. Before it writes any of that, it logs what it does,
4238
+ * reports each retirement (reportRetiredAwareness) and raises the delivery
4239
+ * alert for reactions that reach the bound: each is written once, so a
4240
+ * notice given after the write would be lost for good if the write landed
4241
+ * and the process ended before the notice. A ledger it can't read stops
4242
+ * the start: it can't tell whether a suppression's body is pending.
4243
+ */
4244
+ private reconcileDiscordAwarenessAtStartup;
4245
+ /** What a start's reconciliation retires and records unanswered, before it is written. */
4246
+ private announceDiscordAwarenessRecovery;
4247
+ /**
4248
+ * A version 2 ledger's rewrite as version 3, before it is written (the
4249
+ * outbox's announceImport): the work agent-framework 0.22.x had still to
4250
+ * do is never sent, since nobody chose it, and the batches it never
4251
+ * activated are retired (a suppression whose body may be pending, once a
4252
+ * start on its branch finishes the body). A retract of a batch 0.22.x
4253
+ * activated takes off the mark of the batch's emoji from each of its
4254
+ * messages, whichever batch placed it.
4255
+ */
4256
+ private announceDiscordAwarenessImport;
4257
+ /**
4258
+ * Report a batch a start retires, before that is recorded, with the redo
4259
+ * that applies what was lost: the
4260
+ * surgery again from its source, if that still has every message the
4261
+ * surgery removed (a hide there, or the source's deletion, changes that),
4262
+ * onto a new branch name, choosing marks again (framework.switchBranch,
4263
+ * then rollbackToMessage or suppressMessages; offline, the recover CLI).
4264
+ * A batch doesn't say which surgery made it: an offline recovery's reads
4265
+ * as a rollback's, or as a suppression's when the recovery suppressed, so
4266
+ * the report names both. One with marks not applied raises an ops alert;
4267
+ * one without (no marks chosen, or its marks cancelled) is only logged.
4268
+ */
4269
+ private reportRetiredAwareness;
4270
+ /**
4271
+ * Deliver one server's owed awareness requests, one at a time, oldest act
4272
+ * first. Every request is written ahead to the ledger before it can leave,
4273
+ * and its answer is recorded from what the connection can actually know
4274
+ * (McplRequestError.outcome): a request that was never written stays
4275
+ * owed, one written and never answered may land, and a Discord answer is
4276
+ * definitive (permanent when Discord says the message or channel is gone
4277
+ * or inaccessible). A server that is not connected is skipped: its work
4278
+ * simply stays queued.
3678
4279
  */
3679
4280
  private drainDiscordAwarenessOutbox;
3680
- private readDiscordAwarenessPending;
3681
- private writeDiscordAwarenessSuccess;
3682
- private writeDiscordAwarenessFailure;
3683
- private beginDiscordAwarenessBarrier;
3684
- /**
3685
- * One server's drain for a new generation: a gate completes only after
3686
- * every operation pending when it was armed has been attempted. A drain
3687
- * already running can't promise that. It never re-sends a key it has
3688
- * attempted, so an operation re-pended while it runs (a rollback, its undo,
3689
- * then a redo, all mid-drain) stays pending, and it may already have made
3690
- * its last read of the ledger, missing a batch activated since. So a
3691
- * generation that finds a drain running waits for it, then drains again
3692
- * with a fresh pass that reads the ledger anew. Two generations waiting on
3693
- * the same drain share the fresh pass that follows it. Once stop() has
3694
- * begun, a drain sends nothing more, so a gate armed then completes with
3695
- * what it found pending left for the next start.
3696
- */
3697
- private drainForGeneration;
3698
- /**
3699
- * Wait out the awareness gate for an inbound event: the generation current
3700
- * now, and any generation installed while waiting, until none is current
3701
- * or the current one is one already waited for. A handler that waited only
3702
- * for the generation it first saw would go on behind a newer one armed
3703
- * meanwhile. Rejects as the generation it waited for rejects.
3704
- */
3705
- private awaitDiscordAwarenessBarriers;
4281
+ /**
4282
+ * One pass of drainDiscordAwarenessOutbox. It leaves the registry in the
4283
+ * microtasks that follow its last claim, a claim that found nothing owed,
4284
+ * so a registered pass always has a claim ahead of it or running: a
4285
+ * trigger that joins it is served by it, unless its route goes away or
4286
+ * stop() begins first, when the pass stops claiming and the work stays
4287
+ * queued for the next pass. Within a pass, a request is claimed once; a
4288
+ * trigger that joined it also has what the pass already tried claimed
4289
+ * once more before it leaves, so an operator's sync, a retract or a
4290
+ * reconnect meeting a running pass doesn't leave a retryable mark untried. A request made owed after its last claim
4291
+ * starts a new pass: the act that makes it owed runs after that claim's,
4292
+ * and resolves only once its write is on disk, by when the pass has left.
4293
+ * Leaving any later, when its promise settles, would let a request join a
4294
+ * pass that will never claim again, and that work would stay due until
4295
+ * some unrelated trigger.
4296
+ */
4297
+ private runDiscordAwarenessDrain;
4298
+ private readDiscordAwarenessDue;
4299
+ /**
4300
+ * Open MCPL connections' planes (every connection when none is given). A
4301
+ * connection whose policy exchange is in flight stays closed, both planes,
4302
+ * until its grant exists: its exchange's caller opens it once that settles
4303
+ * (mcplPlanesMayOpen). A quiesced host (issue #122) opens only control
4304
+ * planes, so data planes stay held for the whole maintenance window;
4305
+ * resume() calls this again once the flag is cleared. Otherwise a control
4306
+ * plane comes up even while quiesced, since host/command (and with it
4307
+ * resume) rides it.
4308
+ */
4309
+ private readyMcplPlanes;
3706
4310
  /**
3707
4311
  * Per connection, the transport epoch whose §5.3 policy exchange is in
3708
4312
  * flight: a connect's, from when the registry hands the connection back,
3709
4313
  * or a reconnect's, from its 'reconnect' event. Until the exchange settles,
3710
- * that transport's traffic must wait for its grant, so a gate that opens
3711
- * every connection's planes meanwhile (another server's list change, a
3712
- * resume, an awareness sync, startup's staged open) passes it by
3713
- * (mcplPlanesMayOpen), and the exchange's own caller opens them once it
3714
- * settles (openMcplPlanesAfterExchange).
4314
+ * that transport's traffic must wait for its grant, so readyMcplPlanes,
4315
+ * which a resume and startup's staged open run over every connection,
4316
+ * passes it by (mcplPlanesMayOpen), and the exchange's own caller opens its
4317
+ * planes once it settles.
3715
4318
  */
3716
4319
  private readonly mcplPolicyExchanges;
3717
- /** Whether a gate may open this connection's planes: no policy exchange is
3718
- * in flight on its current transport (see mcplPolicyExchanges). */
4320
+ /** Whether readyMcplPlanes may open this connection's planes: no policy
4321
+ * exchange is in flight on its current transport (see mcplPolicyExchanges). */
3719
4322
  private mcplPlanesMayOpen;
3720
4323
  /**
3721
4324
  * Run a connection's §5.3 policy exchange with its planes held: it is
3722
- * marked in flight for the transport it runs on, so no gate releases that
3723
- * transport's traffic before its grant exists. With `epoch`, it runs only
3724
- * on that transport: a runtime connect passes the one it registered, and
3725
- * if that transport is gone, the exchange isn't run, since a reconnect
4325
+ * marked in flight for the transport it runs on, so no opener releases
4326
+ * that transport's traffic before its grant exists. With `epoch`, it runs
4327
+ * only on that transport: a runtime connect passes the one it registered,
4328
+ * and if that transport is gone, the exchange isn't run, since a reconnect
3726
4329
  * that adopts a next transport, if one comes, runs that one's. With
3727
4330
  * `closeOnFailure`, as for a runtime connect or restart, an exchange that
3728
4331
  * throws closes the connection for good, through the registry, before it
3729
4332
  * lifts the marker: left live, the connection would be half registered,
3730
- * and unmarked before its close, a gate completing in between would let
4333
+ * and unmarked before its close, an opener running in between would let
3731
4334
  * out what it held with no grant. A close that fails keeps the connection
3732
4335
  * registered, but closed for good, it readies nothing but its own reports.
3733
4336
  * Without `closeOnFailure`, as for a reconnect or a staged startup connect,
@@ -3735,32 +4338,6 @@ export declare class AgentFramework {
3735
4338
  * reached, empty if the policy step itself threw, and the marker lifts.
3736
4339
  */
3737
4340
  private settlePolicyExchange;
3738
- /**
3739
- * Open a connection's planes once its exchange has settled, when the gate
3740
- * its connect or reconnect installed was replaced during the exchange: the
3741
- * newer gate passed the connection by, and if it has completed, nothing
3742
- * else would open it. A connection whose transport dropped meanwhile is
3743
- * readied as any gate readies one between transports, so its own reports
3744
- * go on. How far follows what is held now: while a gate is up, only the
3745
- * control plane opens, since a gate holds data planes alone, and its
3746
- * completion, which no longer passes this connection by, opens the data
3747
- * plane; a quiesced host (issue #122) likewise opens only control planes;
3748
- * otherwise both open.
3749
- */
3750
- private openMcplPlanesAfterExchange;
3751
- /**
3752
- * Install one framework-global Discord-awareness generation before releasing
3753
- * any inference-bearing event. With pending work or a drain still running,
3754
- * every MCPL data plane is paused while the control planes remain live,
3755
- * but for a connection whose policy exchange is in flight, which neither
3756
- * the release nor the completion opens (mcplPlanesMayOpen).
3757
- * With neither, ready() runs synchronously so request responders preserve
3758
- * their historical same-stack behavior.
3759
- */
3760
- private installMcplDataPlaneGate;
3761
- private releaseMcplDataPlaneGate;
3762
- private completeMcplDataPlaneGate;
3763
- private failMcplDataPlaneGate;
3764
4341
  /**
3765
4342
  * Close a legacy connection for good through the registry. A close that
3766
4343
  * can't confirm its child exited keeps the connection registered, holding
@@ -3840,6 +4417,13 @@ export declare class AgentFramework {
3840
4417
  * disconnect are resumed, not reset.
3841
4418
  */
3842
4419
  private registerMcplServerFeatures;
4420
+ /**
4421
+ * Whether this server's child takes the framework's protective reaction
4422
+ * default: a stdio server with no baseline declared in its env or
4423
+ * inherited from the host. Only such a connect reads the awareness
4424
+ * ledger (getPlacedReactionBaseline).
4425
+ */
4426
+ private derivesReactionBaseline;
3843
4427
  /**
3844
4428
  * Snapshot the protective Discord reaction default for this deployment, as
3845
4429
  * suppression tokens: the forms the Discord adapter's suppression matcher
@@ -4060,8 +4644,7 @@ export declare class AgentFramework {
4060
4644
  * A list change, including the relist after a reconnect, takes the legacy
4061
4645
  * engine's refresh path (`handleToolsListChanged`), so any wake it causes
4062
4646
  * goes through ordinary admission: it parks under quiesce or a hold like
4063
- * every other wake. It installs no awareness gate, since that gate orders
4064
- * MCPL data-plane traffic, which this family doesn't carry.
4647
+ * every other wake.
4065
4648
  */
4066
4649
  private wireModernEvents;
4067
4650
  /** An MCP tool call's trace: a result the server marked an error (or one
@@ -4113,6 +4696,9 @@ export declare class AgentFramework {
4113
4696
  * is in flight (mcpServerOps) or a restart holds the id, and "gone"
4114
4697
  * otherwise. */
4115
4698
  private mcplServerAbsentText;
4699
+ /** Whether a connect of this server id is in flight (mcpServerOps), or a
4700
+ * restart holds the id: this host is connecting to it. */
4701
+ private mcplConnectInFlight;
4116
4702
  /** A modern connection a connect still under way registered: it registers
4117
4703
  * before it starts, so until its first session is up it's no server to
4118
4704
  * call, and a call reads the "connecting" text, as one during a legacy
@@ -4189,9 +4775,10 @@ export declare class AgentFramework {
4189
4775
  * every sibling in the round to settle; if one never does, fail closed
4190
4776
  * rather than trust an index the batch may still change. Sibling saves
4191
4777
  * produce no images and are not waited on (two saves in one batch would
4192
- * otherwise deadlock into a double timeout). Script-inner calls
4193
- * (`pytc-…`) run sequentially inside their script host and skip the
4194
- * barrier — the host call itself is the only pending sibling they'd see.
4778
+ * otherwise deadlock into a double timeout). A script's own calls
4779
+ * (`pytc-…`) skip the barrier: the batch's pending siblings include the
4780
+ * code_execution call running that script, so waiting on them would wait
4781
+ * on itself.
4195
4782
  */
4196
4783
  private awaitSiblingToolCalls;
4197
4784
  /**