@animalabs/agent-framework 0.23.3 → 0.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. package/README.md +212 -42
  2. package/dist/src/agent.d.ts +65 -9
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +98 -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/clock-rows.d.ts +115 -0
  10. package/dist/src/clock-rows.d.ts.map +1 -0
  11. package/dist/src/clock-rows.js +222 -0
  12. package/dist/src/clock-rows.js.map +1 -0
  13. package/dist/src/code-execution/engine.d.ts +177 -0
  14. package/dist/src/code-execution/engine.d.ts.map +1 -0
  15. package/dist/src/code-execution/engine.js +494 -0
  16. package/dist/src/code-execution/engine.js.map +1 -0
  17. package/dist/src/code-execution/index.d.ts +5 -10
  18. package/dist/src/code-execution/index.d.ts.map +1 -1
  19. package/dist/src/code-execution/index.js +5 -9
  20. package/dist/src/code-execution/index.js.map +1 -1
  21. package/dist/src/code-execution/isolate/calls.d.ts +114 -0
  22. package/dist/src/code-execution/isolate/calls.d.ts.map +1 -0
  23. package/dist/src/code-execution/isolate/calls.js +145 -0
  24. package/dist/src/code-execution/isolate/calls.js.map +1 -0
  25. package/dist/src/code-execution/isolate/child-entry.d.ts +2 -0
  26. package/dist/src/code-execution/isolate/child-entry.d.ts.map +1 -0
  27. package/dist/src/code-execution/isolate/child-entry.js +5 -0
  28. package/dist/src/code-execution/isolate/child-entry.js.map +1 -0
  29. package/dist/src/code-execution/isolate/child-main.d.ts +26 -0
  30. package/dist/src/code-execution/isolate/child-main.d.ts.map +1 -0
  31. package/dist/src/code-execution/isolate/child-main.js +132 -0
  32. package/dist/src/code-execution/isolate/child-main.js.map +1 -0
  33. package/dist/src/code-execution/isolate/child.d.ts +44 -0
  34. package/dist/src/code-execution/isolate/child.d.ts.map +1 -0
  35. package/dist/src/code-execution/isolate/child.js +315 -0
  36. package/dist/src/code-execution/isolate/child.js.map +1 -0
  37. package/dist/src/code-execution/isolate/frames.d.ts +80 -0
  38. package/dist/src/code-execution/isolate/frames.d.ts.map +1 -0
  39. package/dist/src/code-execution/isolate/frames.js +210 -0
  40. package/dist/src/code-execution/isolate/frames.js.map +1 -0
  41. package/dist/src/code-execution/isolate/output.d.ts +68 -0
  42. package/dist/src/code-execution/isolate/output.d.ts.map +1 -0
  43. package/dist/src/code-execution/isolate/output.js +143 -0
  44. package/dist/src/code-execution/isolate/output.js.map +1 -0
  45. package/dist/src/code-execution/isolate/prelude.d.ts +109 -0
  46. package/dist/src/code-execution/isolate/prelude.d.ts.map +1 -0
  47. package/dist/src/code-execution/isolate/prelude.js +401 -0
  48. package/dist/src/code-execution/isolate/prelude.js.map +1 -0
  49. package/dist/src/code-execution/isolate/protocol.d.ts +151 -0
  50. package/dist/src/code-execution/isolate/protocol.d.ts.map +1 -0
  51. package/dist/src/code-execution/isolate/protocol.js +150 -0
  52. package/dist/src/code-execution/isolate/protocol.js.map +1 -0
  53. package/dist/src/code-execution/isolate/render.d.ts +57 -0
  54. package/dist/src/code-execution/isolate/render.d.ts.map +1 -0
  55. package/dist/src/code-execution/isolate/render.js +214 -0
  56. package/dist/src/code-execution/isolate/render.js.map +1 -0
  57. package/dist/src/code-execution/isolate/runner.d.ts +250 -0
  58. package/dist/src/code-execution/isolate/runner.d.ts.map +1 -0
  59. package/dist/src/code-execution/isolate/runner.js +854 -0
  60. package/dist/src/code-execution/isolate/runner.js.map +1 -0
  61. package/dist/src/code-execution/isolate/scripts.d.ts +175 -0
  62. package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -0
  63. package/dist/src/code-execution/isolate/scripts.js +357 -0
  64. package/dist/src/code-execution/isolate/scripts.js.map +1 -0
  65. package/dist/src/code-execution/quickjs.wasm +0 -0
  66. package/dist/src/code-execution/tool-definition.d.ts +93 -43
  67. package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
  68. package/dist/src/code-execution/tool-definition.js +176 -142
  69. package/dist/src/code-execution/tool-definition.js.map +1 -1
  70. package/dist/src/deadline-timer.d.ts +3 -0
  71. package/dist/src/deadline-timer.d.ts.map +1 -1
  72. package/dist/src/deadline-timer.js +1 -1
  73. package/dist/src/deadline-timer.js.map +1 -1
  74. package/dist/src/framework.d.ts +1120 -457
  75. package/dist/src/framework.d.ts.map +1 -1
  76. package/dist/src/framework.js +4635 -2505
  77. package/dist/src/framework.js.map +1 -1
  78. package/dist/src/gate/event-gate.d.ts +28 -4
  79. package/dist/src/gate/event-gate.d.ts.map +1 -1
  80. package/dist/src/gate/event-gate.js +89 -13
  81. package/dist/src/gate/event-gate.js.map +1 -1
  82. package/dist/src/held-writes.d.ts +16 -3
  83. package/dist/src/held-writes.d.ts.map +1 -1
  84. package/dist/src/held-writes.js +16 -3
  85. package/dist/src/held-writes.js.map +1 -1
  86. package/dist/src/index.d.ts +8 -6
  87. package/dist/src/index.d.ts.map +1 -1
  88. package/dist/src/index.js +10 -8
  89. package/dist/src/index.js.map +1 -1
  90. package/dist/src/mcpl/channel-registry.d.ts +483 -115
  91. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  92. package/dist/src/mcpl/channel-registry.js +1735 -425
  93. package/dist/src/mcpl/channel-registry.js.map +1 -1
  94. package/dist/src/mcpl/conversation-router.d.ts +19 -39
  95. package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
  96. package/dist/src/mcpl/conversation-router.js +27 -59
  97. package/dist/src/mcpl/conversation-router.js.map +1 -1
  98. package/dist/src/mcpl/convert-block.d.ts.map +1 -1
  99. package/dist/src/mcpl/convert-block.js +9 -5
  100. package/dist/src/mcpl/convert-block.js.map +1 -1
  101. package/dist/src/mcpl/inbound-source.d.ts +50 -0
  102. package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
  103. package/dist/src/mcpl/inbound-source.js +130 -0
  104. package/dist/src/mcpl/inbound-source.js.map +1 -1
  105. package/dist/src/mcpl/index.d.ts +2 -1
  106. package/dist/src/mcpl/index.d.ts.map +1 -1
  107. package/dist/src/mcpl/index.js +3 -2
  108. package/dist/src/mcpl/index.js.map +1 -1
  109. package/dist/src/mcpl/log-value.d.ts +6 -0
  110. package/dist/src/mcpl/log-value.d.ts.map +1 -1
  111. package/dist/src/mcpl/log-value.js +8 -0
  112. package/dist/src/mcpl/log-value.js.map +1 -1
  113. package/dist/src/mcpl/modern-connection.d.ts +15 -6
  114. package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
  115. package/dist/src/mcpl/modern-connection.js +168 -53
  116. package/dist/src/mcpl/modern-connection.js.map +1 -1
  117. package/dist/src/mcpl/prose-grammar.d.ts +4 -5
  118. package/dist/src/mcpl/prose-grammar.d.ts.map +1 -1
  119. package/dist/src/mcpl/prose-grammar.js +4 -5
  120. package/dist/src/mcpl/prose-grammar.js.map +1 -1
  121. package/dist/src/mcpl/protocol-family.d.ts +97 -10
  122. package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
  123. package/dist/src/mcpl/protocol-family.js +174 -17
  124. package/dist/src/mcpl/protocol-family.js.map +1 -1
  125. package/dist/src/mcpl/push-coalescer.d.ts +132 -14
  126. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  127. package/dist/src/mcpl/push-coalescer.js +227 -50
  128. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  129. package/dist/src/mcpl/push-handler.d.ts +9 -20
  130. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  131. package/dist/src/mcpl/push-handler.js +7 -49
  132. package/dist/src/mcpl/push-handler.js.map +1 -1
  133. package/dist/src/mcpl/reference-fetcher.d.ts +2 -2
  134. package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
  135. package/dist/src/mcpl/reference-fetcher.js +4 -4
  136. package/dist/src/mcpl/reference-fetcher.js.map +1 -1
  137. package/dist/src/mcpl/server-connection.d.ts +50 -21
  138. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  139. package/dist/src/mcpl/server-connection.js +158 -74
  140. package/dist/src/mcpl/server-connection.js.map +1 -1
  141. package/dist/src/mcpl/tags.d.ts +24 -0
  142. package/dist/src/mcpl/tags.d.ts.map +1 -1
  143. package/dist/src/mcpl/tags.js +33 -0
  144. package/dist/src/mcpl/tags.js.map +1 -1
  145. package/dist/src/mcpl/tool-result-normalize.d.ts +2 -1
  146. package/dist/src/mcpl/tool-result-normalize.d.ts.map +1 -1
  147. package/dist/src/mcpl/tool-result-normalize.js.map +1 -1
  148. package/dist/src/mcpl/transport.d.ts +55 -7
  149. package/dist/src/mcpl/transport.d.ts.map +1 -1
  150. package/dist/src/mcpl/transport.js +163 -34
  151. package/dist/src/mcpl/transport.js.map +1 -1
  152. package/dist/src/mcpl/types.d.ts +22 -6
  153. package/dist/src/mcpl/types.d.ts.map +1 -1
  154. package/dist/src/mcpl/types.js.map +1 -1
  155. package/dist/src/module-registry.d.ts +4 -2
  156. package/dist/src/module-registry.d.ts.map +1 -1
  157. package/dist/src/module-registry.js +100 -13
  158. package/dist/src/module-registry.js.map +1 -1
  159. package/dist/src/modules/discord/index.d.ts.map +1 -1
  160. package/dist/src/modules/discord/index.js +8 -13
  161. package/dist/src/modules/discord/index.js.map +1 -1
  162. package/dist/src/modules/history/index.d.ts.map +1 -1
  163. package/dist/src/modules/history/index.js +27 -4
  164. package/dist/src/modules/history/index.js.map +1 -1
  165. package/dist/src/modules/history/semantic.d.ts +15 -3
  166. package/dist/src/modules/history/semantic.d.ts.map +1 -1
  167. package/dist/src/modules/history/semantic.js +27 -5
  168. package/dist/src/modules/history/semantic.js.map +1 -1
  169. package/dist/src/modules/index.d.ts +1 -1
  170. package/dist/src/modules/index.d.ts.map +1 -1
  171. package/dist/src/modules/index.js.map +1 -1
  172. package/dist/src/modules/unknown-tool.d.ts +4 -1
  173. package/dist/src/modules/unknown-tool.d.ts.map +1 -1
  174. package/dist/src/modules/unknown-tool.js +4 -1
  175. package/dist/src/modules/unknown-tool.js.map +1 -1
  176. package/dist/src/modules/workspace/branch-intent.d.ts +3 -1
  177. package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
  178. package/dist/src/modules/workspace/branch-intent.js +3 -1
  179. package/dist/src/modules/workspace/branch-intent.js.map +1 -1
  180. package/dist/src/modules/workspace/edit-plan.d.ts +265 -0
  181. package/dist/src/modules/workspace/edit-plan.d.ts.map +1 -0
  182. package/dist/src/modules/workspace/edit-plan.js +794 -0
  183. package/dist/src/modules/workspace/edit-plan.js.map +1 -0
  184. package/dist/src/modules/workspace/edit-text.d.ts +117 -0
  185. package/dist/src/modules/workspace/edit-text.d.ts.map +1 -0
  186. package/dist/src/modules/workspace/edit-text.js +584 -0
  187. package/dist/src/modules/workspace/edit-text.js.map +1 -0
  188. package/dist/src/modules/workspace/effects.d.ts +5 -4
  189. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  190. package/dist/src/modules/workspace/effects.js +78 -25
  191. package/dist/src/modules/workspace/effects.js.map +1 -1
  192. package/dist/src/modules/workspace/index.d.ts +493 -62
  193. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  194. package/dist/src/modules/workspace/index.js +2216 -652
  195. package/dist/src/modules/workspace/index.js.map +1 -1
  196. package/dist/src/modules/workspace/observe.d.ts +213 -38
  197. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  198. package/dist/src/modules/workspace/observe.js +416 -36
  199. package/dist/src/modules/workspace/observe.js.map +1 -1
  200. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  201. package/dist/src/modules/workspace/reconcile.js +15 -8
  202. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  203. package/dist/src/modules/workspace/text.d.ts +32 -0
  204. package/dist/src/modules/workspace/text.d.ts.map +1 -0
  205. package/dist/src/modules/workspace/text.js +67 -0
  206. package/dist/src/modules/workspace/text.js.map +1 -0
  207. package/dist/src/modules/workspace/types.d.ts +210 -6
  208. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  209. package/dist/src/modules/workspace/types.js.map +1 -1
  210. package/dist/src/modules/workspace/watcher.d.ts +3 -2
  211. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  212. package/dist/src/modules/workspace/watcher.js.map +1 -1
  213. package/dist/src/operator-log.d.ts +52 -24
  214. package/dist/src/operator-log.d.ts.map +1 -1
  215. package/dist/src/operator-log.js.map +1 -1
  216. package/dist/src/recovery/discord-awareness-outbox.d.ts +496 -72
  217. package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
  218. package/dist/src/recovery/discord-awareness-outbox.js +1196 -289
  219. package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
  220. package/dist/src/recovery/offline-branch.d.ts +26 -1
  221. package/dist/src/recovery/offline-branch.d.ts.map +1 -1
  222. package/dist/src/recovery/offline-branch.js +164 -39
  223. package/dist/src/recovery/offline-branch.js.map +1 -1
  224. package/dist/src/recovery/recover-cli.js +23 -4
  225. package/dist/src/recovery/recover-cli.js.map +1 -1
  226. package/dist/src/send-tools.d.ts +11 -0
  227. package/dist/src/send-tools.d.ts.map +1 -0
  228. package/dist/src/send-tools.js +11 -0
  229. package/dist/src/send-tools.js.map +1 -0
  230. package/dist/src/timezone.d.ts +4 -2
  231. package/dist/src/timezone.d.ts.map +1 -1
  232. package/dist/src/timezone.js +4 -2
  233. package/dist/src/timezone.js.map +1 -1
  234. package/dist/src/tool-image-ledger.d.ts +46 -7
  235. package/dist/src/tool-image-ledger.d.ts.map +1 -1
  236. package/dist/src/tool-image-ledger.js +60 -7
  237. package/dist/src/tool-image-ledger.js.map +1 -1
  238. package/dist/src/tool-result-guard.d.ts +14 -11
  239. package/dist/src/tool-result-guard.d.ts.map +1 -1
  240. package/dist/src/tool-result-guard.js +17 -14
  241. package/dist/src/tool-result-guard.js.map +1 -1
  242. package/dist/src/tool-result-history.d.ts +3 -2
  243. package/dist/src/tool-result-history.d.ts.map +1 -1
  244. package/dist/src/tool-result-history.js +3 -2
  245. package/dist/src/tool-result-history.js.map +1 -1
  246. package/dist/src/tune-out/coordinator.d.ts +21 -0
  247. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  248. package/dist/src/tune-out/coordinator.js +142 -40
  249. package/dist/src/tune-out/coordinator.js.map +1 -1
  250. package/dist/src/types/agent.d.ts +31 -6
  251. package/dist/src/types/agent.d.ts.map +1 -1
  252. package/dist/src/types/events.d.ts +66 -9
  253. package/dist/src/types/events.d.ts.map +1 -1
  254. package/dist/src/types/framework.d.ts +69 -62
  255. package/dist/src/types/framework.d.ts.map +1 -1
  256. package/dist/src/types/module.d.ts +40 -8
  257. package/dist/src/types/module.d.ts.map +1 -1
  258. package/dist/src/types/trace.d.ts +111 -10
  259. package/dist/src/types/trace.d.ts.map +1 -1
  260. package/dist/src/usage/types.d.ts +16 -0
  261. package/dist/src/usage/types.d.ts.map +1 -1
  262. package/dist/src/usage/usage-tracker.d.ts +14 -1
  263. package/dist/src/usage/usage-tracker.d.ts.map +1 -1
  264. package/dist/src/usage/usage-tracker.js +81 -41
  265. package/dist/src/usage/usage-tracker.js.map +1 -1
  266. package/package.json +6 -8
  267. package/src/agent.ts +99 -12
  268. package/src/api/server.ts +14 -12
  269. package/src/clock-rows.ts +302 -0
  270. package/src/code-execution/engine.ts +595 -0
  271. package/src/code-execution/index.ts +5 -17
  272. package/src/code-execution/isolate/calls.ts +199 -0
  273. package/src/code-execution/isolate/child-entry.ts +5 -0
  274. package/src/code-execution/isolate/child-main.ts +132 -0
  275. package/src/code-execution/isolate/child.ts +327 -0
  276. package/src/code-execution/isolate/frames.ts +209 -0
  277. package/src/code-execution/isolate/output.ts +161 -0
  278. package/src/code-execution/isolate/prelude.ts +409 -0
  279. package/src/code-execution/isolate/protocol.ts +240 -0
  280. package/src/code-execution/isolate/render.ts +230 -0
  281. package/src/code-execution/isolate/runner.ts +911 -0
  282. package/src/code-execution/isolate/scripts.ts +479 -0
  283. package/src/code-execution/quickjs.wasm +0 -0
  284. package/src/code-execution/quickjs.wasm.LICENSES +149 -0
  285. package/src/code-execution/tool-definition.ts +236 -167
  286. package/src/deadline-timer.ts +1 -1
  287. package/src/framework.ts +4978 -2671
  288. package/src/gate/event-gate.ts +79 -17
  289. package/src/held-writes.ts +17 -3
  290. package/src/index.ts +32 -22
  291. package/src/mcpl/channel-registry.ts +1892 -471
  292. package/src/mcpl/conversation-router.ts +26 -72
  293. package/src/mcpl/convert-block.ts +9 -5
  294. package/src/mcpl/inbound-source.ts +131 -0
  295. package/src/mcpl/index.ts +4 -2
  296. package/src/mcpl/log-value.ts +9 -0
  297. package/src/mcpl/modern-connection.ts +162 -53
  298. package/src/mcpl/prose-grammar.ts +4 -5
  299. package/src/mcpl/protocol-family.ts +200 -22
  300. package/src/mcpl/push-coalescer.ts +306 -62
  301. package/src/mcpl/push-handler.ts +12 -54
  302. package/src/mcpl/reference-fetcher.ts +4 -4
  303. package/src/mcpl/server-connection.ts +180 -79
  304. package/src/mcpl/tags.ts +36 -0
  305. package/src/mcpl/tool-result-normalize.ts +2 -1
  306. package/src/mcpl/transport.ts +162 -33
  307. package/src/mcpl/types.ts +23 -6
  308. package/src/module-registry.ts +92 -13
  309. package/src/modules/discord/index.ts +8 -13
  310. package/src/modules/history/index.ts +25 -3
  311. package/src/modules/history/semantic.ts +29 -6
  312. package/src/modules/index.ts +1 -0
  313. package/src/modules/unknown-tool.ts +4 -1
  314. package/src/modules/workspace/branch-intent.ts +3 -1
  315. package/src/modules/workspace/edit-plan.ts +954 -0
  316. package/src/modules/workspace/edit-text.ts +618 -0
  317. package/src/modules/workspace/effects.ts +70 -19
  318. package/src/modules/workspace/index.ts +2293 -650
  319. package/src/modules/workspace/observe.ts +465 -56
  320. package/src/modules/workspace/reconcile.ts +14 -7
  321. package/src/modules/workspace/text.ts +68 -0
  322. package/src/modules/workspace/types.ts +211 -6
  323. package/src/modules/workspace/watcher.ts +3 -2
  324. package/src/operator-log.ts +47 -19
  325. package/src/recovery/discord-awareness-outbox.ts +1500 -356
  326. package/src/recovery/offline-branch.ts +189 -55
  327. package/src/recovery/recover-cli.ts +25 -4
  328. package/src/send-tools.ts +11 -0
  329. package/src/timezone.ts +4 -2
  330. package/src/tool-image-ledger.ts +62 -8
  331. package/src/tool-result-guard.ts +18 -15
  332. package/src/tool-result-history.ts +3 -2
  333. package/src/tune-out/coordinator.ts +166 -45
  334. package/src/types/agent.ts +32 -6
  335. package/src/types/events.ts +66 -9
  336. package/src/types/framework.ts +69 -62
  337. package/src/types/module.ts +40 -8
  338. package/src/types/trace.ts +121 -15
  339. package/src/usage/types.ts +16 -0
  340. package/src/usage/usage-tracker.ts +86 -43
  341. package/dist/src/code-execution/py-runner.d.ts +0 -191
  342. package/dist/src/code-execution/py-runner.d.ts.map +0 -1
  343. package/dist/src/code-execution/py-runner.js +0 -655
  344. package/dist/src/code-execution/py-runner.js.map +0 -1
  345. package/dist/src/code-execution/runtime-py.d.ts +0 -50
  346. package/dist/src/code-execution/runtime-py.d.ts.map +0 -1
  347. package/dist/src/code-execution/runtime-py.js +0 -677
  348. package/dist/src/code-execution/runtime-py.js.map +0 -1
  349. package/dist/src/mcpl/prose-stream-router.d.ts +0 -88
  350. package/dist/src/mcpl/prose-stream-router.d.ts.map +0 -1
  351. package/dist/src/mcpl/prose-stream-router.js +0 -291
  352. package/dist/src/mcpl/prose-stream-router.js.map +0 -1
  353. package/src/code-execution/py-runner.ts +0 -791
  354. package/src/code-execution/runtime-py.ts +0 -677
  355. 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
