open-multi-agent-kit 1.2.0 → 1.2.2

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 (436) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +2 -2
  3. package/dist/approval-api.d.ts +5 -0
  4. package/dist/approval-api.d.ts.map +1 -0
  5. package/dist/approval-api.js +5 -0
  6. package/dist/approval-api.js.map +1 -0
  7. package/dist/cli/session-picker.d.ts +2 -2
  8. package/dist/cli/session-picker.d.ts.map +1 -1
  9. package/dist/cli/session-picker.js.map +1 -1
  10. package/dist/commands/verified-run-cli.d.ts.map +1 -1
  11. package/dist/commands/verified-run-cli.js +69 -22
  12. package/dist/commands/verified-run-cli.js.map +1 -1
  13. package/dist/commands/verified-run-signal.d.ts +3 -0
  14. package/dist/commands/verified-run-signal.d.ts.map +1 -0
  15. package/dist/commands/verified-run-signal.js +15 -0
  16. package/dist/commands/verified-run-signal.js.map +1 -0
  17. package/dist/coordination/broker.d.ts.map +1 -1
  18. package/dist/coordination/broker.js +13 -6
  19. package/dist/coordination/broker.js.map +1 -1
  20. package/dist/coordination/operation.d.ts +1 -0
  21. package/dist/coordination/operation.d.ts.map +1 -1
  22. package/dist/coordination/operation.js +55 -3
  23. package/dist/coordination/operation.js.map +1 -1
  24. package/dist/coordination/resource.d.ts +1 -1
  25. package/dist/coordination/resource.d.ts.map +1 -1
  26. package/dist/coordination/resource.js +10 -4
  27. package/dist/coordination/resource.js.map +1 -1
  28. package/dist/coordination/types.d.ts.map +1 -1
  29. package/dist/coordination/types.js +1 -1
  30. package/dist/coordination/types.js.map +1 -1
  31. package/dist/core/adaptorch-bridge.d.ts +1 -1
  32. package/dist/core/adaptorch-bridge.d.ts.map +1 -1
  33. package/dist/core/adaptorch-bridge.js +1 -1
  34. package/dist/core/adaptorch-bridge.js.map +1 -1
  35. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  36. package/dist/core/agent-session-runtime.js +16 -16
  37. package/dist/core/agent-session-runtime.js.map +1 -1
  38. package/dist/core/agent-session.d.ts.map +1 -1
  39. package/dist/core/agent-session.js +32 -33
  40. package/dist/core/agent-session.js.map +1 -1
  41. package/dist/core/canonical-json.d.ts +3 -0
  42. package/dist/core/canonical-json.d.ts.map +1 -0
  43. package/dist/core/canonical-json.js +20 -0
  44. package/dist/core/canonical-json.js.map +1 -0
  45. package/dist/core/compaction/compaction.d.ts +7 -3
  46. package/dist/core/compaction/compaction.d.ts.map +1 -1
  47. package/dist/core/compaction/compaction.js +14 -29
  48. package/dist/core/compaction/compaction.js.map +1 -1
  49. package/dist/core/compaction/fallback.d.ts +16 -5
  50. package/dist/core/compaction/fallback.d.ts.map +1 -1
  51. package/dist/core/compaction/fallback.js +4 -3
  52. package/dist/core/compaction/fallback.js.map +1 -1
  53. package/dist/core/compaction/model-failover.d.ts +21 -0
  54. package/dist/core/compaction/model-failover.d.ts.map +1 -0
  55. package/dist/core/compaction/model-failover.js +46 -0
  56. package/dist/core/compaction/model-failover.js.map +1 -0
  57. package/dist/core/compaction/session-summary.d.ts +21 -0
  58. package/dist/core/compaction/session-summary.d.ts.map +1 -0
  59. package/dist/core/compaction/session-summary.js +27 -0
  60. package/dist/core/compaction/session-summary.js.map +1 -0
  61. package/dist/core/export-html/template.js +14 -0
  62. package/dist/core/extensions/index.d.ts +1 -1
  63. package/dist/core/extensions/index.d.ts.map +1 -1
  64. package/dist/core/extensions/index.js.map +1 -1
  65. package/dist/core/extensions/session-lifecycle-types.d.ts +14 -0
  66. package/dist/core/extensions/session-lifecycle-types.d.ts.map +1 -0
  67. package/dist/core/extensions/session-lifecycle-types.js +2 -0
  68. package/dist/core/extensions/session-lifecycle-types.js.map +1 -0
  69. package/dist/core/extensions/types.d.ts +4 -9
  70. package/dist/core/extensions/types.d.ts.map +1 -1
  71. package/dist/core/extensions/types.js.map +1 -1
  72. package/dist/core/http-dispatcher.d.ts.map +1 -1
  73. package/dist/core/http-dispatcher.js +10 -1
  74. package/dist/core/http-dispatcher.js.map +1 -1
  75. package/dist/core/keybindings.d.ts.map +1 -1
  76. package/dist/core/keybindings.js +3 -6
  77. package/dist/core/keybindings.js.map +1 -1
  78. package/dist/core/legacy-resource-policy.d.ts +7 -0
  79. package/dist/core/legacy-resource-policy.d.ts.map +1 -0
  80. package/dist/core/legacy-resource-policy.js +9 -0
  81. package/dist/core/legacy-resource-policy.js.map +1 -0
  82. package/dist/core/mcp/config.d.ts.map +1 -1
  83. package/dist/core/mcp/config.js +17 -3
  84. package/dist/core/mcp/config.js.map +1 -1
  85. package/dist/core/mcp/connection-queue.d.ts +12 -0
  86. package/dist/core/mcp/connection-queue.d.ts.map +1 -0
  87. package/dist/core/mcp/connection-queue.js +46 -0
  88. package/dist/core/mcp/connection-queue.js.map +1 -0
  89. package/dist/core/mcp/manager-runtime.d.ts +55 -0
  90. package/dist/core/mcp/manager-runtime.d.ts.map +1 -0
  91. package/dist/core/mcp/manager-runtime.js +66 -0
  92. package/dist/core/mcp/manager-runtime.js.map +1 -0
  93. package/dist/core/mcp/manager.d.ts +12 -68
  94. package/dist/core/mcp/manager.d.ts.map +1 -1
  95. package/dist/core/mcp/manager.js +33 -113
  96. package/dist/core/mcp/manager.js.map +1 -1
  97. package/dist/core/mcp/protocol.d.ts.map +1 -1
  98. package/dist/core/mcp/protocol.js +70 -40
  99. package/dist/core/mcp/protocol.js.map +1 -1
  100. package/dist/core/package-manager.d.ts +4 -0
  101. package/dist/core/package-manager.d.ts.map +1 -1
  102. package/dist/core/package-manager.js +59 -129
  103. package/dist/core/package-manager.js.map +1 -1
  104. package/dist/core/package-resource-patterns.d.ts +7 -0
  105. package/dist/core/package-resource-patterns.d.ts.map +1 -0
  106. package/dist/core/package-resource-patterns.js +99 -0
  107. package/dist/core/package-resource-patterns.js.map +1 -0
  108. package/dist/core/provider-resilience.d.ts +9 -0
  109. package/dist/core/provider-resilience.d.ts.map +1 -1
  110. package/dist/core/provider-resilience.js +15 -0
  111. package/dist/core/provider-resilience.js.map +1 -1
  112. package/dist/core/reasoning-router-v4.d.ts +5 -2
  113. package/dist/core/reasoning-router-v4.d.ts.map +1 -1
  114. package/dist/core/reasoning-router-v4.js.map +1 -1
  115. package/dist/core/resource-loader.d.ts.map +1 -1
  116. package/dist/core/resource-loader.js +4 -8
  117. package/dist/core/resource-loader.js.map +1 -1
  118. package/dist/core/run-execution-api.d.ts +8 -1
  119. package/dist/core/run-execution-api.d.ts.map +1 -1
  120. package/dist/core/run-execution-api.js +4 -0
  121. package/dist/core/run-execution-api.js.map +1 -1
  122. package/dist/core/run-journal.d.ts +1 -2
  123. package/dist/core/run-journal.d.ts.map +1 -1
  124. package/dist/core/run-journal.js +2 -19
  125. package/dist/core/run-journal.js.map +1 -1
  126. package/dist/core/session-listing.d.ts +51 -0
  127. package/dist/core/session-listing.d.ts.map +1 -0
  128. package/dist/core/session-listing.js +111 -0
  129. package/dist/core/session-listing.js.map +1 -0
  130. package/dist/core/session-manager.d.ts +12 -37
  131. package/dist/core/session-manager.d.ts.map +1 -1
  132. package/dist/core/session-manager.js +12 -118
  133. package/dist/core/session-manager.js.map +1 -1
  134. package/dist/core/session-message-text.d.ts +5 -0
  135. package/dist/core/session-message-text.d.ts.map +1 -0
  136. package/dist/core/session-message-text.js +9 -0
  137. package/dist/core/session-message-text.js.map +1 -0
  138. package/dist/core/skills-catalog-cache.d.ts +2 -0
  139. package/dist/core/skills-catalog-cache.d.ts.map +1 -1
  140. package/dist/core/skills-catalog-cache.js +71 -17
  141. package/dist/core/skills-catalog-cache.js.map +1 -1
  142. package/dist/core/tools/read.d.ts.map +1 -1
  143. package/dist/core/tools/read.js +1 -1
  144. package/dist/core/tools/read.js.map +1 -1
  145. package/dist/core/verified-run/authority-clock.d.ts +3 -0
  146. package/dist/core/verified-run/authority-clock.d.ts.map +1 -0
  147. package/dist/core/verified-run/authority-clock.js +25 -0
  148. package/dist/core/verified-run/authority-clock.js.map +1 -0
  149. package/dist/core/verified-run/authority-errors.d.ts +10 -0
  150. package/dist/core/verified-run/authority-errors.d.ts.map +1 -0
  151. package/dist/core/verified-run/authority-errors.js +17 -0
  152. package/dist/core/verified-run/authority-errors.js.map +1 -0
  153. package/dist/core/verified-run/authority-events.d.ts +126 -0
  154. package/dist/core/verified-run/authority-events.d.ts.map +1 -0
  155. package/dist/core/verified-run/authority-events.js +482 -0
  156. package/dist/core/verified-run/authority-events.js.map +1 -0
  157. package/dist/core/verified-run/authority-journal.d.ts +27 -0
  158. package/dist/core/verified-run/authority-journal.d.ts.map +1 -0
  159. package/dist/core/verified-run/authority-journal.js +83 -0
  160. package/dist/core/verified-run/authority-journal.js.map +1 -0
  161. package/dist/core/verified-run/authority-meaning.d.ts +13 -0
  162. package/dist/core/verified-run/authority-meaning.d.ts.map +1 -0
  163. package/dist/core/verified-run/authority-meaning.js +40 -0
  164. package/dist/core/verified-run/authority-meaning.js.map +1 -0
  165. package/dist/core/verified-run/authority-runtime.d.ts +82 -0
  166. package/dist/core/verified-run/authority-runtime.d.ts.map +1 -0
  167. package/dist/core/verified-run/authority-runtime.js +169 -0
  168. package/dist/core/verified-run/authority-runtime.js.map +1 -0
  169. package/dist/core/verified-run/authority-store.d.ts +204 -0
  170. package/dist/core/verified-run/authority-store.d.ts.map +1 -0
  171. package/dist/core/verified-run/authority-store.js +852 -0
  172. package/dist/core/verified-run/authority-store.js.map +1 -0
  173. package/dist/core/verified-run/broker.d.ts +8 -1
  174. package/dist/core/verified-run/broker.d.ts.map +1 -1
  175. package/dist/core/verified-run/broker.js +94 -90
  176. package/dist/core/verified-run/broker.js.map +1 -1
  177. package/dist/core/verified-run/candidate-policy.d.ts +10 -0
  178. package/dist/core/verified-run/candidate-policy.d.ts.map +1 -0
  179. package/dist/core/verified-run/candidate-policy.js +33 -0
  180. package/dist/core/verified-run/candidate-policy.js.map +1 -0
  181. package/dist/core/verified-run/candidate.d.ts.map +1 -1
  182. package/dist/core/verified-run/candidate.js +5 -10
  183. package/dist/core/verified-run/candidate.js.map +1 -1
  184. package/dist/core/verified-run/coordinator.d.ts +35 -17
  185. package/dist/core/verified-run/coordinator.d.ts.map +1 -1
  186. package/dist/core/verified-run/coordinator.js +111 -57
  187. package/dist/core/verified-run/coordinator.js.map +1 -1
  188. package/dist/core/verified-run/dag-phase.d.ts.map +1 -1
  189. package/dist/core/verified-run/dag-phase.js +1 -1
  190. package/dist/core/verified-run/dag-phase.js.map +1 -1
  191. package/dist/core/verified-run/dag-recovery.d.ts +5 -1
  192. package/dist/core/verified-run/dag-recovery.d.ts.map +1 -1
  193. package/dist/core/verified-run/dag-recovery.js +10 -4
  194. package/dist/core/verified-run/dag-recovery.js.map +1 -1
  195. package/dist/core/verified-run/event-parser.d.ts.map +1 -1
  196. package/dist/core/verified-run/event-parser.js +33 -0
  197. package/dist/core/verified-run/event-parser.js.map +1 -1
  198. package/dist/core/verified-run/evidence-read-projection.d.ts +4 -0
  199. package/dist/core/verified-run/evidence-read-projection.d.ts.map +1 -0
  200. package/dist/core/verified-run/evidence-read-projection.js +27 -0
  201. package/dist/core/verified-run/evidence-read-projection.js.map +1 -0
  202. package/dist/core/verified-run/evidence.d.ts +12 -1
  203. package/dist/core/verified-run/evidence.d.ts.map +1 -1
  204. package/dist/core/verified-run/evidence.js +51 -2
  205. package/dist/core/verified-run/evidence.js.map +1 -1
  206. package/dist/core/verified-run/git-candidate-preflight.d.ts +4 -0
  207. package/dist/core/verified-run/git-candidate-preflight.d.ts.map +1 -0
  208. package/dist/core/verified-run/git-candidate-preflight.js +34 -0
  209. package/dist/core/verified-run/git-candidate-preflight.js.map +1 -0
  210. package/dist/core/verified-run/git-effect-supervisor.d.ts +24 -0
  211. package/dist/core/verified-run/git-effect-supervisor.d.ts.map +1 -0
  212. package/dist/core/verified-run/git-effect-supervisor.js +174 -0
  213. package/dist/core/verified-run/git-effect-supervisor.js.map +1 -0
  214. package/dist/core/verified-run/git-execution.d.ts +27 -0
  215. package/dist/core/verified-run/git-execution.d.ts.map +1 -0
  216. package/dist/core/verified-run/git-execution.js +118 -0
  217. package/dist/core/verified-run/git-execution.js.map +1 -0
  218. package/dist/core/verified-run/git-plumbing.d.ts +37 -0
  219. package/dist/core/verified-run/git-plumbing.d.ts.map +1 -0
  220. package/dist/core/verified-run/git-plumbing.js +171 -0
  221. package/dist/core/verified-run/git-plumbing.js.map +1 -0
  222. package/dist/core/verified-run/git-publication-worker.d.ts +2 -0
  223. package/dist/core/verified-run/git-publication-worker.d.ts.map +1 -0
  224. package/dist/core/verified-run/git-publication-worker.js +54 -0
  225. package/dist/core/verified-run/git-publication-worker.js.map +1 -0
  226. package/dist/core/verified-run/git-sandbox-layout.d.ts +4 -0
  227. package/dist/core/verified-run/git-sandbox-layout.d.ts.map +1 -0
  228. package/dist/core/verified-run/git-sandbox-layout.js +29 -0
  229. package/dist/core/verified-run/git-sandbox-layout.js.map +1 -0
  230. package/dist/core/verified-run/git-worker-protocol.d.ts +19 -0
  231. package/dist/core/verified-run/git-worker-protocol.d.ts.map +1 -0
  232. package/dist/core/verified-run/git-worker-protocol.js +109 -0
  233. package/dist/core/verified-run/git-worker-protocol.js.map +1 -0
  234. package/dist/core/verified-run/git-worker-runtime.d.ts +19 -0
  235. package/dist/core/verified-run/git-worker-runtime.d.ts.map +1 -0
  236. package/dist/core/verified-run/git-worker-runtime.js +74 -0
  237. package/dist/core/verified-run/git-worker-runtime.js.map +1 -0
  238. package/dist/core/verified-run/journal.d.ts +2 -3
  239. package/dist/core/verified-run/journal.d.ts.map +1 -1
  240. package/dist/core/verified-run/journal.js.map +1 -1
  241. package/dist/core/verified-run/namespace-identity.d.ts.map +1 -1
  242. package/dist/core/verified-run/namespace-identity.js +1 -1
  243. package/dist/core/verified-run/namespace-identity.js.map +1 -1
  244. package/dist/core/verified-run/owned-execution.d.ts +10 -1
  245. package/dist/core/verified-run/owned-execution.d.ts.map +1 -1
  246. package/dist/core/verified-run/owned-execution.js +124 -31
  247. package/dist/core/verified-run/owned-execution.js.map +1 -1
  248. package/dist/core/verified-run/phase-context.d.ts +2 -0
  249. package/dist/core/verified-run/phase-context.d.ts.map +1 -1
  250. package/dist/core/verified-run/phase-context.js.map +1 -1
  251. package/dist/core/verified-run/projection.d.ts.map +1 -1
  252. package/dist/core/verified-run/projection.js +51 -1
  253. package/dist/core/verified-run/projection.js.map +1 -1
  254. package/dist/core/verified-run/publish-preflight.d.ts +12 -0
  255. package/dist/core/verified-run/publish-preflight.d.ts.map +1 -0
  256. package/dist/core/verified-run/publish-preflight.js +38 -0
  257. package/dist/core/verified-run/publish-preflight.js.map +1 -0
  258. package/dist/core/verified-run/publish-start.d.ts +5 -0
  259. package/dist/core/verified-run/publish-start.d.ts.map +1 -0
  260. package/dist/core/verified-run/publish-start.js +7 -0
  261. package/dist/core/verified-run/publish-start.js.map +1 -0
  262. package/dist/core/verified-run/recovery-projection.d.ts.map +1 -1
  263. package/dist/core/verified-run/recovery-projection.js +5 -0
  264. package/dist/core/verified-run/recovery-projection.js.map +1 -1
  265. package/dist/core/verified-run/recovery.d.ts +5 -1
  266. package/dist/core/verified-run/recovery.d.ts.map +1 -1
  267. package/dist/core/verified-run/recovery.js +10 -4
  268. package/dist/core/verified-run/recovery.js.map +1 -1
  269. package/dist/core/verified-run/run-plan.d.ts +17 -0
  270. package/dist/core/verified-run/run-plan.d.ts.map +1 -0
  271. package/dist/core/verified-run/run-plan.js +18 -0
  272. package/dist/core/verified-run/run-plan.js.map +1 -0
  273. package/dist/core/verified-run/run-publish-owned.d.ts +6 -0
  274. package/dist/core/verified-run/run-publish-owned.d.ts.map +1 -0
  275. package/dist/core/verified-run/run-publish-owned.js +199 -0
  276. package/dist/core/verified-run/run-publish-owned.js.map +1 -0
  277. package/dist/core/verified-run/run-publish.d.ts +19 -0
  278. package/dist/core/verified-run/run-publish.d.ts.map +1 -0
  279. package/dist/core/verified-run/run-publish.js +210 -0
  280. package/dist/core/verified-run/run-publish.js.map +1 -0
  281. package/dist/core/verified-run/run-status-owned.d.ts +4 -0
  282. package/dist/core/verified-run/run-status-owned.d.ts.map +1 -0
  283. package/dist/core/verified-run/run-status-owned.js +14 -0
  284. package/dist/core/verified-run/run-status-owned.js.map +1 -0
  285. package/dist/core/verified-run/run-status.d.ts +133 -0
  286. package/dist/core/verified-run/run-status.d.ts.map +1 -0
  287. package/dist/core/verified-run/run-status.js +193 -0
  288. package/dist/core/verified-run/run-status.js.map +1 -0
  289. package/dist/core/verified-run/run-types.d.ts +31 -0
  290. package/dist/core/verified-run/run-types.d.ts.map +1 -1
  291. package/dist/core/verified-run/run-types.js.map +1 -1
  292. package/dist/core/verified-run/storage.d.ts.map +1 -1
  293. package/dist/core/verified-run/storage.js +1 -1
  294. package/dist/core/verified-run/storage.js.map +1 -1
  295. package/dist/core/verified-run/supervisor-adapter.d.ts +77 -0
  296. package/dist/core/verified-run/supervisor-adapter.d.ts.map +1 -0
  297. package/dist/core/verified-run/supervisor-adapter.js +164 -0
  298. package/dist/core/verified-run/supervisor-adapter.js.map +1 -0
  299. package/dist/core/verified-run/verification-phase.d.ts.map +1 -1
  300. package/dist/core/verified-run/verification-phase.js +1 -1
  301. package/dist/core/verified-run/verification-phase.js.map +1 -1
  302. package/dist/core/verified-run/writer-phase.d.ts.map +1 -1
  303. package/dist/core/verified-run/writer-phase.js +1 -0
  304. package/dist/core/verified-run/writer-phase.js.map +1 -1
  305. package/dist/core/verified-run/writer-recovery.d.ts +2 -0
  306. package/dist/core/verified-run/writer-recovery.d.ts.map +1 -1
  307. package/dist/core/verified-run/writer-recovery.js +1 -0
  308. package/dist/core/verified-run/writer-recovery.js.map +1 -1
  309. package/dist/core/workload-shard-execution-types.d.ts +4 -1
  310. package/dist/core/workload-shard-execution-types.d.ts.map +1 -1
  311. package/dist/core/workload-shard-execution-types.js.map +1 -1
  312. package/dist/core/workload-shard-executor.d.ts +2 -2
  313. package/dist/core/workload-shard-executor.d.ts.map +1 -1
  314. package/dist/core/workload-shard-executor.js +16 -37
  315. package/dist/core/workload-shard-executor.js.map +1 -1
  316. package/dist/core/workload-shard-frontier.d.ts +5 -0
  317. package/dist/core/workload-shard-frontier.d.ts.map +1 -0
  318. package/dist/core/workload-shard-frontier.js +47 -0
  319. package/dist/core/workload-shard-frontier.js.map +1 -0
  320. package/dist/core/workload-shard-runner.d.ts.map +1 -1
  321. package/dist/core/workload-shard-runner.js +28 -17
  322. package/dist/core/workload-shard-runner.js.map +1 -1
  323. package/dist/index.d.ts +2 -5
  324. package/dist/index.d.ts.map +1 -1
  325. package/dist/index.js +1 -4
  326. package/dist/index.js.map +1 -1
  327. package/dist/main.d.ts.map +1 -1
  328. package/dist/main.js +2 -1
  329. package/dist/main.js.map +1 -1
  330. package/dist/metacognition/bridge-result.d.ts +148 -0
  331. package/dist/metacognition/bridge-result.d.ts.map +1 -0
  332. package/dist/metacognition/bridge-result.js +46 -0
  333. package/dist/metacognition/bridge-result.js.map +1 -0
  334. package/dist/metacognition/calibration-selective.d.ts.map +1 -1
  335. package/dist/metacognition/calibration-selective.js +8 -2
  336. package/dist/metacognition/calibration-selective.js.map +1 -1
  337. package/dist/metacognition/index.d.ts +1 -0
  338. package/dist/metacognition/index.d.ts.map +1 -1
  339. package/dist/metacognition/index.js +1 -0
  340. package/dist/metacognition/index.js.map +1 -1
  341. package/dist/metacognition/risk.d.ts.map +1 -1
  342. package/dist/metacognition/risk.js +28 -14
  343. package/dist/metacognition/risk.js.map +1 -1
  344. package/dist/metacognition/runtime-bridge.d.ts +41 -14
  345. package/dist/metacognition/runtime-bridge.d.ts.map +1 -1
  346. package/dist/metacognition/runtime-bridge.js +357 -39
  347. package/dist/metacognition/runtime-bridge.js.map +1 -1
  348. package/dist/modes/interactive/components/assistant-message.d.ts +2 -0
  349. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  350. package/dist/modes/interactive/components/assistant-message.js +42 -26
  351. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  352. package/dist/modes/interactive/components/chat-container.d.ts +7 -0
  353. package/dist/modes/interactive/components/chat-container.d.ts.map +1 -0
  354. package/dist/modes/interactive/components/chat-container.js +14 -0
  355. package/dist/modes/interactive/components/chat-container.js.map +1 -0
  356. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  357. package/dist/modes/interactive/components/dynamic-border.js +4 -2
  358. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  359. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  360. package/dist/modes/interactive/components/login-dialog.js +0 -1
  361. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  362. package/dist/modes/interactive/components/session-selector-async-search.d.ts +33 -0
  363. package/dist/modes/interactive/components/session-selector-async-search.d.ts.map +1 -0
  364. package/dist/modes/interactive/components/session-selector-async-search.js +109 -0
  365. package/dist/modes/interactive/components/session-selector-async-search.js.map +1 -0
  366. package/dist/modes/interactive/components/session-selector-loaders.d.ts +6 -0
  367. package/dist/modes/interactive/components/session-selector-loaders.d.ts.map +1 -0
  368. package/dist/modes/interactive/components/session-selector-loaders.js +9 -0
  369. package/dist/modes/interactive/components/session-selector-loaders.js.map +1 -0
  370. package/dist/modes/interactive/components/session-selector-search.d.ts +1 -1
  371. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  372. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  373. package/dist/modes/interactive/components/session-selector-tree.d.ts +16 -0
  374. package/dist/modes/interactive/components/session-selector-tree.d.ts.map +1 -0
  375. package/dist/modes/interactive/components/session-selector-tree.js +46 -0
  376. package/dist/modes/interactive/components/session-selector-tree.js.map +1 -0
  377. package/dist/modes/interactive/components/session-selector.d.ts +6 -1
  378. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  379. package/dist/modes/interactive/components/session-selector.js +36 -76
  380. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  381. package/dist/modes/interactive/components/tool-execution-images.d.ts +32 -0
  382. package/dist/modes/interactive/components/tool-execution-images.d.ts.map +1 -0
  383. package/dist/modes/interactive/components/tool-execution-images.js +144 -0
  384. package/dist/modes/interactive/components/tool-execution-images.js.map +1 -0
  385. package/dist/modes/interactive/components/tool-execution.d.ts +3 -4
  386. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  387. package/dist/modes/interactive/components/tool-execution.js +22 -71
  388. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  389. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  390. package/dist/modes/interactive/interactive-mode.js +7 -9
  391. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  392. package/dist/modes/interactive/tui-diagnostics.d.ts +8 -4
  393. package/dist/modes/interactive/tui-diagnostics.d.ts.map +1 -1
  394. package/dist/modes/interactive/tui-diagnostics.js +35 -1
  395. package/dist/modes/interactive/tui-diagnostics.js.map +1 -1
  396. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  397. package/dist/modes/rpc/rpc-mode.js +14 -17
  398. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  399. package/dist/modes/rpc/rpc-response.d.ts +5 -0
  400. package/dist/modes/rpc/rpc-response.d.ts.map +1 -0
  401. package/dist/modes/rpc/rpc-response.js +17 -0
  402. package/dist/modes/rpc/rpc-response.js.map +1 -0
  403. package/dist/utils/exif-orientation.d.ts.map +1 -1
  404. package/dist/utils/exif-orientation.js +2 -3
  405. package/dist/utils/exif-orientation.js.map +1 -1
  406. package/dist/utils/tools-manager.d.ts.map +1 -1
  407. package/dist/utils/tools-manager.js +3 -5
  408. package/dist/utils/tools-manager.js.map +1 -1
  409. package/docs/adaptorch-preview-spec.md +7 -7
  410. package/docs/atomic-commit-planning.md +69 -0
  411. package/docs/compaction.md +26 -1
  412. package/docs/extensions.md +14 -0
  413. package/docs/mcp.md +22 -0
  414. package/docs/metacognition.md +79 -0
  415. package/docs/model-catalog-refresh.md +159 -1
  416. package/docs/models.md +1 -1
  417. package/docs/runtime-algorithms.md +49 -4
  418. package/docs/session-format.md +8 -0
  419. package/docs/sessions.md +19 -0
  420. package/docs/skills.md +19 -0
  421. package/docs/terminal-setup.md +15 -0
  422. package/docs/tui.md +41 -0
  423. package/docs/verified-run-safety.md +75 -0
  424. package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
  425. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  426. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  427. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  428. package/examples/extensions/doom-overlay/wad-finder.ts +7 -3
  429. package/examples/extensions/gondolin/package-lock.json +2 -2
  430. package/examples/extensions/gondolin/package.json +1 -1
  431. package/examples/extensions/sandbox/package-lock.json +2 -2
  432. package/examples/extensions/sandbox/package.json +1 -1
  433. package/examples/extensions/with-deps/package-lock.json +2 -2
  434. package/examples/extensions/with-deps/package.json +1 -1
  435. package/npm-shrinkwrap.json +18 -18
  436. package/package.json +6 -8
