@animalabs/agent-framework 0.22.1 → 0.22.3

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 (946) hide show
  1. package/README.md +4 -2
  2. package/dist/src/agent.d.ts +266 -28
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +539 -104
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/api/mcp-server-core.d.ts +41 -0
  7. package/dist/src/api/mcp-server-core.d.ts.map +1 -0
  8. package/dist/src/api/mcp-server-core.js +593 -0
  9. package/dist/src/api/mcp-server-core.js.map +1 -0
  10. package/dist/src/api/mcp-server.d.ts +2 -36
  11. package/dist/src/api/mcp-server.d.ts.map +1 -1
  12. package/dist/src/api/mcp-server.js +15 -595
  13. package/dist/src/api/mcp-server.js.map +1 -1
  14. package/dist/src/api/server.d.ts +9 -1
  15. package/dist/src/api/server.d.ts.map +1 -1
  16. package/dist/src/api/server.js +55 -27
  17. package/dist/src/api/server.js.map +1 -1
  18. package/dist/src/api/types.d.ts +10 -2
  19. package/dist/src/api/types.d.ts.map +1 -1
  20. package/dist/src/branch-names.d.ts +14 -0
  21. package/dist/src/branch-names.d.ts.map +1 -0
  22. package/dist/src/branch-names.js +22 -0
  23. package/dist/src/branch-names.js.map +1 -0
  24. package/dist/src/closest-names.d.ts +28 -0
  25. package/dist/src/closest-names.d.ts.map +1 -0
  26. package/dist/src/closest-names.js +98 -0
  27. package/dist/src/closest-names.js.map +1 -0
  28. package/dist/src/code-execution/py-runner.d.ts +16 -5
  29. package/dist/src/code-execution/py-runner.d.ts.map +1 -1
  30. package/dist/src/code-execution/py-runner.js +186 -74
  31. package/dist/src/code-execution/py-runner.js.map +1 -1
  32. package/dist/src/code-execution/runtime-py.d.ts.map +1 -1
  33. package/dist/src/code-execution/runtime-py.js +49 -3
  34. package/dist/src/code-execution/runtime-py.js.map +1 -1
  35. package/dist/src/code-execution/tool-definition.d.ts +12 -1
  36. package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
  37. package/dist/src/code-execution/tool-definition.js +21 -3
  38. package/dist/src/code-execution/tool-definition.js.map +1 -1
  39. package/dist/src/config-checks.d.ts +28 -0
  40. package/dist/src/config-checks.d.ts.map +1 -0
  41. package/dist/src/config-checks.js +52 -0
  42. package/dist/src/config-checks.js.map +1 -0
  43. package/dist/src/deadline-timer.d.ts +21 -0
  44. package/dist/src/deadline-timer.d.ts.map +1 -0
  45. package/dist/src/deadline-timer.js +43 -0
  46. package/dist/src/deadline-timer.js.map +1 -0
  47. package/dist/src/error-message.d.ts +30 -0
  48. package/dist/src/error-message.d.ts.map +1 -0
  49. package/dist/src/error-message.js +50 -0
  50. package/dist/src/error-message.js.map +1 -0
  51. package/dist/src/framework.d.ts +1212 -192
  52. package/dist/src/framework.d.ts.map +1 -1
  53. package/dist/src/framework.js +6686 -1835
  54. package/dist/src/framework.js.map +1 -1
  55. package/dist/src/gate/event-gate.d.ts +8 -0
  56. package/dist/src/gate/event-gate.d.ts.map +1 -1
  57. package/dist/src/gate/event-gate.js +27 -3
  58. package/dist/src/gate/event-gate.js.map +1 -1
  59. package/dist/src/gate/gate-script.d.ts.map +1 -1
  60. package/dist/src/gate/gate-script.js.map +1 -1
  61. package/dist/src/index.d.ts +5 -3
  62. package/dist/src/index.d.ts.map +1 -1
  63. package/dist/src/index.js +5 -3
  64. package/dist/src/index.js.map +1 -1
  65. package/dist/src/mcpl/capability-grant.d.ts.map +1 -1
  66. package/dist/src/mcpl/channel-registry.d.ts +170 -13
  67. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  68. package/dist/src/mcpl/channel-registry.js +499 -258
  69. package/dist/src/mcpl/channel-registry.js.map +1 -1
  70. package/dist/src/mcpl/checkpoint-manager.d.ts +21 -1
  71. package/dist/src/mcpl/checkpoint-manager.d.ts.map +1 -1
  72. package/dist/src/mcpl/checkpoint-manager.js +91 -30
  73. package/dist/src/mcpl/checkpoint-manager.js.map +1 -1
  74. package/dist/src/mcpl/conversation-router.d.ts +19 -3
  75. package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
  76. package/dist/src/mcpl/conversation-router.js +23 -8
  77. package/dist/src/mcpl/conversation-router.js.map +1 -1
  78. package/dist/src/mcpl/convert-block.d.ts +20 -0
  79. package/dist/src/mcpl/convert-block.d.ts.map +1 -0
  80. package/dist/src/mcpl/convert-block.js +89 -0
  81. package/dist/src/mcpl/convert-block.js.map +1 -0
  82. package/dist/src/mcpl/errors.d.ts +13 -0
  83. package/dist/src/mcpl/errors.d.ts.map +1 -1
  84. package/dist/src/mcpl/errors.js +28 -0
  85. package/dist/src/mcpl/errors.js.map +1 -1
  86. package/dist/src/mcpl/feature-set-manager.d.ts.map +1 -1
  87. package/dist/src/mcpl/feature-set-manager.js +4 -3
  88. package/dist/src/mcpl/feature-set-manager.js.map +1 -1
  89. package/dist/src/mcpl/hook-orchestrator.d.ts +23 -0
  90. package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
  91. package/dist/src/mcpl/hook-orchestrator.js +83 -72
  92. package/dist/src/mcpl/hook-orchestrator.js.map +1 -1
  93. package/dist/src/mcpl/inbound-source.d.ts +114 -0
  94. package/dist/src/mcpl/inbound-source.d.ts.map +1 -0
  95. package/dist/src/mcpl/inbound-source.js +83 -0
  96. package/dist/src/mcpl/inbound-source.js.map +1 -0
  97. package/dist/src/mcpl/index.d.ts +3 -1
  98. package/dist/src/mcpl/index.d.ts.map +1 -1
  99. package/dist/src/mcpl/index.js +3 -1
  100. package/dist/src/mcpl/index.js.map +1 -1
  101. package/dist/src/mcpl/inference-router.d.ts +15 -11
  102. package/dist/src/mcpl/inference-router.d.ts.map +1 -1
  103. package/dist/src/mcpl/inference-router.js +153 -84
  104. package/dist/src/mcpl/inference-router.js.map +1 -1
  105. package/dist/src/mcpl/log-value.d.ts +54 -0
  106. package/dist/src/mcpl/log-value.d.ts.map +1 -0
  107. package/dist/src/mcpl/log-value.js +109 -0
  108. package/dist/src/mcpl/log-value.js.map +1 -0
  109. package/dist/src/mcpl/prose-stream-router.d.ts +6 -6
  110. package/dist/src/mcpl/prose-stream-router.d.ts.map +1 -1
  111. package/dist/src/mcpl/prose-stream-router.js +4 -4
  112. package/dist/src/mcpl/prose-stream-router.js.map +1 -1
  113. package/dist/src/mcpl/push-coalescer.d.ts +64 -7
  114. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  115. package/dist/src/mcpl/push-coalescer.js +121 -24
  116. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  117. package/dist/src/mcpl/push-handler.d.ts +38 -8
  118. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  119. package/dist/src/mcpl/push-handler.js +77 -78
  120. package/dist/src/mcpl/push-handler.js.map +1 -1
  121. package/dist/src/mcpl/reference-fetcher.d.ts +14 -2
  122. package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
  123. package/dist/src/mcpl/reference-fetcher.js +72 -30
  124. package/dist/src/mcpl/reference-fetcher.js.map +1 -1
  125. package/dist/src/mcpl/references.d.ts +49 -14
  126. package/dist/src/mcpl/references.d.ts.map +1 -1
  127. package/dist/src/mcpl/references.js +74 -21
  128. package/dist/src/mcpl/references.js.map +1 -1
  129. package/dist/src/mcpl/refusal-lines.d.ts +37 -0
  130. package/dist/src/mcpl/refusal-lines.d.ts.map +1 -0
  131. package/dist/src/mcpl/refusal-lines.js +61 -0
  132. package/dist/src/mcpl/refusal-lines.js.map +1 -0
  133. package/dist/src/mcpl/scope-manager.d.ts.map +1 -1
  134. package/dist/src/mcpl/server-connection.d.ts +107 -12
  135. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  136. package/dist/src/mcpl/server-connection.js +470 -139
  137. package/dist/src/mcpl/server-connection.js.map +1 -1
  138. package/dist/src/mcpl/server-registry.d.ts +10 -1
  139. package/dist/src/mcpl/server-registry.d.ts.map +1 -1
  140. package/dist/src/mcpl/server-registry.js +14 -3
  141. package/dist/src/mcpl/server-registry.js.map +1 -1
  142. package/dist/src/mcpl/skip-reply-wake.d.ts +36 -0
  143. package/dist/src/mcpl/skip-reply-wake.d.ts.map +1 -0
  144. package/dist/src/mcpl/skip-reply-wake.js +55 -0
  145. package/dist/src/mcpl/skip-reply-wake.js.map +1 -0
  146. package/dist/src/mcpl/tool-classes.d.ts +1 -1
  147. package/dist/src/mcpl/tool-classes.d.ts.map +1 -1
  148. package/dist/src/mcpl/tool-classes.js +3 -2
  149. package/dist/src/mcpl/tool-classes.js.map +1 -1
  150. package/dist/src/mcpl/tool-lifecycle.d.ts.map +1 -1
  151. package/dist/src/mcpl/tool-lifecycle.js.map +1 -1
  152. package/dist/src/mcpl/transport.d.ts +74 -7
  153. package/dist/src/mcpl/transport.d.ts.map +1 -1
  154. package/dist/src/mcpl/transport.js +209 -22
  155. package/dist/src/mcpl/transport.js.map +1 -1
  156. package/dist/src/mcpl/types.d.ts +43 -28
  157. package/dist/src/mcpl/types.d.ts.map +1 -1
  158. package/dist/src/mcpl/types.js.map +1 -1
  159. package/dist/src/mcpl/visible-content.d.ts +15 -0
  160. package/dist/src/mcpl/visible-content.d.ts.map +1 -1
  161. package/dist/src/mcpl/visible-content.js +25 -0
  162. package/dist/src/mcpl/visible-content.js.map +1 -1
  163. package/dist/src/module-registry.d.ts +19 -1
  164. package/dist/src/module-registry.d.ts.map +1 -1
  165. package/dist/src/module-registry.js +54 -25
  166. package/dist/src/module-registry.js.map +1 -1
  167. package/dist/src/modules/api/index.d.ts.map +1 -1
  168. package/dist/src/modules/api/index.js +1 -1
  169. package/dist/src/modules/api/index.js.map +1 -1
  170. package/dist/src/modules/discord/discord-js-client.d.ts +1 -0
  171. package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -1
  172. package/dist/src/modules/discord/discord-js-client.js +25 -9
  173. package/dist/src/modules/discord/discord-js-client.js.map +1 -1
  174. package/dist/src/modules/discord/index.d.ts +29 -3
  175. package/dist/src/modules/discord/index.d.ts.map +1 -1
  176. package/dist/src/modules/discord/index.js +383 -145
  177. package/dist/src/modules/discord/index.js.map +1 -1
  178. package/dist/src/modules/discord/types.d.ts +14 -1
  179. package/dist/src/modules/discord/types.d.ts.map +1 -1
  180. package/dist/src/modules/health/index.d.ts.map +1 -1
  181. package/dist/src/modules/health/index.js +2 -1
  182. package/dist/src/modules/health/index.js.map +1 -1
  183. package/dist/src/modules/history/index.d.ts +3 -1
  184. package/dist/src/modules/history/index.d.ts.map +1 -1
  185. package/dist/src/modules/history/index.js +359 -127
  186. package/dist/src/modules/history/index.js.map +1 -1
  187. package/dist/src/modules/history/semantic.d.ts +28 -1
  188. package/dist/src/modules/history/semantic.d.ts.map +1 -1
  189. package/dist/src/modules/history/semantic.js +177 -32
  190. package/dist/src/modules/history/semantic.js.map +1 -1
  191. package/dist/src/modules/unknown-tool.d.ts +10 -0
  192. package/dist/src/modules/unknown-tool.d.ts.map +1 -0
  193. package/dist/src/modules/unknown-tool.js +17 -0
  194. package/dist/src/modules/unknown-tool.js.map +1 -0
  195. package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
  196. package/dist/src/modules/workspace/branch-intent.js.map +1 -1
  197. package/dist/src/modules/workspace/disk-agreement.d.ts +54 -6
  198. package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
  199. package/dist/src/modules/workspace/disk-agreement.js +93 -27
  200. package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
  201. package/dist/src/modules/workspace/effects.d.ts +64 -6
  202. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  203. package/dist/src/modules/workspace/effects.js +291 -44
  204. package/dist/src/modules/workspace/effects.js.map +1 -1
  205. package/dist/src/modules/workspace/index.d.ts +127 -27
  206. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  207. package/dist/src/modules/workspace/index.js +821 -248
  208. package/dist/src/modules/workspace/index.js.map +1 -1
  209. package/dist/src/modules/workspace/observe.d.ts +117 -15
  210. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  211. package/dist/src/modules/workspace/observe.js +436 -51
  212. package/dist/src/modules/workspace/observe.js.map +1 -1
  213. package/dist/src/modules/workspace/reconcile.d.ts +75 -8
  214. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  215. package/dist/src/modules/workspace/reconcile.js +576 -68
  216. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  217. package/dist/src/modules/workspace/types.d.ts +42 -3
  218. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  219. package/dist/src/modules/workspace/types.js.map +1 -1
  220. package/dist/src/modules/workspace/watcher.d.ts +7 -2
  221. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  222. package/dist/src/modules/workspace/watcher.js +28 -4
  223. package/dist/src/modules/workspace/watcher.js.map +1 -1
  224. package/dist/src/operator-log.d.ts.map +1 -1
  225. package/dist/src/operator-log.js.map +1 -1
  226. package/dist/src/prose-drafts.d.ts +240 -0
  227. package/dist/src/prose-drafts.d.ts.map +1 -0
  228. package/dist/src/prose-drafts.js +362 -0
  229. package/dist/src/prose-drafts.js.map +1 -0
  230. package/dist/src/prose-segments.d.ts +21 -2
  231. package/dist/src/prose-segments.d.ts.map +1 -1
  232. package/dist/src/prose-segments.js +46 -9
  233. package/dist/src/prose-segments.js.map +1 -1
  234. package/dist/src/provider-waits.d.ts.map +1 -1
  235. package/dist/src/provider-waits.js.map +1 -1
  236. package/dist/src/queue.d.ts.map +1 -1
  237. package/dist/src/record-journal.d.ts.map +1 -1
  238. package/dist/src/record-journal.js.map +1 -1
  239. package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
  240. package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
  241. package/dist/src/recovery/offline-branch.d.ts +1 -0
  242. package/dist/src/recovery/offline-branch.d.ts.map +1 -1
  243. package/dist/src/recovery/offline-branch.js +32 -25
  244. package/dist/src/recovery/offline-branch.js.map +1 -1
  245. package/dist/src/recovery/recover-cli.js.map +1 -1
  246. package/dist/src/runtime/liveness-watchdog.d.ts.map +1 -1
  247. package/dist/src/runtime/liveness-watchdog.js.map +1 -1
  248. package/dist/src/safe-slice.d.ts +5 -1
  249. package/dist/src/safe-slice.d.ts.map +1 -1
  250. package/dist/src/safe-slice.js +9 -1
  251. package/dist/src/safe-slice.js.map +1 -1
  252. package/dist/src/shutdown.d.ts.map +1 -1
  253. package/dist/src/shutdown.js.map +1 -1
  254. package/dist/src/stored-removal.d.ts +73 -0
  255. package/dist/src/stored-removal.d.ts.map +1 -0
  256. package/dist/src/stored-removal.js +100 -0
  257. package/dist/src/stored-removal.js.map +1 -0
  258. package/dist/src/thinking-token-stamp.js.map +1 -1
  259. package/dist/src/tool-image-ledger.d.ts +87 -19
  260. package/dist/src/tool-image-ledger.d.ts.map +1 -1
  261. package/dist/src/tool-image-ledger.js +135 -32
  262. package/dist/src/tool-image-ledger.js.map +1 -1
  263. package/dist/src/tool-presentation.d.ts +9 -0
  264. package/dist/src/tool-presentation.d.ts.map +1 -1
  265. package/dist/src/tool-presentation.js +257 -60
  266. package/dist/src/tool-presentation.js.map +1 -1
  267. package/dist/src/tool-result-guard.d.ts.map +1 -1
  268. package/dist/src/tool-result-guard.js +7 -10
  269. package/dist/src/tool-result-guard.js.map +1 -1
  270. package/dist/src/tool-result-history.d.ts +32 -3
  271. package/dist/src/tool-result-history.d.ts.map +1 -1
  272. package/dist/src/tool-result-history.js +106 -19
  273. package/dist/src/tool-result-history.js.map +1 -1
  274. package/dist/src/tune-out/coordinator.d.ts +25 -1
  275. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  276. package/dist/src/tune-out/coordinator.js +260 -65
  277. package/dist/src/tune-out/coordinator.js.map +1 -1
  278. package/dist/src/tune-out/tools.d.ts +1 -1
  279. package/dist/src/tune-out/tools.d.ts.map +1 -1
  280. package/dist/src/types/agent.d.ts +59 -11
  281. package/dist/src/types/agent.d.ts.map +1 -1
  282. package/dist/src/types/events.d.ts +17 -0
  283. package/dist/src/types/events.d.ts.map +1 -1
  284. package/dist/src/types/framework.d.ts +31 -5
  285. package/dist/src/types/framework.d.ts.map +1 -1
  286. package/dist/src/types/inference-log.d.ts +1 -1
  287. package/dist/src/types/inference-log.d.ts.map +1 -1
  288. package/dist/src/types/module.d.ts +30 -7
  289. package/dist/src/types/module.d.ts.map +1 -1
  290. package/dist/src/types/trace.d.ts +151 -11
  291. package/dist/src/types/trace.d.ts.map +1 -1
  292. package/dist/src/usage/usage-tracker.d.ts +5 -0
  293. package/dist/src/usage/usage-tracker.d.ts.map +1 -1
  294. package/dist/src/usage/usage-tracker.js +35 -8
  295. package/dist/src/usage/usage-tracker.js.map +1 -1
  296. package/package.json +10 -9
  297. package/src/agent.ts +572 -105
  298. package/src/api/mcp-server-core.ts +681 -0
  299. package/src/api/mcp-server.ts +16 -685
  300. package/src/api/server.ts +55 -30
  301. package/src/api/types.ts +10 -2
  302. package/src/branch-names.ts +19 -0
  303. package/src/closest-names.ts +94 -0
  304. package/src/code-execution/py-runner.ts +200 -76
  305. package/src/code-execution/runtime-py.ts +49 -3
  306. package/src/code-execution/tool-definition.ts +28 -4
  307. package/src/config-checks.ts +48 -0
  308. package/src/deadline-timer.ts +44 -0
  309. package/src/error-message.ts +48 -0
  310. package/src/framework.ts +7158 -1936
  311. package/src/gate/event-gate.ts +28 -3
  312. package/src/index.ts +12 -3
  313. package/src/mcpl/channel-registry.ts +615 -289
  314. package/src/mcpl/checkpoint-manager.ts +104 -29
  315. package/src/mcpl/conversation-router.ts +28 -8
  316. package/src/mcpl/convert-block.ts +97 -0
  317. package/src/mcpl/errors.ts +28 -0
  318. package/src/mcpl/feature-set-manager.ts +4 -3
  319. package/src/mcpl/hook-orchestrator.ts +84 -77
  320. package/src/mcpl/inbound-source.ts +156 -0
  321. package/src/mcpl/index.ts +10 -1
  322. package/src/mcpl/inference-router.ts +174 -99
  323. package/src/mcpl/log-value.ts +116 -0
  324. package/src/mcpl/prose-stream-router.ts +6 -6
  325. package/src/mcpl/push-coalescer.ts +124 -24
  326. package/src/mcpl/push-handler.ts +86 -84
  327. package/src/mcpl/reference-fetcher.ts +71 -26
  328. package/src/mcpl/references.ts +81 -22
  329. package/src/mcpl/refusal-lines.ts +59 -0
  330. package/src/mcpl/server-connection.ts +496 -142
  331. package/src/mcpl/server-registry.ts +15 -4
  332. package/src/mcpl/skip-reply-wake.ts +73 -0
  333. package/src/mcpl/tool-classes.ts +3 -2
  334. package/src/mcpl/transport.ts +219 -26
  335. package/src/mcpl/types.ts +18 -3
  336. package/src/mcpl/visible-content.ts +27 -0
  337. package/src/module-registry.ts +58 -23
  338. package/src/modules/api/index.ts +1 -1
  339. package/src/modules/discord/discord-js-client.ts +26 -10
  340. package/src/modules/discord/index.ts +395 -160
  341. package/src/modules/discord/types.ts +15 -2
  342. package/src/modules/health/index.ts +2 -1
  343. package/src/modules/history/index.ts +410 -120
  344. package/src/modules/history/semantic.ts +189 -32
  345. package/src/modules/unknown-tool.ts +16 -0
  346. package/src/modules/workspace/disk-agreement.ts +125 -21
  347. package/src/modules/workspace/effects.ts +279 -35
  348. package/src/modules/workspace/index.ts +841 -261
  349. package/src/modules/workspace/observe.ts +456 -56
  350. package/src/modules/workspace/reconcile.ts +688 -76
  351. package/src/modules/workspace/types.ts +41 -2
  352. package/src/modules/workspace/watcher.ts +27 -4
  353. package/src/prose-drafts.ts +481 -0
  354. package/src/prose-segments.ts +51 -8
  355. package/src/recovery/offline-branch.ts +36 -29
  356. package/src/safe-slice.ts +9 -1
  357. package/src/stored-removal.ts +126 -0
  358. package/src/tool-image-ledger.ts +153 -34
  359. package/src/tool-presentation.ts +224 -40
  360. package/src/tool-result-guard.ts +7 -8
  361. package/src/tool-result-history.ts +124 -20
  362. package/src/tune-out/coordinator.ts +259 -65
  363. package/src/types/agent.ts +59 -13
  364. package/src/types/events.ts +17 -0
  365. package/src/types/framework.ts +31 -5
  366. package/src/types/inference-log.ts +1 -1
  367. package/src/types/module.ts +31 -7
  368. package/src/types/trace.ts +158 -12
  369. package/src/usage/usage-tracker.ts +32 -8
  370. package/dist/test/activation-request-sanitize.test.d.ts +0 -2
  371. package/dist/test/activation-request-sanitize.test.d.ts.map +0 -1
  372. package/dist/test/activation-request-sanitize.test.js +0 -89
  373. package/dist/test/activation-request-sanitize.test.js.map +0 -1
  374. package/dist/test/agent-cache-ttl.test.d.ts +0 -2
  375. package/dist/test/agent-cache-ttl.test.d.ts.map +0 -1
  376. package/dist/test/agent-cache-ttl.test.js +0 -41
  377. package/dist/test/agent-cache-ttl.test.js.map +0 -1
  378. package/dist/test/agent-runtime-settings.test.d.ts +0 -2
  379. package/dist/test/agent-runtime-settings.test.d.ts.map +0 -1
  380. package/dist/test/agent-runtime-settings.test.js +0 -462
  381. package/dist/test/agent-runtime-settings.test.js.map +0 -1
  382. package/dist/test/api-admin-gate.test.d.ts +0 -2
  383. package/dist/test/api-admin-gate.test.d.ts.map +0 -1
  384. package/dist/test/api-admin-gate.test.js +0 -116
  385. package/dist/test/api-admin-gate.test.js.map +0 -1
  386. package/dist/test/assistant-persist-refusal.test.d.ts +0 -2
  387. package/dist/test/assistant-persist-refusal.test.d.ts.map +0 -1
  388. package/dist/test/assistant-persist-refusal.test.js +0 -63
  389. package/dist/test/assistant-persist-refusal.test.js.map +0 -1
  390. package/dist/test/batched-wake-locus.test.d.ts +0 -2
  391. package/dist/test/batched-wake-locus.test.d.ts.map +0 -1
  392. package/dist/test/batched-wake-locus.test.js +0 -166
  393. package/dist/test/batched-wake-locus.test.js.map +0 -1
  394. package/dist/test/busy-agent-scheduler.test.d.ts +0 -2
  395. package/dist/test/busy-agent-scheduler.test.d.ts.map +0 -1
  396. package/dist/test/busy-agent-scheduler.test.js +0 -92
  397. package/dist/test/busy-agent-scheduler.test.js.map +0 -1
  398. package/dist/test/channel-incoming-targeting.test.d.ts +0 -2
  399. package/dist/test/channel-incoming-targeting.test.d.ts.map +0 -1
  400. package/dist/test/channel-incoming-targeting.test.js +0 -81
  401. package/dist/test/channel-incoming-targeting.test.js.map +0 -1
  402. package/dist/test/channel-label-history.test.d.ts +0 -2
  403. package/dist/test/channel-label-history.test.d.ts.map +0 -1
  404. package/dist/test/channel-label-history.test.js +0 -424
  405. package/dist/test/channel-label-history.test.js.map +0 -1
  406. package/dist/test/channel-lifecycle-provenance.test.d.ts +0 -2
  407. package/dist/test/channel-lifecycle-provenance.test.d.ts.map +0 -1
  408. package/dist/test/channel-lifecycle-provenance.test.js +0 -47
  409. package/dist/test/channel-lifecycle-provenance.test.js.map +0 -1
  410. package/dist/test/channel-registry-routing.test.d.ts +0 -2
  411. package/dist/test/channel-registry-routing.test.d.ts.map +0 -1
  412. package/dist/test/channel-registry-routing.test.js +0 -446
  413. package/dist/test/channel-registry-routing.test.js.map +0 -1
  414. package/dist/test/channel-registry-typing.test.d.ts +0 -2
  415. package/dist/test/channel-registry-typing.test.d.ts.map +0 -1
  416. package/dist/test/channel-registry-typing.test.js +0 -91
  417. package/dist/test/channel-registry-typing.test.js.map +0 -1
  418. package/dist/test/channels-changed-respond-first.test.d.ts +0 -2
  419. package/dist/test/channels-changed-respond-first.test.d.ts.map +0 -1
  420. package/dist/test/channels-changed-respond-first.test.js +0 -74
  421. package/dist/test/channels-changed-respond-first.test.js.map +0 -1
  422. package/dist/test/checkpoint-attribution.test.d.ts +0 -2
  423. package/dist/test/checkpoint-attribution.test.d.ts.map +0 -1
  424. package/dist/test/checkpoint-attribution.test.js +0 -200
  425. package/dist/test/checkpoint-attribution.test.js.map +0 -1
  426. package/dist/test/code-execution.test.d.ts +0 -11
  427. package/dist/test/code-execution.test.d.ts.map +0 -1
  428. package/dist/test/code-execution.test.js +0 -1272
  429. package/dist/test/code-execution.test.js.map +0 -1
  430. package/dist/test/component-defaults.test.d.ts +0 -2
  431. package/dist/test/component-defaults.test.d.ts.map +0 -1
  432. package/dist/test/component-defaults.test.js +0 -54
  433. package/dist/test/component-defaults.test.js.map +0 -1
  434. package/dist/test/conversation-fork-injection-scoping.test.d.ts +0 -2
  435. package/dist/test/conversation-fork-injection-scoping.test.d.ts.map +0 -1
  436. package/dist/test/conversation-fork-injection-scoping.test.js +0 -200
  437. package/dist/test/conversation-fork-injection-scoping.test.js.map +0 -1
  438. package/dist/test/conversation-router.test.d.ts +0 -2
  439. package/dist/test/conversation-router.test.d.ts.map +0 -1
  440. package/dist/test/conversation-router.test.js +0 -174
  441. package/dist/test/conversation-router.test.js.map +0 -1
  442. package/dist/test/conversation-routing.test.d.ts +0 -7
  443. package/dist/test/conversation-routing.test.d.ts.map +0 -1
  444. package/dist/test/conversation-routing.test.js +0 -387
  445. package/dist/test/conversation-routing.test.js.map +0 -1
  446. package/dist/test/deferred-wake-integrity.test.d.ts +0 -29
  447. package/dist/test/deferred-wake-integrity.test.d.ts.map +0 -1
  448. package/dist/test/deferred-wake-integrity.test.js +0 -320
  449. package/dist/test/deferred-wake-integrity.test.js.map +0 -1
  450. package/dist/test/discord-awareness-outbox.test.d.ts +0 -2
  451. package/dist/test/discord-awareness-outbox.test.d.ts.map +0 -1
  452. package/dist/test/discord-awareness-outbox.test.js +0 -267
  453. package/dist/test/discord-awareness-outbox.test.js.map +0 -1
  454. package/dist/test/discord-history-delete-window.test.d.ts +0 -2
  455. package/dist/test/discord-history-delete-window.test.d.ts.map +0 -1
  456. package/dist/test/discord-history-delete-window.test.js +0 -81
  457. package/dist/test/discord-history-delete-window.test.js.map +0 -1
  458. package/dist/test/discord-history-sync.test.d.ts +0 -2
  459. package/dist/test/discord-history-sync.test.d.ts.map +0 -1
  460. package/dist/test/discord-history-sync.test.js +0 -56
  461. package/dist/test/discord-history-sync.test.js.map +0 -1
  462. package/dist/test/ephemeral-settle.test.d.ts +0 -2
  463. package/dist/test/ephemeral-settle.test.d.ts.map +0 -1
  464. package/dist/test/ephemeral-settle.test.js +0 -354
  465. package/dist/test/ephemeral-settle.test.js.map +0 -1
  466. package/dist/test/event-gate-passthrough.test.d.ts +0 -15
  467. package/dist/test/event-gate-passthrough.test.d.ts.map +0 -1
  468. package/dist/test/event-gate-passthrough.test.js +0 -289
  469. package/dist/test/event-gate-passthrough.test.js.map +0 -1
  470. package/dist/test/event-gate-policy-mutation.test.d.ts +0 -2
  471. package/dist/test/event-gate-policy-mutation.test.d.ts.map +0 -1
  472. package/dist/test/event-gate-policy-mutation.test.js +0 -137
  473. package/dist/test/event-gate-policy-mutation.test.js.map +0 -1
  474. package/dist/test/event-gate-rate-limit.test.d.ts +0 -2
  475. package/dist/test/event-gate-rate-limit.test.d.ts.map +0 -1
  476. package/dist/test/event-gate-rate-limit.test.js +0 -627
  477. package/dist/test/event-gate-rate-limit.test.js.map +0 -1
  478. package/dist/test/event-gate-script.test.d.ts +0 -2
  479. package/dist/test/event-gate-script.test.d.ts.map +0 -1
  480. package/dist/test/event-gate-script.test.js +0 -95
  481. package/dist/test/event-gate-script.test.js.map +0 -1
  482. package/dist/test/event-gate-selfwake.test.d.ts +0 -15
  483. package/dist/test/event-gate-selfwake.test.d.ts.map +0 -1
  484. package/dist/test/event-gate-selfwake.test.js +0 -125
  485. package/dist/test/event-gate-selfwake.test.js.map +0 -1
  486. package/dist/test/event-gate-tags.test.d.ts +0 -2
  487. package/dist/test/event-gate-tags.test.d.ts.map +0 -1
  488. package/dist/test/event-gate-tags.test.js +0 -76
  489. package/dist/test/event-gate-tags.test.js.map +0 -1
  490. package/dist/test/event-gate.test.d.ts +0 -2
  491. package/dist/test/event-gate.test.d.ts.map +0 -1
  492. package/dist/test/event-gate.test.js +0 -919
  493. package/dist/test/event-gate.test.js.map +0 -1
  494. package/dist/test/explicit-prose-routing.test.d.ts +0 -11
  495. package/dist/test/explicit-prose-routing.test.d.ts.map +0 -1
  496. package/dist/test/explicit-prose-routing.test.js +0 -1394
  497. package/dist/test/explicit-prose-routing.test.js.map +0 -1
  498. package/dist/test/framework.test.d.ts +0 -5
  499. package/dist/test/framework.test.d.ts.map +0 -1
  500. package/dist/test/framework.test.js +0 -1048
  501. package/dist/test/framework.test.js.map +0 -1
  502. package/dist/test/gather-context-timeout.test.d.ts +0 -2
  503. package/dist/test/gather-context-timeout.test.d.ts.map +0 -1
  504. package/dist/test/gather-context-timeout.test.js +0 -120
  505. package/dist/test/gather-context-timeout.test.js.map +0 -1
  506. package/dist/test/health-snapshot.test.d.ts +0 -2
  507. package/dist/test/health-snapshot.test.d.ts.map +0 -1
  508. package/dist/test/health-snapshot.test.js +0 -74
  509. package/dist/test/health-snapshot.test.js.map +0 -1
  510. package/dist/test/helpers/coalescing-fixture.d.ts +0 -72
  511. package/dist/test/helpers/coalescing-fixture.d.ts.map +0 -1
  512. package/dist/test/helpers/coalescing-fixture.js +0 -146
  513. package/dist/test/helpers/coalescing-fixture.js.map +0 -1
  514. package/dist/test/helpers/coalescing-kill-child.d.ts +0 -2
  515. package/dist/test/helpers/coalescing-kill-child.d.ts.map +0 -1
  516. package/dist/test/helpers/coalescing-kill-child.js +0 -24
  517. package/dist/test/helpers/coalescing-kill-child.js.map +0 -1
  518. package/dist/test/helpers/mock-membrane.d.ts +0 -53
  519. package/dist/test/helpers/mock-membrane.d.ts.map +0 -1
  520. package/dist/test/helpers/mock-membrane.js +0 -168
  521. package/dist/test/helpers/mock-membrane.js.map +0 -1
  522. package/dist/test/helpers/pytc-stop-rows.d.ts +0 -11
  523. package/dist/test/helpers/pytc-stop-rows.d.ts.map +0 -1
  524. package/dist/test/helpers/pytc-stop-rows.js +0 -143
  525. package/dist/test/helpers/pytc-stop-rows.js.map +0 -1
  526. package/dist/test/helpers/quiesce-crash-child.d.ts +0 -2
  527. package/dist/test/helpers/quiesce-crash-child.d.ts.map +0 -1
  528. package/dist/test/helpers/quiesce-crash-child.js +0 -156
  529. package/dist/test/helpers/quiesce-crash-child.js.map +0 -1
  530. package/dist/test/history-module-overview.test.d.ts +0 -2
  531. package/dist/test/history-module-overview.test.d.ts.map +0 -1
  532. package/dist/test/history-module-overview.test.js +0 -711
  533. package/dist/test/history-module-overview.test.js.map +0 -1
  534. package/dist/test/history-module-realstore.test.d.ts +0 -2
  535. package/dist/test/history-module-realstore.test.d.ts.map +0 -1
  536. package/dist/test/history-module-realstore.test.js +0 -363
  537. package/dist/test/history-module-realstore.test.js.map +0 -1
  538. package/dist/test/history-module-semantic.test.d.ts +0 -2
  539. package/dist/test/history-module-semantic.test.d.ts.map +0 -1
  540. package/dist/test/history-module-semantic.test.js +0 -213
  541. package/dist/test/history-module-semantic.test.js.map +0 -1
  542. package/dist/test/history-module-ux.test.d.ts +0 -2
  543. package/dist/test/history-module-ux.test.d.ts.map +0 -1
  544. package/dist/test/history-module-ux.test.js +0 -304
  545. package/dist/test/history-module-ux.test.js.map +0 -1
  546. package/dist/test/history-module.test.d.ts +0 -2
  547. package/dist/test/history-module.test.d.ts.map +0 -1
  548. package/dist/test/history-module.test.js +0 -619
  549. package/dist/test/history-module.test.js.map +0 -1
  550. package/dist/test/history-semantic-review-findings.test.d.ts +0 -2
  551. package/dist/test/history-semantic-review-findings.test.d.ts.map +0 -1
  552. package/dist/test/history-semantic-review-findings.test.js +0 -338
  553. package/dist/test/history-semantic-review-findings.test.js.map +0 -1
  554. package/dist/test/history-semantic-sync-converges.test.d.ts +0 -2
  555. package/dist/test/history-semantic-sync-converges.test.d.ts.map +0 -1
  556. package/dist/test/history-semantic-sync-converges.test.js +0 -109
  557. package/dist/test/history-semantic-sync-converges.test.js.map +0 -1
  558. package/dist/test/host-quiesce.test.d.ts +0 -2
  559. package/dist/test/host-quiesce.test.d.ts.map +0 -1
  560. package/dist/test/host-quiesce.test.js +0 -863
  561. package/dist/test/host-quiesce.test.js.map +0 -1
  562. package/dist/test/inference-exhaustion-rewind.test.d.ts +0 -2
  563. package/dist/test/inference-exhaustion-rewind.test.d.ts.map +0 -1
  564. package/dist/test/inference-exhaustion-rewind.test.js +0 -309
  565. package/dist/test/inference-exhaustion-rewind.test.js.map +0 -1
  566. package/dist/test/inference-failure-bounds.test.d.ts +0 -2
  567. package/dist/test/inference-failure-bounds.test.d.ts.map +0 -1
  568. package/dist/test/inference-failure-bounds.test.js +0 -1201
  569. package/dist/test/inference-failure-bounds.test.js.map +0 -1
  570. package/dist/test/inference-failure-observability.test.d.ts +0 -2
  571. package/dist/test/inference-failure-observability.test.d.ts.map +0 -1
  572. package/dist/test/inference-failure-observability.test.js +0 -84
  573. package/dist/test/inference-failure-observability.test.js.map +0 -1
  574. package/dist/test/journal-tool.test.d.ts +0 -2
  575. package/dist/test/journal-tool.test.d.ts.map +0 -1
  576. package/dist/test/journal-tool.test.js +0 -33
  577. package/dist/test/journal-tool.test.js.map +0 -1
  578. package/dist/test/kv-unified-open-flight-retry.test.d.ts +0 -2
  579. package/dist/test/kv-unified-open-flight-retry.test.d.ts.map +0 -1
  580. package/dist/test/kv-unified-open-flight-retry.test.js +0 -189
  581. package/dist/test/kv-unified-open-flight-retry.test.js.map +0 -1
  582. package/dist/test/kv-unified-wiring.test.d.ts +0 -2
  583. package/dist/test/kv-unified-wiring.test.d.ts.map +0 -1
  584. package/dist/test/kv-unified-wiring.test.js +0 -95
  585. package/dist/test/kv-unified-wiring.test.js.map +0 -1
  586. package/dist/test/late-events-after-stop.test.d.ts +0 -2
  587. package/dist/test/late-events-after-stop.test.d.ts.map +0 -1
  588. package/dist/test/late-events-after-stop.test.js +0 -122
  589. package/dist/test/late-events-after-stop.test.js.map +0 -1
  590. package/dist/test/liveness-watchdog.test.d.ts +0 -2
  591. package/dist/test/liveness-watchdog.test.d.ts.map +0 -1
  592. package/dist/test/liveness-watchdog.test.js +0 -94
  593. package/dist/test/liveness-watchdog.test.js.map +0 -1
  594. package/dist/test/machine-close-provenance.test.d.ts +0 -2
  595. package/dist/test/machine-close-provenance.test.d.ts.map +0 -1
  596. package/dist/test/machine-close-provenance.test.js +0 -116
  597. package/dist/test/machine-close-provenance.test.js.map +0 -1
  598. package/dist/test/maintenance-timer.test.d.ts +0 -2
  599. package/dist/test/maintenance-timer.test.d.ts.map +0 -1
  600. package/dist/test/maintenance-timer.test.js +0 -265
  601. package/dist/test/maintenance-timer.test.js.map +0 -1
  602. package/dist/test/mcpl-access-provider.test.d.ts +0 -2
  603. package/dist/test/mcpl-access-provider.test.d.ts.map +0 -1
  604. package/dist/test/mcpl-access-provider.test.js +0 -20
  605. package/dist/test/mcpl-access-provider.test.js.map +0 -1
  606. package/dist/test/mcpl-awareness-barrier.test.d.ts +0 -2
  607. package/dist/test/mcpl-awareness-barrier.test.d.ts.map +0 -1
  608. package/dist/test/mcpl-awareness-barrier.test.js +0 -769
  609. package/dist/test/mcpl-awareness-barrier.test.js.map +0 -1
  610. package/dist/test/mcpl-capability-grant.test.d.ts +0 -10
  611. package/dist/test/mcpl-capability-grant.test.d.ts.map +0 -1
  612. package/dist/test/mcpl-capability-grant.test.js +0 -111
  613. package/dist/test/mcpl-capability-grant.test.js.map +0 -1
  614. package/dist/test/mcpl-capability-scoping.test.d.ts +0 -2
  615. package/dist/test/mcpl-capability-scoping.test.d.ts.map +0 -1
  616. package/dist/test/mcpl-capability-scoping.test.js +0 -266
  617. package/dist/test/mcpl-capability-scoping.test.js.map +0 -1
  618. package/dist/test/mcpl-child-env.test.d.ts +0 -2
  619. package/dist/test/mcpl-child-env.test.d.ts.map +0 -1
  620. package/dist/test/mcpl-child-env.test.js +0 -158
  621. package/dist/test/mcpl-child-env.test.js.map +0 -1
  622. package/dist/test/mcpl-coalescing.test.d.ts +0 -2
  623. package/dist/test/mcpl-coalescing.test.d.ts.map +0 -1
  624. package/dist/test/mcpl-coalescing.test.js +0 -1125
  625. package/dist/test/mcpl-coalescing.test.js.map +0 -1
  626. package/dist/test/mcpl-config-diagnostics.test.d.ts +0 -2
  627. package/dist/test/mcpl-config-diagnostics.test.d.ts.map +0 -1
  628. package/dist/test/mcpl-config-diagnostics.test.js +0 -452
  629. package/dist/test/mcpl-config-diagnostics.test.js.map +0 -1
  630. package/dist/test/mcpl-empty-content.test.d.ts +0 -2
  631. package/dist/test/mcpl-empty-content.test.d.ts.map +0 -1
  632. package/dist/test/mcpl-empty-content.test.js +0 -368
  633. package/dist/test/mcpl-empty-content.test.js.map +0 -1
  634. package/dist/test/mcpl-gate-roundtrip.test.d.ts +0 -2
  635. package/dist/test/mcpl-gate-roundtrip.test.d.ts.map +0 -1
  636. package/dist/test/mcpl-gate-roundtrip.test.js +0 -285
  637. package/dist/test/mcpl-gate-roundtrip.test.js.map +0 -1
  638. package/dist/test/mcpl-list-status.test.d.ts +0 -2
  639. package/dist/test/mcpl-list-status.test.d.ts.map +0 -1
  640. package/dist/test/mcpl-list-status.test.js +0 -82
  641. package/dist/test/mcpl-list-status.test.js.map +0 -1
  642. package/dist/test/mcpl-manifest-changed.test.d.ts +0 -2
  643. package/dist/test/mcpl-manifest-changed.test.d.ts.map +0 -1
  644. package/dist/test/mcpl-manifest-changed.test.js +0 -178
  645. package/dist/test/mcpl-manifest-changed.test.js.map +0 -1
  646. package/dist/test/mcpl-push-convert.test.d.ts +0 -2
  647. package/dist/test/mcpl-push-convert.test.d.ts.map +0 -1
  648. package/dist/test/mcpl-push-convert.test.js +0 -42
  649. package/dist/test/mcpl-push-convert.test.js.map +0 -1
  650. package/dist/test/mcpl-reconnect-events.test.d.ts +0 -2
  651. package/dist/test/mcpl-reconnect-events.test.d.ts.map +0 -1
  652. package/dist/test/mcpl-reconnect-events.test.js +0 -144
  653. package/dist/test/mcpl-reconnect-events.test.js.map +0 -1
  654. package/dist/test/mcpl-reconnect-reregistration.test.d.ts +0 -2
  655. package/dist/test/mcpl-reconnect-reregistration.test.d.ts.map +0 -1
  656. package/dist/test/mcpl-reconnect-reregistration.test.js +0 -236
  657. package/dist/test/mcpl-reconnect-reregistration.test.js.map +0 -1
  658. package/dist/test/mcpl-reference-fetcher.test.d.ts +0 -2
  659. package/dist/test/mcpl-reference-fetcher.test.d.ts.map +0 -1
  660. package/dist/test/mcpl-reference-fetcher.test.js +0 -427
  661. package/dist/test/mcpl-reference-fetcher.test.js.map +0 -1
  662. package/dist/test/mcpl-reference-fields.test.d.ts +0 -2
  663. package/dist/test/mcpl-reference-fields.test.d.ts.map +0 -1
  664. package/dist/test/mcpl-reference-fields.test.js +0 -149
  665. package/dist/test/mcpl-reference-fields.test.js.map +0 -1
  666. package/dist/test/mcpl-request-timeout.test.d.ts +0 -2
  667. package/dist/test/mcpl-request-timeout.test.d.ts.map +0 -1
  668. package/dist/test/mcpl-request-timeout.test.js +0 -138
  669. package/dist/test/mcpl-request-timeout.test.js.map +0 -1
  670. package/dist/test/mcpl-runtime-lifecycle.test.d.ts +0 -7
  671. package/dist/test/mcpl-runtime-lifecycle.test.d.ts.map +0 -1
  672. package/dist/test/mcpl-runtime-lifecycle.test.js +0 -142
  673. package/dist/test/mcpl-runtime-lifecycle.test.js.map +0 -1
  674. package/dist/test/mcpl-tool-class-listing.test.d.ts +0 -2
  675. package/dist/test/mcpl-tool-class-listing.test.d.ts.map +0 -1
  676. package/dist/test/mcpl-tool-class-listing.test.js +0 -147
  677. package/dist/test/mcpl-tool-class-listing.test.js.map +0 -1
  678. package/dist/test/mcpl-tool-classes.test.d.ts +0 -7
  679. package/dist/test/mcpl-tool-classes.test.d.ts.map +0 -1
  680. package/dist/test/mcpl-tool-classes.test.js +0 -80
  681. package/dist/test/mcpl-tool-classes.test.js.map +0 -1
  682. package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts +0 -2
  683. package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts.map +0 -1
  684. package/dist/test/mcpl-tool-lifecycle-e2e.test.js +0 -237
  685. package/dist/test/mcpl-tool-lifecycle-e2e.test.js.map +0 -1
  686. package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts +0 -11
  687. package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts.map +0 -1
  688. package/dist/test/mcpl-tool-lifecycle-emitter.test.js +0 -412
  689. package/dist/test/mcpl-tool-lifecycle-emitter.test.js.map +0 -1
  690. package/dist/test/mcpl-tool-lifecycle-script.test.d.ts +0 -2
  691. package/dist/test/mcpl-tool-lifecycle-script.test.d.ts.map +0 -1
  692. package/dist/test/mcpl-tool-lifecycle-script.test.js +0 -288
  693. package/dist/test/mcpl-tool-lifecycle-script.test.js.map +0 -1
  694. package/dist/test/mcpl-tool-lifecycle.test.d.ts +0 -11
  695. package/dist/test/mcpl-tool-lifecycle.test.d.ts.map +0 -1
  696. package/dist/test/mcpl-tool-lifecycle.test.js +0 -270
  697. package/dist/test/mcpl-tool-lifecycle.test.js.map +0 -1
  698. package/dist/test/mcpl-ws-transport.test.d.ts +0 -2
  699. package/dist/test/mcpl-ws-transport.test.d.ts.map +0 -1
  700. package/dist/test/mcpl-ws-transport.test.js +0 -258
  701. package/dist/test/mcpl-ws-transport.test.js.map +0 -1
  702. package/dist/test/module-context-integration.test.d.ts +0 -18
  703. package/dist/test/module-context-integration.test.d.ts.map +0 -1
  704. package/dist/test/module-context-integration.test.js +0 -181
  705. package/dist/test/module-context-integration.test.js.map +0 -1
  706. package/dist/test/offline-recovery-branch.test.d.ts +0 -2
  707. package/dist/test/offline-recovery-branch.test.d.ts.map +0 -1
  708. package/dist/test/offline-recovery-branch.test.js +0 -226
  709. package/dist/test/offline-recovery-branch.test.js.map +0 -1
  710. package/dist/test/operator-surgery.test.d.ts +0 -2
  711. package/dist/test/operator-surgery.test.d.ts.map +0 -1
  712. package/dist/test/operator-surgery.test.js +0 -398
  713. package/dist/test/operator-surgery.test.js.map +0 -1
  714. package/dist/test/ops-alert.test.d.ts +0 -2
  715. package/dist/test/ops-alert.test.d.ts.map +0 -1
  716. package/dist/test/ops-alert.test.js +0 -153
  717. package/dist/test/ops-alert.test.js.map +0 -1
  718. package/dist/test/overbudget-drain-breaker.test.d.ts +0 -2
  719. package/dist/test/overbudget-drain-breaker.test.d.ts.map +0 -1
  720. package/dist/test/overbudget-drain-breaker.test.js +0 -197
  721. package/dist/test/overbudget-drain-breaker.test.js.map +0 -1
  722. package/dist/test/per-agent-delivery.test.d.ts +0 -2
  723. package/dist/test/per-agent-delivery.test.d.ts.map +0 -1
  724. package/dist/test/per-agent-delivery.test.js +0 -108
  725. package/dist/test/per-agent-delivery.test.js.map +0 -1
  726. package/dist/test/physical-window-restart.test.d.ts +0 -14
  727. package/dist/test/physical-window-restart.test.d.ts.map +0 -1
  728. package/dist/test/physical-window-restart.test.js +0 -222
  729. package/dist/test/physical-window-restart.test.js.map +0 -1
  730. package/dist/test/placed-reaction-baseline.test.d.ts +0 -2
  731. package/dist/test/placed-reaction-baseline.test.d.ts.map +0 -1
  732. package/dist/test/placed-reaction-baseline.test.js +0 -312
  733. package/dist/test/placed-reaction-baseline.test.js.map +0 -1
  734. package/dist/test/present-while-acting.test.d.ts +0 -19
  735. package/dist/test/present-while-acting.test.d.ts.map +0 -1
  736. package/dist/test/present-while-acting.test.js +0 -706
  737. package/dist/test/present-while-acting.test.js.map +0 -1
  738. package/dist/test/prose-segments.test.d.ts +0 -2
  739. package/dist/test/prose-segments.test.d.ts.map +0 -1
  740. package/dist/test/prose-segments.test.js +0 -52
  741. package/dist/test/prose-segments.test.js.map +0 -1
  742. package/dist/test/prose-stream-router.test.d.ts +0 -2
  743. package/dist/test/prose-stream-router.test.d.ts.map +0 -1
  744. package/dist/test/prose-stream-router.test.js +0 -171
  745. package/dist/test/prose-stream-router.test.js.map +0 -1
  746. package/dist/test/provider-acceleration-cooldown.test.d.ts +0 -2
  747. package/dist/test/provider-acceleration-cooldown.test.d.ts.map +0 -1
  748. package/dist/test/provider-acceleration-cooldown.test.js +0 -435
  749. package/dist/test/provider-acceleration-cooldown.test.js.map +0 -1
  750. package/dist/test/provider-waits.test.d.ts +0 -2
  751. package/dist/test/provider-waits.test.d.ts.map +0 -1
  752. package/dist/test/provider-waits.test.js +0 -2196
  753. package/dist/test/provider-waits.test.js.map +0 -1
  754. package/dist/test/puppet-tool-call.test.d.ts +0 -2
  755. package/dist/test/puppet-tool-call.test.d.ts.map +0 -1
  756. package/dist/test/puppet-tool-call.test.js +0 -224
  757. package/dist/test/puppet-tool-call.test.js.map +0 -1
  758. package/dist/test/puppet-turn-reservation.test.d.ts +0 -2
  759. package/dist/test/puppet-turn-reservation.test.d.ts.map +0 -1
  760. package/dist/test/puppet-turn-reservation.test.js +0 -139
  761. package/dist/test/puppet-turn-reservation.test.js.map +0 -1
  762. package/dist/test/reaction-baseline-platform.test.d.ts +0 -2
  763. package/dist/test/reaction-baseline-platform.test.d.ts.map +0 -1
  764. package/dist/test/reaction-baseline-platform.test.js +0 -124
  765. package/dist/test/reaction-baseline-platform.test.js.map +0 -1
  766. package/dist/test/record-journal.test.d.ts +0 -6
  767. package/dist/test/record-journal.test.d.ts.map +0 -1
  768. package/dist/test/record-journal.test.js +0 -269
  769. package/dist/test/record-journal.test.js.map +0 -1
  770. package/dist/test/refusal-reaction-baseline.test.d.ts +0 -2
  771. package/dist/test/refusal-reaction-baseline.test.d.ts.map +0 -1
  772. package/dist/test/refusal-reaction-baseline.test.js +0 -81
  773. package/dist/test/refusal-reaction-baseline.test.js.map +0 -1
  774. package/dist/test/refusal-rewind.test.d.ts +0 -2
  775. package/dist/test/refusal-rewind.test.d.ts.map +0 -1
  776. package/dist/test/refusal-rewind.test.js +0 -108
  777. package/dist/test/refusal-rewind.test.js.map +0 -1
  778. package/dist/test/refusal-single-call.test.d.ts +0 -2
  779. package/dist/test/refusal-single-call.test.d.ts.map +0 -1
  780. package/dist/test/refusal-single-call.test.js +0 -177
  781. package/dist/test/refusal-single-call.test.js.map +0 -1
  782. package/dist/test/release-changelog.test.d.ts +0 -2
  783. package/dist/test/release-changelog.test.d.ts.map +0 -1
  784. package/dist/test/release-changelog.test.js +0 -159
  785. package/dist/test/release-changelog.test.js.map +0 -1
  786. package/dist/test/same-round-think-policy.test.d.ts +0 -2
  787. package/dist/test/same-round-think-policy.test.d.ts.map +0 -1
  788. package/dist/test/same-round-think-policy.test.js +0 -853
  789. package/dist/test/same-round-think-policy.test.js.map +0 -1
  790. package/dist/test/save-recent-image.test.d.ts +0 -26
  791. package/dist/test/save-recent-image.test.d.ts.map +0 -1
  792. package/dist/test/save-recent-image.test.js +0 -974
  793. package/dist/test/save-recent-image.test.js.map +0 -1
  794. package/dist/test/shutdown-errors.test.d.ts +0 -2
  795. package/dist/test/shutdown-errors.test.d.ts.map +0 -1
  796. package/dist/test/shutdown-errors.test.js +0 -662
  797. package/dist/test/shutdown-errors.test.js.map +0 -1
  798. package/dist/test/silent-heartbeat-rows.test.d.ts +0 -2
  799. package/dist/test/silent-heartbeat-rows.test.d.ts.map +0 -1
  800. package/dist/test/silent-heartbeat-rows.test.js +0 -451
  801. package/dist/test/silent-heartbeat-rows.test.js.map +0 -1
  802. package/dist/test/silent-heartbeat.test.d.ts +0 -2
  803. package/dist/test/silent-heartbeat.test.d.ts.map +0 -1
  804. package/dist/test/silent-heartbeat.test.js +0 -165
  805. package/dist/test/silent-heartbeat.test.js.map +0 -1
  806. package/dist/test/state-scaling-e2e.test.d.ts +0 -22
  807. package/dist/test/state-scaling-e2e.test.d.ts.map +0 -1
  808. package/dist/test/state-scaling-e2e.test.js +0 -206
  809. package/dist/test/state-scaling-e2e.test.js.map +0 -1
  810. package/dist/test/state-scaling.test.d.ts +0 -12
  811. package/dist/test/state-scaling.test.d.ts.map +0 -1
  812. package/dist/test/state-scaling.test.js +0 -251
  813. package/dist/test/state-scaling.test.js.map +0 -1
  814. package/dist/test/stop-with-work-in-flight.test.d.ts +0 -23
  815. package/dist/test/stop-with-work-in-flight.test.d.ts.map +0 -1
  816. package/dist/test/stop-with-work-in-flight.test.js +0 -672
  817. package/dist/test/stop-with-work-in-flight.test.js.map +0 -1
  818. package/dist/test/surgery-marks-receipt.test.d.ts +0 -2
  819. package/dist/test/surgery-marks-receipt.test.d.ts.map +0 -1
  820. package/dist/test/surgery-marks-receipt.test.js +0 -540
  821. package/dist/test/surgery-marks-receipt.test.js.map +0 -1
  822. package/dist/test/thinking-token-stamp.test.d.ts +0 -12
  823. package/dist/test/thinking-token-stamp.test.d.ts.map +0 -1
  824. package/dist/test/thinking-token-stamp.test.js +0 -129
  825. package/dist/test/thinking-token-stamp.test.js.map +0 -1
  826. package/dist/test/timezone.test.d.ts +0 -2
  827. package/dist/test/timezone.test.d.ts.map +0 -1
  828. package/dist/test/timezone.test.js +0 -18
  829. package/dist/test/timezone.test.js.map +0 -1
  830. package/dist/test/tool-batch-hook.test.d.ts +0 -8
  831. package/dist/test/tool-batch-hook.test.d.ts.map +0 -1
  832. package/dist/test/tool-batch-hook.test.js +0 -275
  833. package/dist/test/tool-batch-hook.test.js.map +0 -1
  834. package/dist/test/tool-policy.test.d.ts +0 -2
  835. package/dist/test/tool-policy.test.d.ts.map +0 -1
  836. package/dist/test/tool-policy.test.js +0 -51
  837. package/dist/test/tool-policy.test.js.map +0 -1
  838. package/dist/test/tool-presentation.test.d.ts +0 -2
  839. package/dist/test/tool-presentation.test.d.ts.map +0 -1
  840. package/dist/test/tool-presentation.test.js +0 -268
  841. package/dist/test/tool-presentation.test.js.map +0 -1
  842. package/dist/test/tool-result-content.test.d.ts +0 -2
  843. package/dist/test/tool-result-content.test.d.ts.map +0 -1
  844. package/dist/test/tool-result-content.test.js +0 -37
  845. package/dist/test/tool-result-content.test.js.map +0 -1
  846. package/dist/test/tool-result-guard.test.d.ts +0 -2
  847. package/dist/test/tool-result-guard.test.d.ts.map +0 -1
  848. package/dist/test/tool-result-guard.test.js +0 -3607
  849. package/dist/test/tool-result-guard.test.js.map +0 -1
  850. package/dist/test/tool-result-history.test.d.ts +0 -7
  851. package/dist/test/tool-result-history.test.d.ts.map +0 -1
  852. package/dist/test/tool-result-history.test.js +0 -156
  853. package/dist/test/tool-result-history.test.js.map +0 -1
  854. package/dist/test/tool-result-spill.test.d.ts +0 -13
  855. package/dist/test/tool-result-spill.test.d.ts.map +0 -1
  856. package/dist/test/tool-result-spill.test.js +0 -586
  857. package/dist/test/tool-result-spill.test.js.map +0 -1
  858. package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts +0 -2
  859. package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts.map +0 -1
  860. package/dist/test/tool-wrapper-prose-guard-integration.test.js +0 -485
  861. package/dist/test/tool-wrapper-prose-guard-integration.test.js.map +0 -1
  862. package/dist/test/tool-wrapper-prose-guard.test.d.ts +0 -2
  863. package/dist/test/tool-wrapper-prose-guard.test.d.ts.map +0 -1
  864. package/dist/test/tool-wrapper-prose-guard.test.js +0 -34
  865. package/dist/test/tool-wrapper-prose-guard.test.js.map +0 -1
  866. package/dist/test/tools-observe-parser-conformance.test.d.ts +0 -2
  867. package/dist/test/tools-observe-parser-conformance.test.d.ts.map +0 -1
  868. package/dist/test/tools-observe-parser-conformance.test.js +0 -129
  869. package/dist/test/tools-observe-parser-conformance.test.js.map +0 -1
  870. package/dist/test/trunk-channel-routing.test.d.ts +0 -19
  871. package/dist/test/trunk-channel-routing.test.d.ts.map +0 -1
  872. package/dist/test/trunk-channel-routing.test.js +0 -329
  873. package/dist/test/trunk-channel-routing.test.js.map +0 -1
  874. package/dist/test/tune-out-e2e.test.d.ts +0 -2
  875. package/dist/test/tune-out-e2e.test.d.ts.map +0 -1
  876. package/dist/test/tune-out-e2e.test.js +0 -142
  877. package/dist/test/tune-out-e2e.test.js.map +0 -1
  878. package/dist/test/tune-out-gate-composition.test.d.ts +0 -2
  879. package/dist/test/tune-out-gate-composition.test.d.ts.map +0 -1
  880. package/dist/test/tune-out-gate-composition.test.js +0 -221
  881. package/dist/test/tune-out-gate-composition.test.js.map +0 -1
  882. package/dist/test/tune-out-lifecycle.test.d.ts +0 -2
  883. package/dist/test/tune-out-lifecycle.test.d.ts.map +0 -1
  884. package/dist/test/tune-out-lifecycle.test.js +0 -121
  885. package/dist/test/tune-out-lifecycle.test.js.map +0 -1
  886. package/dist/test/turn-trigger-provenance.test.d.ts +0 -2
  887. package/dist/test/turn-trigger-provenance.test.d.ts.map +0 -1
  888. package/dist/test/turn-trigger-provenance.test.js +0 -137
  889. package/dist/test/turn-trigger-provenance.test.js.map +0 -1
  890. package/dist/test/unconvertible-tool-result.test.d.ts +0 -2
  891. package/dist/test/unconvertible-tool-result.test.d.ts.map +0 -1
  892. package/dist/test/unconvertible-tool-result.test.js +0 -358
  893. package/dist/test/unconvertible-tool-result.test.js.map +0 -1
  894. package/dist/test/usage-accounting.test.d.ts +0 -2
  895. package/dist/test/usage-accounting.test.d.ts.map +0 -1
  896. package/dist/test/usage-accounting.test.js +0 -13
  897. package/dist/test/usage-accounting.test.js.map +0 -1
  898. package/dist/test/usage-tracker.test.d.ts +0 -2
  899. package/dist/test/usage-tracker.test.d.ts.map +0 -1
  900. package/dist/test/usage-tracker.test.js +0 -129
  901. package/dist/test/usage-tracker.test.js.map +0 -1
  902. package/dist/test/utils-surface.test.d.ts +0 -2
  903. package/dist/test/utils-surface.test.d.ts.map +0 -1
  904. package/dist/test/utils-surface.test.js +0 -145
  905. package/dist/test/utils-surface.test.js.map +0 -1
  906. package/dist/test/workspace-branch-continuation.test.d.ts +0 -15
  907. package/dist/test/workspace-branch-continuation.test.d.ts.map +0 -1
  908. package/dist/test/workspace-branch-continuation.test.js +0 -183
  909. package/dist/test/workspace-branch-continuation.test.js.map +0 -1
  910. package/dist/test/workspace-materialize-freshness.test.d.ts +0 -16
  911. package/dist/test/workspace-materialize-freshness.test.d.ts.map +0 -1
  912. package/dist/test/workspace-materialize-freshness.test.js +0 -252
  913. package/dist/test/workspace-materialize-freshness.test.js.map +0 -1
  914. package/dist/test/workspace-path-containment.test.d.ts +0 -19
  915. package/dist/test/workspace-path-containment.test.d.ts.map +0 -1
  916. package/dist/test/workspace-path-containment.test.js +0 -91
  917. package/dist/test/workspace-path-containment.test.js.map +0 -1
  918. package/dist/test/workspace-read-file-from-disk.test.d.ts +0 -17
  919. package/dist/test/workspace-read-file-from-disk.test.d.ts.map +0 -1
  920. package/dist/test/workspace-read-file-from-disk.test.js +0 -174
  921. package/dist/test/workspace-read-file-from-disk.test.js.map +0 -1
  922. package/dist/test/workspace-read-image.test.d.ts +0 -2
  923. package/dist/test/workspace-read-image.test.d.ts.map +0 -1
  924. package/dist/test/workspace-read-image.test.js +0 -597
  925. package/dist/test/workspace-read-image.test.js.map +0 -1
  926. package/dist/test/workspace-read-text.test.d.ts +0 -2
  927. package/dist/test/workspace-read-text.test.d.ts.map +0 -1
  928. package/dist/test/workspace-read-text.test.js +0 -101
  929. package/dist/test/workspace-read-text.test.js.map +0 -1
  930. package/dist/test/workspace-restore-order.test.d.ts +0 -16
  931. package/dist/test/workspace-restore-order.test.d.ts.map +0 -1
  932. package/dist/test/workspace-restore-order.test.js +0 -140
  933. package/dist/test/workspace-restore-order.test.js.map +0 -1
  934. package/dist/test/workspace-three-way.test.d.ts +0 -12
  935. package/dist/test/workspace-three-way.test.d.ts.map +0 -1
  936. package/dist/test/workspace-three-way.test.js +0 -3194
  937. package/dist/test/workspace-three-way.test.js.map +0 -1
  938. package/dist/test/workspace-watcher.test.d.ts +0 -2
  939. package/dist/test/workspace-watcher.test.d.ts.map +0 -1
  940. package/dist/test/workspace-watcher.test.js +0 -281
  941. package/dist/test/workspace-watcher.test.js.map +0 -1
  942. package/dist/test/xml-round-persist.test.d.ts +0 -19
  943. package/dist/test/xml-round-persist.test.d.ts.map +0 -1
  944. package/dist/test/xml-round-persist.test.js +0 -235
  945. package/dist/test/xml-round-persist.test.js.map +0 -1
  946. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -26,6 +26,7 @@