@@ -568,8 +597,15 @@ export declare class AgentFramework {
568
597
  * ephemeral agents have isolated slots and are their own only readers.
569
598
  */
570
599
  private readonly sharedSlotAgents;
600
+ /** Rounds of tool calls, by their results array, that a save_recent_image
601
+ * in the round counted by their share of the bound: such a round is
602
+ * stored by its share whether or not it fits (buildStoredToolResultContent). */
603
+ private readonly toolRoundsByShare;
571
604
  /** The windows of forks and runs deregistered while the host was quiesced,
572
- * by agent name; resume() releases them (releaseWindowNowOrAfterResume). */
605
+ * by agent name (releaseWindowNowOrAfterResume); resume() releases them
606
+ * (runReleasesAfterResume), or stop() passes on what they left, unread or
607
+ * queued, and clears them. While a name is here, no other flush drains
608
+ * its queue (drainDeferredFor). */
573
609
  private readonly releasesAfterResume;
574
610
  /** The coalescing commit in flight, if any (see commitCoalescingDurable). */
575
611
  private coalescingCommit;
@@ -594,25 +630,20 @@ export declare class AgentFramework {
594
630
  /** Forks whose TTL closure turn has been queued — disposed (removed from
595
631
  * agents/agentConfigs/conversationAgentHomes) when their stream ends. */
596
632
  private closingConversationAgents;
597
- private codeExecutionConfig;
598
- private codeExecutionRunners;
633
+ private codeExecution;
599
634
  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;
635
+ /** Per agent, a round that called code_execution and waits for those calls'
636
+ * results before its prose is routed (ScriptRound). */
637
+ private scriptRounds;
638
+ /** Each code_execution result, by the round that dispatched its call: it
639
+ * settles only that round, even if a newer round reuses its call id. */
640
+ private scriptRoundOfResult;
641
+ /** Each code_execution call of a round that waits, by its watch, whether
642
+ * the round waits on that call or not, a stop's included, though no call
643
+ * a script makes once its stop is asked reaches a tool, since the runner
644
+ * refuses it: its script's calls that reach the host while that call
645
+ * watches it, which the round counts (ScriptRound.scripts). */
646
+ private scriptRoundCalls;
616
647
  /** Resident-set per-agent tool-result inline cap (chars), via
617
648
  * agent_settings `tool_result_inline_max_chars`. DURABLE: persisted in
618
649
  * framework state like the core runtime settings and restored at create
@@ -662,7 +693,7 @@ export declare class AgentFramework {
662
693
  /** Modern-MCP (2026-07-28) servers, by id; read through modernServers().
663
694
  * They are kept apart from the MCPL registry on purpose: they have no
664
695
  * grant, planes or server→host traffic, so the MCPL machinery (quiesce's
665
- * plane pauses, awareness gates, policy) never sees them. They take part
696
+ * plane pauses, policy) never sees them. They take part
666
697
  * only through the tool paths, and their list changes reach agents
667
698
  * through ordinary admission. */
668
699
  private modernMcpConnections;
@@ -687,8 +718,9 @@ export declare class AgentFramework {
687
718
  * subsystem can be lazily initialized by connectMcplServer when the
688
719
  * framework started with zero configured servers. */
689
720
  private mcplInferenceRoutingConfig;
690
- /** Durable, non-Chronicle projection queue for messages removed by a branch. */
691
- private discordAwarenessOutbox;
721
+ /** The awareness ledger; null for a framework with neither storePath nor
722
+ * discordAwarenessOutboxPath, which refuses a marks choice. */
723
+ private readonly discordAwarenessOutbox;
692
724
  private discordAwarenessEmoji;
693
725
  private discordAwarenessDeadlineMs;
694
726
  /** Durable JSONL record of operator-initiated mutations (see operator-log.ts). */
@@ -703,9 +735,10 @@ export declare class AgentFramework {
703
735
  private surgeryHold;
704
736
  /** Serialize per-server drains so reconnect and an online undo cannot race. */
705
737
  private discordAwarenessDrains;
706
- /** Framework-global inference gate; older generations cannot release it. */
707
- private discordAwarenessBarrier;
708
- private discordAwarenessBarrierGeneration;
738
+ /** The servers whose running pass a later trigger joined
739
+ * (drainDiscordAwarenessOutbox): before it leaves, that pass tries once
740
+ * more what it had already tried. */
741
+ private discordAwarenessDrainsJoined;
709
742
  private eventGate;
710
743
  private usageTracker;
711
744
  /** Explicit-send or private suppression carried into a tool-result-guard retry. */
@@ -719,9 +752,9 @@ export declare class AgentFramework {
719
752
  * try again in the same process: the framework it had begun is stopped, as
720
753
  * stop() stops one, but giving up after 30 s on each of stop()'s cleanup
721
754
  * 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.
755
+ * modules and MCPL servers, and then for awareness drains still running,
756
+ * such as its startup's delivery, and a store it opened is closed. A store
757
+ * the caller passed in is left open.
725
758
  */
726
759
  static create(config: FrameworkConfig): Promise<AgentFramework>;
727
760
  /**
@@ -814,6 +847,14 @@ export declare class AgentFramework {
814
847
  * iteration.
815
848
  * - a later stop() waits again, within its own budget, for any stream or
816
849
  * loop this one left running, so the store never closes under it.
850
+ *
851
+ * Each conversation fork still live ends, as a closing fork's end does,
852
+ * whatever its stream is doing, as each run does: its channel unbinds, and
853
+ * its window's release passes on to the primary the notices it left that
854
+ * the primary takes in its place, unread in its window, or still queued
855
+ * for it unless it read the copy that landed there. Its end settles a
856
+ * tool-result batch its stream still held and removes the stream's
857
+ * entries, and once it has left, its stream's late events are dropped.
817
858
  */
818
859
  stop(teardownTimeoutMs?: number | undefined): Promise<void>;
819
860
  /** What start() and addModule() pass before either begins work of a
@@ -872,6 +913,10 @@ export declare class AgentFramework {
872
913
  private acquirePrimaryProviderGate;
873
914
  private releasePrimaryProviderGate;
874
915
  private flushAuxiliaryAdmission;
916
+ /** A provider hold's released requests start no turn (the scheduler drops
917
+ * them): the primary turn the release left pending won't run, so the
918
+ * recovery ends and auxiliary admission reopens. */
919
+ private endPendingPrimary;
875
920
  private waitForAuxiliaryIdle;
876
921
  private withAuxiliaryAdmission;
877
922
  /**
@@ -913,6 +958,12 @@ export declare class AgentFramework {
913
958
  * and the cap applies only to AF's own default. A negative stated wait is
914
959
  * a stated 0, as in ProviderWaits: the 1 s floor, plus jitter. */
915
960
  private accelerationCooldownMs;
961
+ /** Whether two requests are one wake, for a provider hold's dedup: the
962
+ * same agent, reason, source, time and channel, and the same coalescing
963
+ * marks: a batch wake's subject, a batch-only merge's subjects (it has no
964
+ * single subject), and the write a wake reads. A wake with any of them
965
+ * can be withdrawn or dropped on its own, and must not stand for one
966
+ * without. (coalescingBatch is set only beside one of the first two.) */
916
967
  private sameInferenceRequest;
917
968
  private consultProviderHold;
918
969
  /** A host hold whose slice expired: ask the host again before spending an
@@ -977,9 +1028,8 @@ export declare class AgentFramework {
977
1028
  /**
978
1029
  * Refuse an auxiliary call to a model the provider asked this agent to wait
979
1030
  * 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
1031
+ * the remaining wait, so a caller that paces waits it out instead of
1032
+ * spending a call. It is marked
983
1033
  * `providerAdmission: 'deferred'`: no call was made, so a caller can keep
984
1034
  * the wait without counting a failed call (room-225 #47927).
985
1035
  */
@@ -1165,7 +1215,7 @@ export declare class AgentFramework {
1165
1215
  /** The registered workspace module, if any (used by save_image). */
1166
1216
  private getWorkspaceModule;
1167
1217
  /** RFC-005 host-mediated reference fetcher (lazy; needs server configs +
1168
- * a writable workspace mount for storage). */
1218
+ * a read-write workspace mount without an include for storage). */
1169
1219
  private referenceFetcherInstance?;
1170
1220
  private getReferenceFetcher;
1171
1221
  /** Register every RFC-005 reference in an MCPL peer's tool-result content
@@ -1354,14 +1404,16 @@ export declare class AgentFramework {
1354
1404
  * acknowledged once: the chronicle is synced, then the persisted queue is
1355
1405
  * rewritten without the batch (ackDeferredWrites). Until then the batch
1356
1406
  * 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.
1407
+ * boot, which skips each entry that already landed, by its deferredWriteId —
1408
+ * no loss, no duplicates. The batch is stored in queue order, whatever its
1409
+ * targets (writeDrainedInOrder). A write the store rejects stays queued,
1410
+ * logged, with what is queued behind it for its target, so the flush never
1411
+ * stores that target's later entries ahead of it, and other targets' entries
1412
+ * go on. One the store refuses as malformed, which it would at every flush,
1413
+ * is logged and dropped instead, and what is behind it goes on. (A write
1414
+ * that isn't deferred can still land ahead of it, such as one for an idle
1415
+ * agent once the host has resumed.) A boot that meets it again logs it and
1416
+ * goes on.
1365
1417
  *
1366
1418
  * Per-target: an agent whose turn is still alive keeps ITS messages
1367
1419
  * deferred for its own turn boundary; everyone else's flush now.
@@ -1434,8 +1486,8 @@ export declare class AgentFramework {
1434
1486
  * memory-only: they land within the turn, at a tool boundary or at its
1435
1487
  * end, and a crash before then loses them. That window runs to the turn's
1436
1488
  * 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.
1489
+ * stream that declares it can't carry injected messages (membrane's XML
1490
+ * prefill path, from 0.6.0), for every message deferred during the turn.
1439
1491
  *
1440
1492
  * A write that fails, or a queue over the cap, which writes nothing,
1441
1493
  * leaves the record as it last held it, except that store only, a write
@@ -1662,7 +1714,17 @@ export declare class AgentFramework {
1662
1714
  *
1663
1715
  * This is create()'s first read of framework/state, so it also refuses a
1664
1716
  * 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. */
1717
+ * take it as holding nothing, and its first write would replace it.
1718
+ *
1719
+ * A stored entry restores into the shared ephemeral entry, rather than
1720
+ * under its own name, when it is marked as the shared entry, when it was an
1721
+ * ephemeral agent's from before they shared one entry, its name having an
1722
+ * ephemeral agent's namespace in the store (subagent/<name>, as
1723
+ * createEphemeralAgent opens it), or when it is the shared entry an earlier
1724
+ * framework wrote back without its mark. A name a persistent agent has keeps
1725
+ * an unmarked entry either way: one in `configured`, or one with a
1726
+ * resident's or a conversation agent's namespace (agents/<name>,
1727
+ * conversations/<name>). */
1666
1728
  private restoreUsageState;
1667
1729
  private persistUsageState;
1668
1730
  /** An agent's persisted record, or null when it has none. Throws the
@@ -1858,9 +1920,12 @@ export declare class AgentFramework {
1858
1920
  /**
1859
1921
  * Mark an inference refusal visibly: react on the message that holds the
1860
1922
  * 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.
1923
+ * message that isn't a reaction, reaction removal, edit or deletion
1924
+ * marker, apart from an edit the coalescer delivers on acceptance as the
1925
+ * agent's first view; an ephemeral run has none, so a subagent's refusal
1926
+ * marks no message) with a category-specific emoji. Best-effort —
1927
+ * failures are logged, never thrown, and non-Discord loci are silently
1928
+ * skipped.
1864
1929
  */
1865
1930
  private reactToRefusal;
1866
1931
  /**
@@ -1949,7 +2014,7 @@ export declare class AgentFramework {
1949
2014
  * advancing merges during a quiesce window.
1950
2015
  *
1951
2016
  * host-status — report the quiesce state (drained / parked wakes /
1952
- * running background scripts).
2017
+ * scripts left running).
1953
2018
  *
1954
2019
  * release-provider-wait — end an agent's provider wait (a provider's
1955
2020
  * stated retry-after, kept across restarts) for one `model` or all, as an
@@ -1989,14 +2054,14 @@ export declare class AgentFramework {
1989
2054
  */
1990
2055
  tailProcessLogs(count?: number, eventType?: string): ProcessLogEntryWithId[];
1991
2056
  /**
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.
2057
+ * Switch the store to an existing branch and re-materialize the config
2058
+ * mount from it. A switch adds or removes no Discord awareness marks: they
2059
+ * are one-shot, a surgery's or an operator's explicit choice. Resolves once
2060
+ * the mount has run; if it fails, it rejects with the store already moved.
2061
+ * It moves the store once any maintenance already running has finished, so
2062
+ * the move can come after the call returns, and a refusal moves nothing.
2063
+ * An operator's operation: refused once stop() has begun, and waited for
2064
+ * by stop() while it runs.
2000
2065
  *
2001
2066
  * The branch moves under every agent sharing the store, so the switch
2002
2067
  * reserves the store as a surgery does: every agent must be idle, or it is
@@ -2072,6 +2137,29 @@ export declare class AgentFramework {
2072
2137
  * does. Always release in `finally`: a token nobody clears wedges the fleet.
2073
2138
  */
2074
2139
  private reserveStoreForSurgery;
2140
+ /**
2141
+ * A surgery's marker batch, recorded before its body change. If it can't
2142
+ * be recorded, the surgery doesn't start, and the error says what the
2143
+ * ledger may hold (DiscordAwarenessOutbox.prepare). Without a ledger there
2144
+ * is none: a marks choice was refused before this (refuseMarksWithoutLedger),
2145
+ * and a suppression runs with no record to resume it from.
2146
+ */
2147
+ private prepareMarkerBatch;
2148
+ /**
2149
+ * A marks choice needs a ledger to keep it: a framework that has none
2150
+ * refuses one before anything is planned or changed.
2151
+ */
2152
+ private refuseMarksWithoutLedger;
2153
+ /**
2154
+ * After a failed surgery has put the source back: retire its prepared
2155
+ * awareness batch, but only when the store is confirmed on the source. If
2156
+ * it isn't, the batch stays prepared as the evidence of an unfinished body
2157
+ * (a start on its target finishes a suppression's removals). Either way
2158
+ * none of its marks is ever sent: a start retires what this can't.
2159
+ * Never throws: the caller is already reporting the surgery's failure;
2160
+ * returns a clause to append to it.
2161
+ */
2162
+ private retireAfterRestore;
2075
2163
  /**
2076
2164
  * After a failed switch or redaction: put the store back on `sourceBranch`
2077
2165
  * if it moved, and return a sentence saying what actually happened. Never
@@ -2082,14 +2170,17 @@ export declare class AgentFramework {
2082
2170
  * Roll the active branch back so `messageId` becomes its tail: fork the
2083
2171
  * chronicle at that message (origin-sequence time-travel branch) and switch
2084
2172
  * 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.
2173
+ *
2174
+ * The rollback is local to the resident. Marking removed Discord messages
2175
+ * with an awareness reaction is a separate, explicit publication choice
2176
+ * (`marks`, default `none`); `previewSurgeryMarks` shows what each scope
2177
+ * would cover, and passing its `refs` binds the choice to exactly that set.
2087
2178
  *
2088
2179
  * Returns once the switch has landed: the body is applied, with a
2089
2180
  * 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.
2181
+ * accept the reactions: delivery is started and continues without the
2182
+ * caller, the store reservation or MCPL traffic waiting on it; what
2183
+ * Discord answers is kept in the awareness ledger.
2093
2184
  *
2094
2185
  * Throws `OperatorActionError` (`agent-busy`, `unknown-message`, …) — the
2095
2186
  * agent must be idle; nothing is queued.
@@ -2100,6 +2191,8 @@ export declare class AgentFramework {
2100
2191
  note?: string;
2101
2192
  /** Branch name for the fork (default `rollback/<agent>/<ts>`, or with `-2`, `-3`, … appended when the store already holds that name). */
2102
2193
  branchName?: string;
2194
+ /** Publication choice for awareness marks; default `none`. */
2195
+ marks?: DiscordAwarenessMarks;
2103
2196
  }): Promise<{
2104
2197
  agentName: string;
2105
2198
  sourceBranch: string;
@@ -2127,9 +2220,10 @@ export declare class AgentFramework {
2127
2220
  * source branch: fork at the current head (by default `suppress/<agent>/<ts>`,
2128
2221
  * numbered `-2`, `-3`, … when the store already holds that name), redact
2129
2222
  * 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).
2223
+ * removed together. With a marks choice, the Discord originals get awareness
2224
+ * marks through the ledger: the batch is activated only after every removal
2225
+ * succeeded, and a crash mid-way is finished at next boot
2226
+ * (resumePreparedDiscordSuppressions), its marks retired unsent.
2133
2227
  * Like rollbackToMessage, it returns once the body change has landed, with
2134
2228
  * a marker-scheduling receipt (`markers`); delivery continues without the
2135
2229
  * caller waiting on it.
@@ -2144,6 +2238,8 @@ export declare class AgentFramework {
2144
2238
  note?: string;
2145
2239
  /** Branch name for the fork (default `suppress/<agent>/<ts>`, or with `-2`, `-3`, … appended when the store already holds that name). */
2146
2240
  branchName?: string;
2241
+ /** Publication choice for awareness marks; default `none`. */
2242
+ marks?: DiscordAwarenessMarks;
2147
2243
  }): Promise<{
2148
2244
  agentName: string;
2149
2245
  sourceBranch: string;
@@ -2163,66 +2259,94 @@ export declare class AgentFramework {
2163
2259
  preview?: string;
2164
2260
  } | null;
2165
2261
  }>;
2262
+ /**
2263
+ * The messages a rollback to `messageId` would remove, validated, without
2264
+ * changing anything. Never bisects a body group: chronicle refuses that
2265
+ * for removals and branchAt has no such guard, so the target snaps to the
2266
+ * group's last shard.
2267
+ */
2268
+ private planRollback;
2269
+ /**
2270
+ * The removal intervals a suppression of `requestedIds` would apply
2271
+ * (index-ordered, newest first), validated, without changing anything. A
2272
+ * shard expands to its whole body group (chronicle refuses to bisect one),
2273
+ * and a group interval is always removed as a range.
2274
+ */
2275
+ private planSuppression;
2276
+ /**
2277
+ * What a rollback or suppression would remove, and which Discord messages
2278
+ * each publication scope would mark, without changing anything or reading
2279
+ * message content. A surface shows this before an operator chooses
2280
+ * `marks`; passing a scope's `refs` back as `marks.refs` binds the choice
2281
+ * to exactly that set, so a later application never widens it.
2282
+ */
2283
+ previewSurgeryMarks(agentName: string, target: {
2284
+ rollbackTo: string;
2285
+ } | {
2286
+ suppress: string[];
2287
+ }): SurgeryMarksPreview;
2288
+ /** The awareness ledger's batches and retract requests, for operator surfaces. */
2289
+ listDiscordAwareness(): DiscordAwarenessView[];
2290
+ /**
2291
+ * Stop all further sends and retries of a batch's marks, or of a retract
2292
+ * request's removals (by its request id). Never removes a reaction and
2293
+ * never undoes one: requests already on the wire, or whose outcome is
2294
+ * unknown, are reported and may still land.
2295
+ */
2296
+ cancelDiscordAwareness(target: string, opts?: {
2297
+ requester?: OperatorRequester;
2298
+ note?: string;
2299
+ }): Promise<DiscordAwarenessCancelReceipt>;
2300
+ /**
2301
+ * Remove this bot's awareness mark, through each ref's configured MCPL
2302
+ * route, from a batch's refs, or (`all`) from every ref of every batch not
2303
+ * retired and every reaction the ledger holds. The receipt says how many
2304
+ * removals were queued and on how many of those reactions an earlier add
2305
+ * may land afterwards.
2306
+ */
2307
+ retractDiscordAwareness(target: string | 'all', opts?: {
2308
+ requester?: OperatorRequester;
2309
+ note?: string;
2310
+ }): Promise<DiscordAwarenessRetractReceipt>;
2311
+ private awarenessOperatorAction;
2166
2312
  /**
2167
2313
  * Record a surgery's prepared marker batch as active once its body change
2168
2314
  * has landed, and say what happened. Never throws: the body is already
2169
2315
  * applied, so a ledger failure here is reported in the receipt rather than
2170
2316
  * 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.
2317
+ * activated is retired, so no later start can deliver it behind a receipt
2318
+ * saying it was not scheduled (`not-scheduled`). If retiring fails too, it
2319
+ * stays prepared, and a start retires it, unsent: the receipt is
2320
+ * `not-scheduled` either way.
2178
2321
  *
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.
2322
+ * A batch with no refs (a suppression's resume record, with nothing
2323
+ * addressable) is still activated, which closes it. It schedules no marks,
2324
+ * so it reports `none` whatever the ledger does, and a failure is logged.
2325
+ * If it can be neither activated nor retired, it stays prepared, and
2326
+ * closes at the next start on its branch: every interval it names has
2327
+ * already committed, so the resume skips them all and retires it.
2185
2328
  */
2186
2329
  private activateSurgeryMarkers;
2187
2330
  /**
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;
2331
+ * The receipt for a batch whose body change has landed, from what the
2332
+ * ledger settled. Anything short of `queued` is logged and raised as an
2333
+ * ops alert: the body stands either way.
2334
+ */
2335
+ private settledMarkerReceipt;
2336
+ /**
2337
+ * Start awareness delivery without the caller awaiting it. The drain starts
2338
+ * now and continues independently. Delivery never gates MCPL traffic or
2339
+ * turns; a failure is logged and raised as an ops alert, and the queued
2340
+ * work stays in the ledger for the next pass. It isn't an
2341
+ * operator's operation, as syncDiscordAwarenessMarkers is: stop() waits
2342
+ * for running drains only once it has closed their servers, within its
2343
+ * budget, and once stop() has begun none is started, since the teardown
2344
+ * would cut it off. The next start delivers what is due. A quiesce doesn't
2345
+ * hold it, as it holds turns and what servers send: a delivery starts no
2346
+ * turn, and the answers to the host's own requests are never held, so a
2347
+ * surgery made during a quiesce has its marks sent then.
2348
+ */
2349
+ private deliverDiscordAwarenessInBackground;
2226
2350
  /** Start config file IO without holding the caller or a surgery's store
2227
2351
  * reservation. The gate picks it up by mtime; stop() still waits for it. */
2228
2352
  private materializeConfigMountAfterBranchSwitch;
@@ -2324,10 +2448,10 @@ export declare class AgentFramework {
2324
2448
  /**
2325
2449
  * Spawn a persistent per-channel conversation agent ("fork") from the
2326
2450
  * 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.
2451
+ * with the template's compiled context without its thinking, its channel
2452
+ * and by-name notices, or its unpaired tool blocks (the SubagentModule
2453
+ * wholesale-copy pattern; see the seeding comment below), registered in the
2454
+ * event loop like any agent — but never primary.
2331
2455
  */
2332
2456
  private createConversationAgent;
2333
2457
  /**
@@ -2360,6 +2484,15 @@ export declare class AgentFramework {
2360
2484
  * in flight for the channel, and only this spawn's settlement removes it,
2361
2485
  * so the entry it removes is its own. It's removed before anyone waiting
2362
2486
  * on it resumes, so a waiter that decides again doesn't find it.
2487
+ *
2488
+ * It binds only while the fork it created is still the agent registered
2489
+ * under its name. stop() ends each live fork and unbinds the channels
2490
+ * bound to them, so a fork it ends while this spawn waits for the creation
2491
+ * to return has no binding yet, and binding it then would route the
2492
+ * channel to a name that's gone. The spawn rejects instead, as a failed
2493
+ * spawn does. Its fork's name stays used, so the router's counter for the
2494
+ * channel first moves to the spawn's generation, which the store already
2495
+ * holds, and the channel's next qualifying message spawns the next one.
2363
2496
  */
2364
2497
  private spawnConversationAgent;
2365
2498
  /**
@@ -2378,17 +2511,27 @@ export declare class AgentFramework {
2378
2511
  */
2379
2512
  private storeConversationGeneration;
2380
2513
  /**
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.
2514
+ * Remove a conversation fork from the framework, once its closure turn has
2515
+ * finished or when stop() ends it: the home mapping has served its purpose,
2516
+ * and keeping the agent registered would just grow every agent scan and
2517
+ * broadcast filter forever. Its window is released now, or, while the host
2518
+ * is quiesced, at resume (releaseWindowNowOrAfterResume); when stop() ends
2519
+ * it then, stop()'s pass for postponed releases passes on the failed
2520
+ * replies it left unread instead. No binding names it
2521
+ * by then: the idle sweep unbinds its channel as the closure begins,
2522
+ * stop() unbinds it just before it ends the fork, and a spawn whose fork
2523
+ * stop() has ended binds nothing (spawnConversationAgent). The fork's
2524
+ * context stays in Chronicle for investigation.
2385
2525
  */
2386
2526
  private disposeConversationAgent;
2387
2527
  /**
2388
2528
  * 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.
2529
+ * injections that are another registered channel's context (injection
2530
+ * namespace = channelId by adapter convention), keep its own channel and
2531
+ * anything that isn't channel context. A channel's context is its own
2532
+ * whether or not it's open: one the agent closed, or one whose server's
2533
+ * transport closed and that isn't confirmed again yet, still belongs to
2534
+ * its own fork.
2392
2535
  */
2393
2536
  private scopeInjectionsForAgent;
2394
2537
  /**
@@ -2466,6 +2609,20 @@ export declare class AgentFramework {
2466
2609
  * stamped (a direct framework caller), which is the closest observation.
2467
2610
  */
2468
2611
  private channelSource;
2612
+ /**
2613
+ * An inbound item's metadata with its stored copy's own digest
2614
+ * (`storedBodyDigest`): the delivered-body digest's function over exactly
2615
+ * the blocks handed to storage here — every decoration included, before
2616
+ * storage shards them. That function hashes blocks as the store keeps them
2617
+ * (inline media re-encoded and relabeled from its bytes), so an unsharded
2618
+ * copy read back hashes to this too. A body the store shards (adaptive
2619
+ * ingress chunking) carries this on every shard, with its metadata, and no
2620
+ * shard hashes to it. Taken at each storage site, never earlier, because
2621
+ * a path can still decorate the body after ingestion stamped it (the
2622
+ * closed-channel invitation; room-220 #48282). An edit through
2623
+ * editMessage keeps metadata but not this hash.
2624
+ */
2625
+ private static withStoredDigest;
2469
2626
  /** Source envelope of a channels/incoming event (lane facts as given). */
2470
2627
  private channelEventSource;
2471
2628
  /** Source envelope of a push event: its derived channel, else unscoped. */
@@ -2517,7 +2674,7 @@ export declare class AgentFramework {
2517
2674
  /** Queue a wake for each agent of the batch's audience, when its latest
2518
2675
  * occurrence triggers inference. `plain`: an ordinary push wake, without
2519
2676
  * the subject a withdrawal of the batch's wakes goes by, for a render
2520
- * placed in its agent's deferred queue (wakeToRead). */
2677
+ * placed in its agent's deferred queue (wakeToRead), at `readsDeferredWrite`. */
2521
2678
  private queueCoalescedWakes;
2522
2679
  /** Withdraw unstarted wakes whose sole cause is this subject (§4.2). */
2523
2680
  private cancelCoalescedWakes;
@@ -2527,11 +2684,18 @@ export declare class AgentFramework {
2527
2684
  * scanning the unread tail (above the watermark) — never below it.
2528
2685
  */
2529
2686
  private resolvePlacement;
2687
+ /** Unread (the coalescer's isUnread) by the consumed watermark, or, by the
2688
+ * shown watermark, never possibly shown (its isUnshown). A placement still
2689
+ * in the deferred queue is both, once settled (settleUnknownLandings): one
2690
+ * whose write may already be stored, its store unsearchable, is a doubt,
2691
+ * which counts as read and as shown. */
2530
2692
  private isUnreadPlacement;
2531
2693
  /**
2532
2694
  * Unread = stored, above the agent's consumed watermark on the current
2533
2695
  * branch, not a body-group shard (immutable), and not folded into any
2534
2696
  * summary (compression is consumption, §3.3). Conservative on every doubt.
2697
+ * By the shown watermark (Agent.getShownWatermark), the same test says the
2698
+ * message may never have been shown.
2535
2699
  */
2536
2700
  private isUnreadStoredMessage;
2537
2701
  private removePlacement;
@@ -2543,23 +2707,9 @@ export declare class AgentFramework {
2543
2707
  * Whether a batched gate wake's addressed route may become `agentName`'s
2544
2708
  * speech locus. The gate broadcasts to every agent, conversation forks
2545
2709
  * included. A fork speaks only in its home channel, and a channel bound to
2546
- * a fork is that fork's conversation, so no other agent takes it. Two
2547
- * servers' channels with one id are two conversations, each bound to its
2548
- * own fork with that id as its home, so a fork takes the route only where
2549
- * the router binds the route's channel, its server and id, to it; a route
2550
- * with no server names a fork only where one fork is bound to that id.
2710
+ * a fork is that fork's conversation, so no other agent takes it.
2551
2711
  */
2552
2712
  private mayTakeGateRoute;
2553
- /**
2554
- * The channel a push names, and a server that registers it, when another
2555
- * server registers that channel id and the pushing server doesn't. A
2556
- * channel's id is the agent's locus on its own, so the reply to such a
2557
- * push would go out through the server that registers it: the push
2558
- * boundary refuses it (PushHandler). A push naming a channel no server
2559
- * registers isn't refused, and registers it for the pushing server
2560
- * (ensureChannelRegistered).
2561
- */
2562
- private channelOfAnotherServer;
2563
2713
  /**
2564
2714
  * Derive the MCPL composite channel id (the outbound routing locus) for a
2565
2715
  * push event from its server-defined `origin`, if it carries one.
@@ -2600,7 +2750,7 @@ export declare class AgentFramework {
2600
2750
  * (Named for its first use, the silent tick.)
2601
2751
  */
2602
2752
  private silentTurnRowMetadata;
2603
- /** Record plain-prose segments this turn suppressed without drafts (proseRouting=disabled). */
2753
+ /** Record plain-prose segments this turn suppressed without drafts (proseRouting=disabled, or a round withheld before its scripts returned). */
2604
2754
  private recordProseSuppression;
2605
2755
  /**
2606
2756
  * Silenced plain speech: an explicit send holds it as resendable drafts; a
@@ -2736,13 +2886,47 @@ export declare class AgentFramework {
2736
2886
  private announceLocusIfChanged;
2737
2887
  /**
2738
2888
  * The channel a message moves its turn's locus to, by the addressed
2739
- * re-pin rule (2026-07-31, n=6 and n=7): a conversational message (not a
2740
- * reaction or a system marker) that addressed the agent, or that follows
2741
- * up in a channel the turn sent into (TurnRouting.engaged). Undefined for
2742
- * any other message. A tool boundary weighs the messages it injects by it,
2889
+ * re-pin rule (2026-07-31, n=6 and n=7): a conversational message (by
2890
+ * isConversationalInjection: not a system marker, nor a reaction, reaction
2891
+ * removal, edit or deletion marker, apart from an edit the coalescer marks
2892
+ * as the agent's first view) that addressed the agent, or that follows up
2893
+ * in a channel the turn sent into (TurnRouting.engaged). Undefined for any
2894
+ * other message. A tool boundary weighs the messages it injects by it,
2743
2895
  * and noteArrival the ones no boundary of the turn weighs.
2744
2896
  */
2745
2897
  private repinChannel;
2898
+ /** Whether `agent` has a turn alive: starting, streaming or waiting on its tools. */
2899
+ private turnAlive;
2900
+ /**
2901
+ * Store the clock row due in `agent`'s window (clock-rows.ts), if the agent
2902
+ * has clock rows and a boundary has passed since the window's last clock,
2903
+ * or the window holds no clock row yet (planClock), and return it. The
2904
+ * caller places it, by calling this right before what the clock precedes
2905
+ * is written: an incoming event while no turn of the agent's is alive (or
2906
+ * one is assembling before its compile), a fresh turn's inputs before its
2907
+ * compile, or, mid-turn, the messages a tool boundary injects, where the
2908
+ * caller injects the clock first. Each is a place where a row is either in
2909
+ * the request that follows or before every request still to come, so the
2910
+ * window and the live stream keep matching.
2911
+ *
2912
+ * None while the host is quiesced (the window is frozen for surgery), and
2913
+ * none in the residents' shared slot while another of its readers (the
2914
+ * subconscious among them, through its merged view) has a turn alive: the
2915
+ * row would sit inside that turn without joining its stream. A clock that
2916
+ * can't be planned or stored is logged and skipped: it never holds up what
2917
+ * it would have preceded. One whose write threw after it landed is the
2918
+ * window's all the same, so it's returned, and a tool boundary injects it.
2919
+ */
2920
+ private storeDueClock;
2921
+ /** Rows a window's last-clock scan reads at a time. */
2922
+ private static readonly CLOCK_SCAN_ROWS;
2923
+ /** What the next clock is planned from: the window's newest row's time and
2924
+ * the time its last clock row reads, found by reading back from the
2925
+ * newest row, CLOCK_SCAN_ROWS at a time, until a clock row comes, however
2926
+ * far back it is. In the steady state the newest chunk holds it, unless
2927
+ * more rows than that have come since the last clock; a window with no
2928
+ * clock row is read whole once, and then takes one (planClock). */
2929
+ private lastClockOf;
2746
2930
  /**
2747
2931
  * Weigh a message that no tool boundary of the agent's open logical turn
2748
2932
  * will weigh: one that would re-pin the locus becomes one of the turn's
@@ -2765,6 +2949,12 @@ export declare class AgentFramework {
2765
2949
  * its own agent, so no boundary of another resident's turn weighs it.
2766
2950
  */
2767
2951
  private noteForOtherResidents;
2952
+ /**
2953
+ * Show the turn's typing indicator in `channelId`, stopping the one it last
2954
+ * showed elsewhere: this stream's, or one an earlier stream of the turn
2955
+ * left running when it handed the turn on.
2956
+ */
2957
+ private showTurnTyping;
2768
2958
  /**
2769
2959
  * The channel of the turn's newest arrival whose message is still in the
2770
2960
  * agent's store (TurnRouting.arrivals). A message removed since it was
@@ -2790,15 +2980,155 @@ export declare class AgentFramework {
2790
2980
  /**
2791
2981
  * Durable window notice for a channel the agent did not ask to open: a
2792
2982
  * subscription-policy admission, announced as the decision before its
2793
- * transport RPC (a failed open keeps the decision, and channel_list shows
2794
- * transport state), or an open that the agent's own delivery or reply
2795
- * caused (`opened-by-delivery`, `opened-by-reply`), once its transport is
2796
- * confirmed. Either way it names `channel_close` as the opt-out (their
2797
- * decision outranks policy). What an open channel delivers is its server's
2798
- * to say (#406), so the notice doesn't promise its traffic. System message:
2799
- * never triggers inference, never conversational, never locus-eligible.
2983
+ * transport RPC (a failed open keeps the decision, and the host tries again
2984
+ * when the server next registers the channel), or an open that the agent's
2985
+ * own delivery or reply caused (`opened-by-delivery`, `opened-by-reply`),
2986
+ * once its transport is confirmed. It names `channel_close` as the opt-out
2987
+ * (neither the subscription policy nor the server's default reopens a
2988
+ * channel the agent closed) only where the agent it's addressed to can
2989
+ * call it for every channel it names (canCloseChannels): a conversation
2990
+ * fork may close only its home channel, and an agent's allowedTools can leave
2991
+ * channel_close out. The other residents can read it too, where several
2992
+ * share one slot (#291); a fork's seed leaves it out (primaryNoticeTexts).
2993
+ * Where an
2994
+ * agent's own send opened a channel it can't close, the primary is told by
2995
+ * name too, if it's registered and can close it, and the agent is told
2996
+ * that it was. What an open channel delivers is its server's to say (#406),
2997
+ * so the notice says how servers differ rather than promising its traffic,
2998
+ * and says that only to an agent whose window holds the channel's traffic
2999
+ * (holdsChannelTraffic).
3000
+ * System message: never triggers inference, never conversational, never
3001
+ * locus-eligible.
2800
3002
  */
2801
3003
  private recordChannelAutoOpenNotice;
3004
+ /**
3005
+ * Write a builder's channel notices in order, each on its own: one that
3006
+ * can't be written is logged, and the rest are still written. A reader's
3007
+ * notice that says the primary was told comes after the primary's, and is
3008
+ * written in its `untold` words where the primary's write failed, so it
3009
+ * never says the primary was told of a notice that wasn't written. A write
3010
+ * addMessage defers to the primary's next boundary, as it does any write
3011
+ * to an agent mid-turn, counts as written: a memory-only queue loses it at
3012
+ * exit, as it loses any deferred write. Through
3013
+ * framework.addMessage for mid-turn safety (deferral + hear-while-acting
3014
+ * injection): an open a delivery forces happens inside a live turn, and a
3015
+ * direct context-manager append there would store the notice out of order.
3016
+ */
3017
+ private writeChannelNotices;
3018
+ /**
3019
+ * The notices recordChannelAutoOpenNotice writes, in order: the primary's
3020
+ * by name where the reader can't close the channels, then the reader's,
3021
+ * which then says the primary was told (`untold`: its words where that
3022
+ * didn't land). None, logged, for an agent that has ended when there's no
3023
+ * primary to tell.
3024
+ * The reader's carries its inputs (`passOn`), the channels' server among
3025
+ * them, where it's addressed to the agent whose send opened the channels
3026
+ * and that agent was told it can close them, so a release that finds it
3027
+ * unread can tell the primary in its place (channelNoticeForPrimary), which
3028
+ * calls this again for the agent then gone. A policy admission's goes where
3029
+ * addMessage delivers it, to no agent of its own, and carries none.
3030
+ */
3031
+ private channelOpenedNotices;
3032
+ /**
3033
+ * Whether `who` can call channel_close for every one of `channelIds` here:
3034
+ * its allowedTools hold it (canAgentUseTool), and a conversation fork,
3035
+ * whose channel_close dispatchChannelToolCall refuses for any channel but
3036
+ * its home, only for its home.
3037
+ */
3038
+ private canCloseChannels;
3039
+ /**
3040
+ * Whether `who` holds the traffic of every one of `channelIds`, so that
3041
+ * what an open channel delivers is in its window. Where conversations are
3042
+ * routed, an incoming message goes to the fork its channel is bound to, or
3043
+ * nowhere, and never to the primary (handleMcplChannelIncoming), so a fork
3044
+ * holds only its home's, and only while the router binds its home to it.
3045
+ * An idle expiry's sweep unbinds the home before the fork's closure turn
3046
+ * (ConversationRouter.expired), and from then the closing fork holds none;
3047
+ * a newer fork the home is bound to holds it instead. Elsewhere an
3048
+ * incoming message is stored with no forAgent, in deliveryAgent()'s store,
3049
+ * and where that's the residents' shared slot, every agent that reads the
3050
+ * slot holds it (sharedSlotAgents: the ordinary residents, and the
3051
+ * subconscious through its merged view); a run's store is its own. (A push
3052
+ * names its channel and lands in the primary's window either way, but it
3053
+ * comes whether or not the channel is open, so it isn't what opening one
3054
+ * delivers.)
3055
+ */
3056
+ private holdsChannelTraffic;
3057
+ /**
3058
+ * Whether `who`'s window holds the traffic of the channels it may open or close, for the words its channel_open and
3059
+ * channel_close carry. A conversation fork does for its home, the one
3060
+ * channel it may close, decided by the home rather than the binding, so a fork whose binding expired keeps its words
3061
+ * through its closure turn: changing them then would send its whole window uncached, for a sentence false for that
3062
+ * turn only. Otherwise as holdsChannelTraffic has it: on a host that routes conversations, the trunk holds none, and
3063
+ * otherwise the delivery agent and the readers of the residents' shared slot do. An ephemeral run holds none.
3064
+ */
3065
+ private holdsChannelTrafficForTools;
3066
+ /** Whether `who` is the delivery agent, or reads the residents' shared slot it stores into. */
3067
+ private residentHoldsTraffic;
3068
+ /**
3069
+ * How a notice to the primary names `agentName`: a conversation fork by the
3070
+ * channel it's bound to, as notices name channels, with its own name once,
3071
+ * after "named", and as "that fork" after that ("your fork" where the
3072
+ * primary is the template forks are made from); any other agent by its
3073
+ * name. `first` is said mid-sentence, so a fork's ends with a comma. A
3074
+ * fork's home is known while it's registered and through its release; a
3075
+ * notice passed on later, at resume or at boot, names it by its name.
3076
+ */
3077
+ private agentForPrimary;
3078
+ /**
3079
+ * How a notice to `reader` names the primary it says was told: "Your
3080
+ * primary" to a conversation fork made from the primary, whose
3081
+ * configuration is the primary's with only its name changed, so its prompt
3082
+ * may give the primary's name as its own; the primary's name to any other
3083
+ * agent, a fork made from another template included.
3084
+ */
3085
+ private primaryForReader;
3086
+ /** Whether `agentName` is a conversation fork made from the primary: the
3087
+ * router's template is the primary (connectome-host's is). */
3088
+ private forkOfPrimary;
3089
+ /**
3090
+ * Window notice for a reply whose channel couldn't be opened: the reply
3091
+ * went out through its send tool, but the open that engaging the channel
3092
+ * asks for failed. Without it the agent would wait for a conversation it
3093
+ * won't see. It goes to the agent whose reply it was, or, when no agent
3094
+ * is named, where addMessage delivers an unrouted message (deliveryAgent:
3095
+ * the primary, else the first registered agent), as the opened notice
3096
+ * does, and its advice is judged for that agent. Where the channel stays
3097
+ * closed, an agent that has ended is told nothing, and nor is anyone in
3098
+ * its place: nothing follows from the failure. Where it's selected for
3099
+ * opening, the primary is told by name in its place, if one is registered,
3100
+ * as the opened notice tells it of an open by an agent that has ended, so
3101
+ * an agent that could close the channel hears it may open. It names
3102
+ * channel_open as the way to try again only where the agent it's addressed
3103
+ * to can call it: a conversation fork's channel_open is refused outright
3104
+ * (dispatchChannelToolCall), and an agent's allowedTools can leave it out.
3105
+ * The other residents can read it too, where several share one slot
3106
+ * (#291); a fork's seed leaves it out (primaryNoticeTexts).
3107
+ * Where the channel is selected for opening, it says so and why, as
3108
+ * speech's failure does, and what that means: where the host couldn't
3109
+ * record putting the channel's decision back, a later delivery or
3110
+ * reconnect tries again; where the
3111
+ * server's latest announcement or the subscription policy lifted the
3112
+ * default put back, the host tries again itself, so channel_open isn't
3113
+ * named. Either way channel_close withdraws that, named only to an agent
3114
+ * that can call it here (a fork may close only its home channel). Where
3115
+ * the reader can't, the primary is told by name too, if it's registered
3116
+ * and can close it, and the reader is told that it was. System message, as
3117
+ * the opened notice is.
3118
+ */
3119
+ private recordReplyOpenFailedNotice;
3120
+ /**
3121
+ * The notices recordReplyOpenFailedNotice writes, in order: the primary's
3122
+ * by name where the reader can't close a channel selected for opening,
3123
+ * then the reader's, which then says the primary was told (`untold`: its
3124
+ * words where that didn't land). None, logged, where the agent has ended and the channel
3125
+ * stays closed, or there's no primary to tell. The reader's carries its
3126
+ * inputs (`passOn`), the channel's server among them, where it's addressed
3127
+ * to the agent whose reply it was, the channel is selected for opening and
3128
+ * that agent was told it can close it, so a release that finds it unread
3129
+ * can tell the primary in its place (channelNoticeForPrimary).
3130
+ */
3131
+ private replyOpenFailedNotices;
2802
3132
  /**
2803
3133
  * A `!` continuation the turn asked for (`>>#x !`, `>>>#x !`): start another
2804
3134
  * turn now instead of pausing until the next external event. It reads the
@@ -2812,19 +3142,20 @@ export declare class AgentFramework {
2812
3142
  /** The agent's routing state for its current turn, made when it has none. */
2813
3143
  private routingOf;
2814
3144
  /**
2815
- * Explicit-prose-routing delivery gateway (docs/explicit-prose-routing.md).
2816
- * Every prose segment of an `explicit`-mode agent flows through here:
2817
- * parse the `>>` prefix, resolve the target, deliver — or bounce to the
2818
- * held bounce draft with a resend notice. Misdelivery is structurally impossible:
2819
- * nothing is ever sent to a destination the model did not name (directly
2820
- * or via the turn's sticky target).
3145
+ * Explicit-prose-routing delivery gateway (docs/explicit-prose-routing.md),
3146
+ * entered directly: parse the `>>` prefix, resolve the target, deliver, or
3147
+ * bounce to the held bounce draft with a resend notice. Misdelivery is
3148
+ * structurally impossible: nothing is ever sent to a destination the model
3149
+ * did not name (directly or via the turn's sticky target). A stream's own
3150
+ * deliveries go through deliverAdmittedProse with its outgoing stream
3151
+ * (onPublished); this entry has no stream, and only tests call it.
2821
3152
  */
2822
3153
  private deliverProse;
2823
3154
  /**
2824
3155
  * Explicit prose's envelopes, each `>>` target resolved now, once. A live
2825
- * round is admitted at its boundary: its turn's destination is decided from
2826
- * these resolutions (roundDestination), and its queued delivery posts to
2827
- * them, however the registry's names change before it runs.
3156
+ * round is admitted as it ends, at its tool-calls event, and its queued
3157
+ * delivery posts to these resolutions, however the registry's names change
3158
+ * before it runs.
2828
3159
  */
2829
3160
  private admitProse;
2830
3161
  private deliverAdmittedProse;
@@ -2849,13 +3180,6 @@ export declare class AgentFramework {
2849
3180
  /** A draft's state as the journal reads it now: after a write that failed
2850
3181
  * and was reconciled, whatever reached the journal counts. */
2851
3182
  private draftStateNow;
2852
- /**
2853
- * Where a delivered round leaves its turn's sticky destination, as the
2854
- * explicit gateway sets it once the round's envelopes run: each `>>`
2855
- * envelope whose target resolved becomes the destination. One that didn't
2856
- * resolve bounces and leaves it, as do `>>skip_reply` and unprefixed text.
2857
- */
2858
- private roundDestination;
2859
3183
  /** Locus-preserving explicit publication. Source remains byte-identical in Chronicle. */
2860
3184
  private deliverHybridProse;
2861
3185
  /** `>>skip_reply {{unsent}}` and its hybrid form: set the latest bounce
@@ -2956,8 +3280,9 @@ export declare class AgentFramework {
2956
3280
  executeToolCall(call: ToolCall): Promise<ToolResult>;
2957
3281
  /**
2958
3282
  * Admin puppet: execute ONE tool call AS an agent and persist the
2959
- * tool_use + tool_result pair in that agent's window exactly as a
2960
- * model-initiated call is stored.
3283
+ * tool_use + tool_result pair in that agent's window as a
3284
+ * model-initiated call is stored, but under the inline cap its call
3285
+ * carried, whereas a model's call takes the cap at the store.
2961
3286
  *
2962
3287
  * Born from the princess exemplar surgery (2026-08-23). Her folded
2963
3288
  * narrative said "I have no tools"; every past tool_use/tool_result pair
@@ -3002,51 +3327,67 @@ export declare class AgentFramework {
3002
3327
  /** Event-pushing wrapper for the model-driven dispatch path. */
3003
3328
  private dispatchCodeExecutionToolCall;
3004
3329
  /**
3005
- * Run one code_execution script for an agent. Never rejects.
3330
+ * A model-issued tool's result has arrived. When it answers the last of
3331
+ * the code_execution calls a round waits on (ScriptRound), the round's
3332
+ * prose is routed now, its scripts' calls counted.
3333
+ */
3334
+ private settleScriptRound;
3335
+ /**
3336
+ * Whether a code_execution call watches a script that can change its
3337
+ * round's routing, so the round waits for the call (ScriptRound): a run's
3338
+ * script, or the script a wait names by its script_id, as it would watch
3339
+ * it. Its code must name a tool whose call can change the round's routing
3340
+ * in the turn's mode, under its same-round policy (routingToolsNamed,
3341
+ * changesRouting). The reading is coarse, so a comment or a string naming
3342
+ * such a tool holds the round as well, for no longer than the call's yield,
3343
+ * and a name built at runtime isn't seen: its round is routed at once, as a
3344
+ * round was before scripts counted. A stop's watch counts what reaches the
3345
+ * host as any call's does (scriptRoundCalls), but nothing a script makes
3346
+ * once its stop is asked reaches a tool, since the runner refuses it, so a
3347
+ * stop holds no round, and a list returns at once.
3348
+ * Without code execution, or for an agent whose allowedTools doesn't name
3349
+ * code_execution, no script runs, and the call's answer settles no round,
3350
+ * so a round waiting for it would be withheld when its stream ended.
3351
+ */
3352
+ private scriptMayRoute;
3353
+ /**
3354
+ * One code_execution call: run a script, or wait for, stop or list the
3355
+ * agent's scripts. Never rejects.
3006
3356
  *
3007
- * The script runs in the agent's persistent python interpreter with every
3008
- * tool on the agent's CURRENT surface injected (minus code_execution
3009
- * itself). Inner tool calls are dispatched through dispatchToolCall — the
3010
- * exact model path, including MCPL state/checkpoint handling, channel
3011
- * routing, and traces — and resolved via scriptToolWaiters, so their
3012
- * results reach the running script and never the model context.
3357
+ * A script runs in a process of its own, on the engine, with every tool on
3358
+ * the agent's CURRENT surface (minus code_execution itself). Its calls come
3359
+ * back through dispatchToolCall as the agent's — the exact model path,
3360
+ * including MCPL state/checkpoint handling, channel routing, and traces —
3361
+ * and are resolved via scriptToolWaiters, so their results reach the script
3362
+ * and never the model context (scriptToolCall). The return says how the
3363
+ * script ended, or that it's still running, first; then its calls, its
3364
+ * value and its output since the last return (renderReturn). `roundCalls`,
3365
+ * when a round waits on this call (ScriptRound), takes the script's calls
3366
+ * that reach the host while this call watches it.
3013
3367
  */
3014
3368
  private runCodeExecution;
3015
- /** Background scripts are the primary agent's, or any agent's when no primary agent is named. */
3016
- private runsBackgroundScripts;
3017
- /** How many background scripts an agent may have running at once. */
3018
- private maxBackgroundScripts;
3019
- /** How many of this agent's background scripts are running now. */
3020
- private runningBackgroundScripts;
3021
- /**
3022
- * Start a background script: dedicated interpreter, output journaled to a
3023
- * workspace file, wake_agent() available in-script. The tool result
3024
- * returns immediately; the script runs until it ends, hits the lifetime
3025
- * ceiling, or is cancelled. Scripts DIE WITH THE HOST PROCESS — that
3026
- * limitation is stated in the tool description so agents can calibrate
3027
- * how much to rely on an armed wake.
3028
- */
3029
- private startBackgroundScript;
3030
- /** First read-write mount name, or null. */
3031
- private firstWritableMountName;
3369
+ /** code_execution's settings and every agent's scripts, made once code execution is on. */
3370
+ private makeCodeExecution;
3371
+ /** The tools a script of this agent may call now: the agent's own surface, without code_execution. */
3372
+ private scriptTools;
3032
3373
  /**
3033
- * wake_agent() from a background script: enforce the per-script wake cap
3034
- * and rate floor (delay, not drop — the script awaits the ack), then
3035
- * inject the provenance envelope + payload and request inference.
3036
- * Resolves null on delivery; an error string refuses the wake (raises
3037
- * RuntimeError inside the script).
3374
+ * The first read-write mount without an include, or null. The framework
3375
+ * keeps its own files there (`tool-results/`, `refs/`). A mount with an
3376
+ * include holds only the files it names, so it would refuse them, and a
3377
+ * setup whose only writable mount has one is treated as having none.
3038
3378
  */
3039
- private handleScriptWake;
3040
- /** Background script ended (clean, crash, deadline, cancel/dispose). */
3041
- private settleBackgroundScript;
3379
+ private firstWritableMountName;
3042
3380
  /**
3043
- * Deliver a background-script event: provenance envelope into the agent's
3044
- * context + an inference request. Deliberately does NOT consult the event
3381
+ * A script's word to its agent: a wake_agent() payload, or the ending of a
3382
+ * left script that failed, crashed or was stopped at its limit. It enters
3383
+ * the agent's context, spilled to the workspace past the agent's inline
3384
+ * cap, with an inference request. Deliberately does NOT consult the event
3045
3385
  * gate — the agent armed this wake themselves (wake-through-sleep
3046
3386
  * authority); it enters tagged so gate policies could be taught about it
3047
- * later if that ever needs revisiting.
3387
+ * later if that ever needs revisiting. Throws when it can't be delivered,
3388
+ * so the script's wake_agent() says so.
3048
3389
  */
3049
- private injectScriptWake;
3390
+ private scriptWake;
3050
3391
  /**
3051
3392
  * Oversized content policy (antra, 2026-07-31; completed for issue #89):
3052
3393
  * never hit the agent in the face with a huge blob, never silently destroy
@@ -3054,7 +3395,7 @@ export declare class AgentFramework {
3054
3395
  * file (readable with the agent's own tools — deterministic name, kept
3055
3396
  * until the workspace owner deletes it) and replaced by a truncated head +
3056
3397
  * a trailing file reference. Falls back to EXPLICIT plain truncation when
3057
- * there is no writable workspace. Cap resolution lives in
3398
+ * there is no read-write mount without an include. Cap resolution lives in
3058
3399
  * resolveToolResultInlineCap; callers pass the resolved cap.
3059
3400
  */
3060
3401
  /**
@@ -3083,8 +3424,8 @@ export declare class AgentFramework {
3083
3424
  */
3084
3425
  private storedToolResultText;
3085
3426
  /** Where a tool result labelled `label` is written: `<first writable
3086
- * mount>/tool-results/<label>.txt`, or null when there is no writable
3087
- * workspace. */
3427
+ * mount without an include>/tool-results/<label>.txt` (see
3428
+ * firstWritableMountName), or null when there is no such mount. */
3088
3429
  private toolResultFilePlace;
3089
3430
  /**
3090
3431
  * A withheld original uses the remaining time in its batch's deadline.
@@ -3101,54 +3442,41 @@ export declare class AgentFramework {
3101
3442
  /**
3102
3443
  * Write one tool result's text to its tool-results file (see
3103
3444
  * toolResultFilePlace): the one place both the inline cap's spill and the
3104
- * guard's withheld originals go. null when there is no writable workspace.
3445
+ * guard's withheld originals go. null when there is no writable mount
3446
+ * without an include.
3105
3447
  * A failed write is reported, traced and logged here, never thrown. With a
3106
3448
  * branch, the file lands on that branch or isn't written (see writeBinary).
3107
3449
  */
3108
3450
  private writeToolResultFile;
3451
+ /** How to read a tool result's file back a page at a time, with each page
3452
+ * sized to come back within `cap`, and, where `canRaise`, that raising
3453
+ * the inline cap would show more: where a cap at the readers' bound would
3454
+ * keep a longer head, or the whole result. */
3455
+ private spillPageAdvice;
3109
3456
  private spillOrTruncate;
3110
- private getOrCreateScriptRunner;
3111
3457
  /**
3112
- * Resolve one script-inner tool call to the string the script's tool
3113
- * function returns, and whether that result is an error (the script's
3114
- * `.is_error`). Never rejects: a failure without structured content becomes
3115
- * an "Error: ..." string, matching the managed PTC runtime ("Claude's code
3116
- * receives this error"), and a structured one its JSON object.
3117
- *
3118
- * A result without structured content is serialized with the HISTORY
3119
- * serializer: images become placeholders, since a script variable holding
3120
- * megabytes of base64 helps nobody. A result with structured content is
3121
- * one JSON object holding both of the server's views
3122
- * (scriptStructuredResult), so its content blocks reach the script as the
3123
- * dispatch gave them, images and payloads included. A module's result that
3124
- * can't be stored or sent, such as a cyclic object or a BigInt, is already
3125
- * an error naming the tool when the dispatch returns it (storableToolResult),
3126
- * so a script reads that error's text.
3127
- */
3128
- private handleScriptToolCall;
3129
- /** The 5MB protocol safety cap on what a script receives. */
3130
- private static readonly SCRIPT_RESULT_MAX_CHARS;
3131
- /**
3132
- * A structured MCP result as a script receives it: one JSON object holding
3133
- * both of the server's views, `{ content, structuredContent, isError }`,
3134
- * plus `error` (the text) on a tool error. `content` is the content array
3135
- * the dispatch gave this call (the direct reading): the server's blocks as
3136
- * sent, so payloads and images survive, except that an MCPL peer's blocks
3137
- * get the treatment RFC-005 gives them on every lane the model reads
3138
- * (referenceBlockForScript). `structuredContent` is the tool's own JSON, as
3139
- * sent. Past the size cap the result stays valid JSON: the whole object is
3140
- * saved to the workspace, and the script gets
3141
- * `{ isError, oversized: { chars, savedTo } }`. If it can't be saved, the
3142
- * script gets a failure to materialize the result, saying the tool may
3143
- * already have completed, never a success missing its result. A result
3144
- * that can't be converted to JSON (a cyclic object, a BigInt), which the
3145
- * dispatch's own check makes unlikely here, gets the same object empty,
3146
- * `{ content: [], structuredContent: null, isError: true, error }`, the
3147
- * error naming the tool. In every form, the script's `.is_error` is the
3148
- * `isError` of the object its string holds, and its `.structured` is read
3149
- * from that string.
3150
- */
3151
- private scriptStructuredResult;
3458
+ * The bridge: one of a script's calls, as its agent's, through the ordinary
3459
+ * dispatcher, so the agent's allowlist and every gate apply as they do to
3460
+ * its own call: the bridge's half of adding nothing to what the agent's
3461
+ * tools allow. Never rejects. A call the dispatcher refused before it
3462
+ * opened (ToolResult.refused) reaches the script as a ToolRefused Error with
3463
+ * the refusal's text; any other result, a failure included, reaches it in
3464
+ * the one shape every tool answers (scriptResultAnswer).
3465
+ */
3466
+ private scriptToolCall;
3467
+ /**
3468
+ * A dispatched result as a script receives it: `{ content, structuredContent,
3469
+ * isError }`, one shape for every tool. `content` is
3470
+ * what the model would read: a structured result's blocks as the dispatch
3471
+ * gave them (the direct reading, with RFC-005's treatment of an MCPL peer's
3472
+ * blocks), and otherwise one text block of the model's text, which for a
3473
+ * failure is its error. `structuredContent` is the tool's own structured
3474
+ * content where it sent one, `false`, `0` and `null` included, else null.
3475
+ * A result that can't be converted to JSON (a cyclic object, a BigInt),
3476
+ * which the dispatch's own check makes unlikely here, is a failure naming
3477
+ * the tool and saying the call itself completed.
3478
+ */
3479
+ private scriptResultAnswer;
3152
3480
  /**
3153
3481
  * Dispatch a script-inner tool call through the NORMAL dispatch path and
3154
3482
  * resolve with its result. The waiter intercept in handleProcessEvent
@@ -3161,8 +3489,25 @@ export declare class AgentFramework {
3161
3489
  * `turnId` is the turn the call was made in (dispatchToolCall).
3162
3490
  */
3163
3491
  private dispatchScriptToolCall;
3164
- /** Abort the agent's script, running or still starting, when the turn it belongs to ends or is reset to run again. */
3165
- private abortAgentScript;
3492
+ /**
3493
+ * A stream's turn ended without its calls' answers, or is reset to run
3494
+ * again (a stream cancelled, failed or waiting on its provider): the
3495
+ * agent's scripts take it as an abandoned end of that stream's turn
3496
+ * (AgentScripts.turnEnded). A quiesce abandons its stream's own turn (or
3497
+ * every turn, when it has none to name), and the host stopping every turn
3498
+ * of the agent's (`'every'`).
3499
+ */
3500
+ private abandonAgentScripts;
3501
+ /**
3502
+ * The agent's turns still live, for its scripts (AgentScripts.turnEnded):
3503
+ * its open logical turn, and the turn of its start in progress, unless
3504
+ * that's `ending`'s or has settled. A start is in progress while it holds
3505
+ * the agent's turn token, from its dequeue through its hooks, compile,
3506
+ * stream and restarts to its settled teardown (activeTurnTokens); its turn
3507
+ * ends at its settle, and the teardown after it, such as its speech's
3508
+ * delivery, is no longer the turn's (settledTurns).
3509
+ */
3510
+ private liveTurns;
3166
3511
  private toMembraneToolResult;
3167
3512
  /**
3168
3513
  * If `data` is an MCP tool-result content array carrying at least one image,
@@ -3170,8 +3515,10 @@ export declare class AgentFramework {
3170
3515
  * the array is text-only (let JSON path handle it; saves a code path).
3171
3516
  * `maxChars`, when provided, caps each accompanying text block so an image
3172
3517
  * inlined alongside an enormous text payload can't blow the context. A
3173
- * block is cut as the stored copy is (toolResultCutAt), never inside a
3174
- * slot, so the stored copy can keep exactly the slots this showed (#403).
3518
+ * block is cut at the cap as the stored copy's cut at that cap is
3519
+ * (toolResultCutAt), never inside a slot, so the stored copy can keep
3520
+ * exactly the slots this showed (#403); under a readers' bound the stored
3521
+ * copy's cut can come earlier (cutStoredToolResultToFit).
3175
3522
  */
3176
3523
  private tryNativeToolResultContent;
3177
3524
  private toolImageLedgerFor;
@@ -3186,8 +3533,22 @@ export declare class AgentFramework {
3186
3533
  * (Sol's #94 ruling: a durable preference must not be a durable path for
3187
3534
  * one tool result to exceed maxMessageTokens; the way to see the whole
3188
3535
  * result is the spill file, not an over-bound blob in live context).
3536
+ * An ordinary resident's results land in the shared slot, which each of
3537
+ * its readers compiles under its own strategy, so the bound is the
3538
+ * smallest of theirs, as the tune-out dump's is (residentMessageChars); a
3539
+ * fork's or an ephemeral agent's store has itself as its only reader.
3189
3540
  */
3190
3541
  private resolveToolResultInlineCap;
3542
+ /**
3543
+ * A tool call's resultMaxChars: how long its result may be and still reach
3544
+ * its caller whole. A call from a running script resolves to the script,
3545
+ * which takes any result that fits its memory (scriptResultMaxChars). Any
3546
+ * other call's result is stored in its agent's context under the agent's
3547
+ * inline cap, unless its round's results together pass the readers' bound,
3548
+ * when each takes its share (buildStoredToolResultContent), and a call for
3549
+ * an agent the framework doesn't hold gets the house default.
3550
+ */
3551
+ private resultMaxCharsFor;
3191
3552
  private approximateDecodedBase64Bytes;
3192
3553
  private sanitizeProcessLogValue;
3193
3554
  /** Writes one inference-log entry. A stream's entries go through its
@@ -3248,25 +3609,44 @@ export declare class AgentFramework {
3248
3609
  * while unregistered. Genuine legacy caller names retain their surface. */
3249
3610
  private canAgentUseTool;
3250
3611
  private agentToolPermissionFailure;
3612
+ /**
3613
+ * A dispatched call answered without running its tool. RFC-007's lifecycle
3614
+ * forgets it, and its result says it was refused (`ToolResult.refused`), both
3615
+ * from here, so the two can't disagree.
3616
+ */
3617
+ private refusedResult;
3251
3618
  /**
3252
3619
  * Why this host refuses a skip_reply call, as the model will read it, or
3253
3620
  * undefined when it doesn't (skipReplyWakeRefusal): without an EventGate,
3254
3621
  * any wake_in_seconds; with one, a wake_in_seconds that isn't a number of
3255
3622
  * seconds. Only when the channel registry handles skip_reply. The dispatch
3256
3623
  * that refuses the call reads it here, and so does the turn's bookkeeping of
3257
- * a refused round, for the model's own calls: the silence before it, which
3258
- * comes back after its round, and in XML mode which round's prose stays
3259
- * private. A skip_reply round's own prose stays private by the tool's name,
3260
- * refused or not.
3624
+ * a refused round (roundCallOf), for the model's calls and a script's calls
3625
+ * that reach the host while a call of the round watches it: the silence
3626
+ * before it, which comes back after its round, and in XML mode which round's
3627
+ * prose stays private. A skip_reply round's own prose stays private by the
3628
+ * tool's name, refused or not.
3261
3629
  */
3262
3630
  private skipReplyRefusal;
3263
3631
  private refusesSelfWake;
3632
+ /**
3633
+ * A call as its round's routing counts it, made directly, or by a script
3634
+ * and reaching the host while a run or wait call of the round watches it
3635
+ * (ScriptRound). A skip_reply refused, because the agent's allowedTools
3636
+ * doesn't name it or because this host can't set the wake it asks for, is
3637
+ * marked refused: it keeps its own round private and silences nothing after
3638
+ * it. A refusal withholds the call's effect, not the model's choice to keep
3639
+ * its words private. Any other call the list refuses posted nothing, so it
3640
+ * gives no cause. A script's call the bridge refuses before dispatch
3641
+ * (`refusedHere`) counts as one the list refuses.
3642
+ */
3643
+ private roundCallOf;
3264
3644
  /**
3265
3645
  * Dispatch a call the agent made. `turnId` is the turn it was made in
3266
3646
  * (TurnRouting.turnId), as its caller knows it: a model's call, the turn
3267
- * whose stream made it; a foreground script's inner call, the turn of the
3268
- * code_execution call whose script is running when the call arrives. A
3269
- * background script's call has none.
3647
+ * whose stream made it; a script's call, the turn of the code_execution
3648
+ * call watching the script when the call reaches the host. A call of a
3649
+ * script left running, which no call watches, has none.
3270
3650
  */
3271
3651
  private dispatchToolCall;
3272
3652
  private dispatchToolCallEvent;
@@ -3294,6 +3674,31 @@ export declare class AgentFramework {
3294
3674
  * keeps them while the framework runs.
3295
3675
  */
3296
3676
  private requeueDrained;
3677
+ /**
3678
+ * What the next compile sends for each of `ids`, messages a tool boundary
3679
+ * has just stored, as the agent's strategy renders them as the newest of
3680
+ * its window (ContextManager.renderAsNewest): cut by the per-message cap,
3681
+ * a sharded body joined, and the image limits applied over the batch, so
3682
+ * the live stream hears what the next compile sends. An id comes back as
3683
+ * null where that compile won't send the message among its newest.
3684
+ * Undefined where the strategy has no such hook, or the render threw,
3685
+ * which is logged: the boundary then injects what it stored, as it did
3686
+ * before strategies could say.
3687
+ */
3688
+ private renderForInjection;
3689
+ /**
3690
+ * Tell the agent of the messages a tool boundary stored and left out of
3691
+ * its injection, since the next compile won't send them among its newest:
3692
+ * who sent each and its size, and how to read it, `history--extract`
3693
+ * around it where the agent is shown that tool, else its id. None of a
3694
+ * message's words: the line stands in for a message the live round
3695
+ * doesn't carry. A system line, so it's no conversation: it neither
3696
+ * re-pins the turn nor clears its send suppression. It names the agent
3697
+ * it's for, since every resident sharing the slot reads it too. Returns
3698
+ * the notice as stored, for the boundary to inject after the batch, or
3699
+ * undefined when it couldn't be stored, which is logged.
3700
+ */
3701
+ private recordLeftOutNotice;
3297
3702
  /**
3298
3703
  * Write drained entries in queue (seq) order, whatever their targets:
3299
3704
  * residents share one message slot, so the order entries arrived in is the
@@ -3305,18 +3710,53 @@ export declare class AgentFramework {
3305
3710
  *
3306
3711
  * So none of a target's entries lands ahead of an earlier one, and a queued
3307
3712
  * tool_use that can't be stored keeps the tool_result queued behind it from
3308
- * being stored alone. (A tool_use that is stored, followed by a tool_result
3309
- * that can't be, stays stored without it until the tool_result lands at a
3310
- * later flush. The only queued pair is puppetToolCall's defensive one,
3311
- * which no path reaches today.) An entry that keeps failing is logged by
3312
- * id at each flush, and holds its target's later queued writes rather than
3313
- * letting them land out of order.
3713
+ * being stored alone, unless context-manager refused it as malformed
3714
+ * (below). (A tool_use that is stored, followed by a tool_result that
3715
+ * can't be, stays stored without it until the tool_result lands at a later
3716
+ * flush, or for good when the store refuses the tool_result as malformed.
3717
+ * The only queued pair is puppetToolCall's, queued only when its turn's
3718
+ * token is no longer its own once the pair is built, which its comment
3719
+ * calls defensive.) An entry that keeps failing is logged by id at each
3720
+ * flush, and holds its target's later queued writes rather than letting
3721
+ * them land out of order.
3314
3722
  *
3315
- * The hold is the queue's alone. A write that isn't deferred is stored at
3316
- * once and can land ahead of a held entry: a fresh tool_result, whatever
3317
- * its agent's state, and any write while its agent's turn, stream and tool
3318
- * cycle are all idle and the host isn't quiesced. So an entry that keeps
3319
- * failing holds only what is deferred behind it.
3723
+ * An entry context-manager refuses as malformed (MalformedContentError) is
3724
+ * the exception for the store's own validation: context-manager checks
3725
+ * content and every shard before writing. A custom synchronous strategy
3726
+ * hook can throw the same class after append (context-manager #288);
3727
+ * unreadable landing in that callback escape remains a limitation until
3728
+ * the CM follow-up lands. A copy actually found still counts first. Other
3729
+ * ambiguous errors remain queued for ID reconciliation before retry. A
3730
+ * malformed refusal would fail every flush and hold its target's later
3731
+ * writes for good, so it's logged and dropped instead, and its
3732
+ * target isn't cut: left in the un-acked set, the next ack drops it from
3733
+ * the durable queue. A tool_use dropped this way leaves a tool_result
3734
+ * queued behind it to be stored alone. context-manager mends a tool_use
3735
+ * whose input isn't an object, so it refuses one only when that input has
3736
+ * no JSON form or the block itself is malformed. addMessage refuses such
3737
+ * content before it's queued, so an entry meets this here from a queue an
3738
+ * earlier process persisted, as puppetToolCall's pair, which it queues
3739
+ * itself, or when the strategy's chunking splits well-formed content into a
3740
+ * shard the store refuses, which the store's error names.
3741
+ *
3742
+ * From a fresh turn's start to the end of its coalescing assembly, before
3743
+ * its checkpoint, every write deferred for its agent lands in that
3744
+ * request, in arrival order, up to one that can't be stored and unless the
3745
+ * host is quiesced (flushForStart). The turn-start flush writes the queue;
3746
+ * while the assembly runs, each write it makes into the agent's own window
3747
+ * (addMessage's bypassDeferralFor) first writes what was deferred since;
3748
+ * and what was deferred during the assembly is written once it ends. A
3749
+ * write the assembly makes while an entry is held waits behind it in the
3750
+ * queue, so the hold covers the assembly's writes too, and so does one
3751
+ * made while the host is quiesced with anything queued for the agent: a
3752
+ * quiesce that begins while an assembly awaits a render lets that turn
3753
+ * drain, and what is queued waits for resume(). Outside that window the
3754
+ * hold is the queue's alone: a write that isn't deferred is stored at once
3755
+ * and can land ahead of a held entry, as a fresh tool_result does whatever
3756
+ * its agent's state, and any write does while its agent's turn, stream and
3757
+ * tool cycle are all idle and the host isn't quiesced. So an entry that
3758
+ * keeps failing holds what is deferred behind it and the assembly's writes
3759
+ * for its agent.
3320
3760
  *
3321
3761
  * A write can throw after its message is stored: a store listener, the
3322
3762
  * strategy's handling of the add, or a later shard of a sharded body can
@@ -3326,24 +3766,28 @@ export declare class AgentFramework {
3326
3766
  * written, at most once: the entry isn't requeued and stored a second
3327
3767
  * time, and what landed, as later compiles render it (asCompiled), is what
3328
3768
  * it returns as the entry's content. For a sharded body, that can be its
3329
- * first shards alone, since the append loop stops at the throw; the rest
3330
- * of the body isn't stored. (Requeued, the
3769
+ * first shards alone if rollback could not remove them; context-manager
3770
+ * from 0.15 otherwise removes shards from a failed append. (Requeued, the
3331
3771
  * landed shards would be stored twice, and only the rest could not be
3332
3772
  * appended later without splitting the body.) Boot's scan for landed
3333
3773
  * writes counts a landed shard the same way. When the store can't be read
3334
- * back (storedCopiesOf logs it), nothing is found, and the entry is put
3335
- * back as one that couldn't be stored: if it had landed, a later flush
3336
- * stores it again.
3774
+ * back (storedCopiesOf logs it), or couldn't say how many messages it held
3775
+ * before the write, whether the entry landed is unknown: it's put back
3776
+ * marked so (`landing`), and before it's written again the store is
3777
+ * searched for its id (landedCopiesById). Found, it counts as written, as
3778
+ * above, at the flush that finds it; not found, it's written; and while
3779
+ * the store can't be searched, it stays queued, holding what's behind it.
3337
3780
  *
3338
3781
  * Returns what was written (stored, or deferred again by addMessage, whose
3339
- * id is then empty), in queue order: for one target, a prefix of its
3340
- * entries. Each comes with its content: as given, unless the store took it
3341
- * as more than one message (a sharded body) and can be read back, when its
3342
- * copies are returned joined, as later compiles render them (asCompiled),
3343
- * or its write threw after storing it (above). `onLanded` hears an entry
3344
- * whose write threw after storing it, with the id it landed under, as soon
3345
- * as it's found: before the writes after it, so whatever it records keeps
3346
- * their order.
3782
+ * id is then empty), in queue order: for one target, its entries up to the
3783
+ * first that couldn't be stored, less entries refused as malformed and dropped. Each comes
3784
+ * with its content: as given, unless the store took it as more than one
3785
+ * message (a sharded body) and can be read back, when its copies are
3786
+ * returned joined, as later compiles render them (asCompiled), or its write
3787
+ * threw after storing it (above). `onLanded` hears an entry whose write
3788
+ * threw after storing it, with the id it landed under, as soon as it's
3789
+ * found: before the writes after it, so whatever it records keeps their
3790
+ * order.
3347
3791
  */
3348
3792
  private writeDrainedInOrder;
3349
3793
  /** How many messages the agent's store holds: undefined when its store
@@ -3352,26 +3796,68 @@ export declare class AgentFramework {
3352
3796
  /** The messages carrying `deferredWriteId` among those the agent's store
3353
3797
  * gained from position `from` on, in store order, with their blobs
3354
3798
  * resolved, as a request carries them. A sharded body's carry its
3355
- * `bodyGroupId`. */
3799
+ * `bodyGroupId`. Undefined when the store can't be read back, which is
3800
+ * logged: not the same as nothing found. */
3356
3801
  private storedCopiesOf;
3802
+ /** The messages `match` picks among those the agent's store gained from
3803
+ * position `from` on, in store order, with their blobs resolved. Undefined
3804
+ * when the store can't be read back, which is logged under `tag`, naming
3805
+ * `what` was written: not the same as nothing found. */
3806
+ private storedSince;
3807
+ /** The messages carrying `deferredWriteId` anywhere in the agent's store,
3808
+ * found by their id (queryMessages, as landedRow finds a held write's),
3809
+ * so no position is needed. Undefined when the store can't be searched,
3810
+ * which is logged. */
3811
+ private landedCopiesById;
3357
3812
  /** The line naming a drained write that threw: one that couldn't be stored,
3358
- * which is already back in the queue, or, with `landed`, one stored before
3359
- * the throw (for a sharded body, how many of its shards). Logging mustn't
3360
- * fail the flush that met it, so a thrown value that has no text is named
3361
- * as such. */
3813
+ * which is already back in the queue; with 'dropped', a malformed refusal
3814
+ * from the store's pre-write validation (see the CM #288 caveat above);
3815
+ * with a count, one stored before the
3816
+ * throw (for a sharded body, how many of its shards), or, with
3817
+ * `foundLater`, one an earlier write of which landed and was found by its
3818
+ * id; with `'unknown'`, one whose store couldn't be read to tell
3819
+ * whether it landed, back in the queue to be looked up first; and with
3820
+ * `'still-unknown'`, one that still can't be looked up. Logging mustn't
3821
+ * fail the flush that met it, so a thrown value that has no text is
3822
+ * named as such. */
3362
3823
  private logDeferredWriteError;
3824
+ /**
3825
+ * Write what is queued for `agent` into its window past its deferral, in
3826
+ * queue order and cut at a write that fails, though one the store refuses
3827
+ * as malformed is dropped and what follows goes on (writeDrainedInOrder),
3828
+ * between a fresh turn's start and its checkpoint, where what is stored is
3829
+ * the turn's input: at the start, before each write the coalescing
3830
+ * assembly makes for the agent, and once the assembly ends, the last two
3831
+ * not while the host is quiesced, when what is queued waits for resume().
3832
+ * What is stored is weighed for the start now beginning and for every
3833
+ * other resident's open turn. Returns whether anything is still queued for
3834
+ * the agent.
3835
+ */
3836
+ private flushForStart;
3837
+ /** Whether anything is queued for `agentName`, by drainDeferredFor's
3838
+ * target rule. */
3839
+ private queuedFor;
3363
3840
  /** Re-add drained entries through addMessage, which stores each or defers
3364
3841
  * it again, in queue order and cut per target (writeDrainedInOrder). With
3365
3842
  * `bypassDeferral`, each is stored past its target's deferral (stop()). A
3366
3843
  * write that threw after storing missed the notes addMessage takes after a
3367
3844
  * store, so they're taken for what landed as soon as it's found, before
3368
3845
  * the writes after it: an open turn's arrivals keep the order the writes
3369
- * landed in, and its newest stays the newest (remainingArrival). */
3846
+ * landed in, and its newest stays the newest (remainingArrival).
3847
+ *
3848
+ * A target no longer registered (a fork or a run that has ended, here or
3849
+ * before a crash) has no window to land in: a failed reply queued for it,
3850
+ * or a channel notice it could have acted on, becomes the primary's
3851
+ * by-name notice, under the entry's own id and place in the queue
3852
+ * (queuedNoticeForPrimary), and is written with the rest; any other write
3853
+ * is dropped, logged, by addMessage. Nothing here reads the gone agent's
3854
+ * window, so such a notice an earlier write of which landed there, and
3855
+ * which the agent read, goes on too. */
3370
3856
  private readdDrained;
3371
3857
  /**
3372
3858
  * Where a notice about an agent's own action belongs: its failed reply, its
3373
- * bounced prose (beside its `{{unsent}}` clipboard), its background script's
3374
- * wake, the notices about its drafts. Every registered agent's notice is
3859
+ * bounced prose (beside its `{{unsent}}` clipboard), its script's wake, the
3860
+ * notices about its drafts. Every registered agent's notice is
3375
3861
  * addressed to that agent, so it lands in the window that agent reads and
3376
3862
  * waits on that agent's own turn, stream and tool cycle: a conversation
3377
3863
  * fork or an ephemeral run reads only its isolated slot, and a resident's
@@ -3382,9 +3868,10 @@ export declare class AgentFramework {
3382
3868
  * null when the agent is no longer registered (a fork or a run already
3383
3869
  * released): there is no window to write, so the caller writes nothing,
3384
3870
  * traces nothing and requests no wake. The drop is logged here, once. A
3385
- * failed reply is passed on by name instead (passFailedReplyToPrimary). The
3386
- * notice of a channel an agent's own send opened follows the same rule in
3387
- * recordChannelAutoOpenNotice, which passes it on by name too.
3871
+ * failed reply is passed on by name instead (passNoticeToPrimary). The
3872
+ * notices of a channel an agent's own send opened, or a reply couldn't
3873
+ * open, follow the same rule in their builders (channelOpenedNotices,
3874
+ * replyOpenFailedNotices), which pass them on by name too.
3388
3875
  */
3389
3876
  private noticeTargetFor;
3390
3877
  /**
@@ -3393,33 +3880,77 @@ export declare class AgentFramework {
3393
3880
  * (releaseWindowNowOrAfterResume), since a write could land mid-surgery.
3394
3881
  *
3395
3882
  * The agent never reads its window again, so every failed-reply notice it
3396
- * never read is passed to the primary, by name, once: each one stored in
3397
- * its window above its consumed watermark (flushed there at its turn's end,
3398
- * or stored while it was idle) and not heard at a tool boundary, and each
3399
- * one still queued for it. Writes still
3400
- * queued would wait for a boundary it never reaches, and the flush that
3401
- * finds it gone would drop them, so they land in its own window now, which
3402
- * Chronicle keeps for investigation. Its stream is over or cancelled, so it
3403
- * compiles nothing more. One path still stores after these writes: a
3404
- * `complete` that arrived while the agent still waited for tools awaits
3405
- * the spill of its last tool results, and stores them once that resolves,
3406
- * even if a watchdog has ended the run meanwhile. A tool boundary stores
3407
- * nothing for a round whose turn was stopped while its results were
3883
+ * never read, and every channel notice it could act on and never read, is
3884
+ * passed to the primary, by name, once (passesToPrimary,
3885
+ * passOnFromReleasedWindow): each one stored in its window above its
3886
+ * consumed watermark (flushed there at its turn's end, or stored while it
3887
+ * was idle) and not heard at a tool boundary, and each one still queued
3888
+ * for it, pending or un-acked. One with an entry still in the durable
3889
+ * queue goes on only as that entry, under its own id and seq, so a crash
3890
+ * before the ack below replays it once; a copy of it in the window decides
3891
+ * only whether the agent read it. Writes still queued would wait for a
3892
+ * boundary it never reaches, and a flush that finds it gone would drop all
3893
+ * but the notices it passes on, so they land in its own window now, which
3894
+ * Chronicle keeps for investigation. One whose earlier write may have
3895
+ * landed (`landing` unknown) is looked up there by its id first, or, where
3896
+ * the store can't be searched, in the window's own read: found, it isn't
3897
+ * stored again; where neither can see the store, it's stored anyway, with
3898
+ * a line saying it may now be stored twice, or, where storing it fails
3899
+ * too, that it may be stored once, twice or not at all. Its stream is over
3900
+ * or cancelled, or, when stop() ends it, may still run past its cancel, and
3901
+ * then drops each event that comes after the agent has left (driveStream);
3902
+ * a turn of its still assembling or compiling, as when stop() ends it,
3903
+ * drops before it sends anything. One path still stores after these
3904
+ * writes: a `complete` that arrived while the agent still waited for tools
3905
+ * awaits the spill of its last tool results, and stores them once that
3906
+ * resolves, even if a watchdog has ended the run meanwhile. A tool boundary
3907
+ * stores nothing for a round whose turn was stopped while its results were
3408
3908
  * prepared.
3409
3909
  */
3410
3910
  private releaseWindow;
3411
3911
  /**
3412
- * The failed-reply notices stored in `agent`'s window that it never read:
3413
- * those above the lower of its consumed watermark and the point where the
3414
- * watermark's branch and the current one part (branchesPartAt), or every
3415
- * one, when it never compiled. The watermark moves at a compile, and at a
3416
- * tool boundary whose
3417
- * stream declares it carries the messages injected there
3418
- * (markContextConsumed), so a notice the live stream heard is under it, and
3419
- * one a boundary stored without sending (a turn a tool ended, a budget
3420
- * restart, a stream that may drop injections) is above it.
3421
- */
3422
- private unreadFailedReplies;
3912
+ * The part of a released agent's pass to the primary that its release and
3913
+ * stop() share (stop() runs it for a release the quiesce postponed). Each
3914
+ * notice stored in its window that it never read and the primary takes in
3915
+ * its place (passesToPrimary: a failed reply, or a channel notice its
3916
+ * reader could act on) goes on as stored, by name (passNoticeToPrimary),
3917
+ * except a copy of an entry for it still in the durable queue, pending or
3918
+ * un-acked: that entry is the notice's one identity until its ack, the one
3919
+ * boot's check for landed writes knows, so it's the entry that goes on, as
3920
+ * the primary's by-name notice under its own id and seq (`passOn`,
3921
+ * queuedNoticeForPrimary), and a crash before the ack replays it once, not
3922
+ * twice. A queued notice goes on unless the agent read a copy of it that
3923
+ * landed in its window; where the window can't be read, it goes on, since
3924
+ * telling the primary of a notice the agent may have read costs less than
3925
+ * telling no one. Both callers run this before their drain, which hands
3926
+ * pending entries to the un-acked set, so the un-acked entries for the
3927
+ * agent here have all landed (their write went through, or a lookup found
3928
+ * it: settleFound), and they go on here; the pending ones are the
3929
+ * caller's. Returns the window's read, `passOn`, what it has queued so far
3930
+ * for the primary, and how many un-acked entries the agent had.
3931
+ */
3932
+ private passOnFromReleasedWindow;
3933
+ /**
3934
+ * What a released agent's window holds that its pass to the primary reads
3935
+ * (passOnFromReleasedWindow): `unread`, the notices stored there that it
3936
+ * never read and the primary takes in its place (passesToPrimary: its
3937
+ * failed replies, and the channel notices it was told it could act on),
3938
+ * other than copies of the entries `held` names; and `held`, for each of
3939
+ * those entries with a copy there, its copies and whether any of them is
3940
+ * unread. A notice is read below the lower of its consumed watermark and
3941
+ * the point where the watermark's branch and the current one part
3942
+ * (branchesPartAt), and unread everywhere when it has no watermark. The
3943
+ * watermark is set when the agent is created, and moves at a compile, and
3944
+ * at a tool boundary whose stream declares it carries the messages
3945
+ * injected there (markContextConsumed). So a notice such a stream carried
3946
+ * is under it. One a boundary stored without sending (a turn a tool ended,
3947
+ * a budget restart) is above it, and so is one injected into a stream that
3948
+ * doesn't declare it carries injections, which may have dropped it:
3949
+ * counted as unread, it goes to the primary even if the agent heard it,
3950
+ * rather than to no one where the stream dropped it. null when the window
3951
+ * can't be read, which is logged.
3952
+ */
3953
+ private releasedWindow;
3423
3954
  /**
3424
3955
  * The last sequence two branches' histories share: Infinity for one branch,
3425
3956
  * and for two, the point where they part. A branch's records are numbered
@@ -3438,39 +3969,71 @@ export declare class AgentFramework {
3438
3969
  * deregistered, so its stream can't dispatch anything more and resume
3439
3970
  * doesn't weigh its context, and a write addressed to it meanwhile is
3440
3971
  * treated as for any agent no longer registered (dropped, or passed to the
3441
- * primary if it's a failed reply).
3972
+ * primary if it's a failed reply, or a channel notice its reader could act
3973
+ * on).
3442
3974
  */
3443
3975
  private releaseWindowNowOrAfterResume;
3444
3976
  /** resume(): the windows whose release the quiesce window postponed, each on its own. */
3445
3977
  private runReleasesAfterResume;
3446
3978
  /**
3447
- * A fork or an ephemeral run ended before reading that its reply's delivery
3448
- * to a channel failed: it was released with the notice stored in its window
3449
- * unread, or its delivery failed after release. (A notice still queued for
3450
- * it, at release or restored at boot, goes on as the queue entry itself:
3451
- * queuedFailedReplyForPrimary.) Tell the primary instead, naming the
3452
- * speaker, so an agent who can still act learns of it and can tell the
3453
- * human. It gives the reply's length, not its words, which stay in the
3454
- * speaker's window. Its wording follows the speaker's own notice
3455
- * (onRouteFailure): a delivery that wasn't confirmed may have been posted,
3456
- * and neither text says no one saw the reply, since only this channel's
3457
- * routing failed. Only for a delivery to a channel; a reply that had no
3458
- * channel to go to (no locus) had no human waiting for it. Never throws:
3459
- * it runs inside a release, which must complete whatever this write meets.
3460
- */
3461
- private passFailedReplyToPrimary;
3462
- /**
3463
- * A queued failed-reply entry for `speaker`, who is gone, as the primary's
3464
- * by-name notice (passFailedReplyToPrimary's words): the same entry, under
3465
- * its own id and seq, now addressed to the primary. Written through the
3466
- * drain, it lands stamped with that id, or waits in the queue under it, so
3467
- * boot's exactly-once holds for it: a crash before the original's ack
3468
- * replays one entry, never the original and a separate notice. null when no
3469
- * one is told (logged): a reply that had no channel to reach, or no primary.
3470
- */
3471
- private queuedFailedReplyForPrimary;
3979
+ * A fork or an ephemeral run ended before reading a notice the primary
3980
+ * takes in its place (passesToPrimary): it was released with the notice
3981
+ * stored in its window unread, or, for a failed reply, its delivery failed
3982
+ * after release. (A notice still queued for it, at release or restored at
3983
+ * boot, goes on as the queue entry itself: queuedNoticeForPrimary.) Tell
3984
+ * the primary instead, naming the speaker, so an agent who can still act
3985
+ * learns of it (noticeForPrimary). Never throws: it runs inside a release,
3986
+ * which must complete whatever this write meets.
3987
+ */
3988
+ private passNoticeToPrimary;
3989
+ /**
3990
+ * A queued entry for `speaker`, who is gone, that the primary takes in its
3991
+ * place, as the primary's by-name notice (noticeForPrimary): the same
3992
+ * entry, under its own id and seq, now addressed to the primary. Written
3993
+ * through the drain, it lands stamped with that id, or waits in the queue
3994
+ * under it, so boot's exactly-once holds for it: a crash before the
3995
+ * original's ack replays one entry, never the original and a separate
3996
+ * notice. An entry marked as one whose earlier write may have landed
3997
+ * (`landing`) keeps the mark, so before it's written it's looked up by its
3998
+ * id in the primary's window, where it would land now
3999
+ * (writeDrainedInOrder). A release has looked in the speaker's own window
4000
+ * first (releaseWindow). null when no one is told (logged where it's
4001
+ * decided).
4002
+ */
4003
+ private queuedNoticeForPrimary;
4004
+ /**
4005
+ * The primary's by-name notice in place of one `speaker` never read, and
4006
+ * what it's about, as a log line says it: a failed reply's
4007
+ * (failedReplyNoticeForPrimary) or a channel notice's
4008
+ * (channelNoticeForPrimary). null when no one is told, which is logged
4009
+ * where it's decided.
4010
+ */
4011
+ private noticeForPrimary;
4012
+ /**
4013
+ * The primary's by-name notice in place of a channel notice `speaker` was
4014
+ * told it could act on and never read: its builder, called again now that
4015
+ * `speaker` has ended, gives the words it gives an agent that has ended,
4016
+ * judged for the primary, or nothing, logged, with no primary to tell.
4017
+ * They speak of the open or the failure as it was, as the notice did, a
4018
+ * failed one's reason for its selection included, which an agent's
4019
+ * channel_open since replaces in the record and not in the words, and
4020
+ * only of what still holds by each channel's durable decision on its own
4021
+ * server: the registry's (getDesiredState), or before there is one, as at
4022
+ * a serving boot's flush, the lifecycle log's (desiredStateInLog). An
4023
+ * opened channel is kept while it's decided open or tuned out, whatever its
4024
+ * transport is doing at that moment: the decision is what channel_close
4025
+ * changes and what the host carries out once the transport is back, and at
4026
+ * a serving boot no transport is up yet. A failed one is kept only while
4027
+ * it's still decided open and its transport isn't open, since "Not open"
4028
+ * would misstate an open one. One tuned out since is left out too: the
4029
+ * tune-out is a newer decision, by an agent that knows the channel, and
4030
+ * the notice's reason and its channel_open advice, which a tuned-out
4031
+ * channel refuses, would misstate it. With nothing left, no one is told,
4032
+ * logged here.
4033
+ */
4034
+ private channelNoticeForPrimary;
3472
4035
  /** The primary's by-name notice of `speaker`'s failed reply, or null when no
3473
- * one is told, which is logged here (see passFailedReplyToPrimary). */
4036
+ * one is told, which is logged here (see passNoticeToPrimary). */
3474
4037
  private failedReplyNoticeForPrimary;
3475
4038
  /**
3476
4039
  * A channel as a notice names it: the label when the registry has one, since
@@ -3493,17 +4056,18 @@ export declare class AgentFramework {
3493
4056
  * slot (sharedSlotAgents). A write whose target is gone isn't among them:
3494
4057
  * no module reads that agent's store, and the write waits for its window's
3495
4058
  * release (drainDeferredFor) or, at its flush, is dropped (addMessage), a
3496
- * failed reply passing to the primary as its notice
3497
- * (queuedFailedReplyForPrimary).
4059
+ * failed reply, or a channel notice its reader could act on, passing to the
4060
+ * primary as its notice (queuedNoticeForPrimary).
3498
4061
  */
3499
4062
  private heldWritesFor;
3500
4063
  /**
3501
4064
  * The writes held for `reader`'s store (heldWritesFor) as the rows a
3502
- * module's context reads: each under its handle, marked `held`, with the
3503
- * participant, content and metadata it was written with, the time it was
3504
- * first held as its timestamp, and a sequence after every row the store
3505
- * holds, in queue order. The sequence and timestamp are provisional: the
3506
- * stored row has the store's own.
4065
+ * module's context reads: each under its handle, marked `held`, and
4066
+ * `heldFromResidents` too when its metadata carries a tune-out's stamp
4067
+ * (asModuleRow), with the participant, content and metadata it was
4068
+ * written with, the time it was first held as its timestamp, and a
4069
+ * sequence after every row the store holds, in queue order. The sequence
4070
+ * and timestamp are provisional: the stored row has the store's own.
3507
4071
  */
3508
4072
  private heldRows;
3509
4073
  /** The row a held write landed as, found by the id it's stored with
@@ -3511,6 +4075,54 @@ export declare class AgentFramework {
3511
4075
  * as addMessage answers a stored write. Null when it hasn't landed, or is
3512
4076
  * no longer in the store. */
3513
4077
  private landedRow;
4078
+ /**
4079
+ * Settle held writes whose landing is unknown (DeferredWrite.landing),
4080
+ * among those `which` picks, before a path reads or changes held writes:
4081
+ * each is looked up by its id in its target's store (landedCopiesById).
4082
+ * Found, the write landed (settleFound). Not found, the mark goes, and
4083
+ * it's an ordinary held write, which is persisted as an edit is. Where the
4084
+ * store can't be searched, it stays marked, a doubt each path reads by its
4085
+ * own rule.
4086
+ */
4087
+ private settleUnknownLandings;
4088
+ /**
4089
+ * A marked held write found to have landed, as `stored`: it leaves the
4090
+ * pending queue for the un-acked set, as a drained write does, so it stays
4091
+ * in the durable queue until the next ack has synced the store that holds
4092
+ * it, and it's a stored write from then on, so the paths for a landed
4093
+ * write apply to it. It takes the notes a store takes (noteStored), which
4094
+ * its first write missed when it threw, as a flush that finds such a write
4095
+ * takes them (readdDrained), and is logged by its id. It isn't carried
4096
+ * into a turn, as a flush that finds it carries it: the agent reads it at
4097
+ * its next compile, where the store holds it.
4098
+ */
4099
+ private settleFound;
4100
+ /**
4101
+ * A stored row a module names by its id: where it carries the
4102
+ * deferredWriteId of a marked held write the reader's store holds, it's
4103
+ * that write's copy, so the write landed, and it's settled as found
4104
+ * (settleFound) before the row is read or changed. A lookup by the id
4105
+ * can't be needed then, so this holds where the store can't be searched
4106
+ * too.
4107
+ */
4108
+ private settleByCopy;
4109
+ /** A held write whose landing stays unknown after settling, its store
4110
+ * unsearchable, can't be edited or removed: it may already be stored, and
4111
+ * changing only the queued entry could leave its stored copy as it was.
4112
+ * Throws with nothing changed. */
4113
+ private refuseUnsettled;
4114
+ /** Whether the agent has nothing left to read of a deferred write, on
4115
+ * evidence only: the row it landed as is at or below the agent's consumed
4116
+ * watermark on its current branch, or it's in neither the queue (drained
4117
+ * entries not yet stored included) nor the store's current branch:
4118
+ * removed, or left on a branch the agent has switched from, where a turn
4119
+ * now would find nothing of it (switching back brings it back unread,
4120
+ * with no wake, as main's wake spent on this branch leaves it). Any doubt
4121
+ * reads as unread, such as a watermark that a branch switch or an undo
4122
+ * left on another branch, or a store that can't be read: a turn that
4123
+ * finds nothing new costs less than a write no wake brings the agent to
4124
+ * read. */
4125
+ private deferredWriteReadOrGone;
3514
4126
  private editMessage;
3515
4127
  private removeMessage;
3516
4128
  private getMessage;
@@ -3668,80 +4280,132 @@ export declare class AgentFramework {
3668
4280
  * closeAll does. `timeoutMs` bounds the wait without cancelling cleanup. */
3669
4281
  private closeModernMcpConnections;
3670
4282
  /**
3671
- * Reconcile the durable ledger with Chronicle, then deliver every server's
3672
- * work. A drain still running is waited for and then followed by a fresh
3673
- * pass (drainForGeneration). Like the other operator entry points, it's
3674
- * refused once stop() has begun, and stop() waits for one already running.
3675
- * The framework's own branch moves start their delivery without awaiting
3676
- * it (startDiscordAwarenessDelivery).
4283
+ * Deliver every server's queued awareness operations now (or only
4284
+ * `onlyServerId`'s) and wait for this pass, and for a pass already under
4285
+ * way on a server, whose last request may still be on the wire with
4286
+ * nothing left due. Like the other operator entry points, it's refused
4287
+ * once stop() has begun, and stop() waits for one already running.
4288
+ * Delivery never gates MCPL traffic or turns: the framework's own
4289
+ * deliveries run in the background (deliverDiscordAwarenessInBackground).
4290
+ * A server that is not connected is skipped (its work stays queued until
4291
+ * it connects).
3677
4292
  */
3678
4293
  syncDiscordAwarenessMarkers(onlyServerId?: string): Promise<void>;
3679
- /** The sync's work. It installs the MCPL data-plane gate before its first
3680
- * await, so a caller that starts it while holding the store puts the gate
3681
- * up before releasing the store. */
4294
+ /** One delivery pass over every server with due work, or only `onlyServerId`'s. */
3682
4295
  private runDiscordAwarenessSync;
4296
+ /**
4297
+ * Finish the removals of every suppression pending on the active branch
4298
+ * (an interrupted surgery's, or a version 2 ledger's that 0.22.x never
4299
+ * activated). Its batch is then retired, none of its marks sent, and
4300
+ * reported with the redo that applies them (reportRetiredAwareness): a
4301
+ * start never activates a surgery's marks. An interval whose messages are
4302
+ * only partly present can't be finished safely, and stops the start.
4303
+ */
3683
4304
  private resumePreparedDiscordSuppressions;
3684
4305
  /**
3685
- * Deliver every due ref independently. Permanent Discord failures are kept
3686
- * in the ledger for audit but do not block later operations; retryable
3687
- * failures remain pending for the next reconnect/list-change attempt.
3688
- * Once stop() has begun, a drain sends nothing more and records nothing
3689
- * for what it hasn't sent: that stays pending, as it was, for the next
3690
- * start's barrier. stop() closes the connections and then waits for each
3691
- * drain still running to record the call it had in flight.
4306
+ * The start's reconciliation of the awareness ledger, before any
4307
+ * delivery. It derives nothing from branch ancestry and activates nothing
4308
+ * (recoverAtStartup): a batch an interrupted surgery left is retired, none
4309
+ * of its marks sent, except a suppression whose removals are pending, which
4310
+ * a start on its branch finishes (resumePreparedDiscordSuppressions); a
4311
+ * request the previous process left on the wire is recorded unanswered. No
4312
+ * content is read. Before it writes any of that, it logs what it does,
4313
+ * reports each retirement (reportRetiredAwareness) and raises the delivery
4314
+ * alert for reactions that reach the bound: each is written once, so a
4315
+ * notice given after the write would be lost for good if the write landed
4316
+ * and the process ended before the notice. A ledger it can't read stops
4317
+ * the start: it can't tell whether a suppression's body is pending.
4318
+ */
4319
+ private reconcileDiscordAwarenessAtStartup;
4320
+ /** What a start's reconciliation retires and records unanswered, before it is written. */
4321
+ private announceDiscordAwarenessRecovery;
4322
+ /**
4323
+ * A version 2 ledger's rewrite as version 3, before it is written (the
4324
+ * outbox's announceImport): the work agent-framework 0.22.x had still to
4325
+ * do is never sent, since nobody chose it, and the batches it never
4326
+ * activated are retired (a suppression whose body may be pending, once a
4327
+ * start on its branch finishes the body). A retract of a batch 0.22.x
4328
+ * activated takes off the mark of the batch's emoji from each of its
4329
+ * messages, whichever batch placed it.
4330
+ */
4331
+ private announceDiscordAwarenessImport;
4332
+ /**
4333
+ * Report a batch a start retires, before that is recorded, with the redo
4334
+ * that applies what was lost: the
4335
+ * surgery again from its source, if that still has every message the
4336
+ * surgery removed (a hide there, or the source's deletion, changes that),
4337
+ * onto a new branch name, choosing marks again (framework.switchBranch,
4338
+ * then rollbackToMessage or suppressMessages; offline, the recover CLI).
4339
+ * A batch doesn't say which surgery made it: an offline recovery's reads
4340
+ * as a rollback's, or as a suppression's when the recovery suppressed, so
4341
+ * the report names both. One with marks not applied raises an ops alert;
4342
+ * one without (no marks chosen, or its marks cancelled) is only logged.
4343
+ */
4344
+ private reportRetiredAwareness;
4345
+ /**
4346
+ * Deliver one server's owed awareness requests, one at a time, oldest act
4347
+ * first. Every request is written ahead to the ledger before it can leave,
4348
+ * and its answer is recorded from what the connection can actually know
4349
+ * (McplRequestError.outcome): a request that was never written stays
4350
+ * owed, one written and never answered may land, and a Discord answer is
4351
+ * definitive (permanent when Discord says the message or channel is gone
4352
+ * or inaccessible). A server that is not connected is skipped: its work
4353
+ * simply stays queued.
3692
4354
  */
3693
4355
  private drainDiscordAwarenessOutbox;
3694
- private readDiscordAwarenessPending;
3695
- private writeDiscordAwarenessSuccess;
3696
- private writeDiscordAwarenessFailure;
3697
- private beginDiscordAwarenessBarrier;
3698
- /**
3699
- * One server's drain for a new generation: a gate completes only after
3700
- * every operation pending when it was armed has been attempted. A drain
3701
- * already running can't promise that. It never re-sends a key it has
3702
- * attempted, so an operation re-pended while it runs (a rollback, its undo,
3703
- * then a redo, all mid-drain) stays pending, and it may already have made
3704
- * its last read of the ledger, missing a batch activated since. So a
3705
- * generation that finds a drain running waits for it, then drains again
3706
- * with a fresh pass that reads the ledger anew. Two generations waiting on
3707
- * the same drain share the fresh pass that follows it. Once stop() has
3708
- * begun, a drain sends nothing more, so a gate armed then completes with
3709
- * what it found pending left for the next start.
3710
- */
3711
- private drainForGeneration;
3712
- /**
3713
- * Wait out the awareness gate for an inbound event: the generation current
3714
- * now, and any generation installed while waiting, until none is current
3715
- * or the current one is one already waited for. A handler that waited only
3716
- * for the generation it first saw would go on behind a newer one armed
3717
- * meanwhile. Rejects as the generation it waited for rejects.
3718
- */
3719
- private awaitDiscordAwarenessBarriers;
4356
+ /**
4357
+ * One pass of drainDiscordAwarenessOutbox. It leaves the registry in the
4358
+ * microtasks that follow its last claim, a claim that found nothing owed,
4359
+ * so a registered pass always has a claim ahead of it or running: a
4360
+ * trigger that joins it is served by it, unless its route goes away or
4361
+ * stop() begins first, when the pass stops claiming and the work stays
4362
+ * queued for the next pass. Within a pass, a request is claimed once; a
4363
+ * trigger that joined it also has what the pass already tried claimed
4364
+ * once more before it leaves, so an operator's sync, a retract or a
4365
+ * reconnect meeting a running pass doesn't leave a retryable mark untried. A request made owed after its last claim
4366
+ * starts a new pass: the act that makes it owed runs after that claim's,
4367
+ * and resolves only once its write is on disk, by when the pass has left.
4368
+ * Leaving any later, when its promise settles, would let a request join a
4369
+ * pass that will never claim again, and that work would stay due until
4370
+ * some unrelated trigger.
4371
+ */
4372
+ private runDiscordAwarenessDrain;
4373
+ private readDiscordAwarenessDue;
4374
+ /**
4375
+ * Open MCPL connections' planes (every connection when none is given). A
4376
+ * connection whose policy exchange is in flight stays closed, both planes,
4377
+ * until its grant exists: its exchange's caller opens it once that settles
4378
+ * (mcplPlanesMayOpen). A quiesced host (issue #122) opens only control
4379
+ * planes, so data planes stay held for the whole maintenance window;
4380
+ * resume() calls this again once the flag is cleared. Otherwise a control
4381
+ * plane comes up even while quiesced, since host/command (and with it
4382
+ * resume) rides it.
4383
+ */
4384
+ private readyMcplPlanes;
3720
4385
  /**
3721
4386
  * Per connection, the transport epoch whose §5.3 policy exchange is in
3722
4387
  * flight: a connect's, from when the registry hands the connection back,
3723
4388
  * or a reconnect's, from its 'reconnect' event. Until the exchange settles,
3724
- * that transport's traffic must wait for its grant, so a gate that opens
3725
- * every connection's planes meanwhile (another server's list change, a
3726
- * resume, an awareness sync, startup's staged open) passes it by
3727
- * (mcplPlanesMayOpen), and the exchange's own caller opens them once it
3728
- * settles (openMcplPlanesAfterExchange).
4389
+ * that transport's traffic must wait for its grant, so readyMcplPlanes,
4390
+ * which a resume and startup's staged open run over every connection,
4391
+ * passes it by (mcplPlanesMayOpen), and the exchange's own caller opens its
4392
+ * planes once it settles.
3729
4393
  */
3730
4394
  private readonly mcplPolicyExchanges;
3731
- /** Whether a gate may open this connection's planes: no policy exchange is
3732
- * in flight on its current transport (see mcplPolicyExchanges). */
4395
+ /** Whether readyMcplPlanes may open this connection's planes: no policy
4396
+ * exchange is in flight on its current transport (see mcplPolicyExchanges). */
3733
4397
  private mcplPlanesMayOpen;
3734
4398
  /**
3735
4399
  * Run a connection's §5.3 policy exchange with its planes held: it is
3736
- * marked in flight for the transport it runs on, so no gate releases that
3737
- * transport's traffic before its grant exists. With `epoch`, it runs only
3738
- * on that transport: a runtime connect passes the one it registered, and
3739
- * if that transport is gone, the exchange isn't run, since a reconnect
4400
+ * marked in flight for the transport it runs on, so no opener releases
4401
+ * that transport's traffic before its grant exists. With `epoch`, it runs
4402
+ * only on that transport: a runtime connect passes the one it registered,
4403
+ * and if that transport is gone, the exchange isn't run, since a reconnect
3740
4404
  * that adopts a next transport, if one comes, runs that one's. With
3741
4405
  * `closeOnFailure`, as for a runtime connect or restart, an exchange that
3742
4406
  * throws closes the connection for good, through the registry, before it
3743
4407
  * lifts the marker: left live, the connection would be half registered,
3744
- * and unmarked before its close, a gate completing in between would let
4408
+ * and unmarked before its close, an opener running in between would let
3745
4409
  * out what it held with no grant. A close that fails keeps the connection
3746
4410
  * registered, but closed for good, it readies nothing but its own reports.
3747
4411
  * Without `closeOnFailure`, as for a reconnect or a staged startup connect,
@@ -3749,32 +4413,6 @@ export declare class AgentFramework {
3749
4413
  * reached, empty if the policy step itself threw, and the marker lifts.
3750
4414
  */
3751
4415
  private settlePolicyExchange;
3752
- /**
3753
- * Open a connection's planes once its exchange has settled, when the gate
3754
- * its connect or reconnect installed was replaced during the exchange: the
3755
- * newer gate passed the connection by, and if it has completed, nothing
3756
- * else would open it. A connection whose transport dropped meanwhile is
3757
- * readied as any gate readies one between transports, so its own reports
3758
- * go on. How far follows what is held now: while a gate is up, only the
3759
- * control plane opens, since a gate holds data planes alone, and its
3760
- * completion, which no longer passes this connection by, opens the data
3761
- * plane; a quiesced host (issue #122) likewise opens only control planes;
3762
- * otherwise both open.
3763
- */
3764
- private openMcplPlanesAfterExchange;
3765
- /**
3766
- * Install one framework-global Discord-awareness generation before releasing
3767
- * any inference-bearing event. With pending work or a drain still running,
3768
- * every MCPL data plane is paused while the control planes remain live,
3769
- * but for a connection whose policy exchange is in flight, which neither
3770
- * the release nor the completion opens (mcplPlanesMayOpen).
3771
- * With neither, ready() runs synchronously so request responders preserve
3772
- * their historical same-stack behavior.
3773
- */
3774
- private installMcplDataPlaneGate;
3775
- private releaseMcplDataPlaneGate;
3776
- private completeMcplDataPlaneGate;
3777
- private failMcplDataPlaneGate;
3778
4416
  /**
3779
4417
  * Close a legacy connection for good through the registry. A close that
3780
4418
  * can't confirm its child exited keeps the connection registered, holding
@@ -3854,6 +4492,13 @@ export declare class AgentFramework {
3854
4492
  * disconnect are resumed, not reset.
3855
4493
  */
3856
4494
  private registerMcplServerFeatures;
4495
+ /**
4496
+ * Whether this server's child takes the framework's protective reaction
4497
+ * default: a stdio server with no baseline declared in its env or
4498
+ * inherited from the host. Only such a connect reads the awareness
4499
+ * ledger (getPlacedReactionBaseline).
4500
+ */
4501
+ private derivesReactionBaseline;
3857
4502
  /**
3858
4503
  * Snapshot the protective Discord reaction default for this deployment, as
3859
4504
  * suppression tokens: the forms the Discord adapter's suppression matcher
@@ -4074,8 +4719,7 @@ export declare class AgentFramework {
4074
4719
  * A list change, including the relist after a reconnect, takes the legacy
4075
4720
  * engine's refresh path (`handleToolsListChanged`), so any wake it causes
4076
4721
  * goes through ordinary admission: it parks under quiesce or a hold like
4077
- * every other wake. It installs no awareness gate, since that gate orders
4078
- * MCPL data-plane traffic, which this family doesn't carry.
4722
+ * every other wake.
4079
4723
  */
4080
4724
  private wireModernEvents;
4081
4725
  /** An MCP tool call's trace: a result the server marked an error (or one
@@ -4127,6 +4771,9 @@ export declare class AgentFramework {
4127
4771
  * is in flight (mcpServerOps) or a restart holds the id, and "gone"
4128
4772
  * otherwise. */
4129
4773
  private mcplServerAbsentText;
4774
+ /** Whether a connect of this server id is in flight (mcpServerOps), or a
4775
+ * restart holds the id: this host is connecting to it. */
4776
+ private mcplConnectInFlight;
4130
4777
  /** A modern connection a connect still under way registered: it registers
4131
4778
  * before it starts, so until its first session is up it's no server to
4132
4779
  * call, and a call reads the "connecting" text, as one during a legacy
@@ -4161,6 +4808,21 @@ export declare class AgentFramework {
4161
4808
  * an MCPL peer's blocks given RFC-005's treatment (referenceBlockForScript).
4162
4809
  */
4163
4810
  private mcpToolResult;
4811
+ /**
4812
+ * A tune-out on record where this host has no tune-out coordinator: a
4813
+ * start with no subconscious makes none, and neither does a channel
4814
+ * subsystem brought up after start by connectMcplServer. Nothing then
4815
+ * diverts the channel's traffic or ever cancels its tune-out, tune_out
4816
+ * isn't offered, and channel_open, channel_close and channel_decline
4817
+ * refuse a tuned-out channel, so the channel would stay held by a decision
4818
+ * nothing here can change. Each one ends here instead, its channel decided
4819
+ * open again as a cancel leaves it, under the tune-out's own source, so an
4820
+ * agent's tune-out keeps the agent's provenance (the housekeeping guard
4821
+ * reads it). A log line names the channel and says how many of the
4822
+ * messages it diverted are held here, stored or still queued to be
4823
+ * written, which nothing will now deliver as its backlog.
4824
+ */
4825
+ private endTuneOutsWithoutCoordinator;
4164
4826
  /**
4165
4827
  * Build BeforeInferenceParams from agent state and trigger context.
4166
4828
  */
@@ -4203,9 +4865,10 @@ export declare class AgentFramework {
4203
4865
  * every sibling in the round to settle; if one never does, fail closed
4204
4866
  * rather than trust an index the batch may still change. Sibling saves
4205
4867
  * produce no images and are not waited on (two saves in one batch would
4206
- * otherwise deadlock into a double timeout). Script-inner calls
4207
- * (`pytc-…`) run sequentially inside their script host and skip the
4208
- * barrier — the host call itself is the only pending sibling they'd see.
4868
+ * otherwise deadlock into a double timeout). A script's own calls
4869
+ * (`pytc-…`) skip the barrier: the batch's pending siblings include the
4870
+ * code_execution call running that script, so waiting on them would wait
4871
+ * on itself.
4209
4872
  */
4210
4873
  private awaitSiblingToolCalls;
4211
4874
  /**