@@ -0,0 +1,852 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { closeSync, existsSync, constants as fsConstants, fstatSync, fsyncSync, ftruncateSync, mkdirSync, openSync, readFileSync, renameSync, unlinkSync, writeSync, } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { canonicalClaim, claimSetsConflict, sameClaimSet, } from "../../coordination/resource.js";
5
+ import { SETTLED_EFFECT_STATES, sequence } from "../../coordination/types.js";
6
+ import { atomicRewriteFileSync } from "../atomic-session-file.js";
7
+ import { acquireDurableFileLockSync, acquireDurableFileMutationLockSync, DurableFileLockBusyError, inspectDurableFileLockSync, } from "../durable-file-identity.js";
8
+ import { fsyncDirectorySync, writeExclusiveFileDurablySync } from "../durable-file-io.js";
9
+ import { canonicalJson } from "../run-journal.js";
10
+ import { createAuthorityClock } from "./authority-clock.js";
11
+ import { AuthorityLeaseHeldError, AuthorityStoreError } from "./authority-errors.js";
12
+ import { applyAuthorityEvents, authorityPendingReconcile, parseAuthorityEvent, snapshotFromProjection, } from "./authority-events.js";
13
+ import { GENESIS_PREVIOUS, materializeRecord, parseCommitted, recordLine, } from "./authority-journal.js";
14
+ import { assertSameCommandMeaning, authorizationStillOpen, expiryEvents, sameGrantToken } from "./authority-meaning.js";
15
+ import { readRunClock } from "./recovery-clock.js";
16
+ import { VerifiedRunError } from "./storage.js";
17
+ import { probeOwnedNamespace } from "./supervisor-adapter.js";
18
+ /**
19
+ * Durable authority store (WP03): the single-writer boundary for supervisor
20
+ * authorization state.
21
+ *
22
+ * Storage is a head-sidecar pair — `authority.events.jsonl` plus
23
+ * `authority.events.jsonl.head` — mirroring `ReplayLedgerStore`: the committed
24
+ * head is the transaction boundary, bytes after `head.size` are uncommitted
25
+ * and get quarantined then truncated on the next open, and every append is an
26
+ * expected-head CAS inside the `"mutation"` lock critical section. Cross-process
27
+ * exclusion is the `"authority"` scope durable-file lease held for the store's
28
+ * lifetime; its owner record (pid+host+token) is the writer identity, and dead
29
+ * owners are reclaimed by the existing reclaim protocol.
30
+ *
31
+ * Authority epoch durability: `open` appends `authority-epoch-advanced` inside
32
+ * the lease critical section — never the in-memory default "1" — and leaves the
33
+ * epoch unreconciled. Only `reconcile()` (termination-witness probes per
34
+ * quarantined effect, then `authority-reconciled`) reopens admission. A crash
35
+ * between the epoch event and reconciliation leaves `pendingReconcile` set;
36
+ * the next open adopts that epoch instead of advancing again.
37
+ */
38
+ export { AuthorityLeaseHeldError, AuthorityStoreError } from "./authority-errors.js";
39
+ const AUTHORITY_SCOPE = "authority";
40
+ export const authorityStorePath = (root) => join(root, "authority.events.jsonl");
41
+ const EMPTY_AUTHORITY_HEAD = Object.freeze({
42
+ fileIdentity: null,
43
+ size: 0,
44
+ lastSeq: 0,
45
+ lastHash: GENESIS_PREVIOUS,
46
+ });
47
+ function authorityHeadsEqual(left, right) {
48
+ return (left.size === right.size &&
49
+ left.lastSeq === right.lastSeq &&
50
+ left.lastHash === right.lastHash &&
51
+ (left.fileIdentity === null
52
+ ? right.fileIdentity === null
53
+ : right.fileIdentity !== null &&
54
+ left.fileIdentity.dev === right.fileIdentity.dev &&
55
+ left.fileIdentity.ino === right.fileIdentity.ino));
56
+ }
57
+ function parseHead(raw) {
58
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw))
59
+ throw new AuthorityStoreError("corrupt");
60
+ const value = raw;
61
+ if (Object.keys(value).sort().join(",") !== "fileIdentity,lastHash,lastSeq,size")
62
+ throw new AuthorityStoreError("corrupt");
63
+ let fileIdentity = null;
64
+ if (value.fileIdentity !== null) {
65
+ if (typeof value.fileIdentity !== "object" || Array.isArray(value.fileIdentity))
66
+ throw new AuthorityStoreError("corrupt");
67
+ const identity = value.fileIdentity;
68
+ if (Object.keys(identity).sort().join(",") !== "dev,ino" ||
69
+ typeof identity.dev !== "string" ||
70
+ !/^\d+$/.test(identity.dev) ||
71
+ typeof identity.ino !== "string" ||
72
+ !/^\d+$/.test(identity.ino))
73
+ throw new AuthorityStoreError("corrupt");
74
+ fileIdentity = Object.freeze({ dev: identity.dev, ino: identity.ino });
75
+ }
76
+ if (!Number.isSafeInteger(value.size) ||
77
+ value.size < 0 ||
78
+ !Number.isSafeInteger(value.lastSeq) ||
79
+ value.lastSeq < 0 ||
80
+ typeof value.lastHash !== "string" ||
81
+ (value.lastSeq === 0 ? value.lastHash !== GENESIS_PREVIOUS : !/^[0-9a-f]{64}$/.test(value.lastHash)))
82
+ throw new AuthorityStoreError("corrupt");
83
+ return Object.freeze({
84
+ fileIdentity,
85
+ size: value.size,
86
+ lastSeq: value.lastSeq,
87
+ lastHash: value.lastHash,
88
+ });
89
+ }
90
+ function fileIdentityOf(stat) {
91
+ return Object.freeze({ dev: String(stat.dev), ino: String(stat.ino) });
92
+ }
93
+ function sameFileIdentity(left, right) {
94
+ return left === null ? right === null : right !== null && left.dev === right.dev && left.ino === right.ino;
95
+ }
96
+ function writeAll(fd, bytes) {
97
+ let offset = 0;
98
+ while (offset < bytes.byteLength)
99
+ offset += writeSync(fd, bytes, offset, bytes.byteLength - offset);
100
+ }
101
+ function appendDurably(path, bytes) {
102
+ const fd = openSync(path, fsConstants.O_CREAT | fsConstants.O_APPEND | fsConstants.O_WRONLY, 0o600);
103
+ try {
104
+ writeAll(fd, bytes);
105
+ fsyncSync(fd);
106
+ }
107
+ finally {
108
+ closeSync(fd);
109
+ }
110
+ }
111
+ function publishHead(context, head) {
112
+ const temp = `${context.headPath}.${randomUUID()}.tmp`;
113
+ const fd = openSync(temp, fsConstants.O_CREAT | fsConstants.O_EXCL | fsConstants.O_WRONLY, 0o600);
114
+ try {
115
+ writeAll(fd, Buffer.from(`${JSON.stringify(head)}\n`, "utf8"));
116
+ fsyncSync(fd);
117
+ }
118
+ finally {
119
+ closeSync(fd);
120
+ }
121
+ try {
122
+ renameSync(temp, context.headPath);
123
+ fsyncDirectorySync(dirname(context.headPath));
124
+ }
125
+ catch (error) {
126
+ if (existsSync(temp))
127
+ unlinkSync(temp);
128
+ throw error;
129
+ }
130
+ }
131
+ function quarantineSuffix(context, bytes) {
132
+ context.hooks.beforeQuarantineFsync?.();
133
+ writeExclusiveFileDurablySync(`${context.path}.quarantine-${randomUUID()}`, bytes);
134
+ }
135
+ /**
136
+ * Load committed state. With `repair`, an uncommitted suffix is quarantined
137
+ * and truncated; a file whose identity no longer matches its head is accepted
138
+ * only when it begins with exactly the GC snapshot continuation of that head
139
+ * (the GC rename-landed/head-publish-crashed window), otherwise the store is
140
+ * tampered and opens refuse. Without `repair` the suffix is left untouched
141
+ * and simply not part of committed state.
142
+ */
143
+ function loadCommitted(context, repair, cached) {
144
+ const fileExists = existsSync(context.path);
145
+ const headExists = existsSync(context.headPath);
146
+ const empty = {
147
+ head: EMPTY_AUTHORITY_HEAD,
148
+ parsed: parseCommitted(Buffer.alloc(0)),
149
+ };
150
+ if (!fileExists && !headExists)
151
+ return empty;
152
+ if (fileExists && !headExists) {
153
+ const fd = openSync(context.path, fsConstants.O_RDONLY | (fsConstants.O_NOFOLLOW ?? 0));
154
+ try {
155
+ const stat = fstatSync(fd);
156
+ if (!stat.isFile() || stat.size !== 0)
157
+ throw new AuthorityStoreError("corrupt");
158
+ }
159
+ finally {
160
+ closeSync(fd);
161
+ }
162
+ if (!repair)
163
+ return empty;
164
+ unlinkSync(context.path);
165
+ fsyncDirectorySync(dirname(context.path));
166
+ return empty;
167
+ }
168
+ if (!fileExists)
169
+ throw new AuthorityStoreError("corrupt");
170
+ let head;
171
+ try {
172
+ head = parseHead(JSON.parse(readFileSync(context.headPath, "utf8")));
173
+ }
174
+ catch (error) {
175
+ if (error instanceof AuthorityStoreError || error instanceof VerifiedRunError)
176
+ throw error;
177
+ throw new AuthorityStoreError("corrupt");
178
+ }
179
+ const fd = openSync(context.path, fsConstants.O_RDWR | (fsConstants.O_NOFOLLOW ?? 0));
180
+ try {
181
+ const before = fstatSync(fd);
182
+ const bytes = readFileSync(fd);
183
+ const after = fstatSync(fd);
184
+ if (!before.isFile() ||
185
+ !after.isFile() ||
186
+ before.size !== after.size ||
187
+ before.ctimeMs !== after.ctimeMs ||
188
+ after.size !== bytes.byteLength)
189
+ throw new AuthorityStoreError("tampered");
190
+ const actual = fileIdentityOf(after);
191
+ if (!sameFileIdentity(head.fileIdentity, actual)) {
192
+ head = healGarbageCollect(context, head, bytes, actual, repair);
193
+ }
194
+ if (head.size > after.size)
195
+ throw new AuthorityStoreError("tampered");
196
+ const committed = Buffer.from(bytes.subarray(0, head.size));
197
+ const prefix = cached &&
198
+ sameFileIdentity(cached.head.fileIdentity, actual) &&
199
+ head.size >= cached.head.size &&
200
+ head.lastSeq >= cached.head.lastSeq
201
+ ? cached.parsed
202
+ : undefined;
203
+ const parsed = parseCommitted(committed, prefix);
204
+ if (parsed.lastSeq !== head.lastSeq || parsed.lastHash !== head.lastHash)
205
+ throw new AuthorityStoreError("tampered");
206
+ if (head.size < after.size && repair) {
207
+ quarantineSuffix(context, bytes.subarray(head.size));
208
+ ftruncateSync(fd, head.size);
209
+ fsyncSync(fd);
210
+ fsyncDirectorySync(dirname(context.path));
211
+ }
212
+ return { head, parsed };
213
+ }
214
+ finally {
215
+ closeSync(fd);
216
+ }
217
+ }
218
+ /**
219
+ * The only legal file whose identity differs from its head: an atomic GC
220
+ * rewrite that landed but whose head publish never committed. Its first
221
+ * record must be exactly the snapshot continuing `head`; the healed head
222
+ * covers just that record, and any bytes after it are uncommitted suffix.
223
+ */
224
+ function healGarbageCollect(context, head, bytes, actual, repair) {
225
+ if (!repair)
226
+ throw new AuthorityStoreError("tampered");
227
+ let healed = null;
228
+ try {
229
+ const newline = bytes.indexOf(10);
230
+ if (newline > 0) {
231
+ const first = bytes.subarray(0, newline + 1);
232
+ const raw = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(first).slice(0, -1));
233
+ const event = typeof raw === "object" && raw !== null && "event" in raw
234
+ ? parseAuthorityEvent(raw.event)
235
+ : null;
236
+ if (event?.kind === "authority-snapshot") {
237
+ const record = materializeRecord(event.archivedThroughSequence + 1, event.continuesHash, event);
238
+ // Only the snapshot line itself must be proven: any bytes after it
239
+ // (including a torn tail) are uncommitted suffix and go to quarantine.
240
+ if (canonicalJson(raw) === canonicalJson(record) &&
241
+ event.archivedThroughSequence === head.lastSeq &&
242
+ event.continuesHash === head.lastHash) {
243
+ healed = Object.freeze({
244
+ fileIdentity: actual,
245
+ size: first.byteLength,
246
+ lastSeq: record.seq,
247
+ lastHash: record.hash,
248
+ });
249
+ }
250
+ }
251
+ }
252
+ }
253
+ catch (error) {
254
+ if (!(error instanceof AuthorityStoreError || error instanceof VerifiedRunError))
255
+ throw error;
256
+ }
257
+ if (!healed)
258
+ throw new AuthorityStoreError("tampered");
259
+ publishHead(context, healed);
260
+ return healed;
261
+ }
262
+ function defaultProbe(grant) {
263
+ if (!grant.identity)
264
+ return "unknown";
265
+ return probeOwnedNamespace(grant.identity);
266
+ }
267
+ function nextSequenceValue(value) {
268
+ return sequence(String(BigInt(value) + 1n));
269
+ }
270
+ function assertNonNegativeInteger(value, label) {
271
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)
272
+ throw new TypeError(`${label} must be a nonnegative safe integer`);
273
+ }
274
+ /** The durable single-writer authority boundary. */
275
+ export class AuthorityStore {
276
+ context;
277
+ capacity;
278
+ probe;
279
+ lease;
280
+ accepted;
281
+ released = false;
282
+ now;
283
+ incrementalReplay;
284
+ constructor(context, lease, accepted, options) {
285
+ this.context = context;
286
+ this.lease = lease;
287
+ this.accepted = accepted;
288
+ this.capacity = options.capacity;
289
+ this.probe = options.probe ?? defaultProbe;
290
+ this.now = createAuthorityClock(options.clock);
291
+ this.incrementalReplay = options.incrementalReplay !== false;
292
+ }
293
+ /**
294
+ * Take the `"authority"` scope lease and advance the persisted epoch.
295
+ * When the previous epoch never reconciled, this restart adopts it — the
296
+ * pending reconciliation must finish before new admission, and the epoch
297
+ * is not bumped again (review §5 fault row).
298
+ */
299
+ static open(path, options) {
300
+ assertNonNegativeInteger(options.capacity, "capacity");
301
+ mkdirSync(dirname(path), { recursive: true });
302
+ const context = { path, headPath: `${path}.head`, hooks: options.hooks ?? {} };
303
+ const mutation = acquireDurableFileMutationLockSync(path);
304
+ let lease;
305
+ try {
306
+ lease = acquireDurableFileLockSync(path, AUTHORITY_SCOPE, { timeoutMs: 0 });
307
+ }
308
+ catch (error) {
309
+ const failure = error instanceof DurableFileLockBusyError
310
+ ? new AuthorityLeaseHeldError(inspectDurableFileLockSync(path, AUTHORITY_SCOPE))
311
+ : error;
312
+ try {
313
+ mutation.release();
314
+ }
315
+ catch (cleanupError) {
316
+ throw new AggregateError([failure, cleanupError instanceof Error ? cleanupError : new Error(String(cleanupError))], "Authority lease acquisition cleanup failed");
317
+ }
318
+ throw failure;
319
+ }
320
+ let store;
321
+ try {
322
+ store = new AuthorityStore(context, lease, loadCommitted(context, true), options);
323
+ }
324
+ catch (error) {
325
+ try {
326
+ lease.release();
327
+ }
328
+ catch (releaseError) {
329
+ throw new AggregateError([error, releaseError instanceof Error ? releaseError : new Error(String(releaseError))], "Authority store open cleanup failed");
330
+ }
331
+ throw error;
332
+ }
333
+ finally {
334
+ mutation.release();
335
+ }
336
+ try {
337
+ if (store.state.epoch === null || !authorityPendingReconcile(store.state)) {
338
+ // Fresh store or fully reconciled previous epoch: this restart
339
+ // durably advances the epoch. A pending epoch is adopted, not bumped.
340
+ store.commitEpochAdvance();
341
+ }
342
+ }
343
+ catch (error) {
344
+ try {
345
+ store.release();
346
+ }
347
+ catch (releaseError) {
348
+ throw new AggregateError([error, releaseError instanceof Error ? releaseError : new Error(String(releaseError))], "Authority store open cleanup failed");
349
+ }
350
+ throw error;
351
+ }
352
+ return store;
353
+ }
354
+ /** Read-only committed projection; performs no repair and writes nothing. */
355
+ static inspect(path) {
356
+ const context = { path, headPath: `${path}.head`, hooks: {} };
357
+ return loadCommitted(context, false).parsed.state;
358
+ }
359
+ /**
360
+ * Read-only committed journal: projection plus the hashed records it was
361
+ * replayed from, so callers can see transition causes (cancel-requested vs
362
+ * authorization-expired vs epoch restart) and termination witnesses — the
363
+ * projection alone intentionally does not restate them.
364
+ */
365
+ static inspectJournal(path) {
366
+ const context = { path, headPath: `${path}.head`, hooks: {} };
367
+ const committed = loadCommitted(context, false);
368
+ return Object.freeze({
369
+ state: committed.parsed.state,
370
+ records: committed.parsed.records,
371
+ head: committed.head,
372
+ });
373
+ }
374
+ get path() {
375
+ return this.context.path;
376
+ }
377
+ get head() {
378
+ return this.accepted.head;
379
+ }
380
+ get state() {
381
+ return structuredClone(this.accepted.parsed.state);
382
+ }
383
+ get lastReplay() {
384
+ return this.accepted.parsed.replay;
385
+ }
386
+ get pendingReconcile() {
387
+ return authorityPendingReconcile(this.state);
388
+ }
389
+ writerId() {
390
+ try {
391
+ return `${readRunClock().bootId}:${process.pid}`;
392
+ }
393
+ catch {
394
+ return `unknown:${process.pid}`;
395
+ }
396
+ }
397
+ /**
398
+ * Commit events as one transaction: mutation lock → committed-head CAS →
399
+ * reducer pre-validation → append+fsync → head publish → re-read
400
+ * verification. The head CAS is the fencing boundary — a store whose lease
401
+ * was reclaimed and taken by another writer sees a changed head and fails
402
+ * closed instead of authorizing. Persist failures never mint in-memory
403
+ * state (docs/04: no memory-only authorization after storage failure).
404
+ */
405
+ commit(events) {
406
+ if (this.released)
407
+ throw new AuthorityStoreError("stale_owner");
408
+ const mutation = acquireDurableFileMutationLockSync(this.context.path);
409
+ try {
410
+ const current = loadCommitted(this.context, true, this.incrementalReplay ? this.accepted : undefined);
411
+ if (!authorityHeadsEqual(current.head, this.accepted.head))
412
+ throw new AuthorityStoreError("stale_head");
413
+ if (events.length === 0) {
414
+ this.accepted = current;
415
+ return;
416
+ }
417
+ // Every event must be accepted by the deterministic reducer before a
418
+ // single byte reaches disk.
419
+ applyAuthorityEvents(current.parsed.state, events);
420
+ const lines = [];
421
+ let seq = current.parsed.lastSeq;
422
+ let previous = current.parsed.lastHash;
423
+ for (const event of events) {
424
+ seq += 1;
425
+ const record = materializeRecord(seq, previous, event);
426
+ lines.push(recordLine(record));
427
+ previous = record.hash;
428
+ }
429
+ const payload = Buffer.from(lines.join(""), "utf8");
430
+ (this.context.hooks.persistRecord ?? appendDurably)(this.context.path, payload);
431
+ const fd = openSync(this.context.path, fsConstants.O_RDWR | (fsConstants.O_NOFOLLOW ?? 0));
432
+ let head;
433
+ try {
434
+ const stat = fstatSync(fd);
435
+ // CAS on the file itself: for an established store the inode must be
436
+ // the one the committed head names; for genesis the append must have
437
+ // produced exactly the expected size. Anything else is a replaced or
438
+ // foreign file and commits must not bless it.
439
+ if (stat.size !== current.head.size + payload.byteLength ||
440
+ (current.head.fileIdentity !== null &&
441
+ !sameFileIdentity(current.head.fileIdentity, fileIdentityOf(stat))))
442
+ throw new AuthorityStoreError("stale_head");
443
+ head = Object.freeze({
444
+ fileIdentity: fileIdentityOf(stat),
445
+ size: stat.size,
446
+ lastSeq: seq,
447
+ lastHash: previous,
448
+ });
449
+ }
450
+ finally {
451
+ closeSync(fd);
452
+ }
453
+ this.context.hooks.afterLedgerFsync?.();
454
+ publishHead(this.context, head);
455
+ const verified = loadCommitted(this.context, false, this.incrementalReplay ? current : undefined);
456
+ if (verified.parsed.lastSeq !== head.lastSeq || verified.parsed.lastHash !== head.lastHash)
457
+ throw new AuthorityStoreError("corrupt");
458
+ this.accepted = verified;
459
+ }
460
+ finally {
461
+ mutation.release();
462
+ }
463
+ }
464
+ commitEpochAdvance() {
465
+ const state = this.state;
466
+ const epoch = nextSequenceValue(state.epoch ?? sequence("0"));
467
+ const transitions = [...state.grants.values()]
468
+ .filter((grant) => !SETTLED_EFFECT_STATES.has(grant.state))
469
+ .map((grant) => Object.freeze({
470
+ grantSequence: grant.token.grantSequence,
471
+ outcome: grant.effectLive ? "quarantined" : "cancelled",
472
+ }));
473
+ this.commit([
474
+ { kind: "authority-epoch-advanced", authorityEpoch: epoch, writerId: this.writerId(), transitions },
475
+ ]);
476
+ }
477
+ /** Announce a session incarnation (S2); the counter survives restarts durably. */
478
+ register(sessionId) {
479
+ if (typeof sessionId !== "string" || sessionId.length === 0)
480
+ throw new TypeError("sessionId must be a non-empty string");
481
+ const current = this.state.incarnations.get(sessionId) ?? sequence("0");
482
+ const incarnation = nextSequenceValue(current);
483
+ this.commit([{ kind: "session-registered", sessionId, incarnation }]);
484
+ return incarnation;
485
+ }
486
+ /**
487
+ * Admit an authorization: claim-overlap check, capacity check, idempotency
488
+ * replay, and the `grant-reserved` record in one lease/mutation-locked
489
+ * critical section — the check and the record are one transaction (docs/04).
490
+ * The lease is held for the store's lifetime, so committed state cannot
491
+ * move between the check and the append; the head CAS in commit() is the
492
+ * backstop if it ever could.
493
+ */
494
+ acquire(input) {
495
+ assertNonNegativeInteger(input.now, "now");
496
+ const weight = input.weight ?? 1;
497
+ assertNonNegativeInteger(weight, "weight");
498
+ if (!Number.isSafeInteger(input.ttl) || input.ttl <= 0)
499
+ throw new TypeError("ttl must be a positive safe integer");
500
+ const authorizationDeadline = input.now + input.ttl;
501
+ if (!Number.isSafeInteger(authorizationDeadline))
502
+ throw new RangeError("authorization deadline overflow");
503
+ const incarnation = sequence(input.incarnation);
504
+ if (this.state.incarnations.get(input.sessionId) !== incarnation)
505
+ throw new AuthorityStoreError("stale_incarnation");
506
+ if (!/^[a-f0-9]{64}$/.test(input.intentDigest))
507
+ throw new TypeError("intentDigest must be a sha256 hex digest");
508
+ if (!Array.isArray(input.claims) || input.claims.length === 0)
509
+ throw new TypeError("an unknown scope must not be admitted as an empty scope");
510
+ const claims = Object.freeze(Array.from(input.claims, (claim) => canonicalClaim(claim)));
511
+ // Idempotency (I08): replayed commands return their recorded disposition
512
+ // without re-executing. A live tombstone returns the result; an expired
513
+ // one reports expiry; an in-flight grant is a duplicate only when the
514
+ // full intent matches — otherwise it is an ID collision (I09/I20).
515
+ const tombstone = this.state.tombstones.get(input.commandId);
516
+ if (tombstone) {
517
+ const grant = this.state.grants.get(tombstone.grantSequence);
518
+ if (!grant)
519
+ throw new AuthorityStoreError("corrupt");
520
+ assertSameCommandMeaning(grant, {
521
+ intentDigest: input.intentDigest,
522
+ sessionId: input.sessionId,
523
+ incarnation,
524
+ claims,
525
+ weight,
526
+ });
527
+ if (tombstone.expiresAtMs <= input.now)
528
+ return { status: "result-expired" };
529
+ return { status: "result", resultDigest: tombstone.resultDigest, token: grant.token };
530
+ }
531
+ for (const grant of this.state.grants.values()) {
532
+ if (grant.commandId !== input.commandId)
533
+ continue;
534
+ assertSameCommandMeaning(grant, {
535
+ intentDigest: input.intentDigest,
536
+ sessionId: input.sessionId,
537
+ incarnation,
538
+ claims,
539
+ weight,
540
+ });
541
+ return { status: "granted", token: grant.token, duplicate: true };
542
+ }
543
+ if (this.pendingReconcile)
544
+ throw new AuthorityStoreError("reconcile_pending");
545
+ const epoch = this.state.epoch;
546
+ if (epoch === null)
547
+ throw new AuthorityStoreError("corrupt");
548
+ const expired = expiryEvents(this.state, input.now, epoch);
549
+ const settledState = expired.length ? applyAuthorityEvents(this.state, expired) : this.state;
550
+ const active = [...settledState.grants.values()].filter((grant) => !SETTLED_EFFECT_STATES.has(grant.state));
551
+ const used = active.reduce((sum, grant) => sum + grant.weight, 0);
552
+ if (weight > this.capacity - used)
553
+ return { status: "blocked" };
554
+ if (active.some((grant) => claimSetsConflict([...claims], [...grant.claims])))
555
+ return { status: "blocked" };
556
+ const grantSequence = nextSequenceValue(this.state.grantCounter);
557
+ const grant = Object.freeze({
558
+ token: Object.freeze({
559
+ authorityEpoch: epoch,
560
+ grantSequence,
561
+ sessionId: input.sessionId,
562
+ sessionIncarnation: incarnation,
563
+ authorizationDeadline,
564
+ }),
565
+ commandId: input.commandId,
566
+ intentDigest: input.intentDigest,
567
+ claims,
568
+ weight,
569
+ state: "reserved",
570
+ effectLive: false,
571
+ dispatchId: null,
572
+ actualClaims: null,
573
+ identity: null,
574
+ });
575
+ this.commit([...expired, { kind: "grant-reserved", grant }]);
576
+ return { status: "granted", token: grant.token, duplicate: false };
577
+ }
578
+ resolveToken(token, authoritative) {
579
+ const grant = this.state.grants.get(token.grantSequence);
580
+ if (!grant || !sameGrantToken(grant.token, token))
581
+ return undefined;
582
+ if (authoritative) {
583
+ if (this.released)
584
+ return undefined;
585
+ if (token.authorityEpoch !== this.state.epoch ||
586
+ this.state.incarnations.get(token.sessionId) !== token.sessionIncarnation ||
587
+ SETTLED_EFFECT_STATES.has(grant.state))
588
+ return undefined;
589
+ }
590
+ else if (SETTLED_EFFECT_STATES.has(grant.state))
591
+ return undefined;
592
+ return grant;
593
+ }
594
+ /**
595
+ * Persisted dispatch intent. A committed intent whose spawn was never
596
+ * witnessed cannot be assumed un-run; on restart it quarantines like any
597
+ * other possibly-live effect (I01/I02).
598
+ */
599
+ dispatchIntent(token, dispatchId, now = this.now()) {
600
+ if (!/^[A-Za-z0-9_-]{1,128}$/.test(dispatchId))
601
+ throw new TypeError("dispatchId is invalid");
602
+ const grant = this.resolveToken(token, true);
603
+ if (!grant || grant.state !== "reserved")
604
+ return false;
605
+ const epoch = this.state.epoch;
606
+ if (epoch === null)
607
+ return false;
608
+ if (!authorizationStillOpen(now, grant.token.authorizationDeadline)) {
609
+ this.expire(now);
610
+ return false;
611
+ }
612
+ this.commit([
613
+ { kind: "dispatch-intent", grantSequence: grant.token.grantSequence, authorityEpoch: epoch, dispatchId },
614
+ ]);
615
+ return true;
616
+ }
617
+ /** Bind an effect to its reservation; actual claims must equal the reserved set exactly. */
618
+ effectStarted(token, actualClaims, identity, now = this.now()) {
619
+ const grant = this.resolveToken(token, true);
620
+ if (!grant || (grant.state !== "reserved" && grant.state !== "starting"))
621
+ return false;
622
+ if (!authorizationStillOpen(now, grant.token.authorizationDeadline)) {
623
+ this.expire(now);
624
+ return false;
625
+ }
626
+ if (!Array.isArray(actualClaims))
627
+ throw new TypeError("actualClaims must be an array");
628
+ const claims = Object.freeze(Array.from(actualClaims, (entry) => canonicalClaim(entry)));
629
+ if (!sameClaimSet([...claims], [...grant.claims]))
630
+ return false;
631
+ const epoch = this.state.epoch;
632
+ if (epoch === null)
633
+ return false;
634
+ this.commit([
635
+ {
636
+ kind: "effect-started",
637
+ grantSequence: grant.token.grantSequence,
638
+ authorityEpoch: epoch,
639
+ actualClaims: claims,
640
+ ...(identity ? { identity } : {}),
641
+ },
642
+ ]);
643
+ return true;
644
+ }
645
+ /** Revalidate a running effect before its next irreversible boundary, without starting it again. */
646
+ effectAuthorized(token, actualClaims) {
647
+ if (this.released)
648
+ return false;
649
+ this.commit([]);
650
+ const now = this.now();
651
+ const grant = this.resolveToken(token, true);
652
+ if (!grant || grant.state !== "running")
653
+ return false;
654
+ if (!authorizationStillOpen(now, token.authorizationDeadline)) {
655
+ this.expire(now);
656
+ return false;
657
+ }
658
+ return sameClaimSet(Array.from(actualClaims, (claim) => canonicalClaim(claim)), grant.claims);
659
+ }
660
+ /** Requested cancellation is not observed termination; live effects quarantine. */
661
+ cancel(token) {
662
+ const grant = this.resolveToken(token, false);
663
+ if (!grant)
664
+ return false;
665
+ const epoch = this.state.epoch;
666
+ if (epoch === null)
667
+ return false;
668
+ this.commit([
669
+ {
670
+ kind: "cancel-requested",
671
+ grantSequence: grant.token.grantSequence,
672
+ authorityEpoch: epoch,
673
+ outcome: grant.effectLive ? "quarantined" : "cancelled",
674
+ },
675
+ ]);
676
+ return true;
677
+ }
678
+ /** Settle lapsed authorizations; never evicts a live effect. */
679
+ expire(now) {
680
+ assertNonNegativeInteger(now, "now");
681
+ const epoch = this.state.epoch;
682
+ if (epoch === null)
683
+ return;
684
+ const events = expiryEvents(this.state, now, epoch);
685
+ if (events.length)
686
+ this.commit(events);
687
+ }
688
+ /**
689
+ * Trusted supervisor witness: this exact effect is gone. Accepted across
690
+ * superseded epochs so a restarted authority can settle what the previous
691
+ * one started, never to authorize new work.
692
+ */
693
+ confirmTerminated(token) {
694
+ const grant = this.resolveToken(token, false);
695
+ if (!grant)
696
+ return false;
697
+ const epoch = this.state.epoch;
698
+ if (epoch === null)
699
+ return false;
700
+ this.commit([{ kind: "termination-observed", grantSequence: grant.token.grantSequence, authorityEpoch: epoch }]);
701
+ return true;
702
+ }
703
+ /** Retain the final result as an idempotency tombstone (S3, docs/04). */
704
+ retainResult(commandId, resultDigest, now, retentionMs) {
705
+ assertNonNegativeInteger(now, "now");
706
+ if (!Number.isSafeInteger(retentionMs) || retentionMs <= 0)
707
+ throw new TypeError("retentionMs must be a positive safe integer");
708
+ if (!/^[a-f0-9]{64}$/.test(resultDigest))
709
+ throw new TypeError("resultDigest must be a sha256 hex digest");
710
+ const grant = [...this.state.grants.values()].find((entry) => entry.commandId === commandId);
711
+ if (!grant)
712
+ throw new AuthorityStoreError("unknown_command");
713
+ if (!SETTLED_EFFECT_STATES.has(grant.state))
714
+ throw new AuthorityStoreError("unsettled");
715
+ if (this.state.tombstones.has(commandId))
716
+ throw new AuthorityStoreError("duplicate");
717
+ this.commit([
718
+ {
719
+ kind: "result-retained",
720
+ commandId,
721
+ grantSequence: grant.token.grantSequence,
722
+ resultDigest,
723
+ retainedAtMs: now,
724
+ expiresAtMs: now + retentionMs,
725
+ },
726
+ ]);
727
+ }
728
+ /** Command disposition without re-execution (I08/I31). */
729
+ lookup(commandId, now) {
730
+ assertNonNegativeInteger(now, "now");
731
+ const tombstone = this.state.tombstones.get(commandId);
732
+ if (tombstone) {
733
+ const grant = this.state.grants.get(tombstone.grantSequence);
734
+ if (!grant)
735
+ throw new AuthorityStoreError("corrupt");
736
+ return tombstone.expiresAtMs <= now
737
+ ? { status: "result-expired", token: grant.token }
738
+ : { status: "result", resultDigest: tombstone.resultDigest, token: grant.token };
739
+ }
740
+ for (const grant of this.state.grants.values())
741
+ if (grant.commandId === commandId)
742
+ return { status: "pending", token: grant.token };
743
+ return { status: "unknown" };
744
+ }
745
+ /**
746
+ * Finish the restart reconciliation: every quarantined effect is compared
747
+ * against the real execution boundary — only an observed termination
748
+ * settles it ("gone"); "alive"/"unknown" stay quarantined and keep their
749
+ * claims (docs/04, review §6). Ends with `authority-reconciled` for the
750
+ * current epoch; the reconciled scope only then admits new work.
751
+ */
752
+ reconcile(probe) {
753
+ const state = this.state;
754
+ const epoch = state.epoch;
755
+ if (epoch === null)
756
+ throw new AuthorityStoreError("corrupt");
757
+ if (!authorityPendingReconcile(state))
758
+ return;
759
+ const check = probe ?? this.probe;
760
+ const events = [];
761
+ for (const grant of state.grants.values()) {
762
+ if (grant.state !== "quarantined")
763
+ continue;
764
+ if (check(grant) === "terminated") {
765
+ events.push({
766
+ kind: "termination-observed",
767
+ grantSequence: grant.token.grantSequence,
768
+ authorityEpoch: epoch,
769
+ });
770
+ }
771
+ }
772
+ events.push({ kind: "authority-reconciled", authorityEpoch: epoch });
773
+ this.commit(events);
774
+ }
775
+ /**
776
+ * GC (review §7): fold droppable state into an `authority-snapshot` and
777
+ * atomically rewrite the log to that snapshot. Retained: the epoch pair,
778
+ * incarnation counters, the grant counter (I31 — sequences never reissue),
779
+ * every unsettled grant, every settled grant still referenced by an
780
+ * unexpired tombstone, and the unexpired tombstones themselves. A crash
781
+ * between the atomic rewrite and head publish self-heals on next open via
782
+ * the snapshot continuation check.
783
+ */
784
+ compact(now) {
785
+ assertNonNegativeInteger(now, "now");
786
+ if (this.released)
787
+ throw new AuthorityStoreError("stale_owner");
788
+ const mutation = acquireDurableFileMutationLockSync(this.context.path);
789
+ try {
790
+ const current = loadCommitted(this.context, true);
791
+ if (!authorityHeadsEqual(current.head, this.accepted.head))
792
+ throw new AuthorityStoreError("stale_head");
793
+ const state = current.parsed.state;
794
+ if (state.epoch === null)
795
+ return { dropped: 0 };
796
+ const keepGrant = new Set();
797
+ const keepTombstone = new Set();
798
+ for (const tombstone of state.tombstones.values()) {
799
+ if (tombstone.expiresAtMs > now) {
800
+ keepTombstone.add(tombstone.commandId);
801
+ keepGrant.add(tombstone.grantSequence);
802
+ }
803
+ }
804
+ const grants = [...state.grants.values()].filter((grant) => !SETTLED_EFFECT_STATES.has(grant.state) || keepGrant.has(grant.token.grantSequence));
805
+ const tombstones = [...state.tombstones.values()].filter((stone) => keepTombstone.has(stone.commandId));
806
+ const dropped = state.grants.size - grants.length + (state.tombstones.size - tombstones.length);
807
+ if (dropped === 0)
808
+ return { dropped: 0 };
809
+ const snapshot = snapshotFromProjection({
810
+ ...state,
811
+ grants: new Map(grants.map((grant) => [grant.token.grantSequence, grant])),
812
+ tombstones: new Map(tombstones.map((stone) => [stone.commandId, stone])),
813
+ });
814
+ const record = materializeRecord(current.parsed.lastSeq + 1, current.parsed.lastHash, {
815
+ kind: "authority-snapshot",
816
+ archivedThroughSequence: current.parsed.lastSeq,
817
+ continuesHash: current.parsed.lastHash,
818
+ state: snapshot,
819
+ });
820
+ atomicRewriteFileSync(this.context.path, recordLine(record));
821
+ this.context.hooks.afterAtomicRewrite?.();
822
+ const fd = openSync(this.context.path, fsConstants.O_RDONLY | (fsConstants.O_NOFOLLOW ?? 0));
823
+ let head;
824
+ try {
825
+ const stat = fstatSync(fd);
826
+ head = Object.freeze({
827
+ fileIdentity: fileIdentityOf(stat),
828
+ size: stat.size,
829
+ lastSeq: record.seq,
830
+ lastHash: record.hash,
831
+ });
832
+ }
833
+ finally {
834
+ closeSync(fd);
835
+ }
836
+ publishHead(this.context, head);
837
+ this.accepted = loadCommitted(this.context, false);
838
+ return { dropped };
839
+ }
840
+ finally {
841
+ mutation.release();
842
+ }
843
+ }
844
+ /** Release the authority lease; further commits fail closed. */
845
+ release() {
846
+ if (this.released)
847
+ return;
848
+ this.released = true;
849
+ this.lease.release();
850
+ }
851
+ }
852
+ //# sourceMappingURL=authority-store.js.map