26
26
 
27
27
  import type { ContextManager, StoredMessage } from '@animalabs/context-manager';
28
28
  import type { ContentBlock } from '@animalabs/membrane';
29
+ import { safeSlice } from '../../safe-slice.js';
29
30
 
30
31
  export interface SemanticIndexConfig {
31
32
  /** Base URL of the embed-service, e.g. `http://100.90.161.34:8804`. */
@@ -104,6 +105,35 @@ export interface SearchResponse {
104
105
 
105
106
  const PRIVATE_PROSE_TOOLS = new Set(['think', 'journal', 'skip_reply', 'private_note']);
106
107
 
108
+ /**
109
+ * The semantic index service's failure, said of the service alone: it didn't
110
+ * answer in time, couldn't be reached, cut its answer off, answered without
111
+ * what its request's caller reads, or answered with an HTTP error. `status` is
112
+ * the answer's HTTP status, and null where no whole answer came. Each caller
113
+ * says what that meant for its own work, a search or the background sync.
114
+ */
115
+ export class EmbedServiceError extends Error {
116
+ constructor(message: string, readonly status: number | null) {
117
+ super(message);
118
+ this.name = 'EmbedServiceError';
119
+ }
120
+ }
121
+
122
+ /**
123
+ * What stopped a request reaching the service: fetch's cause, such as a
124
+ * refused connection. When several addresses were tried, as for a name like
125
+ * localhost with both an IPv6 and an IPv4 address, the cause is an
126
+ * AggregateError with no message of its own, and each address's error says it.
127
+ */
128
+ function unreachedReason(e: unknown): string {
129
+ const cause = (e as { cause?: unknown } | null)?.cause;
130
+ if (cause instanceof AggregateError && !cause.message) {
131
+ const each = cause.errors.map((err) => (err instanceof Error ? err.message : String(err))).filter(Boolean);
132
+ if (each.length > 0) return each.join('; ');
133
+ }
134
+ return (cause instanceof Error && cause.message) || (e instanceof Error ? e.message : String(e));
135
+ }
136
+
107
137
  export class SemanticIndexClient {
108
138
  private readonly base: string;
109
139
  private readonly ns: string;
@@ -114,21 +144,69 @@ export class SemanticIndexClient {
114
144
  this.timeoutMs = cfg.requestTimeoutMs ?? 30_000;
115
145
  }
116
146
 
117
- private async call<T>(method: 'GET' | 'POST', path: string, body?: unknown): Promise<T> {
147
+ /**
148
+ * A request's answer, as JSON. `expect` is what the caller reads of it: an
149
+ * answer without that, such as a web page at a wrong address, fails as
150
+ * one, with its status, since the service did answer.
151
+ */
152
+ private async call<T>(
153
+ method: 'GET' | 'POST', path: string, body?: unknown, expect?: { what: string; is: (json: unknown) => boolean },
154
+ ): Promise<T> {
118
155
  const headers: Record<string, string> = { 'content-type': 'application/json' };
119
156
  if (this.cfg.token) headers.authorization = `Bearer ${this.cfg.token}`;
120
157
  const ctrl = new AbortController();
121
158
  const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
159
+ // The request's kind, for a message: search, upsert, delete or stats.
160
+ const request = path.slice(path.lastIndexOf('/') + 1);
161
+ // The timeout as the client used it: whole seconds, or else milliseconds.
162
+ const within = this.timeoutMs % 1000 === 0 ? `${this.timeoutMs / 1000} s` : `${this.timeoutMs} ms`;
122
163
  try {
123
- const res = await fetch(`${this.base}${path}`, {
124
- method, headers, body: body === undefined ? undefined : JSON.stringify(body), signal: ctrl.signal,
125
- });
126
- const text = await res.text();
164
+ let res: Response;
165
+ let text: string;
166
+ let answered = false;
167
+ try {
168
+ res = await fetch(`${this.base}${path}`, {
169
+ method, headers, body: body === undefined ? undefined : JSON.stringify(body), signal: ctrl.signal,
170
+ });
171
+ answered = true;
172
+ // An answer cut off after its status, or not finished within the
173
+ // timeout, counts as no answer. That's rare, and a stats or delete
174
+ // request that misses its 404 this way is made again on a later pass
175
+ // of the sync.
176
+ text = await res.text();
177
+ } catch (e) {
178
+ throw new EmbedServiceError(
179
+ answered
180
+ ? ctrl.signal.aborted
181
+ ? `the semantic index service's answer to the ${request} request didn't finish within ${within}`
182
+ : `the semantic index service's answer to the ${request} request was cut off (${unreachedReason(e)})`
183
+ : ctrl.signal.aborted
184
+ ? `the semantic index service didn't answer the ${request} request within ${within}`
185
+ : `the semantic index service couldn't be reached for the ${request} request (${unreachedReason(e)})`,
186
+ null,
187
+ );
188
+ }
127
189
  let json: unknown;
128
190
  try { json = JSON.parse(text); } catch { json = undefined; }
129
191
  if (!res.ok) {
130
- const msg = (json as { error?: { message?: string } } | undefined)?.error?.message ?? text.slice(0, 200);
131
- throw new Error(`embed-service ${method} ${path} → ${res.status}: ${msg}`);
192
+ // The service's message, or any other body, is quoted to at most its
193
+ // first 200 UTF-16 units, one fewer rather than end on half of a
194
+ // surrogate pair, and a quote that's cut ends in "…". A message that
195
+ // isn't text quotes the body instead.
196
+ const given = (json as { error?: { message?: unknown } } | undefined)?.error?.message;
197
+ const quoted = typeof given === 'string' ? given : text;
198
+ const cut = safeSlice(quoted, 0, 200);
199
+ const msg = cut.length < quoted.length ? `${cut}…` : cut;
200
+ throw new EmbedServiceError(
201
+ `the semantic index service answered the ${request} request with an error (HTTP ${res.status}${msg ? `: ${msg}` : ''})`,
202
+ res.status,
203
+ );
204
+ }
205
+ if (expect && !expect.is(json)) {
206
+ throw new EmbedServiceError(
207
+ `the semantic index service answered the ${request} request without ${expect.what} (HTTP ${res.status})`,
208
+ res.status,
209
+ );
132
210
  }
133
211
  return json as T;
134
212
  } finally {
@@ -139,15 +217,17 @@ export class SemanticIndexClient {
139
217
  /** Stats for this namespace; `null` when the namespace does not exist yet. */
140
218
  async stats(): Promise<IndexStats | null> {
141
219
  try {
142
- return await this.call<IndexStats>('GET', `/v1/index/${this.ns}/stats`);
220
+ return await this.call<IndexStats>('GET', `/v1/index/${this.ns}/stats`, undefined, {
221
+ what: 'stats by kind', is: (json) => isObject((json as { by_kind?: unknown } | undefined)?.by_kind),
222
+ });
143
223
  } catch (e) {
144
- if (e instanceof Error && /→ 404/.test(e.message)) return null;
224
+ if (e instanceof EmbedServiceError && e.status === 404) return null;
145
225
  throw e;
146
226
  }
147
227
  }
148
228
 
149
229
  async upsert(items: IndexItem[]): Promise<{ inserted: number; updated: number; unchanged: number; count: number }> {
150
- return this.call('POST', `/v1/index/${this.ns}/upsert`, { items });
230
+ return this.call('POST', `/v1/index/${this.ns}/upsert`, { items }, { what: 'a JSON object', is: isObject });
151
231
  }
152
232
 
153
233
  async delete(ids: string[]): Promise<{ deleted: number }> {
@@ -155,10 +235,29 @@ export class SemanticIndexClient {
155
235
  }
156
236
 
157
237
  async search(req: SearchRequest): Promise<SearchResponse> {
158
- return this.call<SearchResponse>('POST', `/v1/index/${this.ns}/search`, req);
238
+ return this.call('POST', `/v1/index/${this.ns}/search`, req, {
239
+ what: 'a list of hits, each with an id', is: (json) => {
240
+ const hits = (json as { hits?: unknown } | undefined)?.hits;
241
+ return Array.isArray(hits) && hits.every(isHit);
242
+ },
243
+ });
159
244
  }
160
245
  }
161
246
 
247
+ /** A JSON object: not null, and not a list. */
248
+ function isObject(json: unknown): boolean {
249
+ return typeof json === 'object' && json !== null && !Array.isArray(json);
250
+ }
251
+
252
+ /**
253
+ * A hit as semantic_search needs one: an object with a string id, which it
254
+ * reads of every hit. Its ts and meta are read only for the hits it returns,
255
+ * and as far as they can be read.
256
+ */
257
+ function isHit(hit: unknown): boolean {
258
+ return isObject(hit) && typeof (hit as { id?: unknown }).id === 'string';
259
+ }
260
+
162
261
  /** Text to embed for one message, or '' when there is nothing worth indexing. */
163
262
  export function messageIndexText(msg: StoredMessage, includePrivateTools = true): string {
164
263
  const parts: string[] = [];
@@ -194,7 +293,7 @@ export function messageToItem(msg: StoredMessage, cfg: { includePrivateTools?: b
194
293
  const tsMs = msg.timestamp.getTime();
195
294
  return {
196
295
  id: `msg:${String(msg.id)}`,
197
- text: text.slice(0, cfg.maxChars ?? 32_000),
296
+ text: safeSlice(text, 0, cfg.maxChars ?? 32_000),
198
297
  ts: tsMs / 1000,
199
298
  channel: channelOf(msg),
200
299
  kind: 'message',
@@ -221,7 +320,7 @@ export function summaryToItem(s: SummaryLike, cfg: { maxChars?: number }): Index
221
320
  if (!text) return null;
222
321
  return {
223
322
  id: `sum:${s.id}`,
224
- text: text.slice(0, cfg.maxChars ?? 32_000),
323
+ text: safeSlice(text, 0, cfg.maxChars ?? 32_000),
225
324
  ts: s.startMs / 1000,
226
325
  kind: 'summary',
227
326
  level: s.level,
@@ -258,6 +357,11 @@ export class SemanticIndexer {
258
357
  private readonly log: (msg: string) => void = () => {},
259
358
  ) {}
260
359
 
360
+ /** A line for the host's log, naming this indexer's index first, since a host can keep several. */
361
+ warn(line: string): void {
362
+ this.log(`[history/semantic] index ${JSON.stringify(this.cfg.namespace)}: ${line}`);
363
+ }
364
+
261
365
  /**
262
366
  * Edits and removals since the last successful sync. The time-cursor walk
263
367
  * only revisits the overlap window, so an edit to an older message (its
@@ -271,7 +375,16 @@ export class SemanticIndexer {
271
375
  private readonly editedIds = new Set<string>();
272
376
  private readonly removedIds = new Set<string>();
273
377
  private detach: (() => void) | null = null;
274
- /** Set once the service answers 404 to /delete (a build without the route): removals are dropped from then on. */
378
+ /**
379
+ * Set once the service answers 404 to /delete in a pass whose /stats
380
+ * answered with stats, which shows the index is made, so the 404 means a
381
+ * build without the route. From then on, removals are dropped as they come
382
+ * and no pass calls /delete, until the host restarts or binds the module
383
+ * again, which makes a new indexer. A pass whose /stats answers 404 has no
384
+ * index to remove from and makes no /delete call; a /delete 404 in a pass
385
+ * whose /stats answered with something that isn't stats is re-queued like
386
+ * any other failure, since that answer doesn't show the index is made.
387
+ */
275
388
  private deleteUnsupported = false;
276
389
  /** Called whenever the pending edit/remove sets change. */
277
390
  onPendingChange: ((p: PendingChanges) => void) | null = null;
@@ -290,7 +403,7 @@ export class SemanticIndexer {
290
403
  if (this.detach) return;
291
404
  const on = (this.cm as { onMessage?: ContextManager['onMessage'] }).onMessage;
292
405
  if (typeof on !== 'function') {
293
- this.log('[history/semantic] context-manager has no onMessage: edits and removals will not reach the index');
406
+ this.warn("the context-manager has no onMessage, so edits and removals won't reach the index");
294
407
  return;
295
408
  }
296
409
  this.detach = on.call(this.cm, (e) => {
@@ -323,8 +436,27 @@ export class SemanticIndexer {
323
436
  const report: SyncReport = { pushed: 0, inserted: 0, updated: 0, unchanged: 0, more: false, messagesScanned: 0, summariesScanned: 0 };
324
437
  if (this.backingOff) { report.more = true; return report; }
325
438
  const batchSize = Math.min(256, Math.max(1, this.cfg.syncBatch ?? 128));
439
+ // Failures of the edits and removals phase, which don't end the pass, and a
440
+ // stats answer that isn't stats: lastError names each, ended or not.
441
+ const phaseErrors: string[] = [];
442
+ let notStats: EmbedServiceError | null = null;
326
443
  try {
327
- const stats = await this.client.stats();
444
+ // A 2xx that isn't stats, such as a web page from a wrong route, gives no
445
+ // watermark: the pass walks from the start, as for a namespace that
446
+ // doesn't exist yet, and lastError names the answer. Every pass then
447
+ // starts over, and a history longer than a pass's budget is never
448
+ // walked to its end, so a pass whose budget runs out fails on that
449
+ // answer.
450
+ let stats: IndexStats | null = null;
451
+ try {
452
+ stats = await this.client.stats();
453
+ } catch (e) {
454
+ if (!(e instanceof EmbedServiceError && e.status !== null && e.status >= 200 && e.status < 300)) throw e;
455
+ notStats = e;
456
+ }
457
+ // /stats answered 404, which stats() reads as a namespace that doesn't
458
+ // exist: there's no index to remove from.
459
+ const noIndex = stats === null && notStats === null;
328
460
  const msgWm = stats?.by_kind.message?.max_cursor ?? null;
329
461
  const sumWm = stats?.by_kind.summary?.max_cursor ?? null;
330
462
  let budget = maxItems;
@@ -340,14 +472,14 @@ export class SemanticIndexer {
340
472
  // This phase fails on its own: a failure re-queues its ids, is logged
341
473
  // and reported via lastError, and the tick falls through to summaries
342
474
  // and the time walk, so one bad delete/upsert cannot freeze indexing.
343
- let phaseError: string | null = null;
344
475
  if (this.removedIds.size > 0 || this.editedIds.size > 0) {
345
476
  const removed = [...this.removedIds];
346
477
  // Edits spend the budget like any other upsert, so a large queue left
347
478
  // by an outage cannot make a search's bounded catch-up unbounded; the
348
479
  // rest stay queued for the next pass.
349
- // Only actionable edits (an upsert or a delete) spend it: one whose
350
- // message left the branch is dropped for free.
480
+ // An edit whose message is on the branch spends it, one edited down to
481
+ // nothing indexable too, even in a pass that makes no /delete call; one
482
+ // whose message left the branch is dropped for free.
351
483
  this.removedIds.clear();
352
484
  const edited: string[] = [];
353
485
  const toDelete = removed.map((id) => `msg:${id}`);
@@ -367,22 +499,40 @@ export class SemanticIndexer {
367
499
  if (item) toUpsert.push(item); else { toDelete.push(`msg:${id}`); blanked.push(id); }
368
500
  }
369
501
  if (this.editedIds.size > 0) report.more = true;
370
- if (toDelete.length > 0) {
502
+ // The removals and blanked edits are dropped with no /delete call in
503
+ // two cases. With no index (/stats answered 404), there's nothing to
504
+ // remove, and the index this pass makes takes only what the store
505
+ // holds and can index, which leaves them out. Once the service is known
506
+ // to lack the route (deleteUnsupported), the index keeps them, and
507
+ // search-time checks (on-branch, still indexable) keep them out of
508
+ // results.
509
+ if (toDelete.length > 0 && !noIndex && !this.deleteUnsupported) {
371
510
  try {
372
511
  await this.client.delete(toDelete);
373
512
  } catch (e) {
374
513
  const msg = e instanceof Error ? e.message : String(e);
375
- if (/→ 404/.test(msg)) {
376
- // A service build without /delete (or a namespace that does
377
- // not exist). Drop the removals and blanked edits: search-time
378
- // checks (on-branch, still indexable) keep them out of results.
514
+ // What the delete held, by kind, for the warning.
515
+ const what = [
516
+ removed.length > 0 ? `${removed.length} removal(s)` : null,
517
+ blanked.length > 0 ? `${blanked.length} edit(s) down to nothing indexable` : null,
518
+ ].filter((s): s is string => s !== null).join(' and ');
519
+ if (e instanceof EmbedServiceError && e.status === 404 && stats !== null) {
520
+ // This pass's /stats answered with stats, so the index is made
521
+ // and the 404 is the route's: a service build without /delete.
379
522
  this.deleteUnsupported = true;
380
- this.log(`[history/semantic] /delete unsupported by the embed-service; dropping ${toDelete.length} removal(s): ${msg}`);
523
+ this.warn(
524
+ `/delete answered 404, so the service lacks that route; dropping ${what}. Later removals and edits `
525
+ + `down to nothing indexable are dropped too, until the host restarts or binds the history module `
526
+ + `again: ${msg}`,
527
+ );
381
528
  } else {
529
+ // Any other failure, and a 404 in a pass whose /stats answered
530
+ // with something that isn't stats, which doesn't show the index
531
+ // is made: re-queued, for a later pass.
382
532
  for (const id of removed) this.removedIds.add(id);
383
533
  for (const id of blanked) if (!this.removedIds.has(id)) this.editedIds.add(id);
384
- phaseError = msg;
385
- this.log(`[history/semantic] delete failed, ${removed.length} removal(s) re-queued: ${msg}`);
534
+ phaseErrors.push(msg);
535
+ this.warn(`delete failed, ${what} re-queued: ${msg}`);
386
536
  }
387
537
  }
388
538
  }
@@ -395,8 +545,8 @@ export class SemanticIndexer {
395
545
  } catch (e) {
396
546
  const msg = e instanceof Error ? e.message : String(e);
397
547
  for (const id of edited) if (!this.removedIds.has(id)) this.editedIds.add(id);
398
- phaseError = msg;
399
- this.log(`[history/semantic] edit re-upsert failed, ${edited.length} edit(s) re-queued: ${msg}`);
548
+ phaseErrors.push(msg);
549
+ this.warn(`edit re-upsert failed, ${edited.length} edit(s) re-queued: ${msg}`);
400
550
  }
401
551
  this.pendingChanged();
402
552
  }
@@ -458,16 +608,23 @@ export class SemanticIndexer {
458
608
  fromMs = lastMs;
459
609
  }
460
610
  await flush();
461
- this.consecutiveFailures = 0; this.lastError = phaseError; this.lastSyncAt = Date.now();
611
+ if (notStats && report.more) throw notStats;
612
+ this.consecutiveFailures = 0; this.lastError = named(notStats?.message ?? null, ...phaseErrors); this.lastSyncAt = Date.now();
462
613
  return report;
463
614
  } catch (e) {
464
615
  this.consecutiveFailures++;
465
616
  const delay = Math.min(15 * 60_000, 5_000 * 2 ** Math.min(8, this.consecutiveFailures - 1));
466
617
  this.backoffUntil = Date.now() + delay;
467
- this.lastError = e instanceof Error ? e.message : String(e);
468
- this.log(`[history/semantic] sync failed (${this.consecutiveFailures}×, retry in ${Math.round(delay / 1000)}s): ${this.lastError}`);
618
+ const failure = e instanceof Error ? e.message : String(e);
619
+ this.lastError = named(failure, notStats?.message ?? null, ...phaseErrors);
620
+ this.warn(`sync failed (${this.consecutiveFailures}×, retry in ${Math.round(delay / 1000)}s): ${failure}`);
469
621
  report.more = true;
470
622
  return report;
471
623
  }
472
624
  }
473
625
  }
626
+
627
+ /** Each failure a sync pass met, once, in the order given, for its lastError: null if none. */
628
+ function named(...failures: (string | null)[]): string | null {
629
+ return [...new Set(failures.filter((f): f is string => f !== null))].join('; ') || null;
630
+ }
@@ -0,0 +1,16 @@
1
+ import type { ToolDefinition } from '../types/events.js';
2
+
3
+ /**
4
+ * What a module answers for a tool name it doesn't route: there's no such
5
+ * tool, so nothing ran, and which tools the module has, read from its own
6
+ * getTools() so the list can't drift. The registry hands every `module--name`
7
+ * to its module, even one the module doesn't declare, since some modules route
8
+ * undeclared names on purpose, so this answer is the module's to give.
9
+ */
10
+ export function unknownToolMessage(module: string, name: string, tools: readonly Pick<ToolDefinition, 'name'>[]): string {
11
+ const missing = `There's no tool "${module}--${name}", so nothing ran.`;
12
+ const names = tools.map((tool) => `${module}--${tool.name}`);
13
+ if (names.length === 0) return `${missing} The ${module} module has no tools of its own: every tool you can call is in your tool list.`;
14
+ if (names.length === 1) return `${missing} The ${module} module's one tool is ${names[0]}.`;
15
+ return `${missing} The ${module} module's tools are ${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}.`;
16
+ }
@@ -15,7 +15,9 @@
15
15
  * that isn't that directory any more (an unmounted drive whose mountpoint is
16
16
  * now empty, a replaced directory) is an unavailable mount, never a disk on
17
17
  * which every file was deleted; only an explicit acceptance takes it, and
18
- * that starts its evidence afresh.
18
+ * that starts its evidence afresh. A place, where a walk stopped (`walks`),
19
+ * binds no root: it only says where the next walk starts, in whatever
20
+ * directory the root is by then.
19
21
  *
20
22
  * Every transition is write-ahead (see reconcile.ts): an `intent` entry
21
23
  * (`pending`, with the prior value and the expected one) is durable before the
@@ -46,9 +48,15 @@ export interface Fingerprint {
46
48
  hashedAt: number;
47
49
  }
48
50
 
51
+ /**
52
+ * `mode`: the permission bits disk held (`st_mode & 0o777`). Evidence from
53
+ * before modes were recorded, or recorded after the kernel refused a
54
+ * widening of the workspace's own change, has none: a sync takes disk's mode
55
+ * in.
56
+ */
49
57
  export type Agreed =
50
58
  | { kind: 'absent' }
51
- | { kind: 'content'; hash: string; size: number; fp?: Fingerprint };
59
+ | { kind: 'content'; hash: string; size: number; fp?: Fingerprint; mode?: number };
52
60
 
53
61
  export type Candidate = { kind: 'absent' } | { kind: 'content'; hash: string };
54
62
 
@@ -61,6 +69,21 @@ export interface Pending {
61
69
  expect: Candidate;
62
70
  /** Branch the intent was recorded on (an adoption's meaning is branch-relative). */
63
71
  branchId: string;
72
+ /**
73
+ * For a write whose plan gives the file a mode: the mode it saw (`from`)
74
+ * and the one it gives (`to`); a write that creates the file records `to`
75
+ * for both. A push that goes on as our own narrowing push, stopped before
76
+ * its bytes, records that push's `from`, the old bytes' own mode, and the
77
+ * store's mode now, or where the store records none, the mode the stopped
78
+ * push narrowed to, whether or not it gives a mode itself. It narrows to
79
+ * `from & to` before the bytes and widens to `to` after them, so a stop
80
+ * leaves disk at one of those three, with the old bytes or the new, and
81
+ * those are the push's own. A file that has setuid or setgid
82
+ * when the write checks it loses them before the bytes too, a chmod that
83
+ * keeps the permission bits it has then, so a stop after that chmod alone
84
+ * leaves disk at the mode the write saw, less those bits.
85
+ */
86
+ modes?: { from: number; to: number };
64
87
  }
65
88
 
66
89
  export interface Interrupted {
@@ -92,16 +115,30 @@ type JournalEntry =
92
115
  /** The root's identity; with `reset`, an accepted new root, whose evidence starts empty. */
93
116
  | { t: 'root'; mount: string; identity: RootIdentity; reset?: true }
94
117
  | { t: 'set'; mount: string; path: string; value: Physical }
95
- | { t: 'forget'; mount: string; path: string };
118
+ | { t: 'forget'; mount: string; path: string }
119
+ /**
120
+ * Where a capped walk of `scope` stopped (the last entry it took), or null
121
+ * once a walk covered the scope. It carries no `path` field: agent-framework
122
+ * 0.22 replays an entry it doesn't know as a `forget` of `entry.path`, and
123
+ * so leaves the evidence alone when there is none.
124
+ */
125
+ | { t: 'walk'; mount: string; scope: string; after: string | null };
96
126
 
97
127
  interface MountEvidence {
98
128
  root: string;
99
129
  identity?: RootIdentity;
100
130
  paths: Map<string, Physical>;
131
+ /** By scope ('' for the mount root): where the next walk of it resumes. */
132
+ walks: Map<string, string>;
101
133
  }
102
134
 
103
135
  interface Snapshot {
104
- mounts: Record<string, { root: string; identity?: RootIdentity; paths: Record<string, Physical> }>;
136
+ mounts: Record<string, {
137
+ root: string;
138
+ identity?: RootIdentity;
139
+ paths: Record<string, Physical>;
140
+ walks?: Record<string, string>;
141
+ }>;
105
142
  }
106
143
 
107
144
  export const DISK_AGREEMENT_RECORD_TYPE = 'workspace/disk-agreement';
@@ -117,21 +154,40 @@ export function sameCandidate(a: Candidate, b: Candidate): boolean {
117
154
  return a.kind === b.kind && (a.kind === 'absent' || a.hash === (b as { hash: string }).hash);
118
155
  }
119
156
 
157
+ /** A record with no mode claimed: a content record's, and a pending intent's own modes and its prior's. */
158
+ function withoutModes(value: Physical): Physical {
159
+ if (value.kind === 'content' && value.mode !== undefined) {
160
+ const { mode: _mode, ...rest } = value;
161
+ return rest;
162
+ }
163
+ if (value.kind === 'pending') {
164
+ const { modes: _modes, ...intent } = value;
165
+ if (intent.prior?.kind !== 'content' || intent.prior.mode === undefined) return intent;
166
+ const { mode: _mode, ...prior } = intent.prior;
167
+ return { ...intent, prior };
168
+ }
169
+ return value;
170
+ }
171
+
120
172
  export class DiskAgreement {
121
173
  private readonly store: JsStore;
122
174
  private readonly journal: RecordJournal<JournalEntry, Snapshot>;
123
175
  private readonly mounts = new Map<string, MountEvidence>();
124
176
  private configured: Array<{ name: string; root: string }> = [];
125
177
  /**
126
- * An append (or a rebuild) not yet made durable. Cleared only by a
127
- * barrier that succeeds, so a failed barrier stays owed: a later pass with
128
- * nothing new to record still settles it before deciding anything.
178
+ * An append of evidence (or a rebuild) not yet made durable. Cleared only
179
+ * by a barrier that succeeds, so a failed barrier stays owed: a later pass
180
+ * with nothing new to record still settles it before deciding anything. A
181
+ * place owes none (recordWalk).
129
182
  */
130
183
  private unsynced = false;
184
+ /** Whether this host observes file modes (not on Windows): where it doesn't, no record it writes claims one. */
185
+ private readonly modesObserved: () => boolean;
131
186
 
132
- constructor(store: JsStore) {
187
+ constructor(store: JsStore, opts: { modesObserved?: () => boolean } = {}) {
133
188
  this.store = store;
134
189
  this.journal = new RecordJournal<JournalEntry, Snapshot>(store, { type: DISK_AGREEMENT_RECORD_TYPE });
190
+ this.modesObserved = opts.modesObserved ?? (() => true);
135
191
  }
136
192
 
137
193
  /**
@@ -183,19 +239,19 @@ export class DiskAgreement {
183
239
  root: mount.root,
184
240
  ...(mount.identity ? { identity: mount.identity } : {}),
185
241
  paths: new Map(Object.entries(mount.paths)),
242
+ walks: new Map(Object.entries(mount.walks ?? {})),
186
243
  });
187
244
  }
188
245
  for (const { entry } of entries) {
189
246
  if (entry.t === 'mount') {
190
247
  const existing = replayed.get(entry.mount);
191
- if (!existing || !sameRootPath(existing.root, entry.root)) replayed.set(entry.mount, { root: entry.root, paths: new Map() });
248
+ if (!existing || !sameRootPath(existing.root, entry.root)) {
249
+ replayed.set(entry.mount, { root: entry.root, paths: new Map(), walks: new Map() });
250
+ }
192
251
  continue;
193
252
  }
194
253
  const mount = replayed.get(entry.mount);
195
- if (!mount) continue;
196
- if (entry.t === 'root') applyRoot(mount, entry);
197
- else if (entry.t === 'set') mount.paths.set(entry.path, entry.value);
198
- else mount.paths.delete(entry.path);
254
+ if (mount) apply(mount, entry);
199
255
  }
200
256
  this.mounts.clear();
201
257
  for (const { name, root } of this.configured) {
@@ -203,7 +259,7 @@ export class DiskAgreement {
203
259
  if (found && sameRootPath(found.root, root)) {
204
260
  this.mounts.set(name, found);
205
261
  } else {
206
- this.mounts.set(name, { root, paths: new Map() });
262
+ this.mounts.set(name, { root, paths: new Map(), walks: new Map() });
207
263
  this.journal.append({ t: 'mount', mount: name, root });
208
264
  }
209
265
  }
@@ -250,6 +306,29 @@ export class DiskAgreement {
250
306
  return out;
251
307
  }
252
308
 
309
+ /**
310
+ * Where the next walk of `scope` ('' for the mount root) resumes: the last
311
+ * entry a walk of it took before its cap stopped it, if one did.
312
+ */
313
+ walkResumesAfter(mount: string, scope: string): string | undefined {
314
+ this.ensureReconciled();
315
+ return this.mounts.get(mount)?.walks.get(scope);
316
+ }
317
+
318
+ /**
319
+ * Record where a walk of `scope` stopped (`after`), or that one covered it
320
+ * (null). Kept with the evidence so a restart resumes there too. A place
321
+ * that's lost costs coverage, never a decision: an append that didn't land
322
+ * loses one, and a checkpoint written by a version that doesn't keep them
323
+ * (0.22) loses them all, and each scope's walks start at its top again.
324
+ * So recording one owes no barrier: a pass that moves only its place makes
325
+ * no store sync, and the place becomes durable with the next one.
326
+ */
327
+ recordWalk(mount: string, scope: string, after: string | null): void {
328
+ if ((this.walkResumesAfter(mount, scope) ?? null) === after) return;
329
+ this.write({ t: 'walk', mount, scope, after }, {});
330
+ }
331
+
253
332
  /**
254
333
  * Record an intent. `durable` makes it (and every append before it) stable
255
334
  * before the caller performs the effect; batches pass it on their last one.
@@ -275,7 +354,8 @@ export class DiskAgreement {
275
354
  /**
276
355
  * Put back exactly the evidence a path had before an intent whose effect
277
356
  * never touched it — whatever kind it was (agreed, pending, interrupted, or
278
- * unknown) — so the intent leaves no trace in what P says.
357
+ * unknown) — so the intent leaves no trace in what P says; where modes go
358
+ * unobserved, less any mode it carried, as every record written there.
279
359
  */
280
360
  restore(mount: string, path: string, value: Physical | undefined): void {
281
361
  if (value === undefined) this.forget(mount, path);
@@ -284,14 +364,21 @@ export class DiskAgreement {
284
364
 
285
365
  private write(entry: JournalEntry, opts: { durable?: boolean; afterCommittedState?: boolean }): void {
286
366
  this.ensureReconciled();
287
- this.unsynced = true; // until proven durable: a failed append may still have landed
367
+ // A host that doesn't observe modes has none that's true to record: a
368
+ // record it writes carries no mode, and a host that observes them reads
369
+ // the path's mode as unknown, as for evidence from before modes were
370
+ // recorded. This holds whatever built the record: disk, the store's
371
+ // entry, or an earlier record a POSIX host wrote, put back by a restore.
372
+ // (A checkpoint re-serializes the evidence as it stands, other hosts'
373
+ // records included, as replaying the journal would.)
374
+ if (entry.t === 'set' && !this.modesObserved()) entry = { ...entry, value: withoutModes(entry.value) };
375
+ // Evidence is owed a barrier until proven durable: a failed append may
376
+ // still have landed. A place isn't (recordWalk).
377
+ if (entry.t !== 'walk') this.unsynced = true;
288
378
  this.journal.append(entry, opts);
289
379
  if (opts.durable) this.unsynced = false; // synced after this append, and so everything before it
290
380
  const mount = this.mounts.get((entry as { mount: string }).mount);
291
- if (!mount) return;
292
- if (entry.t === 'root') applyRoot(mount, entry);
293
- else if (entry.t === 'set') mount.paths.set(entry.path, entry.value);
294
- else if (entry.t === 'forget') mount.paths.delete(entry.path);
381
+ if (mount) apply(mount, entry);
295
382
  }
296
383
 
297
384
  /** Checkpoint when the tail has outgrown the live evidence. */
@@ -307,6 +394,7 @@ export class DiskAgreement {
307
394
  root: mount.root,
308
395
  ...(mount.identity ? { identity: mount.identity } : {}),
309
396
  paths: Object.fromEntries(mount.paths),
397
+ ...(mount.walks.size > 0 ? { walks: Object.fromEntries(mount.walks) } : {}),
310
398
  };
311
399
  }
312
400
  this.journal.checkpoint(snapshot);
@@ -319,7 +407,23 @@ export class DiskAgreement {
319
407
  }
320
408
  }
321
409
 
410
+ /** Apply one entry to a mount's evidence; one of a kind this version doesn't know changes nothing. */
411
+ function apply(mount: MountEvidence, entry: JournalEntry): void {
412
+ if (entry.t === 'root') applyRoot(mount, entry);
413
+ else if (entry.t === 'set') mount.paths.set(entry.path, entry.value);
414
+ else if (entry.t === 'forget') mount.paths.delete(entry.path);
415
+ else if (entry.t === 'walk') {
416
+ if (entry.after === null) mount.walks.delete(entry.scope);
417
+ else mount.walks.set(entry.scope, entry.after);
418
+ }
419
+ }
420
+
322
421
  function applyRoot(mount: MountEvidence, entry: Extract<JournalEntry, { t: 'root' }>): void {
323
422
  mount.identity = entry.identity;
324
- if (entry.reset) mount.paths.clear();
423
+ if (entry.reset) {
424
+ // Evidence about another directory says nothing about this one, and the
425
+ // accepted root's walks start at its top.
426
+ mount.paths.clear();
427
+ mount.walks.clear();
428
+ }
325
429
  }