open-multi-agent-kit 1.2.0 → 1.2.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 (436) hide show
  1. package/CHANGELOG.md +54 -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 +81 -0
  296. package/dist/core/verified-run/supervisor-adapter.d.ts.map +1 -0
  297. package/dist/core/verified-run/supervisor-adapter.js +168 -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
package/CHANGELOG.md CHANGED
@@ -1,5 +1,59 @@
1
1
  # Changelog
2
2
 
3
+ ## [Unreleased]
4
+
5
+ ## [1.2.3] - 2026-09-23
6
+
7
+ ### Fixed
8
+
9
+ - Verified-run suite hardening: tests use a 15s cleanup budget so slow namespace teardown on ubuntu-22.04 runners drains before settling, matching the witness contract without weakening fail-closed outcomes (no product-code change).
10
+
11
+ ## [1.2.2] - 2026-09-23
12
+
13
+ ### Fixed
14
+
15
+ - Verified-run termination witness: the supervisor drain now witnesses PID-namespace init death instead of enumerating the host process table, and inconclusive probes retry until the cleanup deadline instead of settling terminal `unknown` early. Host-dependent false positives (zombie tasks keeping their ns link, unreadable same-uid tasks) no longer quarantine every sandboxed dispatch — this was the ubuntu-22.04 CI failure that blocked v1.2.1 publishing.
16
+ - Test infrastructure: `./test.sh` runs the suite against an isolated agent directory (`OMK_CODING_AGENT_DIR` on a throwaway dir) instead of moving the live credential store aside for the whole run. Concurrent sessions no longer read an empty store, fall back to stale environment credentials, or have a freshly written store clobbered by the restore. The test environment preserves `OMK_CODING_AGENT_DIR` while scrubbing other `OMK_*` values so the isolation reaches spawned CLI processes.
17
+ - Compaction no longer livelocks while an extension writes session state. A summary is now committed over `custom` entries appended while it was generated (for example pi-landstrip background-task snapshots every few seconds) when the file only grew by such entries; a message, model change, provenance entry, rewrite or branch move still discards it with `revision_mismatch`.
18
+ - A compaction window may hold up to 65,536 entries (was 4,096), so a session dominated by extension state entries can compact instead of failing with `source.entryIds must be a bounded array`. An older binary cannot open a session whose compaction envelope lists more than 4,096 entries.
19
+
20
+ ## [1.2.1] - 2026-09-23
21
+
22
+ ### New Features
23
+
24
+ - **Verified run authority wiring**: the authority store now runs on the real dispatch path (WP00–WP06) — durable admission leases, an exit proof that Git publication binds to, secret-path refusal, and a separate publish-start gate. See [Verified Run](docs/verified-run.md).
25
+ - **Metadata-first session listing with separate search**: the session picker lists from metadata first and runs search as its own pass, so large session directories render immediately. See [Sessions](docs/sessions.md).
26
+ - **Portable `mcp.json` paths**: `~/` and `$VAR` expand in server paths, so one config works across machines. See [MCP](docs/mcp.md).
27
+ - **New model catalog**: Claude Opus 5.5 and GPT-6 Sol/Luna, with per-route thinking-level contracts so the selector only offers effort the route actually sends. See [Models](docs/models.md).
28
+
29
+ ### Added
30
+
31
+ - Atomic commit planner public API in `omk-agent-core`. See [Atomic commit planning](docs/atomic-commit-planning.md).
32
+ - Terminal output observation (`TerminalOutput`) exposed to interactive diagnostics. See [TUI](docs/tui.md).
33
+
34
+ ### Changed
35
+
36
+ - The MCP manager is split into a connection queue and a runtime, with a startup concurrency cap so many servers connect without unbounded fan-out. See [MCP](docs/mcp.md).
37
+ - Assistant message rendering caches content views, cutting render cost on long transcripts.
38
+ - A cached skill catalog is reused only when its fingerprint is complete; otherwise it reloads. See [Skills](docs/skills.md).
39
+ - SDK auxiliary modules and hooks public paths are reorganized (`package-resource-patterns`, `approval-api`, session-lifecycle types), and redundant development dependencies are removed.
40
+
41
+ ### Fixed
42
+
43
+ - Verified-run publication boundaries: Git publication records ownership and binds the exit proof, refuses secret paths, treats a git-ref authority as authorization rather than a termination proof, blocks inherited hooks and config injection in the publishing Git, and preserves publish-path and authority-reuse semantics.
44
+ - Shard settlement returns permits and waits for sibling task termination.
45
+ - Compaction: prompts are rejected during manual compaction, pre-prompt compaction no longer continues, and replacement-model auth and cancellation handling are strengthened.
46
+ - Coordination primitives and probability boundaries are tightened, with the metacognition contract updated. See [Metacognition](docs/metacognition.md).
47
+ - Resource loading excludes directories (#7106), and an imported session is never overwritten (#8985).
48
+ - The active turn settles before an in-memory fork (#8937).
49
+ - Linux downloads the statically linked musl builds of `fd` and `ripgrep` (#9070), and image scanning walks past non-EXIF APP1 segments (#8616).
50
+ - RPC bash no longer bypasses `user_bash` (#7214).
51
+ - Read errors are not highlighted (#6731) and `stripAnsi` matches `strip-ansi`.
52
+ - Fetch overrides are preserved, the stale hooks export and the DynamicBorder theme crash are fixed, and dependencies reinstall when `git clean` fails (#7570).
53
+ - Share viewer shortcuts use browser-safe keys (#3374), and device-code login no longer opens a browser.
54
+ - Session name changes are emitted to extensions.
55
+ - Test environment: `Date.now` is monotonic so host wall-clock rollbacks cannot surface as `clock_anomaly` failures, and the model-registry fixture references live OpenRouter model ids with a catalog guard test.
56
+
3
57
  ## [1.2.0] - 2026-09-20
4
58
 
5
59
  ### Added
package/README.md CHANGED
@@ -47,7 +47,7 @@ OMK stores user configuration under `~/.omk/agent/` and project configuration un
47
47
  Install `omk-book-to-skill` to compile documents into reusable skills without adding Python extractors to OMK core:
48
48
 
49
49
  ```bash
50
- omk install npm:omk-book-to-skill@1.2.0
50
+ omk install npm:omk-book-to-skill@1.2.3
51
51
  ```
52
52
 
53
53
  It provides compile, update, and verification commands plus a local SHA-256 provenance manifest. See [Book to Skill](https://github.com/dmae97/omk/blob/main/packages/coding-agent/docs/book-to-skill.md).
@@ -258,7 +258,7 @@ npm test
258
258
 
259
259
  See [Development](https://github.com/dmae97/omk/blob/main/packages/coding-agent/docs/development.md) and [CONTRIBUTING.md](https://github.com/dmae97/omk/blob/main/CONTRIBUTING.md).
260
260
 
261
- Release notes: [v1.2.0](https://github.com/dmae97/omk/blob/main/.github/RELEASE_NOTES_v1.2.0.md).
261
+ Release notes: [v1.2.3](https://github.com/dmae97/omk/blob/main/.github/RELEASE_NOTES_v1.2.3.md).
262
262
 
263
263
  ## License
264
264
 
@@ -0,0 +1,5 @@
1
+ export { type ApprovalContentDigest, type ApprovalDecision, type ApprovalPlanDigest, type ApprovalReceipt, type ApprovalReceiptCore, computeApprovalContentDigest, computeApprovalReceiptCoreSha256, createApprovalReceipt, parseApprovalReceipt, serializeApprovalReceipt, validateApprovalReceipt, } from "./approvals/approval-receipt.ts";
2
+ export { ApprovalReceiptStore, type ApprovalReceiptWriteResult } from "./approvals/approval-receipt-store.ts";
3
+ export { type ApprovalExecutionBinding, type ApprovalVerificationFailure, type ApprovalVerificationResult, verifyApprovalForExecution, } from "./approvals/approval-verifier.ts";
4
+ export { type ApprovalEventBus, PLANNOTATOR_REQUEST_CHANNEL, PLANNOTATOR_REVIEW_RESULT_CHANNEL, PlannotatorApprovalBridge, type PlannotatorApprovalBridgeOptions, type PlanReviewCorrelation, type PlanReviewRequest, type ReviewResultOutcome, } from "./approvals/plannotator-approval-bridge.ts";
5
+ //# sourceMappingURL=approval-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-api.d.ts","sourceRoot":"","sources":["../src/approval-api.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,4BAA4B,EAC5B,gCAAgC,EAChC,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,GACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,KAAK,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AAC9G,OAAO,EACN,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,0BAA0B,GAC1B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACN,KAAK,gBAAgB,EACrB,2BAA2B,EAC3B,iCAAiC,EACjC,yBAAyB,EACzB,KAAK,gCAAgC,EACrC,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,GACxB,MAAM,4CAA4C,CAAC","sourcesContent":["export {\n\ttype ApprovalContentDigest,\n\ttype ApprovalDecision,\n\ttype ApprovalPlanDigest,\n\ttype ApprovalReceipt,\n\ttype ApprovalReceiptCore,\n\tcomputeApprovalContentDigest,\n\tcomputeApprovalReceiptCoreSha256,\n\tcreateApprovalReceipt,\n\tparseApprovalReceipt,\n\tserializeApprovalReceipt,\n\tvalidateApprovalReceipt,\n} from \"./approvals/approval-receipt.ts\";\nexport { ApprovalReceiptStore, type ApprovalReceiptWriteResult } from \"./approvals/approval-receipt-store.ts\";\nexport {\n\ttype ApprovalExecutionBinding,\n\ttype ApprovalVerificationFailure,\n\ttype ApprovalVerificationResult,\n\tverifyApprovalForExecution,\n} from \"./approvals/approval-verifier.ts\";\nexport {\n\ttype ApprovalEventBus,\n\tPLANNOTATOR_REQUEST_CHANNEL,\n\tPLANNOTATOR_REVIEW_RESULT_CHANNEL,\n\tPlannotatorApprovalBridge,\n\ttype PlannotatorApprovalBridgeOptions,\n\ttype PlanReviewCorrelation,\n\ttype PlanReviewRequest,\n\ttype ReviewResultOutcome,\n} from \"./approvals/plannotator-approval-bridge.ts\";\n"]}
@@ -0,0 +1,5 @@
1
+ export { computeApprovalContentDigest, computeApprovalReceiptCoreSha256, createApprovalReceipt, parseApprovalReceipt, serializeApprovalReceipt, validateApprovalReceipt, } from "./approvals/approval-receipt.js";
2
+ export { ApprovalReceiptStore } from "./approvals/approval-receipt-store.js";
3
+ export { verifyApprovalForExecution, } from "./approvals/approval-verifier.js";
4
+ export { PLANNOTATOR_REQUEST_CHANNEL, PLANNOTATOR_REVIEW_RESULT_CHANNEL, PlannotatorApprovalBridge, } from "./approvals/plannotator-approval-bridge.js";
5
+ //# sourceMappingURL=approval-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-api.js","sourceRoot":"","sources":["../src/approval-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAMN,4BAA4B,EAC5B,gCAAgC,EAChC,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,GACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAmC,MAAM,uCAAuC,CAAC;AAC9G,OAAO,EAIN,0BAA0B,GAC1B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAEN,2BAA2B,EAC3B,iCAAiC,EACjC,yBAAyB,GAKzB,MAAM,4CAA4C,CAAC","sourcesContent":["export {\n\ttype ApprovalContentDigest,\n\ttype ApprovalDecision,\n\ttype ApprovalPlanDigest,\n\ttype ApprovalReceipt,\n\ttype ApprovalReceiptCore,\n\tcomputeApprovalContentDigest,\n\tcomputeApprovalReceiptCoreSha256,\n\tcreateApprovalReceipt,\n\tparseApprovalReceipt,\n\tserializeApprovalReceipt,\n\tvalidateApprovalReceipt,\n} from \"./approvals/approval-receipt.ts\";\nexport { ApprovalReceiptStore, type ApprovalReceiptWriteResult } from \"./approvals/approval-receipt-store.ts\";\nexport {\n\ttype ApprovalExecutionBinding,\n\ttype ApprovalVerificationFailure,\n\ttype ApprovalVerificationResult,\n\tverifyApprovalForExecution,\n} from \"./approvals/approval-verifier.ts\";\nexport {\n\ttype ApprovalEventBus,\n\tPLANNOTATOR_REQUEST_CHANNEL,\n\tPLANNOTATOR_REVIEW_RESULT_CHANNEL,\n\tPlannotatorApprovalBridge,\n\ttype PlannotatorApprovalBridgeOptions,\n\ttype PlanReviewCorrelation,\n\ttype PlanReviewRequest,\n\ttype ReviewResultOutcome,\n} from \"./approvals/plannotator-approval-bridge.ts\";\n"]}
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * TUI session selector for --resume flag
3
3
  */
4
- import type { SessionInfo, SessionListProgress } from "../core/session-manager.ts";
5
- type SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionInfo[]>;
4
+ import type { SessionListEntry, SessionListProgress } from "../core/session-manager.ts";
5
+ type SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionListEntry[]>;
6
6
  /** Show TUI session selector and return selected session path or null if cancelled */
7
7
  export declare function selectSession(currentSessionsLoader: SessionsLoader, allSessionsLoader: SessionsLoader): Promise<string | null>;
8
8
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"session-picker.d.ts","sourceRoot":"","sources":["../../src/cli/session-picker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGnF,KAAK,cAAc,GAAG,CAAC,UAAU,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;AAEnF,sFAAsF;AACtF,wBAAsB,aAAa,CAClC,qBAAqB,EAAE,cAAc,EACrC,iBAAiB,EAAE,cAAc,GAC/B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoCxB","sourcesContent":["/**\n * TUI session selector for --resume flag\n */\n\nimport { ProcessTerminal, setKeybindings, TUI } from \"omk-tui\";\nimport { KeybindingsManager } from \"../core/keybindings.ts\";\nimport type { SessionInfo, SessionListProgress } from \"../core/session-manager.ts\";\nimport { SessionSelectorComponent } from \"../modes/interactive/components/session-selector.ts\";\n\ntype SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionInfo[]>;\n\n/** Show TUI session selector and return selected session path or null if cancelled */\nexport async function selectSession(\n\tcurrentSessionsLoader: SessionsLoader,\n\tallSessionsLoader: SessionsLoader,\n): Promise<string | null> {\n\treturn new Promise((resolve) => {\n\t\tconst ui = new TUI(new ProcessTerminal());\n\t\tconst keybindings = KeybindingsManager.create();\n\t\tsetKeybindings(keybindings);\n\t\tlet resolved = false;\n\n\t\tconst selector = new SessionSelectorComponent(\n\t\t\tcurrentSessionsLoader,\n\t\t\tallSessionsLoader,\n\t\t\t(path: string) => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(path);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(null);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tui.stop();\n\t\t\t\tprocess.exit(0);\n\t\t\t},\n\t\t\t() => ui.requestRender(),\n\t\t\t{ showRenameHint: false, keybindings },\n\t\t);\n\n\t\tui.addChild(selector);\n\t\tui.setFocus(selector.getSessionList());\n\t\tui.start();\n\t});\n}\n"]}
1
+ {"version":3,"file":"session-picker.d.ts","sourceRoot":"","sources":["../../src/cli/session-picker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGxF,KAAK,cAAc,GAAG,CAAC,UAAU,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;AAExF,sFAAsF;AACtF,wBAAsB,aAAa,CAClC,qBAAqB,EAAE,cAAc,EACrC,iBAAiB,EAAE,cAAc,GAC/B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoCxB","sourcesContent":["/**\n * TUI session selector for --resume flag\n */\n\nimport { ProcessTerminal, setKeybindings, TUI } from \"omk-tui\";\nimport { KeybindingsManager } from \"../core/keybindings.ts\";\nimport type { SessionListEntry, SessionListProgress } from \"../core/session-manager.ts\";\nimport { SessionSelectorComponent } from \"../modes/interactive/components/session-selector.ts\";\n\ntype SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionListEntry[]>;\n\n/** Show TUI session selector and return selected session path or null if cancelled */\nexport async function selectSession(\n\tcurrentSessionsLoader: SessionsLoader,\n\tallSessionsLoader: SessionsLoader,\n): Promise<string | null> {\n\treturn new Promise((resolve) => {\n\t\tconst ui = new TUI(new ProcessTerminal());\n\t\tconst keybindings = KeybindingsManager.create();\n\t\tsetKeybindings(keybindings);\n\t\tlet resolved = false;\n\n\t\tconst selector = new SessionSelectorComponent(\n\t\t\tcurrentSessionsLoader,\n\t\t\tallSessionsLoader,\n\t\t\t(path: string) => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(path);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(null);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tui.stop();\n\t\t\t\tprocess.exit(0);\n\t\t\t},\n\t\t\t() => ui.requestRender(),\n\t\t\t{ showRenameHint: false, keybindings },\n\t\t);\n\n\t\tui.addChild(selector);\n\t\tui.setFocus(selector.getSessionList());\n\t\tui.start();\n\t});\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"session-picker.js","sourceRoot":"","sources":["../../src/cli/session-picker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,qDAAqD,CAAC;AAI/F,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,qBAAqC,EACrC,iBAAiC,EACR;IACzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/B,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,IAAI,eAAe,EAAE,CAAC,CAAC;QAC1C,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,EAAE,CAAC;QAChD,cAAc,CAAC,WAAW,CAAC,CAAC;QAC5B,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,MAAM,QAAQ,GAAG,IAAI,wBAAwB,CAC5C,qBAAqB,EACrB,iBAAiB,EACjB,CAAC,IAAY,EAAE,EAAE,CAAC;YACjB,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,QAAQ,GAAG,IAAI,CAAC;gBAChB,EAAE,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC,CAAC;YACf,CAAC;QAAA,CACD,EACD,GAAG,EAAE,CAAC;YACL,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,QAAQ,GAAG,IAAI,CAAC;gBAChB,EAAE,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC,CAAC;YACf,CAAC;QAAA,CACD,EACD,GAAG,EAAE,CAAC;YACL,EAAE,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAA,CAChB,EACD,GAAG,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,EACxB,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,EAAE,CACtC,CAAC;QAEF,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACtB,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAC;QACvC,EAAE,CAAC,KAAK,EAAE,CAAC;IAAA,CACX,CAAC,CAAC;AAAA,CACH","sourcesContent":["/**\n * TUI session selector for --resume flag\n */\n\nimport { ProcessTerminal, setKeybindings, TUI } from \"omk-tui\";\nimport { KeybindingsManager } from \"../core/keybindings.ts\";\nimport type { SessionInfo, SessionListProgress } from \"../core/session-manager.ts\";\nimport { SessionSelectorComponent } from \"../modes/interactive/components/session-selector.ts\";\n\ntype SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionInfo[]>;\n\n/** Show TUI session selector and return selected session path or null if cancelled */\nexport async function selectSession(\n\tcurrentSessionsLoader: SessionsLoader,\n\tallSessionsLoader: SessionsLoader,\n): Promise<string | null> {\n\treturn new Promise((resolve) => {\n\t\tconst ui = new TUI(new ProcessTerminal());\n\t\tconst keybindings = KeybindingsManager.create();\n\t\tsetKeybindings(keybindings);\n\t\tlet resolved = false;\n\n\t\tconst selector = new SessionSelectorComponent(\n\t\t\tcurrentSessionsLoader,\n\t\t\tallSessionsLoader,\n\t\t\t(path: string) => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(path);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(null);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tui.stop();\n\t\t\t\tprocess.exit(0);\n\t\t\t},\n\t\t\t() => ui.requestRender(),\n\t\t\t{ showRenameHint: false, keybindings },\n\t\t);\n\n\t\tui.addChild(selector);\n\t\tui.setFocus(selector.getSessionList());\n\t\tui.start();\n\t});\n}\n"]}
1
+ {"version":3,"file":"session-picker.js","sourceRoot":"","sources":["../../src/cli/session-picker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,qDAAqD,CAAC;AAI/F,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,qBAAqC,EACrC,iBAAiC,EACR;IACzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/B,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,IAAI,eAAe,EAAE,CAAC,CAAC;QAC1C,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,EAAE,CAAC;QAChD,cAAc,CAAC,WAAW,CAAC,CAAC;QAC5B,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,MAAM,QAAQ,GAAG,IAAI,wBAAwB,CAC5C,qBAAqB,EACrB,iBAAiB,EACjB,CAAC,IAAY,EAAE,EAAE,CAAC;YACjB,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,QAAQ,GAAG,IAAI,CAAC;gBAChB,EAAE,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC,CAAC;YACf,CAAC;QAAA,CACD,EACD,GAAG,EAAE,CAAC;YACL,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,QAAQ,GAAG,IAAI,CAAC;gBAChB,EAAE,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC,CAAC;YACf,CAAC;QAAA,CACD,EACD,GAAG,EAAE,CAAC;YACL,EAAE,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAA,CAChB,EACD,GAAG,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,EACxB,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,EAAE,CACtC,CAAC;QAEF,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACtB,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAC;QACvC,EAAE,CAAC,KAAK,EAAE,CAAC;IAAA,CACX,CAAC,CAAC;AAAA,CACH","sourcesContent":["/**\n * TUI session selector for --resume flag\n */\n\nimport { ProcessTerminal, setKeybindings, TUI } from \"omk-tui\";\nimport { KeybindingsManager } from \"../core/keybindings.ts\";\nimport type { SessionListEntry, SessionListProgress } from \"../core/session-manager.ts\";\nimport { SessionSelectorComponent } from \"../modes/interactive/components/session-selector.ts\";\n\ntype SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionListEntry[]>;\n\n/** Show TUI session selector and return selected session path or null if cancelled */\nexport async function selectSession(\n\tcurrentSessionsLoader: SessionsLoader,\n\tallSessionsLoader: SessionsLoader,\n): Promise<string | null> {\n\treturn new Promise((resolve) => {\n\t\tconst ui = new TUI(new ProcessTerminal());\n\t\tconst keybindings = KeybindingsManager.create();\n\t\tsetKeybindings(keybindings);\n\t\tlet resolved = false;\n\n\t\tconst selector = new SessionSelectorComponent(\n\t\t\tcurrentSessionsLoader,\n\t\t\tallSessionsLoader,\n\t\t\t(path: string) => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(path);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(null);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tui.stop();\n\t\t\t\tprocess.exit(0);\n\t\t\t},\n\t\t\t() => ui.requestRender(),\n\t\t\t{ showRenameHint: false, keybindings },\n\t\t);\n\n\t\tui.addChild(selector);\n\t\tui.setFocus(selector.getSessionList());\n\t\tui.start();\n\t});\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"verified-run-cli.d.ts","sourceRoot":"","sources":["../../src/commands/verified-run-cli.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAoG/E,wBAAsB,iBAAiB,CACtC,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAyHnE","sourcesContent":["import { join } from \"node:path\";\nimport { parseRunContract, RunContractError, VERIFIED_COMMAND_VERSION } from \"omk-protocol\";\nimport { getAgentDir } from \"../config.ts\";\nimport { planVerifiedRun, RunCoordinator } from \"../core/verified-run/coordinator.ts\";\nimport type { VerifiedRunRuntime } from \"../core/verified-run/session-port.ts\";\nimport { digestBytes, readJson, VerifiedRunError } from \"../core/verified-run/storage.ts\";\n\nconst USAGE = `Usage: omk run plan --contract FILE [--json]\n omk run start --contract FILE --approve DIGEST --command-id ID [--state-dir DIR]\n omk run inspect|evidence ID [--state-dir DIR] [--json]\n omk run inspect ID --recovery|--writer-recovery|--task-recovery [--state-dir DIR]\n omk run retry-tasks ID --execute --tasks ID[,ID...]|- --approve DIGEST --base DIGEST --revision N --generation N --command-id ID [--state-dir DIR]\n omk run restart-writer ID --execute --approve DIGEST --base DIGEST --revision N --generation N --command-id ID [--state-dir DIR]\n omk run resume ID --execute --approve DIGEST --candidate DIGEST --revision N --generation N --command-id ID [--state-dir DIR]\n omk run artifact ID --candidate DIGEST --path PATH [--state-dir DIR]\nThe opt-in command, scripted-agent and bounded command-DAG profiles never apply changes to the original workspace.\nResume rechecks a fixed candidate. Writer/task recovery preserves input checkpoints and budgets. Command-DAG concurrency defaults to 1 and supports an explicit cap of 2. Plan amendment, managed apply and TUI/RPC control are not implemented.`;\n\ninterface Parsed {\n\treadonly action:\n\t\t| \"plan\"\n\t\t| \"start\"\n\t\t| \"resume\"\n\t\t| \"restart-writer\"\n\t\t| \"retry-tasks\"\n\t\t| \"inspect\"\n\t\t| \"evidence\"\n\t\t| \"artifact\";\n\treadonly id: string | undefined;\n\treadonly flags: ReadonlyMap<string, string>;\n}\n\nfunction parse(args: readonly string[]): Parsed {\n\tconst action = args[1];\n\tif (\n\t\taction !== \"plan\" &&\n\t\taction !== \"start\" &&\n\t\taction !== \"resume\" &&\n\t\taction !== \"restart-writer\" &&\n\t\taction !== \"retry-tasks\" &&\n\t\taction !== \"inspect\" &&\n\t\taction !== \"evidence\" &&\n\t\taction !== \"artifact\"\n\t)\n\t\tthrow new VerifiedRunError(\"usage\");\n\tconst hasId = action !== \"plan\" && action !== \"start\";\n\tconst id = hasId ? args[2] : undefined;\n\tif (hasId && (!id || id.startsWith(\"--\"))) throw new VerifiedRunError(\"usage\");\n\tconst allowed =\n\t\taction === \"plan\"\n\t\t\t? [\"--contract\", \"--json\"]\n\t\t\t: action === \"start\"\n\t\t\t\t? [\"--contract\", \"--approve\", \"--command-id\", \"--state-dir\", \"--json\"]\n\t\t\t\t: action === \"resume\" || action === \"restart-writer\" || action === \"retry-tasks\"\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t\"--execute\",\n\t\t\t\t\t\t\t\"--approve\",\n\t\t\t\t\t\t\taction === \"resume\" ? \"--candidate\" : \"--base\",\n\t\t\t\t\t\t\t...(action === \"retry-tasks\" ? [\"--tasks\"] : []),\n\t\t\t\t\t\t\t\"--revision\",\n\t\t\t\t\t\t\t\"--generation\",\n\t\t\t\t\t\t\t\"--command-id\",\n\t\t\t\t\t\t\t\"--state-dir\",\n\t\t\t\t\t\t\t\"--json\",\n\t\t\t\t\t\t]\n\t\t\t\t\t: action === \"artifact\"\n\t\t\t\t\t\t? [\"--candidate\", \"--path\", \"--state-dir\", \"--json\"]\n\t\t\t\t\t\t: action === \"inspect\"\n\t\t\t\t\t\t\t? [\"--state-dir\", \"--json\", \"--recovery\", \"--writer-recovery\", \"--task-recovery\"]\n\t\t\t\t\t\t\t: [\"--state-dir\", \"--json\"];\n\tconst flags = new Map<string, string>();\n\tfor (let index = hasId ? 3 : 2; index < args.length; index++) {\n\t\tconst flag = args[index];\n\t\tif (!allowed.includes(flag) || flags.has(flag)) throw new VerifiedRunError(\"usage\");\n\t\tconst value = [\"--json\", \"--execute\", \"--recovery\", \"--writer-recovery\", \"--task-recovery\"].includes(flag)\n\t\t\t? \"true\"\n\t\t\t: args[++index];\n\t\tif (!value || value.startsWith(\"--\")) throw new VerifiedRunError(\"usage\");\n\t\tflags.set(flag, value);\n\t}\n\tif ([\"--recovery\", \"--writer-recovery\", \"--task-recovery\"].filter((flag) => flags.has(flag)).length > 1)\n\t\tthrow new VerifiedRunError(\"usage\");\n\treturn { action, id, flags };\n}\n\nfunction required(parsed: Parsed, name: string): string {\n\tconst value = parsed.flags.get(name);\n\tif (!value) throw new VerifiedRunError(\"usage\");\n\treturn value;\n}\n\nasync function withRunSignal<T>(run: (signal: AbortSignal) => Promise<T>): Promise<T> {\n\tconst controller = new AbortController();\n\tconst cancel = (): void => controller.abort();\n\tprocess.once(\"SIGINT\", cancel);\n\tprocess.once(\"SIGTERM\", cancel);\n\ttry {\n\t\treturn await run(controller.signal);\n\t} finally {\n\t\tprocess.off(\"SIGINT\", cancel);\n\t\tprocess.off(\"SIGTERM\", cancel);\n\t}\n}\n\nexport async function runVerifiedRunCli(\n\targs: string[],\n\truntime?: VerifiedRunRuntime,\n): Promise<{ readonly handled: boolean; readonly exitCode: number }> {\n\tif (args[0] !== \"run\") return { handled: false, exitCode: 0 };\n\tif (args.length === 2 && args[1] === \"--help\") {\n\t\tprocess.stdout.write(`${USAGE}\\n`);\n\t\treturn { handled: true, exitCode: 0 };\n\t}\n\ttry {\n\t\tconst parsed = parse(args);\n\t\tconst coordinator = new RunCoordinator(\n\t\t\tparsed.flags.get(\"--state-dir\") ?? join(getAgentDir(), \"verified-runs\"),\n\t\t\truntime,\n\t\t);\n\t\tlet result: unknown;\n\t\tlet exitCode = 0;\n\t\tswitch (parsed.action) {\n\t\t\tcase \"plan\":\n\t\t\t\tresult = planVerifiedRun(readJson(required(parsed, \"--contract\")));\n\t\t\t\tbreak;\n\t\t\tcase \"start\": {\n\t\t\t\tconst approvedContractDigest = required(parsed, \"--approve\");\n\t\t\t\tconst commandId = required(parsed, \"--command-id\");\n\t\t\t\tconst contract = parseRunContract(readJson(required(parsed, \"--contract\")));\n\t\t\t\tconst state = await withRunSignal((signal) =>\n\t\t\t\t\tcoordinator.start(\n\t\t\t\t\t\tcontract,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tschemaVersion: VERIFIED_COMMAND_VERSION,\n\t\t\t\t\t\t\tkind: \"start\",\n\t\t\t\t\t\t\trunId: contract.runId,\n\t\t\t\t\t\t\tcommandId,\n\t\t\t\t\t\t\texpectedRevision: 0,\n\t\t\t\t\t\t\texpectedGeneration: 0,\n\t\t\t\t\t\t\tcontractDigest: approvedContractDigest,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tresult = state;\n\t\t\t\texitCode = state.application === \"candidate_ready\" ? 0 : 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"resume\":\n\t\t\tcase \"retry-tasks\":\n\t\t\tcase \"restart-writer\": {\n\t\t\t\trequired(parsed, \"--execute\");\n\t\t\t\tconst approvedContractDigest = required(parsed, \"--approve\");\n\t\t\t\tconst request = {\n\t\t\t\t\tschemaVersion: VERIFIED_COMMAND_VERSION,\n\t\t\t\t\trunId: parsed.id ?? \"\",\n\t\t\t\t\tcommandId: required(parsed, \"--command-id\"),\n\t\t\t\t\texpectedRevision: Number(required(parsed, \"--revision\")),\n\t\t\t\t\texpectedGeneration: Number(required(parsed, \"--generation\")),\n\t\t\t\t\tcontractDigest: approvedContractDigest,\n\t\t\t\t};\n\t\t\t\tconst state = await withRunSignal((signal) =>\n\t\t\t\t\tparsed.action === \"retry-tasks\"\n\t\t\t\t\t\t? coordinator.retryTasks(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t...request,\n\t\t\t\t\t\t\t\t\tkind: \"retry_tasks\",\n\t\t\t\t\t\t\t\t\tbaseDigest: required(parsed, \"--base\"),\n\t\t\t\t\t\t\t\t\ttaskIds: required(parsed, \"--tasks\") === \"-\" ? [] : required(parsed, \"--tasks\").split(\",\"),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: parsed.action === \"resume\"\n\t\t\t\t\t\t\t? coordinator.resume(\n\t\t\t\t\t\t\t\t\t{ ...request, kind: \"resume\", candidateDigest: required(parsed, \"--candidate\") },\n\t\t\t\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: coordinator.restartWriter(\n\t\t\t\t\t\t\t\t\t{ ...request, kind: \"restart_writer\", baseDigest: required(parsed, \"--base\") },\n\t\t\t\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tresult = state;\n\t\t\t\texitCode = state.application === \"candidate_ready\" ? 0 : 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"inspect\":\n\t\t\t\tresult = parsed.flags.has(\"--recovery\")\n\t\t\t\t\t? coordinator.inspectRecovery(parsed.id ?? \"\")\n\t\t\t\t\t: parsed.flags.has(\"--writer-recovery\")\n\t\t\t\t\t\t? coordinator.inspectWriterRecovery(parsed.id ?? \"\")\n\t\t\t\t\t\t: parsed.flags.has(\"--task-recovery\")\n\t\t\t\t\t\t\t? coordinator.inspectTaskRecovery(parsed.id ?? \"\")\n\t\t\t\t\t\t\t: coordinator.inspect(parsed.id ?? \"\");\n\t\t\t\tbreak;\n\t\t\tcase \"evidence\":\n\t\t\t\tresult = coordinator.evidence(parsed.id ?? \"\");\n\t\t\t\tbreak;\n\t\t\tcase \"artifact\": {\n\t\t\t\tconst candidate = required(parsed, \"--candidate\");\n\t\t\t\tconst path = required(parsed, \"--path\");\n\t\t\t\tconst bytes = coordinator.artifact(parsed.id ?? \"\", candidate, path);\n\t\t\t\tresult = {\n\t\t\t\t\tcandidateDigest: candidate,\n\t\t\t\t\tpath,\n\t\t\t\t\tdigest: digestBytes(bytes),\n\t\t\t\t\tbyteCount: bytes.length,\n\t\t\t\t\tencoding: \"base64\",\n\t\t\t\t\tdata: bytes.toString(\"base64\"),\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = parsed.action;\n\t\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t\t}\n\t\t}\n\t\tprocess.stdout.write(`${JSON.stringify(result)}\\n`);\n\t\treturn { handled: true, exitCode };\n\t} catch (error) {\n\t\tconst usage = error instanceof RunContractError || (error instanceof VerifiedRunError && error.code === \"usage\");\n\t\tconst message =\n\t\t\terror instanceof VerifiedRunError || error instanceof RunContractError\n\t\t\t\t? error.message\n\t\t\t\t: \"verified-run: operation_failed\";\n\t\tprocess.stderr.write(`${message}\\n${usage ? `${USAGE}\\n` : \"\"}`);\n\t\treturn { handled: true, exitCode: usage ? 2 : 1 };\n\t}\n}\n"]}
1
+ {"version":3,"file":"verified-run-cli.d.ts","sourceRoot":"","sources":["../../src/commands/verified-run-cli.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAgH/E,wBAAsB,iBAAiB,CACtC,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAoKnE","sourcesContent":["import { join } from \"node:path\";\nimport { parseRunContract, RunContractError, VERIFIED_COMMAND_VERSION } from \"omk-protocol\";\nimport { getAgentDir } from \"../config.ts\";\nimport { planVerifiedRun, RunCoordinator } from \"../core/verified-run/coordinator.ts\";\nimport { publishPolicyDigest } from \"../core/verified-run/run-publish.ts\";\nimport type { VerifiedRunRuntime } from \"../core/verified-run/session-port.ts\";\nimport { digestBytes, readJson, VerifiedRunError } from \"../core/verified-run/storage.ts\";\nimport { withRunSignal } from \"./verified-run-signal.ts\";\n\nconst USAGE = `Usage: omk run plan --contract FILE [--json]\n omk run start --contract FILE --approve DIGEST --command-id ID [--state-dir DIR]\n omk run inspect|evidence|status|events ID [--state-dir DIR] [--json]\n omk run authority [--state-dir DIR] [--json]\n omk run inspect ID --recovery|--writer-recovery|--task-recovery [--state-dir DIR]\n omk run retry-tasks ID --execute --tasks ID[,ID...]|- --approve DIGEST --base DIGEST --revision N --generation N --command-id ID [--state-dir DIR]\n omk run restart-writer ID --execute --approve DIGEST --base DIGEST --revision N --generation N --command-id ID [--state-dir DIR]\n omk run resume ID --execute --approve DIGEST --candidate DIGEST --revision N --generation N --command-id ID [--state-dir DIR]\n omk run publish ID --execute --contract FILE --approve DIGEST --candidate DIGEST --parent OID --receipt DIGEST --revision N --generation N --command-id ID [--state-dir DIR]\n omk run artifact ID --candidate DIGEST --path PATH [--state-dir DIR]\nThe opt-in command, scripted-agent and bounded command-DAG profiles never apply changes to the original workspace.\nResume rechecks a fixed candidate. Writer/task recovery preserves input checkpoints and budgets. Command-DAG concurrency defaults to 1 and supports an explicit cap of 2. Plan amendment, managed apply and TUI/RPC control are not implemented.`;\n\ninterface Parsed {\n\treadonly action:\n\t\t| \"plan\"\n\t\t| \"start\"\n\t\t| \"resume\"\n\t\t| \"restart-writer\"\n\t\t| \"retry-tasks\"\n\t\t| \"publish\"\n\t\t| \"inspect\"\n\t\t| \"status\"\n\t\t| \"events\"\n\t\t| \"authority\"\n\t\t| \"evidence\"\n\t\t| \"artifact\";\n\treadonly id: string | undefined;\n\treadonly flags: ReadonlyMap<string, string>;\n}\n\nfunction parse(args: readonly string[]): Parsed {\n\tconst action = args[1];\n\tif (\n\t\taction !== \"plan\" &&\n\t\taction !== \"start\" &&\n\t\taction !== \"resume\" &&\n\t\taction !== \"restart-writer\" &&\n\t\taction !== \"retry-tasks\" &&\n\t\taction !== \"publish\" &&\n\t\taction !== \"inspect\" &&\n\t\taction !== \"status\" &&\n\t\taction !== \"events\" &&\n\t\taction !== \"authority\" &&\n\t\taction !== \"evidence\" &&\n\t\taction !== \"artifact\"\n\t)\n\t\tthrow new VerifiedRunError(\"usage\");\n\tconst hasId = action !== \"plan\" && action !== \"start\" && action !== \"authority\";\n\tconst id = hasId ? args[2] : undefined;\n\tif (hasId && (!id || id.startsWith(\"--\"))) throw new VerifiedRunError(\"usage\");\n\tconst allowed =\n\t\taction === \"plan\"\n\t\t\t? [\"--contract\", \"--json\"]\n\t\t\t: action === \"start\"\n\t\t\t\t? [\"--contract\", \"--approve\", \"--command-id\", \"--state-dir\", \"--json\"]\n\t\t\t\t: action === \"resume\" || action === \"restart-writer\" || action === \"retry-tasks\"\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t\"--execute\",\n\t\t\t\t\t\t\t\"--approve\",\n\t\t\t\t\t\t\taction === \"resume\" ? \"--candidate\" : \"--base\",\n\t\t\t\t\t\t\t...(action === \"retry-tasks\" ? [\"--tasks\"] : []),\n\t\t\t\t\t\t\t\"--revision\",\n\t\t\t\t\t\t\t\"--generation\",\n\t\t\t\t\t\t\t\"--command-id\",\n\t\t\t\t\t\t\t\"--state-dir\",\n\t\t\t\t\t\t\t\"--json\",\n\t\t\t\t\t\t]\n\t\t\t\t\t: action === \"publish\"\n\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t\"--execute\",\n\t\t\t\t\t\t\t\t\"--contract\",\n\t\t\t\t\t\t\t\t\"--approve\",\n\t\t\t\t\t\t\t\t\"--candidate\",\n\t\t\t\t\t\t\t\t\"--parent\",\n\t\t\t\t\t\t\t\t\"--receipt\",\n\t\t\t\t\t\t\t\t\"--revision\",\n\t\t\t\t\t\t\t\t\"--generation\",\n\t\t\t\t\t\t\t\t\"--command-id\",\n\t\t\t\t\t\t\t\t\"--state-dir\",\n\t\t\t\t\t\t\t\t\"--json\",\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t: action === \"artifact\"\n\t\t\t\t\t\t\t? [\"--candidate\", \"--path\", \"--state-dir\", \"--json\"]\n\t\t\t\t\t\t\t: action === \"inspect\"\n\t\t\t\t\t\t\t\t? [\"--state-dir\", \"--json\", \"--recovery\", \"--writer-recovery\", \"--task-recovery\"]\n\t\t\t\t\t\t\t\t: [\"--state-dir\", \"--json\"];\n\tconst flags = new Map<string, string>();\n\tfor (let index = hasId ? 3 : 2; index < args.length; index++) {\n\t\tconst flag = args[index];\n\t\tif (!allowed.includes(flag) || flags.has(flag)) throw new VerifiedRunError(\"usage\");\n\t\tconst value = [\"--json\", \"--execute\", \"--recovery\", \"--writer-recovery\", \"--task-recovery\"].includes(flag)\n\t\t\t? \"true\"\n\t\t\t: args[++index];\n\t\tif (!value || value.startsWith(\"--\")) throw new VerifiedRunError(\"usage\");\n\t\tflags.set(flag, value);\n\t}\n\tif ([\"--recovery\", \"--writer-recovery\", \"--task-recovery\"].filter((flag) => flags.has(flag)).length > 1)\n\t\tthrow new VerifiedRunError(\"usage\");\n\treturn { action, id, flags };\n}\n\nfunction required(parsed: Parsed, name: string): string {\n\tconst value = parsed.flags.get(name);\n\tif (!value) throw new VerifiedRunError(\"usage\");\n\treturn value;\n}\n\nexport async function runVerifiedRunCli(\n\targs: string[],\n\truntime?: VerifiedRunRuntime,\n): Promise<{ readonly handled: boolean; readonly exitCode: number }> {\n\tif (args[0] !== \"run\") return { handled: false, exitCode: 0 };\n\tif (args.length === 2 && args[1] === \"--help\") {\n\t\tprocess.stdout.write(`${USAGE}\\n`);\n\t\treturn { handled: true, exitCode: 0 };\n\t}\n\ttry {\n\t\tconst parsed = parse(args);\n\t\tconst coordinator = new RunCoordinator(\n\t\t\tparsed.flags.get(\"--state-dir\") ?? join(getAgentDir(), \"verified-runs\"),\n\t\t\truntime,\n\t\t);\n\t\tlet result: unknown;\n\t\tlet exitCode = 0;\n\t\tswitch (parsed.action) {\n\t\t\tcase \"plan\":\n\t\t\t\tresult = planVerifiedRun(readJson(required(parsed, \"--contract\")));\n\t\t\t\tbreak;\n\t\t\tcase \"start\": {\n\t\t\t\tconst approvedContractDigest = required(parsed, \"--approve\");\n\t\t\t\tconst commandId = required(parsed, \"--command-id\");\n\t\t\t\tconst contract = parseRunContract(readJson(required(parsed, \"--contract\")));\n\t\t\t\tconst state = await withRunSignal((signal) =>\n\t\t\t\t\tcoordinator.start(\n\t\t\t\t\t\tcontract,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tschemaVersion: VERIFIED_COMMAND_VERSION,\n\t\t\t\t\t\t\tkind: \"start\",\n\t\t\t\t\t\t\trunId: contract.runId,\n\t\t\t\t\t\t\tcommandId,\n\t\t\t\t\t\t\texpectedRevision: 0,\n\t\t\t\t\t\t\texpectedGeneration: 0,\n\t\t\t\t\t\t\tcontractDigest: approvedContractDigest,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tresult = state;\n\t\t\t\texitCode = state.application === \"candidate_ready\" ? 0 : 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"resume\":\n\t\t\tcase \"retry-tasks\":\n\t\t\tcase \"restart-writer\": {\n\t\t\t\trequired(parsed, \"--execute\");\n\t\t\t\tconst approvedContractDigest = required(parsed, \"--approve\");\n\t\t\t\tconst request = {\n\t\t\t\t\tschemaVersion: VERIFIED_COMMAND_VERSION,\n\t\t\t\t\trunId: parsed.id ?? \"\",\n\t\t\t\t\tcommandId: required(parsed, \"--command-id\"),\n\t\t\t\t\texpectedRevision: Number(required(parsed, \"--revision\")),\n\t\t\t\t\texpectedGeneration: Number(required(parsed, \"--generation\")),\n\t\t\t\t\tcontractDigest: approvedContractDigest,\n\t\t\t\t};\n\t\t\t\tconst state = await withRunSignal((signal) =>\n\t\t\t\t\tparsed.action === \"retry-tasks\"\n\t\t\t\t\t\t? coordinator.retryTasks(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t...request,\n\t\t\t\t\t\t\t\t\tkind: \"retry_tasks\",\n\t\t\t\t\t\t\t\t\tbaseDigest: required(parsed, \"--base\"),\n\t\t\t\t\t\t\t\t\ttaskIds: required(parsed, \"--tasks\") === \"-\" ? [] : required(parsed, \"--tasks\").split(\",\"),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: parsed.action === \"resume\"\n\t\t\t\t\t\t\t? coordinator.resume(\n\t\t\t\t\t\t\t\t\t{ ...request, kind: \"resume\", candidateDigest: required(parsed, \"--candidate\") },\n\t\t\t\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: coordinator.restartWriter(\n\t\t\t\t\t\t\t\t\t{ ...request, kind: \"restart_writer\", baseDigest: required(parsed, \"--base\") },\n\t\t\t\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tresult = state;\n\t\t\t\texitCode = state.application === \"candidate_ready\" ? 0 : 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"publish\": {\n\t\t\t\trequired(parsed, \"--execute\");\n\t\t\t\tconst approvedContractDigest = required(parsed, \"--approve\");\n\t\t\t\tconst contract = parseRunContract(readJson(required(parsed, \"--contract\")));\n\t\t\t\tconst state = await withRunSignal((signal) =>\n\t\t\t\t\tcoordinator.publish(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tschemaVersion: VERIFIED_COMMAND_VERSION,\n\t\t\t\t\t\t\tkind: \"publish\",\n\t\t\t\t\t\t\trunId: parsed.id ?? \"\",\n\t\t\t\t\t\t\tcommandId: required(parsed, \"--command-id\"),\n\t\t\t\t\t\t\texpectedRevision: Number(required(parsed, \"--revision\")),\n\t\t\t\t\t\t\texpectedGeneration: Number(required(parsed, \"--generation\")),\n\t\t\t\t\t\t\tcontractDigest: approvedContractDigest,\n\t\t\t\t\t\t\tcandidateDigest: required(parsed, \"--candidate\"),\n\t\t\t\t\t\t\tparentOid: required(parsed, \"--parent\"),\n\t\t\t\t\t\t\treceiptDigest: required(parsed, \"--receipt\"),\n\t\t\t\t\t\t\tpolicyDigest: publishPolicyDigest(contract),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tresult = state;\n\t\t\t\texitCode = state.publication === \"accepted\" ? 0 : 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"inspect\":\n\t\t\t\tresult = parsed.flags.has(\"--recovery\")\n\t\t\t\t\t? coordinator.inspectRecovery(parsed.id ?? \"\")\n\t\t\t\t\t: parsed.flags.has(\"--writer-recovery\")\n\t\t\t\t\t\t? coordinator.inspectWriterRecovery(parsed.id ?? \"\")\n\t\t\t\t\t\t: parsed.flags.has(\"--task-recovery\")\n\t\t\t\t\t\t\t? coordinator.inspectTaskRecovery(parsed.id ?? \"\")\n\t\t\t\t\t\t\t: coordinator.inspect(parsed.id ?? \"\");\n\t\t\t\tbreak;\n\t\t\tcase \"status\": {\n\t\t\t\tconst status = coordinator.status(parsed.id ?? \"\");\n\t\t\t\tresult = status;\n\t\t\t\t// Same truth the start/publish exit codes encode: a recovered,\n\t\t\t\t// quarantined or unverified run is never a clean exit 0.\n\t\t\t\texitCode = status.cleanSuccess ? 0 : 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"events\":\n\t\t\t\tresult = coordinator.events(parsed.id ?? \"\");\n\t\t\t\tbreak;\n\t\t\tcase \"authority\":\n\t\t\t\tresult = coordinator.inspectAuthority();\n\t\t\t\tbreak;\n\t\t\tcase \"evidence\": {\n\t\t\t\tconst projection = coordinator.evidenceRead(parsed.id ?? \"\");\n\t\t\t\tresult = { ...projection.evidence, ...projection };\n\t\t\t\texitCode = projection.authenticity === \"valid\" && projection.verification === \"passed\" ? 0 : 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"artifact\": {\n\t\t\t\tconst candidate = required(parsed, \"--candidate\");\n\t\t\t\tconst path = required(parsed, \"--path\");\n\t\t\t\tconst bytes = coordinator.artifact(parsed.id ?? \"\", candidate, path);\n\t\t\t\tresult = {\n\t\t\t\t\tcandidateDigest: candidate,\n\t\t\t\t\tpath,\n\t\t\t\t\tdigest: digestBytes(bytes),\n\t\t\t\t\tbyteCount: bytes.length,\n\t\t\t\t\tencoding: \"base64\",\n\t\t\t\t\tdata: bytes.toString(\"base64\"),\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = parsed.action;\n\t\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t\t}\n\t\t}\n\t\tprocess.stdout.write(`${JSON.stringify(result)}\\n`);\n\t\treturn { handled: true, exitCode };\n\t} catch (error) {\n\t\tconst usage = error instanceof RunContractError || (error instanceof VerifiedRunError && error.code === \"usage\");\n\t\tconst message =\n\t\t\terror instanceof VerifiedRunError || error instanceof RunContractError\n\t\t\t\t? error.message\n\t\t\t\t: \"verified-run: operation_failed\";\n\t\tprocess.stderr.write(`${message}\\n${usage ? `${USAGE}\\n` : \"\"}`);\n\t\treturn { handled: true, exitCode: usage ? 2 : 1 };\n\t}\n}\n"]}
@@ -2,14 +2,18 @@ import { join } from "node:path";
2
2
  import { parseRunContract, RunContractError, VERIFIED_COMMAND_VERSION } from "omk-protocol";
3
3
  import { getAgentDir } from "../config.js";
4
4
  import { planVerifiedRun, RunCoordinator } from "../core/verified-run/coordinator.js";
5
+ import { publishPolicyDigest } from "../core/verified-run/run-publish.js";
5
6
  import { digestBytes, readJson, VerifiedRunError } from "../core/verified-run/storage.js";
7
+ import { withRunSignal } from "./verified-run-signal.js";
6
8
  const USAGE = `Usage: omk run plan --contract FILE [--json]
7
9
  omk run start --contract FILE --approve DIGEST --command-id ID [--state-dir DIR]
8
- omk run inspect|evidence ID [--state-dir DIR] [--json]
10
+ omk run inspect|evidence|status|events ID [--state-dir DIR] [--json]
11
+ omk run authority [--state-dir DIR] [--json]
9
12
  omk run inspect ID --recovery|--writer-recovery|--task-recovery [--state-dir DIR]
10
13
  omk run retry-tasks ID --execute --tasks ID[,ID...]|- --approve DIGEST --base DIGEST --revision N --generation N --command-id ID [--state-dir DIR]
11
14
  omk run restart-writer ID --execute --approve DIGEST --base DIGEST --revision N --generation N --command-id ID [--state-dir DIR]
12
15
  omk run resume ID --execute --approve DIGEST --candidate DIGEST --revision N --generation N --command-id ID [--state-dir DIR]
16
+ omk run publish ID --execute --contract FILE --approve DIGEST --candidate DIGEST --parent OID --receipt DIGEST --revision N --generation N --command-id ID [--state-dir DIR]
13
17
  omk run artifact ID --candidate DIGEST --path PATH [--state-dir DIR]
14
18
  The opt-in command, scripted-agent and bounded command-DAG profiles never apply changes to the original workspace.
15
19
  Resume rechecks a fixed candidate. Writer/task recovery preserves input checkpoints and budgets. Command-DAG concurrency defaults to 1 and supports an explicit cap of 2. Plan amendment, managed apply and TUI/RPC control are not implemented.`;
@@ -20,11 +24,15 @@ function parse(args) {
20
24
  action !== "resume" &&
21
25
  action !== "restart-writer" &&
22
26
  action !== "retry-tasks" &&
27
+ action !== "publish" &&
23
28
  action !== "inspect" &&
29
+ action !== "status" &&
30
+ action !== "events" &&
31
+ action !== "authority" &&
24
32
  action !== "evidence" &&
25
33
  action !== "artifact")
26
34
  throw new VerifiedRunError("usage");
27
- const hasId = action !== "plan" && action !== "start";
35
+ const hasId = action !== "plan" && action !== "start" && action !== "authority";
28
36
  const id = hasId ? args[2] : undefined;
29
37
  if (hasId && (!id || id.startsWith("--")))
30
38
  throw new VerifiedRunError("usage");
@@ -44,11 +52,25 @@ function parse(args) {
44
52
  "--state-dir",
45
53
  "--json",
46
54
  ]
47
- : action === "artifact"
48
- ? ["--candidate", "--path", "--state-dir", "--json"]
49
- : action === "inspect"
50
- ? ["--state-dir", "--json", "--recovery", "--writer-recovery", "--task-recovery"]
51
- : ["--state-dir", "--json"];
55
+ : action === "publish"
56
+ ? [
57
+ "--execute",
58
+ "--contract",
59
+ "--approve",
60
+ "--candidate",
61
+ "--parent",
62
+ "--receipt",
63
+ "--revision",
64
+ "--generation",
65
+ "--command-id",
66
+ "--state-dir",
67
+ "--json",
68
+ ]
69
+ : action === "artifact"
70
+ ? ["--candidate", "--path", "--state-dir", "--json"]
71
+ : action === "inspect"
72
+ ? ["--state-dir", "--json", "--recovery", "--writer-recovery", "--task-recovery"]
73
+ : ["--state-dir", "--json"];
52
74
  const flags = new Map();
53
75
  for (let index = hasId ? 3 : 2; index < args.length; index++) {
54
76
  const flag = args[index];
@@ -71,19 +93,6 @@ function required(parsed, name) {
71
93
  throw new VerifiedRunError("usage");
72
94
  return value;
73
95
  }
74
- async function withRunSignal(run) {
75
- const controller = new AbortController();
76
- const cancel = () => controller.abort();
77
- process.once("SIGINT", cancel);
78
- process.once("SIGTERM", cancel);
79
- try {
80
- return await run(controller.signal);
81
- }
82
- finally {
83
- process.off("SIGINT", cancel);
84
- process.off("SIGTERM", cancel);
85
- }
86
- }
87
96
  export async function runVerifiedRunCli(args, runtime) {
88
97
  if (args[0] !== "run")
89
98
  return { handled: false, exitCode: 0 };
@@ -144,6 +153,27 @@ export async function runVerifiedRunCli(args, runtime) {
144
153
  exitCode = state.application === "candidate_ready" ? 0 : 1;
145
154
  break;
146
155
  }
156
+ case "publish": {
157
+ required(parsed, "--execute");
158
+ const approvedContractDigest = required(parsed, "--approve");
159
+ const contract = parseRunContract(readJson(required(parsed, "--contract")));
160
+ const state = await withRunSignal((signal) => coordinator.publish({
161
+ schemaVersion: VERIFIED_COMMAND_VERSION,
162
+ kind: "publish",
163
+ runId: parsed.id ?? "",
164
+ commandId: required(parsed, "--command-id"),
165
+ expectedRevision: Number(required(parsed, "--revision")),
166
+ expectedGeneration: Number(required(parsed, "--generation")),
167
+ contractDigest: approvedContractDigest,
168
+ candidateDigest: required(parsed, "--candidate"),
169
+ parentOid: required(parsed, "--parent"),
170
+ receiptDigest: required(parsed, "--receipt"),
171
+ policyDigest: publishPolicyDigest(contract),
172
+ }, { approvedContractDigest, signal }));
173
+ result = state;
174
+ exitCode = state.publication === "accepted" ? 0 : 1;
175
+ break;
176
+ }
147
177
  case "inspect":
148
178
  result = parsed.flags.has("--recovery")
149
179
  ? coordinator.inspectRecovery(parsed.id ?? "")
@@ -153,9 +183,26 @@ export async function runVerifiedRunCli(args, runtime) {
153
183
  ? coordinator.inspectTaskRecovery(parsed.id ?? "")
154
184
  : coordinator.inspect(parsed.id ?? "");
155
185
  break;
156
- case "evidence":
157
- result = coordinator.evidence(parsed.id ?? "");
186
+ case "status": {
187
+ const status = coordinator.status(parsed.id ?? "");
188
+ result = status;
189
+ // Same truth the start/publish exit codes encode: a recovered,
190
+ // quarantined or unverified run is never a clean exit 0.
191
+ exitCode = status.cleanSuccess ? 0 : 1;
158
192
  break;
193
+ }
194
+ case "events":
195
+ result = coordinator.events(parsed.id ?? "");
196
+ break;
197
+ case "authority":
198
+ result = coordinator.inspectAuthority();
199
+ break;
200
+ case "evidence": {
201
+ const projection = coordinator.evidenceRead(parsed.id ?? "");
202
+ result = { ...projection.evidence, ...projection };
203
+ exitCode = projection.authenticity === "valid" && projection.verification === "passed" ? 0 : 1;
204
+ break;
205
+ }
159
206
  case "artifact": {
160
207
  const candidate = required(parsed, "--candidate");
161
208
  const path = required(parsed, "--path");
@@ -1 +1 @@
1
- {"version":3,"file":"verified-run-cli.js","sourceRoot":"","sources":["../../src/commands/verified-run-cli.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { parseRunContract, RunContractError, VERIFIED_COMMAND_VERSION } from \"omk-protocol\";\nimport { getAgentDir } from \"../config.ts\";\nimport { planVerifiedRun, RunCoordinator } from \"../core/verified-run/coordinator.ts\";\nimport type { VerifiedRunRuntime } from \"../core/verified-run/session-port.ts\";\nimport { digestBytes, readJson, VerifiedRunError } from \"../core/verified-run/storage.ts\";\n\nconst USAGE = `Usage: omk run plan --contract FILE [--json]\n omk run start --contract FILE --approve DIGEST --command-id ID [--state-dir DIR]\n omk run inspect|evidence ID [--state-dir DIR] [--json]\n omk run inspect ID --recovery|--writer-recovery|--task-recovery [--state-dir DIR]\n omk run retry-tasks ID --execute --tasks ID[,ID...]|- --approve DIGEST --base DIGEST --revision N --generation N --command-id ID [--state-dir DIR]\n omk run restart-writer ID --execute --approve DIGEST --base DIGEST --revision N --generation N --command-id ID [--state-dir DIR]\n omk run resume ID --execute --approve DIGEST --candidate DIGEST --revision N --generation N --command-id ID [--state-dir DIR]\n omk run artifact ID --candidate DIGEST --path PATH [--state-dir DIR]\nThe opt-in command, scripted-agent and bounded command-DAG profiles never apply changes to the original workspace.\nResume rechecks a fixed candidate. Writer/task recovery preserves input checkpoints and budgets. Command-DAG concurrency defaults to 1 and supports an explicit cap of 2. Plan amendment, managed apply and TUI/RPC control are not implemented.`;\n\ninterface Parsed {\n\treadonly action:\n\t\t| \"plan\"\n\t\t| \"start\"\n\t\t| \"resume\"\n\t\t| \"restart-writer\"\n\t\t| \"retry-tasks\"\n\t\t| \"inspect\"\n\t\t| \"evidence\"\n\t\t| \"artifact\";\n\treadonly id: string | undefined;\n\treadonly flags: ReadonlyMap<string, string>;\n}\n\nfunction parse(args: readonly string[]): Parsed {\n\tconst action = args[1];\n\tif (\n\t\taction !== \"plan\" &&\n\t\taction !== \"start\" &&\n\t\taction !== \"resume\" &&\n\t\taction !== \"restart-writer\" &&\n\t\taction !== \"retry-tasks\" &&\n\t\taction !== \"inspect\" &&\n\t\taction !== \"evidence\" &&\n\t\taction !== \"artifact\"\n\t)\n\t\tthrow new VerifiedRunError(\"usage\");\n\tconst hasId = action !== \"plan\" && action !== \"start\";\n\tconst id = hasId ? args[2] : undefined;\n\tif (hasId && (!id || id.startsWith(\"--\"))) throw new VerifiedRunError(\"usage\");\n\tconst allowed =\n\t\taction === \"plan\"\n\t\t\t? [\"--contract\", \"--json\"]\n\t\t\t: action === \"start\"\n\t\t\t\t? [\"--contract\", \"--approve\", \"--command-id\", \"--state-dir\", \"--json\"]\n\t\t\t\t: action === \"resume\" || action === \"restart-writer\" || action === \"retry-tasks\"\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t\"--execute\",\n\t\t\t\t\t\t\t\"--approve\",\n\t\t\t\t\t\t\taction === \"resume\" ? \"--candidate\" : \"--base\",\n\t\t\t\t\t\t\t...(action === \"retry-tasks\" ? [\"--tasks\"] : []),\n\t\t\t\t\t\t\t\"--revision\",\n\t\t\t\t\t\t\t\"--generation\",\n\t\t\t\t\t\t\t\"--command-id\",\n\t\t\t\t\t\t\t\"--state-dir\",\n\t\t\t\t\t\t\t\"--json\",\n\t\t\t\t\t\t]\n\t\t\t\t\t: action === \"artifact\"\n\t\t\t\t\t\t? [\"--candidate\", \"--path\", \"--state-dir\", \"--json\"]\n\t\t\t\t\t\t: action === \"inspect\"\n\t\t\t\t\t\t\t? [\"--state-dir\", \"--json\", \"--recovery\", \"--writer-recovery\", \"--task-recovery\"]\n\t\t\t\t\t\t\t: [\"--state-dir\", \"--json\"];\n\tconst flags = new Map<string, string>();\n\tfor (let index = hasId ? 3 : 2; index < args.length; index++) {\n\t\tconst flag = args[index];\n\t\tif (!allowed.includes(flag) || flags.has(flag)) throw new VerifiedRunError(\"usage\");\n\t\tconst value = [\"--json\", \"--execute\", \"--recovery\", \"--writer-recovery\", \"--task-recovery\"].includes(flag)\n\t\t\t? \"true\"\n\t\t\t: args[++index];\n\t\tif (!value || value.startsWith(\"--\")) throw new VerifiedRunError(\"usage\");\n\t\tflags.set(flag, value);\n\t}\n\tif ([\"--recovery\", \"--writer-recovery\", \"--task-recovery\"].filter((flag) => flags.has(flag)).length > 1)\n\t\tthrow new VerifiedRunError(\"usage\");\n\treturn { action, id, flags };\n}\n\nfunction required(parsed: Parsed, name: string): string {\n\tconst value = parsed.flags.get(name);\n\tif (!value) throw new VerifiedRunError(\"usage\");\n\treturn value;\n}\n\nasync function withRunSignal<T>(run: (signal: AbortSignal) => Promise<T>): Promise<T> {\n\tconst controller = new AbortController();\n\tconst cancel = (): void => controller.abort();\n\tprocess.once(\"SIGINT\", cancel);\n\tprocess.once(\"SIGTERM\", cancel);\n\ttry {\n\t\treturn await run(controller.signal);\n\t} finally {\n\t\tprocess.off(\"SIGINT\", cancel);\n\t\tprocess.off(\"SIGTERM\", cancel);\n\t}\n}\n\nexport async function runVerifiedRunCli(\n\targs: string[],\n\truntime?: VerifiedRunRuntime,\n): Promise<{ readonly handled: boolean; readonly exitCode: number }> {\n\tif (args[0] !== \"run\") return { handled: false, exitCode: 0 };\n\tif (args.length === 2 && args[1] === \"--help\") {\n\t\tprocess.stdout.write(`${USAGE}\\n`);\n\t\treturn { handled: true, exitCode: 0 };\n\t}\n\ttry {\n\t\tconst parsed = parse(args);\n\t\tconst coordinator = new RunCoordinator(\n\t\t\tparsed.flags.get(\"--state-dir\") ?? join(getAgentDir(), \"verified-runs\"),\n\t\t\truntime,\n\t\t);\n\t\tlet result: unknown;\n\t\tlet exitCode = 0;\n\t\tswitch (parsed.action) {\n\t\t\tcase \"plan\":\n\t\t\t\tresult = planVerifiedRun(readJson(required(parsed, \"--contract\")));\n\t\t\t\tbreak;\n\t\t\tcase \"start\": {\n\t\t\t\tconst approvedContractDigest = required(parsed, \"--approve\");\n\t\t\t\tconst commandId = required(parsed, \"--command-id\");\n\t\t\t\tconst contract = parseRunContract(readJson(required(parsed, \"--contract\")));\n\t\t\t\tconst state = await withRunSignal((signal) =>\n\t\t\t\t\tcoordinator.start(\n\t\t\t\t\t\tcontract,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tschemaVersion: VERIFIED_COMMAND_VERSION,\n\t\t\t\t\t\t\tkind: \"start\",\n\t\t\t\t\t\t\trunId: contract.runId,\n\t\t\t\t\t\t\tcommandId,\n\t\t\t\t\t\t\texpectedRevision: 0,\n\t\t\t\t\t\t\texpectedGeneration: 0,\n\t\t\t\t\t\t\tcontractDigest: approvedContractDigest,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tresult = state;\n\t\t\t\texitCode = state.application === \"candidate_ready\" ? 0 : 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"resume\":\n\t\t\tcase \"retry-tasks\":\n\t\t\tcase \"restart-writer\": {\n\t\t\t\trequired(parsed, \"--execute\");\n\t\t\t\tconst approvedContractDigest = required(parsed, \"--approve\");\n\t\t\t\tconst request = {\n\t\t\t\t\tschemaVersion: VERIFIED_COMMAND_VERSION,\n\t\t\t\t\trunId: parsed.id ?? \"\",\n\t\t\t\t\tcommandId: required(parsed, \"--command-id\"),\n\t\t\t\t\texpectedRevision: Number(required(parsed, \"--revision\")),\n\t\t\t\t\texpectedGeneration: Number(required(parsed, \"--generation\")),\n\t\t\t\t\tcontractDigest: approvedContractDigest,\n\t\t\t\t};\n\t\t\t\tconst state = await withRunSignal((signal) =>\n\t\t\t\t\tparsed.action === \"retry-tasks\"\n\t\t\t\t\t\t? coordinator.retryTasks(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t...request,\n\t\t\t\t\t\t\t\t\tkind: \"retry_tasks\",\n\t\t\t\t\t\t\t\t\tbaseDigest: required(parsed, \"--base\"),\n\t\t\t\t\t\t\t\t\ttaskIds: required(parsed, \"--tasks\") === \"-\" ? [] : required(parsed, \"--tasks\").split(\",\"),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: parsed.action === \"resume\"\n\t\t\t\t\t\t\t? coordinator.resume(\n\t\t\t\t\t\t\t\t\t{ ...request, kind: \"resume\", candidateDigest: required(parsed, \"--candidate\") },\n\t\t\t\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: coordinator.restartWriter(\n\t\t\t\t\t\t\t\t\t{ ...request, kind: \"restart_writer\", baseDigest: required(parsed, \"--base\") },\n\t\t\t\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tresult = state;\n\t\t\t\texitCode = state.application === \"candidate_ready\" ? 0 : 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"inspect\":\n\t\t\t\tresult = parsed.flags.has(\"--recovery\")\n\t\t\t\t\t? coordinator.inspectRecovery(parsed.id ?? \"\")\n\t\t\t\t\t: parsed.flags.has(\"--writer-recovery\")\n\t\t\t\t\t\t? coordinator.inspectWriterRecovery(parsed.id ?? \"\")\n\t\t\t\t\t\t: parsed.flags.has(\"--task-recovery\")\n\t\t\t\t\t\t\t? coordinator.inspectTaskRecovery(parsed.id ?? \"\")\n\t\t\t\t\t\t\t: coordinator.inspect(parsed.id ?? \"\");\n\t\t\t\tbreak;\n\t\t\tcase \"evidence\":\n\t\t\t\tresult = coordinator.evidence(parsed.id ?? \"\");\n\t\t\t\tbreak;\n\t\t\tcase \"artifact\": {\n\t\t\t\tconst candidate = required(parsed, \"--candidate\");\n\t\t\t\tconst path = required(parsed, \"--path\");\n\t\t\t\tconst bytes = coordinator.artifact(parsed.id ?? \"\", candidate, path);\n\t\t\t\tresult = {\n\t\t\t\t\tcandidateDigest: candidate,\n\t\t\t\t\tpath,\n\t\t\t\t\tdigest: digestBytes(bytes),\n\t\t\t\t\tbyteCount: bytes.length,\n\t\t\t\t\tencoding: \"base64\",\n\t\t\t\t\tdata: bytes.toString(\"base64\"),\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = parsed.action;\n\t\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t\t}\n\t\t}\n\t\tprocess.stdout.write(`${JSON.stringify(result)}\\n`);\n\t\treturn { handled: true, exitCode };\n\t} catch (error) {\n\t\tconst usage = error instanceof RunContractError || (error instanceof VerifiedRunError && error.code === \"usage\");\n\t\tconst message =\n\t\t\terror instanceof VerifiedRunError || error instanceof RunContractError\n\t\t\t\t? error.message\n\t\t\t\t: \"verified-run: operation_failed\";\n\t\tprocess.stderr.write(`${message}\\n${usage ? `${USAGE}\\n` : \"\"}`);\n\t\treturn { handled: true, exitCode: usage ? 2 : 1 };\n\t}\n}\n"]}
1
+ {"version":3,"file":"verified-run-cli.js","sourceRoot":"","sources":["../../src/commands/verified-run-cli.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { parseRunContract, RunContractError, VERIFIED_COMMAND_VERSION } from \"omk-protocol\";\nimport { getAgentDir } from \"../config.ts\";\nimport { planVerifiedRun, RunCoordinator } from \"../core/verified-run/coordinator.ts\";\nimport { publishPolicyDigest } from \"../core/verified-run/run-publish.ts\";\nimport type { VerifiedRunRuntime } from \"../core/verified-run/session-port.ts\";\nimport { digestBytes, readJson, VerifiedRunError } from \"../core/verified-run/storage.ts\";\nimport { withRunSignal } from \"./verified-run-signal.ts\";\n\nconst USAGE = `Usage: omk run plan --contract FILE [--json]\n omk run start --contract FILE --approve DIGEST --command-id ID [--state-dir DIR]\n omk run inspect|evidence|status|events ID [--state-dir DIR] [--json]\n omk run authority [--state-dir DIR] [--json]\n omk run inspect ID --recovery|--writer-recovery|--task-recovery [--state-dir DIR]\n omk run retry-tasks ID --execute --tasks ID[,ID...]|- --approve DIGEST --base DIGEST --revision N --generation N --command-id ID [--state-dir DIR]\n omk run restart-writer ID --execute --approve DIGEST --base DIGEST --revision N --generation N --command-id ID [--state-dir DIR]\n omk run resume ID --execute --approve DIGEST --candidate DIGEST --revision N --generation N --command-id ID [--state-dir DIR]\n omk run publish ID --execute --contract FILE --approve DIGEST --candidate DIGEST --parent OID --receipt DIGEST --revision N --generation N --command-id ID [--state-dir DIR]\n omk run artifact ID --candidate DIGEST --path PATH [--state-dir DIR]\nThe opt-in command, scripted-agent and bounded command-DAG profiles never apply changes to the original workspace.\nResume rechecks a fixed candidate. Writer/task recovery preserves input checkpoints and budgets. Command-DAG concurrency defaults to 1 and supports an explicit cap of 2. Plan amendment, managed apply and TUI/RPC control are not implemented.`;\n\ninterface Parsed {\n\treadonly action:\n\t\t| \"plan\"\n\t\t| \"start\"\n\t\t| \"resume\"\n\t\t| \"restart-writer\"\n\t\t| \"retry-tasks\"\n\t\t| \"publish\"\n\t\t| \"inspect\"\n\t\t| \"status\"\n\t\t| \"events\"\n\t\t| \"authority\"\n\t\t| \"evidence\"\n\t\t| \"artifact\";\n\treadonly id: string | undefined;\n\treadonly flags: ReadonlyMap<string, string>;\n}\n\nfunction parse(args: readonly string[]): Parsed {\n\tconst action = args[1];\n\tif (\n\t\taction !== \"plan\" &&\n\t\taction !== \"start\" &&\n\t\taction !== \"resume\" &&\n\t\taction !== \"restart-writer\" &&\n\t\taction !== \"retry-tasks\" &&\n\t\taction !== \"publish\" &&\n\t\taction !== \"inspect\" &&\n\t\taction !== \"status\" &&\n\t\taction !== \"events\" &&\n\t\taction !== \"authority\" &&\n\t\taction !== \"evidence\" &&\n\t\taction !== \"artifact\"\n\t)\n\t\tthrow new VerifiedRunError(\"usage\");\n\tconst hasId = action !== \"plan\" && action !== \"start\" && action !== \"authority\";\n\tconst id = hasId ? args[2] : undefined;\n\tif (hasId && (!id || id.startsWith(\"--\"))) throw new VerifiedRunError(\"usage\");\n\tconst allowed =\n\t\taction === \"plan\"\n\t\t\t? [\"--contract\", \"--json\"]\n\t\t\t: action === \"start\"\n\t\t\t\t? [\"--contract\", \"--approve\", \"--command-id\", \"--state-dir\", \"--json\"]\n\t\t\t\t: action === \"resume\" || action === \"restart-writer\" || action === \"retry-tasks\"\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t\"--execute\",\n\t\t\t\t\t\t\t\"--approve\",\n\t\t\t\t\t\t\taction === \"resume\" ? \"--candidate\" : \"--base\",\n\t\t\t\t\t\t\t...(action === \"retry-tasks\" ? [\"--tasks\"] : []),\n\t\t\t\t\t\t\t\"--revision\",\n\t\t\t\t\t\t\t\"--generation\",\n\t\t\t\t\t\t\t\"--command-id\",\n\t\t\t\t\t\t\t\"--state-dir\",\n\t\t\t\t\t\t\t\"--json\",\n\t\t\t\t\t\t]\n\t\t\t\t\t: action === \"publish\"\n\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t\"--execute\",\n\t\t\t\t\t\t\t\t\"--contract\",\n\t\t\t\t\t\t\t\t\"--approve\",\n\t\t\t\t\t\t\t\t\"--candidate\",\n\t\t\t\t\t\t\t\t\"--parent\",\n\t\t\t\t\t\t\t\t\"--receipt\",\n\t\t\t\t\t\t\t\t\"--revision\",\n\t\t\t\t\t\t\t\t\"--generation\",\n\t\t\t\t\t\t\t\t\"--command-id\",\n\t\t\t\t\t\t\t\t\"--state-dir\",\n\t\t\t\t\t\t\t\t\"--json\",\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t: action === \"artifact\"\n\t\t\t\t\t\t\t? [\"--candidate\", \"--path\", \"--state-dir\", \"--json\"]\n\t\t\t\t\t\t\t: action === \"inspect\"\n\t\t\t\t\t\t\t\t? [\"--state-dir\", \"--json\", \"--recovery\", \"--writer-recovery\", \"--task-recovery\"]\n\t\t\t\t\t\t\t\t: [\"--state-dir\", \"--json\"];\n\tconst flags = new Map<string, string>();\n\tfor (let index = hasId ? 3 : 2; index < args.length; index++) {\n\t\tconst flag = args[index];\n\t\tif (!allowed.includes(flag) || flags.has(flag)) throw new VerifiedRunError(\"usage\");\n\t\tconst value = [\"--json\", \"--execute\", \"--recovery\", \"--writer-recovery\", \"--task-recovery\"].includes(flag)\n\t\t\t? \"true\"\n\t\t\t: args[++index];\n\t\tif (!value || value.startsWith(\"--\")) throw new VerifiedRunError(\"usage\");\n\t\tflags.set(flag, value);\n\t}\n\tif ([\"--recovery\", \"--writer-recovery\", \"--task-recovery\"].filter((flag) => flags.has(flag)).length > 1)\n\t\tthrow new VerifiedRunError(\"usage\");\n\treturn { action, id, flags };\n}\n\nfunction required(parsed: Parsed, name: string): string {\n\tconst value = parsed.flags.get(name);\n\tif (!value) throw new VerifiedRunError(\"usage\");\n\treturn value;\n}\n\nexport async function runVerifiedRunCli(\n\targs: string[],\n\truntime?: VerifiedRunRuntime,\n): Promise<{ readonly handled: boolean; readonly exitCode: number }> {\n\tif (args[0] !== \"run\") return { handled: false, exitCode: 0 };\n\tif (args.length === 2 && args[1] === \"--help\") {\n\t\tprocess.stdout.write(`${USAGE}\\n`);\n\t\treturn { handled: true, exitCode: 0 };\n\t}\n\ttry {\n\t\tconst parsed = parse(args);\n\t\tconst coordinator = new RunCoordinator(\n\t\t\tparsed.flags.get(\"--state-dir\") ?? join(getAgentDir(), \"verified-runs\"),\n\t\t\truntime,\n\t\t);\n\t\tlet result: unknown;\n\t\tlet exitCode = 0;\n\t\tswitch (parsed.action) {\n\t\t\tcase \"plan\":\n\t\t\t\tresult = planVerifiedRun(readJson(required(parsed, \"--contract\")));\n\t\t\t\tbreak;\n\t\t\tcase \"start\": {\n\t\t\t\tconst approvedContractDigest = required(parsed, \"--approve\");\n\t\t\t\tconst commandId = required(parsed, \"--command-id\");\n\t\t\t\tconst contract = parseRunContract(readJson(required(parsed, \"--contract\")));\n\t\t\t\tconst state = await withRunSignal((signal) =>\n\t\t\t\t\tcoordinator.start(\n\t\t\t\t\t\tcontract,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tschemaVersion: VERIFIED_COMMAND_VERSION,\n\t\t\t\t\t\t\tkind: \"start\",\n\t\t\t\t\t\t\trunId: contract.runId,\n\t\t\t\t\t\t\tcommandId,\n\t\t\t\t\t\t\texpectedRevision: 0,\n\t\t\t\t\t\t\texpectedGeneration: 0,\n\t\t\t\t\t\t\tcontractDigest: approvedContractDigest,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tresult = state;\n\t\t\t\texitCode = state.application === \"candidate_ready\" ? 0 : 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"resume\":\n\t\t\tcase \"retry-tasks\":\n\t\t\tcase \"restart-writer\": {\n\t\t\t\trequired(parsed, \"--execute\");\n\t\t\t\tconst approvedContractDigest = required(parsed, \"--approve\");\n\t\t\t\tconst request = {\n\t\t\t\t\tschemaVersion: VERIFIED_COMMAND_VERSION,\n\t\t\t\t\trunId: parsed.id ?? \"\",\n\t\t\t\t\tcommandId: required(parsed, \"--command-id\"),\n\t\t\t\t\texpectedRevision: Number(required(parsed, \"--revision\")),\n\t\t\t\t\texpectedGeneration: Number(required(parsed, \"--generation\")),\n\t\t\t\t\tcontractDigest: approvedContractDigest,\n\t\t\t\t};\n\t\t\t\tconst state = await withRunSignal((signal) =>\n\t\t\t\t\tparsed.action === \"retry-tasks\"\n\t\t\t\t\t\t? coordinator.retryTasks(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t...request,\n\t\t\t\t\t\t\t\t\tkind: \"retry_tasks\",\n\t\t\t\t\t\t\t\t\tbaseDigest: required(parsed, \"--base\"),\n\t\t\t\t\t\t\t\t\ttaskIds: required(parsed, \"--tasks\") === \"-\" ? [] : required(parsed, \"--tasks\").split(\",\"),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: parsed.action === \"resume\"\n\t\t\t\t\t\t\t? coordinator.resume(\n\t\t\t\t\t\t\t\t\t{ ...request, kind: \"resume\", candidateDigest: required(parsed, \"--candidate\") },\n\t\t\t\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: coordinator.restartWriter(\n\t\t\t\t\t\t\t\t\t{ ...request, kind: \"restart_writer\", baseDigest: required(parsed, \"--base\") },\n\t\t\t\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tresult = state;\n\t\t\t\texitCode = state.application === \"candidate_ready\" ? 0 : 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"publish\": {\n\t\t\t\trequired(parsed, \"--execute\");\n\t\t\t\tconst approvedContractDigest = required(parsed, \"--approve\");\n\t\t\t\tconst contract = parseRunContract(readJson(required(parsed, \"--contract\")));\n\t\t\t\tconst state = await withRunSignal((signal) =>\n\t\t\t\t\tcoordinator.publish(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tschemaVersion: VERIFIED_COMMAND_VERSION,\n\t\t\t\t\t\t\tkind: \"publish\",\n\t\t\t\t\t\t\trunId: parsed.id ?? \"\",\n\t\t\t\t\t\t\tcommandId: required(parsed, \"--command-id\"),\n\t\t\t\t\t\t\texpectedRevision: Number(required(parsed, \"--revision\")),\n\t\t\t\t\t\t\texpectedGeneration: Number(required(parsed, \"--generation\")),\n\t\t\t\t\t\t\tcontractDigest: approvedContractDigest,\n\t\t\t\t\t\t\tcandidateDigest: required(parsed, \"--candidate\"),\n\t\t\t\t\t\t\tparentOid: required(parsed, \"--parent\"),\n\t\t\t\t\t\t\treceiptDigest: required(parsed, \"--receipt\"),\n\t\t\t\t\t\t\tpolicyDigest: publishPolicyDigest(contract),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ approvedContractDigest, signal },\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tresult = state;\n\t\t\t\texitCode = state.publication === \"accepted\" ? 0 : 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"inspect\":\n\t\t\t\tresult = parsed.flags.has(\"--recovery\")\n\t\t\t\t\t? coordinator.inspectRecovery(parsed.id ?? \"\")\n\t\t\t\t\t: parsed.flags.has(\"--writer-recovery\")\n\t\t\t\t\t\t? coordinator.inspectWriterRecovery(parsed.id ?? \"\")\n\t\t\t\t\t\t: parsed.flags.has(\"--task-recovery\")\n\t\t\t\t\t\t\t? coordinator.inspectTaskRecovery(parsed.id ?? \"\")\n\t\t\t\t\t\t\t: coordinator.inspect(parsed.id ?? \"\");\n\t\t\t\tbreak;\n\t\t\tcase \"status\": {\n\t\t\t\tconst status = coordinator.status(parsed.id ?? \"\");\n\t\t\t\tresult = status;\n\t\t\t\t// Same truth the start/publish exit codes encode: a recovered,\n\t\t\t\t// quarantined or unverified run is never a clean exit 0.\n\t\t\t\texitCode = status.cleanSuccess ? 0 : 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"events\":\n\t\t\t\tresult = coordinator.events(parsed.id ?? \"\");\n\t\t\t\tbreak;\n\t\t\tcase \"authority\":\n\t\t\t\tresult = coordinator.inspectAuthority();\n\t\t\t\tbreak;\n\t\t\tcase \"evidence\": {\n\t\t\t\tconst projection = coordinator.evidenceRead(parsed.id ?? \"\");\n\t\t\t\tresult = { ...projection.evidence, ...projection };\n\t\t\t\texitCode = projection.authenticity === \"valid\" && projection.verification === \"passed\" ? 0 : 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"artifact\": {\n\t\t\t\tconst candidate = required(parsed, \"--candidate\");\n\t\t\t\tconst path = required(parsed, \"--path\");\n\t\t\t\tconst bytes = coordinator.artifact(parsed.id ?? \"\", candidate, path);\n\t\t\t\tresult = {\n\t\t\t\t\tcandidateDigest: candidate,\n\t\t\t\t\tpath,\n\t\t\t\t\tdigest: digestBytes(bytes),\n\t\t\t\t\tbyteCount: bytes.length,\n\t\t\t\t\tencoding: \"base64\",\n\t\t\t\t\tdata: bytes.toString(\"base64\"),\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = parsed.action;\n\t\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t\t}\n\t\t}\n\t\tprocess.stdout.write(`${JSON.stringify(result)}\\n`);\n\t\treturn { handled: true, exitCode };\n\t} catch (error) {\n\t\tconst usage = error instanceof RunContractError || (error instanceof VerifiedRunError && error.code === \"usage\");\n\t\tconst message =\n\t\t\terror instanceof VerifiedRunError || error instanceof RunContractError\n\t\t\t\t? error.message\n\t\t\t\t: \"verified-run: operation_failed\";\n\t\tprocess.stderr.write(`${message}\\n${usage ? `${USAGE}\\n` : \"\"}`);\n\t\treturn { handled: true, exitCode: usage ? 2 : 1 };\n\t}\n}\n"]}
@@ -0,0 +1,3 @@
1
+ /** Own CLI cancellation listeners for the complete awaited run operation. */
2
+ export declare function withRunSignal<T>(run: (signal: AbortSignal) => Promise<T>): Promise<T>;
3
+ //# sourceMappingURL=verified-run-signal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verified-run-signal.d.ts","sourceRoot":"","sources":["../../src/commands/verified-run-signal.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,wBAAsB,aAAa,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAW3F","sourcesContent":["/** Own CLI cancellation listeners for the complete awaited run operation. */\nexport async function withRunSignal<T>(run: (signal: AbortSignal) => Promise<T>): Promise<T> {\n\tconst controller = new AbortController();\n\tconst cancel = (): void => controller.abort();\n\tprocess.once(\"SIGINT\", cancel);\n\tprocess.once(\"SIGTERM\", cancel);\n\ttry {\n\t\treturn await run(controller.signal);\n\t} finally {\n\t\tprocess.off(\"SIGINT\", cancel);\n\t\tprocess.off(\"SIGTERM\", cancel);\n\t}\n}\n"]}
@@ -0,0 +1,15 @@
1
+ /** Own CLI cancellation listeners for the complete awaited run operation. */
2
+ export async function withRunSignal(run) {
3
+ const controller = new AbortController();
4
+ const cancel = () => controller.abort();
5
+ process.once("SIGINT", cancel);
6
+ process.once("SIGTERM", cancel);
7
+ try {
8
+ return await run(controller.signal);
9
+ }
10
+ finally {
11
+ process.off("SIGINT", cancel);
12
+ process.off("SIGTERM", cancel);
13
+ }
14
+ }
15
+ //# sourceMappingURL=verified-run-signal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verified-run-signal.js","sourceRoot":"","sources":["../../src/commands/verified-run-signal.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,MAAM,CAAC,KAAK,UAAU,aAAa,CAAI,GAAwC,EAAc;IAC5F,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,GAAS,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IAC9C,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC;QACJ,OAAO,MAAM,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;YAAS,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAChC,CAAC;AAAA,CACD","sourcesContent":["/** Own CLI cancellation listeners for the complete awaited run operation. */\nexport async function withRunSignal<T>(run: (signal: AbortSignal) => Promise<T>): Promise<T> {\n\tconst controller = new AbortController();\n\tconst cancel = (): void => controller.abort();\n\tprocess.once(\"SIGINT\", cancel);\n\tprocess.once(\"SIGTERM\", cancel);\n\ttry {\n\t\treturn await run(controller.signal);\n\t} finally {\n\t\tprocess.off(\"SIGINT\", cancel);\n\t\tprocess.off(\"SIGTERM\", cancel);\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"broker.d.ts","sourceRoot":"","sources":["../../src/coordination/broker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAYnF,MAAM,WAAW,sBAAsB;IACtC,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,QAAQ,GAAG,MAAM,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,QAAQ,CAAC,YAAY,EAAE,SAAS,aAAa,EAAE,CAAC;CAChD;AAQD,qBAAa,eAAe;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,cAAc,CAA2B;IACjD,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA+B;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IAEnD,YAAY,OAAO,EAAE,sBAAsB,EAG1C;IAED;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAOpC;IAED,qEAAqE;IACrE,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,GAAG,IAAI,CAuC9C;IAED,kEAAkE;IAClE,OAAO,CAAC,aAAa;IASrB,sEAAsE;IACtE,OAAO,CAAC,UAAU;IAMlB;;;;OAIG;IACH,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAShC;IAED;;;OAGG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAOxB;IAED,kFAAkF;IAClF,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAKjC;IAED;;;;OAIG;IACH,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAM5C;IAED,0EAA0E;IAC1E,OAAO,IAAI,IAAI,CAKd;IAED,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,GAAG,SAAS,CAGlD;IAED,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,aAAa,EAAE,CAGpD;IAED,yEAAyE;IACzE,MAAM,IAAI,OAAO,CAShB;CACD","sourcesContent":["/**\n * In-process admission broker for parallel sessions.\n *\n * Safety property: a grant that may still own a live external effect keeps\n * holding its claims. Expiry, cancellation and authority restart are\n * authorization events; only a trusted supervisor reporting termination frees\n * the claims. Treating a lapsed deadline as \"the effect stopped\" is exactly how\n * two sessions end up writing the same path.\n *\n * Bounded reference semantics: a single trusted state machine, canonical claim\n * keys, and every shared effect crossing this broker. No IPC, no OS fencing,\n * no persistence — those belong to the supervisor this broker reports to.\n */\n\nimport { claimSetsConflict, sameClaimSet } from \"./resource.ts\";\nimport type { EffectState, GrantToken, ResourceClaim, Sequence } from \"./types.ts\";\nimport { nextSequence, SETTLED_EFFECT_STATES, sequence } from \"./types.ts\";\n\ninterface Grant {\n\treadonly token: GrantToken;\n\treadonly claims: readonly ResourceClaim[];\n\treadonly weight: number;\n\tstate: EffectState;\n\t/** True once an external effect may exist. Never inferred from the clock. */\n\teffectLive: boolean;\n}\n\nexport interface AdmissionBrokerOptions {\n\t/** Total admissible weight of concurrently active grants. */\n\treadonly capacity: number;\n}\n\nexport interface AcquireInput {\n\treadonly sessionId: string;\n\treadonly incarnation: Sequence | string;\n\treadonly claims: readonly ResourceClaim[];\n\treadonly now: number;\n\treadonly ttl: number;\n\treadonly weight?: number;\n}\n\nexport interface StartInput {\n\treadonly token: GrantToken;\n\treadonly now: number;\n\t/** Claims the operation actually resolved to after approval hooks. */\n\treadonly actualClaims: readonly ResourceClaim[];\n}\n\nfunction assertNonNegativeInteger(value: number, label: string): void {\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 0) {\n\t\tthrow new TypeError(`${label} must be a nonnegative safe integer`);\n\t}\n}\n\nexport class AdmissionBroker {\n\tprivate readonly capacity: number;\n\tprivate authorityEpoch: Sequence = sequence(\"1\");\n\tprivate grantCounter: Sequence = sequence(\"0\");\n\tprivate readonly incarnations = new Map<string, Sequence>();\n\tprivate readonly grants = new Map<string, Grant>();\n\n\tconstructor(options: AdmissionBrokerOptions) {\n\t\tassertNonNegativeInteger(options.capacity, \"capacity\");\n\t\tthis.capacity = options.capacity;\n\t}\n\n\t/**\n\t * Announce a session incarnation. Re-registering does not free the previous\n\t * incarnation's grants: a restarted session cannot assume its predecessor's\n\t * effects stopped.\n\t */\n\tregister(sessionId: string): Sequence {\n\t\tif (typeof sessionId !== \"string\" || sessionId.length === 0) {\n\t\t\tthrow new TypeError(\"sessionId must be a non-empty string\");\n\t\t}\n\t\tconst next = nextSequence(this.incarnations.get(sessionId) ?? sequence(\"0\"));\n\t\tthis.incarnations.set(sessionId, next);\n\t\treturn next;\n\t}\n\n\t/** Grants still holding their claims, including quarantined ones. */\n\tprivate activeGrants(): Grant[] {\n\t\treturn [...this.grants.values()].filter((g) => !SETTLED_EFFECT_STATES.has(g.state));\n\t}\n\n\tacquire(input: AcquireInput): GrantToken | null {\n\t\tassertNonNegativeInteger(input.now, \"now\");\n\t\tconst weight = input.weight ?? 1;\n\t\tassertNonNegativeInteger(weight, \"weight\");\n\t\tif (!Number.isSafeInteger(input.ttl) || input.ttl <= 0) {\n\t\t\tthrow new TypeError(\"ttl must be a positive safe integer\");\n\t\t}\n\t\tconst incarnation = sequence(input.incarnation);\n\t\tif (this.incarnations.get(input.sessionId) !== incarnation) {\n\t\t\tthrow new TypeError(\"stale session incarnation\");\n\t\t}\n\t\tif (input.claims.length === 0) {\n\t\t\tthrow new TypeError(\"an unknown scope must not be admitted as an empty scope\");\n\t\t}\n\n\t\t// Settle lapsed authorizations first; this never evicts a live effect.\n\t\tthis.expire(input.now);\n\t\tconst active = this.activeGrants();\n\t\tconst used = active.reduce((sum, g) => sum + g.weight, 0);\n\t\tif (weight + used > this.capacity) return null;\n\t\tconst claims = [...input.claims];\n\t\tif (active.some((g) => claimSetsConflict(claims, g.claims))) return null;\n\n\t\tthis.grantCounter = nextSequence(this.grantCounter);\n\t\tconst token: GrantToken = Object.freeze({\n\t\t\tauthorityEpoch: this.authorityEpoch,\n\t\t\tgrantSequence: this.grantCounter,\n\t\t\tsessionId: input.sessionId,\n\t\t\tsessionIncarnation: incarnation,\n\t\t\tauthorizationDeadline: input.now + input.ttl,\n\t\t});\n\t\tthis.grants.set(token.grantSequence, {\n\t\t\ttoken,\n\t\t\tclaims: Object.freeze(claims),\n\t\t\tweight,\n\t\t\tstate: \"reserved\",\n\t\t\teffectLive: false,\n\t\t});\n\t\treturn token;\n\t}\n\n\t/** Resolve a token that is still authoritative for new action. */\n\tprivate authoritative(token: GrantToken): Grant | undefined {\n\t\tconst grant = this.grants.get(token.grantSequence);\n\t\tif (grant === undefined || !sameToken(grant.token, token)) return undefined;\n\t\tif (token.authorityEpoch !== this.authorityEpoch) return undefined;\n\t\tif (this.incarnations.get(token.sessionId) !== token.sessionIncarnation) return undefined;\n\t\tif (SETTLED_EFFECT_STATES.has(grant.state)) return undefined;\n\t\treturn grant;\n\t}\n\n\t/** Resolve a token for settlement only; accepts superseded epochs. */\n\tprivate settleable(token: GrantToken): Grant | undefined {\n\t\tconst grant = this.grants.get(token.grantSequence);\n\t\tif (grant === undefined || !sameToken(grant.token, token)) return undefined;\n\t\treturn SETTLED_EFFECT_STATES.has(grant.state) ? undefined : grant;\n\t}\n\n\t/**\n\t * Bind an effect to its reservation. The actual claims must equal the\n\t * reserved set exactly — an approval hook that widened scope has to be\n\t * re-admitted, not silently allowed to run under the old grant.\n\t */\n\tstart(input: StartInput): boolean {\n\t\tassertNonNegativeInteger(input.now, \"now\");\n\t\tconst grant = this.authoritative(input.token);\n\t\tif (grant === undefined || grant.state !== \"reserved\") return false;\n\t\tif (input.now >= grant.token.authorizationDeadline) return false;\n\t\tif (!sameClaimSet(input.actualClaims, grant.claims)) return false;\n\t\tgrant.state = \"running\";\n\t\tgrant.effectLive = true;\n\t\treturn true;\n\t}\n\n\t/**\n\t * Apply lapsed authorization deadlines. A reservation that never started is\n\t * released; a running effect is quarantined and keeps its claims.\n\t */\n\texpire(now: number): void {\n\t\tassertNonNegativeInteger(now, \"now\");\n\t\tfor (const grant of this.activeGrants()) {\n\t\t\tif (now >= grant.token.authorizationDeadline) {\n\t\t\t\tgrant.state = grant.effectLive ? \"quarantined\" : \"cancelled\";\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Withdraw authorization. Requested cancellation is not observed termination. */\n\tcancel(token: GrantToken): boolean {\n\t\tconst grant = this.settleable(token);\n\t\tif (grant === undefined) return false;\n\t\tgrant.state = grant.effectLive ? \"quarantined\" : \"cancelled\";\n\t\treturn true;\n\t}\n\n\t/**\n\t * Trusted supervisor event: this exact effect is gone. Accepted for\n\t * superseded epochs so a restarted authority can still settle what the\n\t * previous one started, never to authorize new work.\n\t */\n\tconfirmTerminated(token: GrantToken): boolean {\n\t\tconst grant = this.settleable(token);\n\t\tif (grant === undefined) return false;\n\t\tgrant.effectLive = false;\n\t\tgrant.state = \"terminated\";\n\t\treturn true;\n\t}\n\n\t/** Fence the authority. Live effects stay quarantined until confirmed. */\n\trestart(): void {\n\t\tthis.authorityEpoch = nextSequence(this.authorityEpoch);\n\t\tfor (const grant of this.activeGrants()) {\n\t\t\tgrant.state = grant.effectLive ? \"quarantined\" : \"cancelled\";\n\t\t}\n\t}\n\n\tstateOf(token: GrantToken): EffectState | undefined {\n\t\tconst grant = this.grants.get(token.grantSequence);\n\t\treturn grant !== undefined && sameToken(grant.token, token) ? grant.state : undefined;\n\t}\n\n\tclaimsOf(token: GrantToken): readonly ResourceClaim[] {\n\t\tconst grant = this.grants.get(token.grantSequence);\n\t\treturn grant !== undefined && sameToken(grant.token, token) ? grant.claims : [];\n\t}\n\n\t/** Invariant: active grants fit capacity and never pairwise conflict. */\n\tisSafe(): boolean {\n\t\tconst active = this.activeGrants();\n\t\tif (active.reduce((sum, g) => sum + g.weight, 0) > this.capacity) return false;\n\t\tfor (const [index, grant] of active.entries()) {\n\t\t\tfor (const other of active.slice(index + 1)) {\n\t\t\t\tif (claimSetsConflict(grant.claims, other.claims)) return false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n}\n\nfunction sameToken(a: GrantToken, b: GrantToken): boolean {\n\treturn (\n\t\ta.authorityEpoch === b.authorityEpoch &&\n\t\ta.grantSequence === b.grantSequence &&\n\t\ta.sessionId === b.sessionId &&\n\t\ta.sessionIncarnation === b.sessionIncarnation &&\n\t\ta.authorizationDeadline === b.authorizationDeadline\n\t);\n}\n"]}
1
+ {"version":3,"file":"broker.d.ts","sourceRoot":"","sources":["../../src/coordination/broker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAYnF,MAAM,WAAW,sBAAsB;IACtC,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,QAAQ,GAAG,MAAM,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,QAAQ,CAAC,YAAY,EAAE,SAAS,aAAa,EAAE,CAAC;CAChD;AAQD,qBAAa,eAAe;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,cAAc,CAA2B;IACjD,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA+B;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IAEnD,YAAY,OAAO,EAAE,sBAAsB,EAG1C;IAED;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAOpC;IAED,qEAAqE;IACrE,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,GAAG,IAAI,CA0C9C;IAED,kEAAkE;IAClE,OAAO,CAAC,aAAa;IASrB,sEAAsE;IACtE,OAAO,CAAC,UAAU;IAMlB;;;;OAIG;IACH,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAWhC;IAED;;;OAGG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAOxB;IAED,kFAAkF;IAClF,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAKjC;IAED;;;;OAIG;IACH,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAM5C;IAED,0EAA0E;IAC1E,OAAO,IAAI,IAAI,CAKd;IAED,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,GAAG,SAAS,CAGlD;IAED,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,aAAa,EAAE,CAGpD;IAED,yEAAyE;IACzE,MAAM,IAAI,OAAO,CAShB;CACD","sourcesContent":["/**\n * In-process admission broker for parallel sessions.\n *\n * Safety property: a grant that may still own a live external effect keeps\n * holding its claims. Expiry, cancellation and authority restart are\n * authorization events; only a trusted supervisor reporting termination frees\n * the claims. Treating a lapsed deadline as \"the effect stopped\" is exactly how\n * two sessions end up writing the same path.\n *\n * Bounded reference semantics: a single trusted state machine, canonical claim\n * keys, and every shared effect crossing this broker. No IPC, no OS fencing,\n * no persistence — those belong to the supervisor this broker reports to.\n */\n\nimport { canonicalClaim, claimSetsConflict, sameClaimSet } from \"./resource.ts\";\nimport type { EffectState, GrantToken, ResourceClaim, Sequence } from \"./types.ts\";\nimport { nextSequence, SETTLED_EFFECT_STATES, sequence } from \"./types.ts\";\n\ninterface Grant {\n\treadonly token: GrantToken;\n\treadonly claims: readonly ResourceClaim[];\n\treadonly weight: number;\n\tstate: EffectState;\n\t/** True once an external effect may exist. Never inferred from the clock. */\n\teffectLive: boolean;\n}\n\nexport interface AdmissionBrokerOptions {\n\t/** Total admissible weight of concurrently active grants. */\n\treadonly capacity: number;\n}\n\nexport interface AcquireInput {\n\treadonly sessionId: string;\n\treadonly incarnation: Sequence | string;\n\treadonly claims: readonly ResourceClaim[];\n\treadonly now: number;\n\treadonly ttl: number;\n\treadonly weight?: number;\n}\n\nexport interface StartInput {\n\treadonly token: GrantToken;\n\treadonly now: number;\n\t/** Claims the operation actually resolved to after approval hooks. */\n\treadonly actualClaims: readonly ResourceClaim[];\n}\n\nfunction assertNonNegativeInteger(value: number, label: string): void {\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 0) {\n\t\tthrow new TypeError(`${label} must be a nonnegative safe integer`);\n\t}\n}\n\nexport class AdmissionBroker {\n\tprivate readonly capacity: number;\n\tprivate authorityEpoch: Sequence = sequence(\"1\");\n\tprivate grantCounter: Sequence = sequence(\"0\");\n\tprivate readonly incarnations = new Map<string, Sequence>();\n\tprivate readonly grants = new Map<string, Grant>();\n\n\tconstructor(options: AdmissionBrokerOptions) {\n\t\tassertNonNegativeInteger(options.capacity, \"capacity\");\n\t\tthis.capacity = options.capacity;\n\t}\n\n\t/**\n\t * Announce a session incarnation. Re-registering does not free the previous\n\t * incarnation's grants: a restarted session cannot assume its predecessor's\n\t * effects stopped.\n\t */\n\tregister(sessionId: string): Sequence {\n\t\tif (typeof sessionId !== \"string\" || sessionId.length === 0) {\n\t\t\tthrow new TypeError(\"sessionId must be a non-empty string\");\n\t\t}\n\t\tconst next = nextSequence(this.incarnations.get(sessionId) ?? sequence(\"0\"));\n\t\tthis.incarnations.set(sessionId, next);\n\t\treturn next;\n\t}\n\n\t/** Grants still holding their claims, including quarantined ones. */\n\tprivate activeGrants(): Grant[] {\n\t\treturn [...this.grants.values()].filter((g) => !SETTLED_EFFECT_STATES.has(g.state));\n\t}\n\n\tacquire(input: AcquireInput): GrantToken | null {\n\t\tassertNonNegativeInteger(input.now, \"now\");\n\t\tconst weight = input.weight ?? 1;\n\t\tassertNonNegativeInteger(weight, \"weight\");\n\t\tif (!Number.isSafeInteger(input.ttl) || input.ttl <= 0) {\n\t\t\tthrow new TypeError(\"ttl must be a positive safe integer\");\n\t\t}\n\t\tconst authorizationDeadline = input.now + input.ttl;\n\t\tif (!Number.isSafeInteger(authorizationDeadline)) throw new RangeError(\"authorization deadline overflow\");\n\t\tconst incarnation = sequence(input.incarnation);\n\t\tif (this.incarnations.get(input.sessionId) !== incarnation) {\n\t\t\tthrow new TypeError(\"stale session incarnation\");\n\t\t}\n\t\tif (!Array.isArray(input.claims) || input.claims.length === 0) {\n\t\t\tthrow new TypeError(\"an unknown scope must not be admitted as an empty scope\");\n\t\t}\n\t\t// Take owned, validated snapshots before any state mutation.\n\t\tconst claims = Array.from(input.claims, (claim) => canonicalClaim(claim));\n\n\t\t// Settle lapsed authorizations first; this never evicts a live effect.\n\t\tthis.expire(input.now);\n\t\tconst active = this.activeGrants();\n\t\tconst used = active.reduce((sum, g) => sum + g.weight, 0);\n\t\tif (weight > this.capacity - used) return null;\n\t\tif (active.some((g) => claimSetsConflict(claims, g.claims))) return null;\n\n\t\tthis.grantCounter = nextSequence(this.grantCounter);\n\t\tconst token: GrantToken = Object.freeze({\n\t\t\tauthorityEpoch: this.authorityEpoch,\n\t\t\tgrantSequence: this.grantCounter,\n\t\t\tsessionId: input.sessionId,\n\t\t\tsessionIncarnation: incarnation,\n\t\t\tauthorizationDeadline,\n\t\t});\n\t\tthis.grants.set(token.grantSequence, {\n\t\t\ttoken,\n\t\t\tclaims: Object.freeze(claims),\n\t\t\tweight,\n\t\t\tstate: \"reserved\",\n\t\t\teffectLive: false,\n\t\t});\n\t\treturn token;\n\t}\n\n\t/** Resolve a token that is still authoritative for new action. */\n\tprivate authoritative(token: GrantToken): Grant | undefined {\n\t\tconst grant = this.grants.get(token.grantSequence);\n\t\tif (grant === undefined || !sameToken(grant.token, token)) return undefined;\n\t\tif (token.authorityEpoch !== this.authorityEpoch) return undefined;\n\t\tif (this.incarnations.get(token.sessionId) !== token.sessionIncarnation) return undefined;\n\t\tif (SETTLED_EFFECT_STATES.has(grant.state)) return undefined;\n\t\treturn grant;\n\t}\n\n\t/** Resolve a token for settlement only; accepts superseded epochs. */\n\tprivate settleable(token: GrantToken): Grant | undefined {\n\t\tconst grant = this.grants.get(token.grantSequence);\n\t\tif (grant === undefined || !sameToken(grant.token, token)) return undefined;\n\t\treturn SETTLED_EFFECT_STATES.has(grant.state) ? undefined : grant;\n\t}\n\n\t/**\n\t * Bind an effect to its reservation. The actual claims must equal the\n\t * reserved set exactly — an approval hook that widened scope has to be\n\t * re-admitted, not silently allowed to run under the old grant.\n\t */\n\tstart(input: StartInput): boolean {\n\t\tassertNonNegativeInteger(input.now, \"now\");\n\t\tconst grant = this.authoritative(input.token);\n\t\tif (grant === undefined || grant.state !== \"reserved\") return false;\n\t\tif (input.now >= grant.token.authorizationDeadline) return false;\n\t\tif (!Array.isArray(input.actualClaims)) throw new TypeError(\"actualClaims must be an array\");\n\t\tconst actualClaims = Array.from(input.actualClaims, (claim) => canonicalClaim(claim));\n\t\tif (!sameClaimSet(actualClaims, grant.claims)) return false;\n\t\tgrant.state = \"running\";\n\t\tgrant.effectLive = true;\n\t\treturn true;\n\t}\n\n\t/**\n\t * Apply lapsed authorization deadlines. A reservation that never started is\n\t * released; a running effect is quarantined and keeps its claims.\n\t */\n\texpire(now: number): void {\n\t\tassertNonNegativeInteger(now, \"now\");\n\t\tfor (const grant of this.activeGrants()) {\n\t\t\tif (now >= grant.token.authorizationDeadline) {\n\t\t\t\tgrant.state = grant.effectLive ? \"quarantined\" : \"cancelled\";\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Withdraw authorization. Requested cancellation is not observed termination. */\n\tcancel(token: GrantToken): boolean {\n\t\tconst grant = this.settleable(token);\n\t\tif (grant === undefined) return false;\n\t\tgrant.state = grant.effectLive ? \"quarantined\" : \"cancelled\";\n\t\treturn true;\n\t}\n\n\t/**\n\t * Trusted supervisor event: this exact effect is gone. Accepted for\n\t * superseded epochs so a restarted authority can still settle what the\n\t * previous one started, never to authorize new work.\n\t */\n\tconfirmTerminated(token: GrantToken): boolean {\n\t\tconst grant = this.settleable(token);\n\t\tif (grant === undefined) return false;\n\t\tgrant.effectLive = false;\n\t\tgrant.state = \"terminated\";\n\t\treturn true;\n\t}\n\n\t/** Fence the authority. Live effects stay quarantined until confirmed. */\n\trestart(): void {\n\t\tthis.authorityEpoch = nextSequence(this.authorityEpoch);\n\t\tfor (const grant of this.activeGrants()) {\n\t\t\tgrant.state = grant.effectLive ? \"quarantined\" : \"cancelled\";\n\t\t}\n\t}\n\n\tstateOf(token: GrantToken): EffectState | undefined {\n\t\tconst grant = this.grants.get(token.grantSequence);\n\t\treturn grant !== undefined && sameToken(grant.token, token) ? grant.state : undefined;\n\t}\n\n\tclaimsOf(token: GrantToken): readonly ResourceClaim[] {\n\t\tconst grant = this.grants.get(token.grantSequence);\n\t\treturn grant !== undefined && sameToken(grant.token, token) ? grant.claims : [];\n\t}\n\n\t/** Invariant: active grants fit capacity and never pairwise conflict. */\n\tisSafe(): boolean {\n\t\tconst active = this.activeGrants();\n\t\tif (active.reduce((sum, g) => sum + g.weight, 0) > this.capacity) return false;\n\t\tfor (const [index, grant] of active.entries()) {\n\t\t\tfor (const other of active.slice(index + 1)) {\n\t\t\t\tif (claimSetsConflict(grant.claims, other.claims)) return false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n}\n\nfunction sameToken(a: GrantToken, b: GrantToken): boolean {\n\treturn (\n\t\ta.authorityEpoch === b.authorityEpoch &&\n\t\ta.grantSequence === b.grantSequence &&\n\t\ta.sessionId === b.sessionId &&\n\t\ta.sessionIncarnation === b.sessionIncarnation &&\n\t\ta.authorizationDeadline === b.authorizationDeadline\n\t);\n}\n"]}
@@ -11,7 +11,7 @@
11
11
  * keys, and every shared effect crossing this broker. No IPC, no OS fencing,
12
12
  * no persistence — those belong to the supervisor this broker reports to.
13
13
  */
14
- import { claimSetsConflict, sameClaimSet } from "./resource.js";
14
+ import { canonicalClaim, claimSetsConflict, sameClaimSet } from "./resource.js";
15
15
  import { nextSequence, SETTLED_EFFECT_STATES, sequence } from "./types.js";
16
16
  function assertNonNegativeInteger(value, label) {
17
17
  if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
@@ -52,20 +52,24 @@ export class AdmissionBroker {
52
52
  if (!Number.isSafeInteger(input.ttl) || input.ttl <= 0) {
53
53
  throw new TypeError("ttl must be a positive safe integer");
54
54
  }
55
+ const authorizationDeadline = input.now + input.ttl;
56
+ if (!Number.isSafeInteger(authorizationDeadline))
57
+ throw new RangeError("authorization deadline overflow");
55
58
  const incarnation = sequence(input.incarnation);
56
59
  if (this.incarnations.get(input.sessionId) !== incarnation) {
57
60
  throw new TypeError("stale session incarnation");
58
61
  }
59
- if (input.claims.length === 0) {
62
+ if (!Array.isArray(input.claims) || input.claims.length === 0) {
60
63
  throw new TypeError("an unknown scope must not be admitted as an empty scope");
61
64
  }
65
+ // Take owned, validated snapshots before any state mutation.
66
+ const claims = Array.from(input.claims, (claim) => canonicalClaim(claim));
62
67
  // Settle lapsed authorizations first; this never evicts a live effect.
63
68
  this.expire(input.now);
64
69
  const active = this.activeGrants();
65
70
  const used = active.reduce((sum, g) => sum + g.weight, 0);
66
- if (weight + used > this.capacity)
71
+ if (weight > this.capacity - used)
67
72
  return null;
68
- const claims = [...input.claims];
69
73
  if (active.some((g) => claimSetsConflict(claims, g.claims)))
70
74
  return null;
71
75
  this.grantCounter = nextSequence(this.grantCounter);
@@ -74,7 +78,7 @@ export class AdmissionBroker {
74
78
  grantSequence: this.grantCounter,
75
79
  sessionId: input.sessionId,
76
80
  sessionIncarnation: incarnation,
77
- authorizationDeadline: input.now + input.ttl,
81
+ authorizationDeadline,
78
82
  });
79
83
  this.grants.set(token.grantSequence, {
80
84
  token,
@@ -117,7 +121,10 @@ export class AdmissionBroker {
117
121
  return false;
118
122
  if (input.now >= grant.token.authorizationDeadline)
119
123
  return false;
120
- if (!sameClaimSet(input.actualClaims, grant.claims))
124
+ if (!Array.isArray(input.actualClaims))
125
+ throw new TypeError("actualClaims must be an array");
126
+ const actualClaims = Array.from(input.actualClaims, (claim) => canonicalClaim(claim));
127
+ if (!sameClaimSet(actualClaims, grant.claims))
121
128
  return false;
122
129
  grant.state = "running";
123
130
  grant.effectLive = true;