open-multi-agent-kit 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (436) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +2 -2
  3. package/dist/approval-api.d.ts +5 -0
  4. package/dist/approval-api.d.ts.map +1 -0
  5. package/dist/approval-api.js +5 -0
  6. package/dist/approval-api.js.map +1 -0
  7. package/dist/cli/session-picker.d.ts +2 -2
  8. package/dist/cli/session-picker.d.ts.map +1 -1
  9. package/dist/cli/session-picker.js.map +1 -1
  10. package/dist/commands/verified-run-cli.d.ts.map +1 -1
  11. package/dist/commands/verified-run-cli.js +69 -22
  12. package/dist/commands/verified-run-cli.js.map +1 -1
  13. package/dist/commands/verified-run-signal.d.ts +3 -0
  14. package/dist/commands/verified-run-signal.d.ts.map +1 -0
  15. package/dist/commands/verified-run-signal.js +15 -0
  16. package/dist/commands/verified-run-signal.js.map +1 -0
  17. package/dist/coordination/broker.d.ts.map +1 -1
  18. package/dist/coordination/broker.js +13 -6
  19. package/dist/coordination/broker.js.map +1 -1
  20. package/dist/coordination/operation.d.ts +1 -0
  21. package/dist/coordination/operation.d.ts.map +1 -1
  22. package/dist/coordination/operation.js +55 -3
  23. package/dist/coordination/operation.js.map +1 -1
  24. package/dist/coordination/resource.d.ts +1 -1
  25. package/dist/coordination/resource.d.ts.map +1 -1
  26. package/dist/coordination/resource.js +10 -4
  27. package/dist/coordination/resource.js.map +1 -1
  28. package/dist/coordination/types.d.ts.map +1 -1
  29. package/dist/coordination/types.js +1 -1
  30. package/dist/coordination/types.js.map +1 -1
  31. package/dist/core/adaptorch-bridge.d.ts +1 -1
  32. package/dist/core/adaptorch-bridge.d.ts.map +1 -1
  33. package/dist/core/adaptorch-bridge.js +1 -1
  34. package/dist/core/adaptorch-bridge.js.map +1 -1
  35. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  36. package/dist/core/agent-session-runtime.js +16 -16
  37. package/dist/core/agent-session-runtime.js.map +1 -1
  38. package/dist/core/agent-session.d.ts.map +1 -1
  39. package/dist/core/agent-session.js +32 -33
  40. package/dist/core/agent-session.js.map +1 -1
  41. package/dist/core/canonical-json.d.ts +3 -0
  42. package/dist/core/canonical-json.d.ts.map +1 -0
  43. package/dist/core/canonical-json.js +20 -0
  44. package/dist/core/canonical-json.js.map +1 -0
  45. package/dist/core/compaction/compaction.d.ts +7 -3
  46. package/dist/core/compaction/compaction.d.ts.map +1 -1
  47. package/dist/core/compaction/compaction.js +14 -29
  48. package/dist/core/compaction/compaction.js.map +1 -1
  49. package/dist/core/compaction/fallback.d.ts +16 -5
  50. package/dist/core/compaction/fallback.d.ts.map +1 -1
  51. package/dist/core/compaction/fallback.js +4 -3
  52. package/dist/core/compaction/fallback.js.map +1 -1
  53. package/dist/core/compaction/model-failover.d.ts +21 -0
  54. package/dist/core/compaction/model-failover.d.ts.map +1 -0
  55. package/dist/core/compaction/model-failover.js +46 -0
  56. package/dist/core/compaction/model-failover.js.map +1 -0
  57. package/dist/core/compaction/session-summary.d.ts +21 -0
  58. package/dist/core/compaction/session-summary.d.ts.map +1 -0
  59. package/dist/core/compaction/session-summary.js +27 -0
  60. package/dist/core/compaction/session-summary.js.map +1 -0
  61. package/dist/core/export-html/template.js +14 -0
  62. package/dist/core/extensions/index.d.ts +1 -1
  63. package/dist/core/extensions/index.d.ts.map +1 -1
  64. package/dist/core/extensions/index.js.map +1 -1
  65. package/dist/core/extensions/session-lifecycle-types.d.ts +14 -0
  66. package/dist/core/extensions/session-lifecycle-types.d.ts.map +1 -0
  67. package/dist/core/extensions/session-lifecycle-types.js +2 -0
  68. package/dist/core/extensions/session-lifecycle-types.js.map +1 -0
  69. package/dist/core/extensions/types.d.ts +4 -9
  70. package/dist/core/extensions/types.d.ts.map +1 -1
  71. package/dist/core/extensions/types.js.map +1 -1
  72. package/dist/core/http-dispatcher.d.ts.map +1 -1
  73. package/dist/core/http-dispatcher.js +10 -1
  74. package/dist/core/http-dispatcher.js.map +1 -1
  75. package/dist/core/keybindings.d.ts.map +1 -1
  76. package/dist/core/keybindings.js +3 -6
  77. package/dist/core/keybindings.js.map +1 -1
  78. package/dist/core/legacy-resource-policy.d.ts +7 -0
  79. package/dist/core/legacy-resource-policy.d.ts.map +1 -0
  80. package/dist/core/legacy-resource-policy.js +9 -0
  81. package/dist/core/legacy-resource-policy.js.map +1 -0
  82. package/dist/core/mcp/config.d.ts.map +1 -1
  83. package/dist/core/mcp/config.js +17 -3
  84. package/dist/core/mcp/config.js.map +1 -1
  85. package/dist/core/mcp/connection-queue.d.ts +12 -0
  86. package/dist/core/mcp/connection-queue.d.ts.map +1 -0
  87. package/dist/core/mcp/connection-queue.js +46 -0
  88. package/dist/core/mcp/connection-queue.js.map +1 -0
  89. package/dist/core/mcp/manager-runtime.d.ts +55 -0
  90. package/dist/core/mcp/manager-runtime.d.ts.map +1 -0
  91. package/dist/core/mcp/manager-runtime.js +66 -0
  92. package/dist/core/mcp/manager-runtime.js.map +1 -0
  93. package/dist/core/mcp/manager.d.ts +12 -68
  94. package/dist/core/mcp/manager.d.ts.map +1 -1
  95. package/dist/core/mcp/manager.js +33 -113
  96. package/dist/core/mcp/manager.js.map +1 -1
  97. package/dist/core/mcp/protocol.d.ts.map +1 -1
  98. package/dist/core/mcp/protocol.js +70 -40
  99. package/dist/core/mcp/protocol.js.map +1 -1
  100. package/dist/core/package-manager.d.ts +4 -0
  101. package/dist/core/package-manager.d.ts.map +1 -1
  102. package/dist/core/package-manager.js +59 -129
  103. package/dist/core/package-manager.js.map +1 -1
  104. package/dist/core/package-resource-patterns.d.ts +7 -0
  105. package/dist/core/package-resource-patterns.d.ts.map +1 -0
  106. package/dist/core/package-resource-patterns.js +99 -0
  107. package/dist/core/package-resource-patterns.js.map +1 -0
  108. package/dist/core/provider-resilience.d.ts +9 -0
  109. package/dist/core/provider-resilience.d.ts.map +1 -1
  110. package/dist/core/provider-resilience.js +15 -0
  111. package/dist/core/provider-resilience.js.map +1 -1
  112. package/dist/core/reasoning-router-v4.d.ts +5 -2
  113. package/dist/core/reasoning-router-v4.d.ts.map +1 -1
  114. package/dist/core/reasoning-router-v4.js.map +1 -1
  115. package/dist/core/resource-loader.d.ts.map +1 -1
  116. package/dist/core/resource-loader.js +4 -8
  117. package/dist/core/resource-loader.js.map +1 -1
  118. package/dist/core/run-execution-api.d.ts +8 -1
  119. package/dist/core/run-execution-api.d.ts.map +1 -1
  120. package/dist/core/run-execution-api.js +4 -0
  121. package/dist/core/run-execution-api.js.map +1 -1
  122. package/dist/core/run-journal.d.ts +1 -2
  123. package/dist/core/run-journal.d.ts.map +1 -1
  124. package/dist/core/run-journal.js +2 -19
  125. package/dist/core/run-journal.js.map +1 -1
  126. package/dist/core/session-listing.d.ts +51 -0
  127. package/dist/core/session-listing.d.ts.map +1 -0
  128. package/dist/core/session-listing.js +111 -0
  129. package/dist/core/session-listing.js.map +1 -0
  130. package/dist/core/session-manager.d.ts +12 -37
  131. package/dist/core/session-manager.d.ts.map +1 -1
  132. package/dist/core/session-manager.js +12 -118
  133. package/dist/core/session-manager.js.map +1 -1
  134. package/dist/core/session-message-text.d.ts +5 -0
  135. package/dist/core/session-message-text.d.ts.map +1 -0
  136. package/dist/core/session-message-text.js +9 -0
  137. package/dist/core/session-message-text.js.map +1 -0
  138. package/dist/core/skills-catalog-cache.d.ts +2 -0
  139. package/dist/core/skills-catalog-cache.d.ts.map +1 -1
  140. package/dist/core/skills-catalog-cache.js +71 -17
  141. package/dist/core/skills-catalog-cache.js.map +1 -1
  142. package/dist/core/tools/read.d.ts.map +1 -1
  143. package/dist/core/tools/read.js +1 -1
  144. package/dist/core/tools/read.js.map +1 -1
  145. package/dist/core/verified-run/authority-clock.d.ts +3 -0
  146. package/dist/core/verified-run/authority-clock.d.ts.map +1 -0
  147. package/dist/core/verified-run/authority-clock.js +25 -0
  148. package/dist/core/verified-run/authority-clock.js.map +1 -0
  149. package/dist/core/verified-run/authority-errors.d.ts +10 -0
  150. package/dist/core/verified-run/authority-errors.d.ts.map +1 -0
  151. package/dist/core/verified-run/authority-errors.js +17 -0
  152. package/dist/core/verified-run/authority-errors.js.map +1 -0
  153. package/dist/core/verified-run/authority-events.d.ts +126 -0
  154. package/dist/core/verified-run/authority-events.d.ts.map +1 -0
  155. package/dist/core/verified-run/authority-events.js +482 -0
  156. package/dist/core/verified-run/authority-events.js.map +1 -0
  157. package/dist/core/verified-run/authority-journal.d.ts +27 -0
  158. package/dist/core/verified-run/authority-journal.d.ts.map +1 -0
  159. package/dist/core/verified-run/authority-journal.js +83 -0
  160. package/dist/core/verified-run/authority-journal.js.map +1 -0
  161. package/dist/core/verified-run/authority-meaning.d.ts +13 -0
  162. package/dist/core/verified-run/authority-meaning.d.ts.map +1 -0
  163. package/dist/core/verified-run/authority-meaning.js +40 -0
  164. package/dist/core/verified-run/authority-meaning.js.map +1 -0
  165. package/dist/core/verified-run/authority-runtime.d.ts +82 -0
  166. package/dist/core/verified-run/authority-runtime.d.ts.map +1 -0
  167. package/dist/core/verified-run/authority-runtime.js +169 -0
  168. package/dist/core/verified-run/authority-runtime.js.map +1 -0
  169. package/dist/core/verified-run/authority-store.d.ts +204 -0
  170. package/dist/core/verified-run/authority-store.d.ts.map +1 -0
  171. package/dist/core/verified-run/authority-store.js +852 -0
  172. package/dist/core/verified-run/authority-store.js.map +1 -0
  173. package/dist/core/verified-run/broker.d.ts +8 -1
  174. package/dist/core/verified-run/broker.d.ts.map +1 -1
  175. package/dist/core/verified-run/broker.js +94 -90
  176. package/dist/core/verified-run/broker.js.map +1 -1
  177. package/dist/core/verified-run/candidate-policy.d.ts +10 -0
  178. package/dist/core/verified-run/candidate-policy.d.ts.map +1 -0
  179. package/dist/core/verified-run/candidate-policy.js +33 -0
  180. package/dist/core/verified-run/candidate-policy.js.map +1 -0
  181. package/dist/core/verified-run/candidate.d.ts.map +1 -1
  182. package/dist/core/verified-run/candidate.js +5 -10
  183. package/dist/core/verified-run/candidate.js.map +1 -1
  184. package/dist/core/verified-run/coordinator.d.ts +35 -17
  185. package/dist/core/verified-run/coordinator.d.ts.map +1 -1
  186. package/dist/core/verified-run/coordinator.js +111 -57
  187. package/dist/core/verified-run/coordinator.js.map +1 -1
  188. package/dist/core/verified-run/dag-phase.d.ts.map +1 -1
  189. package/dist/core/verified-run/dag-phase.js +1 -1
  190. package/dist/core/verified-run/dag-phase.js.map +1 -1
  191. package/dist/core/verified-run/dag-recovery.d.ts +5 -1
  192. package/dist/core/verified-run/dag-recovery.d.ts.map +1 -1
  193. package/dist/core/verified-run/dag-recovery.js +10 -4
  194. package/dist/core/verified-run/dag-recovery.js.map +1 -1
  195. package/dist/core/verified-run/event-parser.d.ts.map +1 -1
  196. package/dist/core/verified-run/event-parser.js +33 -0
  197. package/dist/core/verified-run/event-parser.js.map +1 -1
  198. package/dist/core/verified-run/evidence-read-projection.d.ts +4 -0
  199. package/dist/core/verified-run/evidence-read-projection.d.ts.map +1 -0
  200. package/dist/core/verified-run/evidence-read-projection.js +27 -0
  201. package/dist/core/verified-run/evidence-read-projection.js.map +1 -0
  202. package/dist/core/verified-run/evidence.d.ts +12 -1
  203. package/dist/core/verified-run/evidence.d.ts.map +1 -1
  204. package/dist/core/verified-run/evidence.js +51 -2
  205. package/dist/core/verified-run/evidence.js.map +1 -1
  206. package/dist/core/verified-run/git-candidate-preflight.d.ts +4 -0
  207. package/dist/core/verified-run/git-candidate-preflight.d.ts.map +1 -0
  208. package/dist/core/verified-run/git-candidate-preflight.js +34 -0
  209. package/dist/core/verified-run/git-candidate-preflight.js.map +1 -0
  210. package/dist/core/verified-run/git-effect-supervisor.d.ts +24 -0
  211. package/dist/core/verified-run/git-effect-supervisor.d.ts.map +1 -0
  212. package/dist/core/verified-run/git-effect-supervisor.js +174 -0
  213. package/dist/core/verified-run/git-effect-supervisor.js.map +1 -0
  214. package/dist/core/verified-run/git-execution.d.ts +27 -0
  215. package/dist/core/verified-run/git-execution.d.ts.map +1 -0
  216. package/dist/core/verified-run/git-execution.js +118 -0
  217. package/dist/core/verified-run/git-execution.js.map +1 -0
  218. package/dist/core/verified-run/git-plumbing.d.ts +37 -0
  219. package/dist/core/verified-run/git-plumbing.d.ts.map +1 -0
  220. package/dist/core/verified-run/git-plumbing.js +171 -0
  221. package/dist/core/verified-run/git-plumbing.js.map +1 -0
  222. package/dist/core/verified-run/git-publication-worker.d.ts +2 -0
  223. package/dist/core/verified-run/git-publication-worker.d.ts.map +1 -0
  224. package/dist/core/verified-run/git-publication-worker.js +54 -0
  225. package/dist/core/verified-run/git-publication-worker.js.map +1 -0
  226. package/dist/core/verified-run/git-sandbox-layout.d.ts +4 -0
  227. package/dist/core/verified-run/git-sandbox-layout.d.ts.map +1 -0
  228. package/dist/core/verified-run/git-sandbox-layout.js +29 -0
  229. package/dist/core/verified-run/git-sandbox-layout.js.map +1 -0
  230. package/dist/core/verified-run/git-worker-protocol.d.ts +19 -0
  231. package/dist/core/verified-run/git-worker-protocol.d.ts.map +1 -0
  232. package/dist/core/verified-run/git-worker-protocol.js +109 -0
  233. package/dist/core/verified-run/git-worker-protocol.js.map +1 -0
  234. package/dist/core/verified-run/git-worker-runtime.d.ts +19 -0
  235. package/dist/core/verified-run/git-worker-runtime.d.ts.map +1 -0
  236. package/dist/core/verified-run/git-worker-runtime.js +74 -0
  237. package/dist/core/verified-run/git-worker-runtime.js.map +1 -0
  238. package/dist/core/verified-run/journal.d.ts +2 -3
  239. package/dist/core/verified-run/journal.d.ts.map +1 -1
  240. package/dist/core/verified-run/journal.js.map +1 -1
  241. package/dist/core/verified-run/namespace-identity.d.ts.map +1 -1
  242. package/dist/core/verified-run/namespace-identity.js +1 -1
  243. package/dist/core/verified-run/namespace-identity.js.map +1 -1
  244. package/dist/core/verified-run/owned-execution.d.ts +10 -1
  245. package/dist/core/verified-run/owned-execution.d.ts.map +1 -1
  246. package/dist/core/verified-run/owned-execution.js +124 -31
  247. package/dist/core/verified-run/owned-execution.js.map +1 -1
  248. package/dist/core/verified-run/phase-context.d.ts +2 -0
  249. package/dist/core/verified-run/phase-context.d.ts.map +1 -1
  250. package/dist/core/verified-run/phase-context.js.map +1 -1
  251. package/dist/core/verified-run/projection.d.ts.map +1 -1
  252. package/dist/core/verified-run/projection.js +51 -1
  253. package/dist/core/verified-run/projection.js.map +1 -1
  254. package/dist/core/verified-run/publish-preflight.d.ts +12 -0
  255. package/dist/core/verified-run/publish-preflight.d.ts.map +1 -0
  256. package/dist/core/verified-run/publish-preflight.js +38 -0
  257. package/dist/core/verified-run/publish-preflight.js.map +1 -0
  258. package/dist/core/verified-run/publish-start.d.ts +5 -0
  259. package/dist/core/verified-run/publish-start.d.ts.map +1 -0
  260. package/dist/core/verified-run/publish-start.js +7 -0
  261. package/dist/core/verified-run/publish-start.js.map +1 -0
  262. package/dist/core/verified-run/recovery-projection.d.ts.map +1 -1
  263. package/dist/core/verified-run/recovery-projection.js +5 -0
  264. package/dist/core/verified-run/recovery-projection.js.map +1 -1
  265. package/dist/core/verified-run/recovery.d.ts +5 -1
  266. package/dist/core/verified-run/recovery.d.ts.map +1 -1
  267. package/dist/core/verified-run/recovery.js +10 -4
  268. package/dist/core/verified-run/recovery.js.map +1 -1
  269. package/dist/core/verified-run/run-plan.d.ts +17 -0
  270. package/dist/core/verified-run/run-plan.d.ts.map +1 -0
  271. package/dist/core/verified-run/run-plan.js +18 -0
  272. package/dist/core/verified-run/run-plan.js.map +1 -0
  273. package/dist/core/verified-run/run-publish-owned.d.ts +6 -0
  274. package/dist/core/verified-run/run-publish-owned.d.ts.map +1 -0
  275. package/dist/core/verified-run/run-publish-owned.js +199 -0
  276. package/dist/core/verified-run/run-publish-owned.js.map +1 -0
  277. package/dist/core/verified-run/run-publish.d.ts +19 -0
  278. package/dist/core/verified-run/run-publish.d.ts.map +1 -0
  279. package/dist/core/verified-run/run-publish.js +210 -0
  280. package/dist/core/verified-run/run-publish.js.map +1 -0
  281. package/dist/core/verified-run/run-status-owned.d.ts +4 -0
  282. package/dist/core/verified-run/run-status-owned.d.ts.map +1 -0
  283. package/dist/core/verified-run/run-status-owned.js +14 -0
  284. package/dist/core/verified-run/run-status-owned.js.map +1 -0
  285. package/dist/core/verified-run/run-status.d.ts +133 -0
  286. package/dist/core/verified-run/run-status.d.ts.map +1 -0
  287. package/dist/core/verified-run/run-status.js +193 -0
  288. package/dist/core/verified-run/run-status.js.map +1 -0
  289. package/dist/core/verified-run/run-types.d.ts +31 -0
  290. package/dist/core/verified-run/run-types.d.ts.map +1 -1
  291. package/dist/core/verified-run/run-types.js.map +1 -1
  292. package/dist/core/verified-run/storage.d.ts.map +1 -1
  293. package/dist/core/verified-run/storage.js +1 -1
  294. package/dist/core/verified-run/storage.js.map +1 -1
  295. package/dist/core/verified-run/supervisor-adapter.d.ts +77 -0
  296. package/dist/core/verified-run/supervisor-adapter.d.ts.map +1 -0
  297. package/dist/core/verified-run/supervisor-adapter.js +164 -0
  298. package/dist/core/verified-run/supervisor-adapter.js.map +1 -0
  299. package/dist/core/verified-run/verification-phase.d.ts.map +1 -1
  300. package/dist/core/verified-run/verification-phase.js +1 -1
  301. package/dist/core/verified-run/verification-phase.js.map +1 -1
  302. package/dist/core/verified-run/writer-phase.d.ts.map +1 -1
  303. package/dist/core/verified-run/writer-phase.js +1 -0
  304. package/dist/core/verified-run/writer-phase.js.map +1 -1
  305. package/dist/core/verified-run/writer-recovery.d.ts +2 -0
  306. package/dist/core/verified-run/writer-recovery.d.ts.map +1 -1
  307. package/dist/core/verified-run/writer-recovery.js +1 -0
  308. package/dist/core/verified-run/writer-recovery.js.map +1 -1
  309. package/dist/core/workload-shard-execution-types.d.ts +4 -1
  310. package/dist/core/workload-shard-execution-types.d.ts.map +1 -1
  311. package/dist/core/workload-shard-execution-types.js.map +1 -1
  312. package/dist/core/workload-shard-executor.d.ts +2 -2
  313. package/dist/core/workload-shard-executor.d.ts.map +1 -1
  314. package/dist/core/workload-shard-executor.js +16 -37
  315. package/dist/core/workload-shard-executor.js.map +1 -1
  316. package/dist/core/workload-shard-frontier.d.ts +5 -0
  317. package/dist/core/workload-shard-frontier.d.ts.map +1 -0
  318. package/dist/core/workload-shard-frontier.js +47 -0
  319. package/dist/core/workload-shard-frontier.js.map +1 -0
  320. package/dist/core/workload-shard-runner.d.ts.map +1 -1
  321. package/dist/core/workload-shard-runner.js +28 -17
  322. package/dist/core/workload-shard-runner.js.map +1 -1
  323. package/dist/index.d.ts +2 -5
  324. package/dist/index.d.ts.map +1 -1
  325. package/dist/index.js +1 -4
  326. package/dist/index.js.map +1 -1
  327. package/dist/main.d.ts.map +1 -1
  328. package/dist/main.js +2 -1
  329. package/dist/main.js.map +1 -1
  330. package/dist/metacognition/bridge-result.d.ts +148 -0
  331. package/dist/metacognition/bridge-result.d.ts.map +1 -0
  332. package/dist/metacognition/bridge-result.js +46 -0
  333. package/dist/metacognition/bridge-result.js.map +1 -0
  334. package/dist/metacognition/calibration-selective.d.ts.map +1 -1
  335. package/dist/metacognition/calibration-selective.js +8 -2
  336. package/dist/metacognition/calibration-selective.js.map +1 -1
  337. package/dist/metacognition/index.d.ts +1 -0
  338. package/dist/metacognition/index.d.ts.map +1 -1
  339. package/dist/metacognition/index.js +1 -0
  340. package/dist/metacognition/index.js.map +1 -1
  341. package/dist/metacognition/risk.d.ts.map +1 -1
  342. package/dist/metacognition/risk.js +28 -14
  343. package/dist/metacognition/risk.js.map +1 -1
  344. package/dist/metacognition/runtime-bridge.d.ts +41 -14
  345. package/dist/metacognition/runtime-bridge.d.ts.map +1 -1
  346. package/dist/metacognition/runtime-bridge.js +357 -39
  347. package/dist/metacognition/runtime-bridge.js.map +1 -1
  348. package/dist/modes/interactive/components/assistant-message.d.ts +2 -0
  349. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  350. package/dist/modes/interactive/components/assistant-message.js +42 -26
  351. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  352. package/dist/modes/interactive/components/chat-container.d.ts +7 -0
  353. package/dist/modes/interactive/components/chat-container.d.ts.map +1 -0
  354. package/dist/modes/interactive/components/chat-container.js +14 -0
  355. package/dist/modes/interactive/components/chat-container.js.map +1 -0
  356. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  357. package/dist/modes/interactive/components/dynamic-border.js +4 -2
  358. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  359. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  360. package/dist/modes/interactive/components/login-dialog.js +0 -1
  361. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  362. package/dist/modes/interactive/components/session-selector-async-search.d.ts +33 -0
  363. package/dist/modes/interactive/components/session-selector-async-search.d.ts.map +1 -0
  364. package/dist/modes/interactive/components/session-selector-async-search.js +109 -0
  365. package/dist/modes/interactive/components/session-selector-async-search.js.map +1 -0
  366. package/dist/modes/interactive/components/session-selector-loaders.d.ts +6 -0
  367. package/dist/modes/interactive/components/session-selector-loaders.d.ts.map +1 -0
  368. package/dist/modes/interactive/components/session-selector-loaders.js +9 -0
  369. package/dist/modes/interactive/components/session-selector-loaders.js.map +1 -0
  370. package/dist/modes/interactive/components/session-selector-search.d.ts +1 -1
  371. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  372. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  373. package/dist/modes/interactive/components/session-selector-tree.d.ts +16 -0
  374. package/dist/modes/interactive/components/session-selector-tree.d.ts.map +1 -0
  375. package/dist/modes/interactive/components/session-selector-tree.js +46 -0
  376. package/dist/modes/interactive/components/session-selector-tree.js.map +1 -0
  377. package/dist/modes/interactive/components/session-selector.d.ts +6 -1
  378. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  379. package/dist/modes/interactive/components/session-selector.js +36 -76
  380. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  381. package/dist/modes/interactive/components/tool-execution-images.d.ts +32 -0
  382. package/dist/modes/interactive/components/tool-execution-images.d.ts.map +1 -0
  383. package/dist/modes/interactive/components/tool-execution-images.js +144 -0
  384. package/dist/modes/interactive/components/tool-execution-images.js.map +1 -0
  385. package/dist/modes/interactive/components/tool-execution.d.ts +3 -4
  386. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  387. package/dist/modes/interactive/components/tool-execution.js +22 -71
  388. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  389. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  390. package/dist/modes/interactive/interactive-mode.js +7 -9
  391. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  392. package/dist/modes/interactive/tui-diagnostics.d.ts +8 -4
  393. package/dist/modes/interactive/tui-diagnostics.d.ts.map +1 -1
  394. package/dist/modes/interactive/tui-diagnostics.js +35 -1
  395. package/dist/modes/interactive/tui-diagnostics.js.map +1 -1
  396. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  397. package/dist/modes/rpc/rpc-mode.js +14 -17
  398. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  399. package/dist/modes/rpc/rpc-response.d.ts +5 -0
  400. package/dist/modes/rpc/rpc-response.d.ts.map +1 -0
  401. package/dist/modes/rpc/rpc-response.js +17 -0
  402. package/dist/modes/rpc/rpc-response.js.map +1 -0
  403. package/dist/utils/exif-orientation.d.ts.map +1 -1
  404. package/dist/utils/exif-orientation.js +2 -3
  405. package/dist/utils/exif-orientation.js.map +1 -1
  406. package/dist/utils/tools-manager.d.ts.map +1 -1
  407. package/dist/utils/tools-manager.js +3 -5
  408. package/dist/utils/tools-manager.js.map +1 -1
  409. package/docs/adaptorch-preview-spec.md +7 -7
  410. package/docs/atomic-commit-planning.md +69 -0
  411. package/docs/compaction.md +26 -1
  412. package/docs/extensions.md +14 -0
  413. package/docs/mcp.md +22 -0
  414. package/docs/metacognition.md +79 -0
  415. package/docs/model-catalog-refresh.md +159 -1
  416. package/docs/models.md +1 -1
  417. package/docs/runtime-algorithms.md +49 -4
  418. package/docs/session-format.md +8 -0
  419. package/docs/sessions.md +19 -0
  420. package/docs/skills.md +19 -0
  421. package/docs/terminal-setup.md +15 -0
  422. package/docs/tui.md +41 -0
  423. package/docs/verified-run-safety.md +75 -0
  424. package/examples/extensions/custom-provider-anthropic/index.ts +1 -1
  425. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  426. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  427. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  428. package/examples/extensions/doom-overlay/wad-finder.ts +7 -3
  429. package/examples/extensions/gondolin/package-lock.json +2 -2
  430. package/examples/extensions/gondolin/package.json +1 -1
  431. package/examples/extensions/sandbox/package-lock.json +2 -2
  432. package/examples/extensions/sandbox/package.json +1 -1
  433. package/examples/extensions/with-deps/package-lock.json +2 -2
  434. package/examples/extensions/with-deps/package.json +1 -1
  435. package/npm-shrinkwrap.json +18 -18
  436. package/package.json +6 -8
@@ -0,0 +1,164 @@
1
+ import { existsSync, readdirSync, readFileSync, readlinkSync, statSync } from "node:fs";
2
+ import { performance } from "node:perf_hooks";
3
+ import { setTimeout as delay } from "node:timers/promises";
4
+ import { probeNamespace } from "./namespace-identity.js";
5
+ import { VerifiedRunError } from "./storage.js";
6
+ /**
7
+ * Owned-process supervisor boundary (WP02).
8
+ *
9
+ * Three concerns are separated here so the broker only orchestrates them:
10
+ *
11
+ * - spawn: `SUPERVISOR_SYSTEM_ARGS` + `loadSupervisorBackend` describe the only
12
+ * backend this package trusts — bubblewrap with `--unshare-all`, which puts
13
+ * the supervised command in a fresh PID namespace whose init is the only
14
+ * process the host can see. A platform without that backend has no way to
15
+ * prove termination, so callers must refuse with `unsupported_boundary`
16
+ * instead of degrading to best-effort signaling.
17
+ * - cancel: `escalateTermination` sends SIGKILL to the supervised direct
18
+ * child (the bwrap supervisor). `--die-with-parent` propagates death to the
19
+ * namespace init, and the kernel then SIGKILLs every remaining task in that
20
+ * namespace — including non-cooperative workers and detached (`setsid`)
21
+ * descendants. Signal delivery is never treated as termination.
22
+ * - termination witness: `probeNamespace` detects the recorded namespace
23
+ * init's death and `awaitBoundaryDrained` waits for it. When a PID
24
+ * namespace's init exits, the kernel SIGKILLs every remaining task in that
25
+ * namespace, so init death is the exact termination witness — a `close`
26
+ * event, a resolved promise, or a dead direct child with surviving
27
+ * descendants is not. `namespaceMemberPids` remains as a diagnostic
28
+ * enumeration only: host process-table scans are environment-dependent
29
+ * (zombies keep their ns link until reaped; foreign same-uid tasks can be
30
+ * unreadable) and have poisoned drains on kernels where either occurs.
31
+ */
32
+ export const SUPERVISOR_BINARY = "/usr/bin/bwrap";
33
+ export const SUPERVISOR_SYSTEM_ARGS = [
34
+ "--unshare-all",
35
+ "--die-with-parent",
36
+ "--new-session",
37
+ "--cap-drop",
38
+ "ALL",
39
+ "--clearenv",
40
+ "--ro-bind",
41
+ "/usr",
42
+ "/usr",
43
+ "--symlink",
44
+ "usr/bin",
45
+ "/bin",
46
+ "--symlink",
47
+ "usr/lib",
48
+ "/lib",
49
+ "--symlink",
50
+ "usr/lib64",
51
+ "/lib64",
52
+ "--proc",
53
+ "/proc",
54
+ "--dev",
55
+ "/dev",
56
+ "--tmpfs",
57
+ "/tmp",
58
+ "--setenv",
59
+ "PATH",
60
+ "/usr/bin:/bin",
61
+ "--setenv",
62
+ "LANG",
63
+ "C.UTF-8",
64
+ ];
65
+ /**
66
+ * The only termination guarantee this package honors: a private PID namespace
67
+ * plus the Linux bwrap supervisor. Anything else is refused at the boundary.
68
+ */
69
+ export function loadSupervisorBackend() {
70
+ if (process.platform !== "linux" || !existsSync(SUPERVISOR_BINARY))
71
+ throw new VerifiedRunError("unsupported_boundary");
72
+ return { binary: SUPERVISOR_BINARY, args: SUPERVISOR_SYSTEM_ARGS };
73
+ }
74
+ /**
75
+ * SIGKILL escalation to the supervised direct child. `--die-with-parent` makes
76
+ * the kernel kill the whole PID namespace once this supervisor dies, so no
77
+ * per-descendant signaling (which PID reuse would make unsafe) is needed.
78
+ */
79
+ export function escalateTermination(child) {
80
+ child.kill("SIGKILL");
81
+ }
82
+ /**
83
+ * Enumerate host PIDs of every task still inside `identity.namespace`.
84
+ *
85
+ * Membership is keyed on the recorded namespace symlink, not on the init's
86
+ * PID: a fabricated or reaped direct child cannot mask surviving descendants.
87
+ *
88
+ * A task whose namespace link cannot be read is only a candidate member when
89
+ * it could belong to the recorded boundary at all. The backend's members
90
+ * always run under our real uid — the pid namespace is owned by a user
91
+ * namespace we created and `CAP_SETUID` is dropped — so a task owned by
92
+ * another uid, or one that vanished mid-scan, cannot be a member and is
93
+ * skipped. An unreadable task owned by our uid is conservatively counted:
94
+ * failing to prove emptiness must fail closed.
95
+ */
96
+ export function namespaceMemberPids(identity) {
97
+ const members = [];
98
+ // A platform without getuid cannot exclude foreign-owned tasks, so every
99
+ // unreadable entry stays a candidate member (fail closed).
100
+ const uid = typeof process.getuid === "function" ? process.getuid() : undefined;
101
+ for (const entry of readdirSync("/proc")) {
102
+ if (!/^\d+$/.test(entry))
103
+ continue;
104
+ try {
105
+ if (readlinkSync(`/proc/${entry}/ns/pid`) !== identity.namespace)
106
+ continue;
107
+ // A zombie still carries the namespace link until reaped, but it
108
+ // cannot run: counting it as a member confuses teardown with
109
+ // survival.
110
+ const stat = readFileSync(`/proc/${entry}/stat`, "utf8");
111
+ const state = stat
112
+ .slice(stat.lastIndexOf(")") + 2)
113
+ .trim()
114
+ .split(/\s+/)[0];
115
+ if (state !== "Z" && state !== "X")
116
+ members.push(Number(entry));
117
+ }
118
+ catch (error) {
119
+ if (!(error instanceof Error && "code" in error))
120
+ continue;
121
+ if (error.code === "ENOENT" || error.code === "ESRCH")
122
+ continue;
123
+ try {
124
+ if (uid === undefined || statSync(`/proc/${entry}`).uid === uid)
125
+ members.push(Number(entry));
126
+ }
127
+ catch (statError) {
128
+ if (!(statError instanceof Error && "code" in statError) ||
129
+ (statError.code !== "ENOENT" && statError.code !== "ESRCH"))
130
+ members.push(Number(entry));
131
+ }
132
+ }
133
+ }
134
+ return members;
135
+ }
136
+ /** Init death terminates the whole namespace; a zombie init already proves teardown finished. */
137
+ export function probeOwnedNamespace(identity) {
138
+ const status = probeNamespace(identity);
139
+ return status === "gone" ? "terminated" : status;
140
+ }
141
+ /**
142
+ * Wait for the namespace init's death within budgetMs. Init death is the
143
+ * termination witness: the kernel SIGKILLs every remaining task in the PID
144
+ * namespace when its init exits, so a drained namespace needs no process-table
145
+ * enumeration. `populated`/`unknown` never release claims.
146
+ *
147
+ * `unknown` is not terminal here: teardown has a transient window where the
148
+ * init's stat is readable but its ns link read is denied or the identity
149
+ * probe is inconclusive, and that window resolves to `gone` once the kernel
150
+ * finishes teardown. Only a probe that is still inconclusive at the deadline
151
+ * stays `unknown`; a still-alive init is `populated`.
152
+ */
153
+ export async function awaitBoundaryDrained(identity, budgetMs) {
154
+ const deadline = performance.now() + Math.max(0, budgetMs);
155
+ for (;;) {
156
+ const status = probeNamespace(identity);
157
+ if (status === "gone")
158
+ return "drained";
159
+ if (performance.now() >= deadline)
160
+ return status === "alive" ? "populated" : "unknown";
161
+ await delay(Math.min(10, Math.max(1, deadline - performance.now())));
162
+ }
163
+ }
164
+ //# sourceMappingURL=supervisor-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supervisor-adapter.js","sourceRoot":"","sources":["../../../src/core/verified-run/supervisor-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readdirSync, readFileSync, readlinkSync, statSync } from \"node:fs\";\nimport { performance } from \"node:perf_hooks\";\nimport { setTimeout as delay } from \"node:timers/promises\";\nimport { type NamespaceIdentity, probeNamespace } from \"./namespace-identity.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\n/**\n * Owned-process supervisor boundary (WP02).\n *\n * Three concerns are separated here so the broker only orchestrates them:\n *\n * - spawn: `SUPERVISOR_SYSTEM_ARGS` + `loadSupervisorBackend` describe the only\n * backend this package trusts — bubblewrap with `--unshare-all`, which puts\n * the supervised command in a fresh PID namespace whose init is the only\n * process the host can see. A platform without that backend has no way to\n * prove termination, so callers must refuse with `unsupported_boundary`\n * instead of degrading to best-effort signaling.\n * - cancel: `escalateTermination` sends SIGKILL to the supervised direct\n * child (the bwrap supervisor). `--die-with-parent` propagates death to the\n * namespace init, and the kernel then SIGKILLs every remaining task in that\n * namespace — including non-cooperative workers and detached (`setsid`)\n * descendants. Signal delivery is never treated as termination.\n * - termination witness: `probeNamespace` detects the recorded namespace\n * init's death and `awaitBoundaryDrained` waits for it. When a PID\n * namespace's init exits, the kernel SIGKILLs every remaining task in that\n * namespace, so init death is the exact termination witness — a `close`\n * event, a resolved promise, or a dead direct child with surviving\n * descendants is not. `namespaceMemberPids` remains as a diagnostic\n * enumeration only: host process-table scans are environment-dependent\n * (zombies keep their ns link until reaped; foreign same-uid tasks can be\n * unreadable) and have poisoned drains on kernels where either occurs.\n */\nexport const SUPERVISOR_BINARY = \"/usr/bin/bwrap\";\n\nexport const SUPERVISOR_SYSTEM_ARGS = [\n\t\"--unshare-all\",\n\t\"--die-with-parent\",\n\t\"--new-session\",\n\t\"--cap-drop\",\n\t\"ALL\",\n\t\"--clearenv\",\n\t\"--ro-bind\",\n\t\"/usr\",\n\t\"/usr\",\n\t\"--symlink\",\n\t\"usr/bin\",\n\t\"/bin\",\n\t\"--symlink\",\n\t\"usr/lib\",\n\t\"/lib\",\n\t\"--symlink\",\n\t\"usr/lib64\",\n\t\"/lib64\",\n\t\"--proc\",\n\t\"/proc\",\n\t\"--dev\",\n\t\"/dev\",\n\t\"--tmpfs\",\n\t\"/tmp\",\n\t\"--setenv\",\n\t\"PATH\",\n\t\"/usr/bin:/bin\",\n\t\"--setenv\",\n\t\"LANG\",\n\t\"C.UTF-8\",\n] as const;\n\nexport type SupervisorChild = { readonly kill: (signal: NodeJS.Signals) => boolean };\n\n/**\n * The only termination guarantee this package honors: a private PID namespace\n * plus the Linux bwrap supervisor. Anything else is refused at the boundary.\n */\nexport function loadSupervisorBackend(): { readonly binary: string; readonly args: readonly string[] } {\n\tif (process.platform !== \"linux\" || !existsSync(SUPERVISOR_BINARY))\n\t\tthrow new VerifiedRunError(\"unsupported_boundary\");\n\treturn { binary: SUPERVISOR_BINARY, args: SUPERVISOR_SYSTEM_ARGS };\n}\n\n/**\n * SIGKILL escalation to the supervised direct child. `--die-with-parent` makes\n * the kernel kill the whole PID namespace once this supervisor dies, so no\n * per-descendant signaling (which PID reuse would make unsafe) is needed.\n */\nexport function escalateTermination(child: SupervisorChild): void {\n\tchild.kill(\"SIGKILL\");\n}\n\n/**\n * Enumerate host PIDs of every task still inside `identity.namespace`.\n *\n * Membership is keyed on the recorded namespace symlink, not on the init's\n * PID: a fabricated or reaped direct child cannot mask surviving descendants.\n *\n * A task whose namespace link cannot be read is only a candidate member when\n * it could belong to the recorded boundary at all. The backend's members\n * always run under our real uid — the pid namespace is owned by a user\n * namespace we created and `CAP_SETUID` is dropped — so a task owned by\n * another uid, or one that vanished mid-scan, cannot be a member and is\n * skipped. An unreadable task owned by our uid is conservatively counted:\n * failing to prove emptiness must fail closed.\n */\nexport function namespaceMemberPids(identity: Pick<NamespaceIdentity, \"namespace\">): number[] {\n\tconst members: number[] = [];\n\t// A platform without getuid cannot exclude foreign-owned tasks, so every\n\t// unreadable entry stays a candidate member (fail closed).\n\tconst uid = typeof process.getuid === \"function\" ? process.getuid() : undefined;\n\tfor (const entry of readdirSync(\"/proc\")) {\n\t\tif (!/^\\d+$/.test(entry)) continue;\n\t\ttry {\n\t\t\tif (readlinkSync(`/proc/${entry}/ns/pid`) !== identity.namespace) continue;\n\t\t\t// A zombie still carries the namespace link until reaped, but it\n\t\t\t// cannot run: counting it as a member confuses teardown with\n\t\t\t// survival.\n\t\t\tconst stat = readFileSync(`/proc/${entry}/stat`, \"utf8\");\n\t\t\tconst state = stat\n\t\t\t\t.slice(stat.lastIndexOf(\")\") + 2)\n\t\t\t\t.trim()\n\t\t\t\t.split(/\\s+/)[0];\n\t\t\tif (state !== \"Z\" && state !== \"X\") members.push(Number(entry));\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof Error && \"code\" in error)) continue;\n\t\t\tif (error.code === \"ENOENT\" || error.code === \"ESRCH\") continue;\n\t\t\ttry {\n\t\t\t\tif (uid === undefined || statSync(`/proc/${entry}`).uid === uid) members.push(Number(entry));\n\t\t\t} catch (statError) {\n\t\t\t\tif (\n\t\t\t\t\t!(statError instanceof Error && \"code\" in statError) ||\n\t\t\t\t\t(statError.code !== \"ENOENT\" && statError.code !== \"ESRCH\")\n\t\t\t\t)\n\t\t\t\t\tmembers.push(Number(entry));\n\t\t\t}\n\t\t}\n\t}\n\treturn members;\n}\n\n/** Init death terminates the whole namespace; a zombie init already proves teardown finished. */\nexport function probeOwnedNamespace(identity: NamespaceIdentity): \"terminated\" | \"alive\" | \"unknown\" {\n\tconst status = probeNamespace(identity);\n\treturn status === \"gone\" ? \"terminated\" : status;\n}\n\n/**\n * Wait for the namespace init's death within budgetMs. Init death is the\n * termination witness: the kernel SIGKILLs every remaining task in the PID\n * namespace when its init exits, so a drained namespace needs no process-table\n * enumeration. `populated`/`unknown` never release claims.\n *\n * `unknown` is not terminal here: teardown has a transient window where the\n * init's stat is readable but its ns link read is denied or the identity\n * probe is inconclusive, and that window resolves to `gone` once the kernel\n * finishes teardown. Only a probe that is still inconclusive at the deadline\n * stays `unknown`; a still-alive init is `populated`.\n */\nexport async function awaitBoundaryDrained(\n\tidentity: NamespaceIdentity,\n\tbudgetMs: number,\n): Promise<\"drained\" | \"populated\" | \"unknown\"> {\n\tconst deadline = performance.now() + Math.max(0, budgetMs);\n\tfor (;;) {\n\t\tconst status = probeNamespace(identity);\n\t\tif (status === \"gone\") return \"drained\";\n\t\tif (performance.now() >= deadline) return status === \"alive\" ? \"populated\" : \"unknown\";\n\t\tawait delay(Math.min(10, Math.max(1, deadline - performance.now())));\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"verification-phase.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/verification-phase.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGpD,qGAAqG;AACrG,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC,CAiDtF","sourcesContent":["import { join } from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport { commandEnvironmentDigest } from \"./broker.ts\";\nimport { captureCandidate, loadCandidate, materializeCandidate } from \"./candidate.ts\";\nimport { storeCheckReceipt } from \"./check-receipt.ts\";\nimport { type CheckObservation, issueRunEvidence } from \"./evidence.ts\";\nimport { executeRunCommand } from \"./owned-execution.ts\";\nimport type { RunPhaseContext } from \"./phase-context.ts\";\nimport { localVerificationDeadline } from \"./recovery-clock.ts\";\nimport type { RunProjection } from \"./run-types.ts\";\nimport { digestBytes, VerifiedRunError } from \"./storage.ts\";\n\n/** Both start and resume use this same verification path; no writer/model code is reachable here. */\nexport async function verifyCandidate(context: RunPhaseContext): Promise<RunProjection> {\n\tconst { contract, journal, runPath } = context;\n\tconst state = journal.state;\n\tif (!state.candidateDigest || !state.budget || state.verificationDeadlineMs === null || !state.environmentDigest)\n\t\tthrow new VerifiedRunError(\"resume_unavailable\");\n\tconst deadline = localVerificationDeadline(state.budget, state.verificationDeadlineMs);\n\tif (commandEnvironmentDigest(contract, \"gated-v1\") !== state.environmentDigest)\n\t\tthrow new VerifiedRunError(\"environment_changed\");\n\tconst candidate = loadCandidate(runPath, state.candidateDigest, contract.budget);\n\tconst fixed = join(runPath, state.generation === 1 ? \"candidate\" : `candidate-${state.generation}`);\n\tmaterializeCandidate(candidate, fixed);\n\tconst checks: CheckObservation[] = [];\n\tfor (const check of contract.checks) {\n\t\tconst { executionId, result, timeoutMs } = await executeRunCommand(\n\t\t\tjournal,\n\t\t\t{ role: \"verifier\", argv: check.argv, workspace: fixed, deadline, claimId: check.claimId },\n\t\t\t{ ...contract.budget, ...(context.signal ? { signal: context.signal } : {}) },\n\t\t);\n\t\tchecks.push({\n\t\t\tclaimId: check.claimId,\n\t\t\texecutionId,\n\t\t\tstdoutDigest: digestBytes(result.stdout),\n\t\t\tstderrDigest: digestBytes(result.stderr),\n\t\t\texitCode: result.exitCode,\n\t\t\tfailure: result.failure,\n\t\t\treceiptCoreDigest: storeCheckReceipt(runPath, contract, {\n\t\t\t\tcheck,\n\t\t\t\texecutionId,\n\t\t\t\tresult,\n\t\t\t\ttimeoutMs,\n\t\t\t\tmanifest: candidate.manifest,\n\t\t\t}),\n\t\t});\n\t}\n\tif (\n\t\tcaptureCandidate(fixed, contract.budget).digest !== state.candidateDigest ||\n\t\tcommandEnvironmentDigest(contract, \"gated-v1\") !== state.environmentDigest\n\t)\n\t\tthrow new VerifiedRunError(\"integrity\");\n\tif (performance.now() >= deadline) throw new VerifiedRunError(\"deadline\");\n\tconst receipt = issueRunEvidence(runPath, contract, {\n\t\tgeneration: state.generation,\n\t\tcandidateDigest: state.candidateDigest,\n\t\tenvironmentDigest: state.environmentDigest,\n\t\tchecks,\n\t});\n\tif (performance.now() >= deadline || journal.state.generation !== state.generation)\n\t\tthrow new VerifiedRunError(\"deadline\");\n\treturn journal.append({ kind: \"evaluated\", receiptDigest: receipt.digest, verified: receipt.verified });\n}\n"]}
1
+ {"version":3,"file":"verification-phase.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/verification-phase.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGpD,qGAAqG;AACrG,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC,CAiDtF","sourcesContent":["import { join } from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport { commandEnvironmentDigest } from \"./broker.ts\";\nimport { captureCandidate, loadCandidate, materializeCandidate } from \"./candidate.ts\";\nimport { storeCheckReceipt } from \"./check-receipt.ts\";\nimport { type CheckObservation, issueRunEvidence } from \"./evidence.ts\";\nimport { executeRunCommand } from \"./owned-execution.ts\";\nimport type { RunPhaseContext } from \"./phase-context.ts\";\nimport { localVerificationDeadline } from \"./recovery-clock.ts\";\nimport type { RunProjection } from \"./run-types.ts\";\nimport { digestBytes, VerifiedRunError } from \"./storage.ts\";\n\n/** Both start and resume use this same verification path; no writer/model code is reachable here. */\nexport async function verifyCandidate(context: RunPhaseContext): Promise<RunProjection> {\n\tconst { contract, journal, runPath } = context;\n\tconst state = journal.state;\n\tif (!state.candidateDigest || !state.budget || state.verificationDeadlineMs === null || !state.environmentDigest)\n\t\tthrow new VerifiedRunError(\"resume_unavailable\");\n\tconst deadline = localVerificationDeadline(state.budget, state.verificationDeadlineMs);\n\tif (commandEnvironmentDigest(contract, \"gated-v1\") !== state.environmentDigest)\n\t\tthrow new VerifiedRunError(\"environment_changed\");\n\tconst candidate = loadCandidate(runPath, state.candidateDigest, contract.budget);\n\tconst fixed = join(runPath, state.generation === 1 ? \"candidate\" : `candidate-${state.generation}`);\n\tmaterializeCandidate(candidate, fixed);\n\tconst checks: CheckObservation[] = [];\n\tfor (const check of contract.checks) {\n\t\tconst { executionId, result, timeoutMs } = await executeRunCommand(\n\t\t\tjournal,\n\t\t\t{ role: \"verifier\", argv: check.argv, workspace: fixed, deadline, claimId: check.claimId },\n\t\t\t{ ...contract.budget, authority: context.authority, ...(context.signal ? { signal: context.signal } : {}) },\n\t\t);\n\t\tchecks.push({\n\t\t\tclaimId: check.claimId,\n\t\t\texecutionId,\n\t\t\tstdoutDigest: digestBytes(result.stdout),\n\t\t\tstderrDigest: digestBytes(result.stderr),\n\t\t\texitCode: result.exitCode,\n\t\t\tfailure: result.failure,\n\t\t\treceiptCoreDigest: storeCheckReceipt(runPath, contract, {\n\t\t\t\tcheck,\n\t\t\t\texecutionId,\n\t\t\t\tresult,\n\t\t\t\ttimeoutMs,\n\t\t\t\tmanifest: candidate.manifest,\n\t\t\t}),\n\t\t});\n\t}\n\tif (\n\t\tcaptureCandidate(fixed, contract.budget).digest !== state.candidateDigest ||\n\t\tcommandEnvironmentDigest(contract, \"gated-v1\") !== state.environmentDigest\n\t)\n\t\tthrow new VerifiedRunError(\"integrity\");\n\tif (performance.now() >= deadline) throw new VerifiedRunError(\"deadline\");\n\tconst receipt = issueRunEvidence(runPath, contract, {\n\t\tgeneration: state.generation,\n\t\tcandidateDigest: state.candidateDigest,\n\t\tenvironmentDigest: state.environmentDigest,\n\t\tchecks,\n\t});\n\tif (performance.now() >= deadline || journal.state.generation !== state.generation)\n\t\tthrow new VerifiedRunError(\"deadline\");\n\treturn journal.append({ kind: \"evaluated\", receiptDigest: receipt.digest, verified: receipt.verified });\n}\n"]}
@@ -21,7 +21,7 @@ export async function verifyCandidate(context) {
21
21
  materializeCandidate(candidate, fixed);
22
22
  const checks = [];
23
23
  for (const check of contract.checks) {
24
- const { executionId, result, timeoutMs } = await executeRunCommand(journal, { role: "verifier", argv: check.argv, workspace: fixed, deadline, claimId: check.claimId }, { ...contract.budget, ...(context.signal ? { signal: context.signal } : {}) });
24
+ const { executionId, result, timeoutMs } = await executeRunCommand(journal, { role: "verifier", argv: check.argv, workspace: fixed, deadline, claimId: check.claimId }, { ...contract.budget, authority: context.authority, ...(context.signal ? { signal: context.signal } : {}) });
25
25
  checks.push({
26
26
  claimId: check.claimId,
27
27
  executionId,
@@ -1 +1 @@
1
- {"version":3,"file":"verification-phase.js","sourceRoot":"","sources":["../../../src/core/verified-run/verification-phase.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport { commandEnvironmentDigest } from \"./broker.ts\";\nimport { captureCandidate, loadCandidate, materializeCandidate } from \"./candidate.ts\";\nimport { storeCheckReceipt } from \"./check-receipt.ts\";\nimport { type CheckObservation, issueRunEvidence } from \"./evidence.ts\";\nimport { executeRunCommand } from \"./owned-execution.ts\";\nimport type { RunPhaseContext } from \"./phase-context.ts\";\nimport { localVerificationDeadline } from \"./recovery-clock.ts\";\nimport type { RunProjection } from \"./run-types.ts\";\nimport { digestBytes, VerifiedRunError } from \"./storage.ts\";\n\n/** Both start and resume use this same verification path; no writer/model code is reachable here. */\nexport async function verifyCandidate(context: RunPhaseContext): Promise<RunProjection> {\n\tconst { contract, journal, runPath } = context;\n\tconst state = journal.state;\n\tif (!state.candidateDigest || !state.budget || state.verificationDeadlineMs === null || !state.environmentDigest)\n\t\tthrow new VerifiedRunError(\"resume_unavailable\");\n\tconst deadline = localVerificationDeadline(state.budget, state.verificationDeadlineMs);\n\tif (commandEnvironmentDigest(contract, \"gated-v1\") !== state.environmentDigest)\n\t\tthrow new VerifiedRunError(\"environment_changed\");\n\tconst candidate = loadCandidate(runPath, state.candidateDigest, contract.budget);\n\tconst fixed = join(runPath, state.generation === 1 ? \"candidate\" : `candidate-${state.generation}`);\n\tmaterializeCandidate(candidate, fixed);\n\tconst checks: CheckObservation[] = [];\n\tfor (const check of contract.checks) {\n\t\tconst { executionId, result, timeoutMs } = await executeRunCommand(\n\t\t\tjournal,\n\t\t\t{ role: \"verifier\", argv: check.argv, workspace: fixed, deadline, claimId: check.claimId },\n\t\t\t{ ...contract.budget, ...(context.signal ? { signal: context.signal } : {}) },\n\t\t);\n\t\tchecks.push({\n\t\t\tclaimId: check.claimId,\n\t\t\texecutionId,\n\t\t\tstdoutDigest: digestBytes(result.stdout),\n\t\t\tstderrDigest: digestBytes(result.stderr),\n\t\t\texitCode: result.exitCode,\n\t\t\tfailure: result.failure,\n\t\t\treceiptCoreDigest: storeCheckReceipt(runPath, contract, {\n\t\t\t\tcheck,\n\t\t\t\texecutionId,\n\t\t\t\tresult,\n\t\t\t\ttimeoutMs,\n\t\t\t\tmanifest: candidate.manifest,\n\t\t\t}),\n\t\t});\n\t}\n\tif (\n\t\tcaptureCandidate(fixed, contract.budget).digest !== state.candidateDigest ||\n\t\tcommandEnvironmentDigest(contract, \"gated-v1\") !== state.environmentDigest\n\t)\n\t\tthrow new VerifiedRunError(\"integrity\");\n\tif (performance.now() >= deadline) throw new VerifiedRunError(\"deadline\");\n\tconst receipt = issueRunEvidence(runPath, contract, {\n\t\tgeneration: state.generation,\n\t\tcandidateDigest: state.candidateDigest,\n\t\tenvironmentDigest: state.environmentDigest,\n\t\tchecks,\n\t});\n\tif (performance.now() >= deadline || journal.state.generation !== state.generation)\n\t\tthrow new VerifiedRunError(\"deadline\");\n\treturn journal.append({ kind: \"evaluated\", receiptDigest: receipt.digest, verified: receipt.verified });\n}\n"]}
1
+ {"version":3,"file":"verification-phase.js","sourceRoot":"","sources":["../../../src/core/verified-run/verification-phase.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport { commandEnvironmentDigest } from \"./broker.ts\";\nimport { captureCandidate, loadCandidate, materializeCandidate } from \"./candidate.ts\";\nimport { storeCheckReceipt } from \"./check-receipt.ts\";\nimport { type CheckObservation, issueRunEvidence } from \"./evidence.ts\";\nimport { executeRunCommand } from \"./owned-execution.ts\";\nimport type { RunPhaseContext } from \"./phase-context.ts\";\nimport { localVerificationDeadline } from \"./recovery-clock.ts\";\nimport type { RunProjection } from \"./run-types.ts\";\nimport { digestBytes, VerifiedRunError } from \"./storage.ts\";\n\n/** Both start and resume use this same verification path; no writer/model code is reachable here. */\nexport async function verifyCandidate(context: RunPhaseContext): Promise<RunProjection> {\n\tconst { contract, journal, runPath } = context;\n\tconst state = journal.state;\n\tif (!state.candidateDigest || !state.budget || state.verificationDeadlineMs === null || !state.environmentDigest)\n\t\tthrow new VerifiedRunError(\"resume_unavailable\");\n\tconst deadline = localVerificationDeadline(state.budget, state.verificationDeadlineMs);\n\tif (commandEnvironmentDigest(contract, \"gated-v1\") !== state.environmentDigest)\n\t\tthrow new VerifiedRunError(\"environment_changed\");\n\tconst candidate = loadCandidate(runPath, state.candidateDigest, contract.budget);\n\tconst fixed = join(runPath, state.generation === 1 ? \"candidate\" : `candidate-${state.generation}`);\n\tmaterializeCandidate(candidate, fixed);\n\tconst checks: CheckObservation[] = [];\n\tfor (const check of contract.checks) {\n\t\tconst { executionId, result, timeoutMs } = await executeRunCommand(\n\t\t\tjournal,\n\t\t\t{ role: \"verifier\", argv: check.argv, workspace: fixed, deadline, claimId: check.claimId },\n\t\t\t{ ...contract.budget, authority: context.authority, ...(context.signal ? { signal: context.signal } : {}) },\n\t\t);\n\t\tchecks.push({\n\t\t\tclaimId: check.claimId,\n\t\t\texecutionId,\n\t\t\tstdoutDigest: digestBytes(result.stdout),\n\t\t\tstderrDigest: digestBytes(result.stderr),\n\t\t\texitCode: result.exitCode,\n\t\t\tfailure: result.failure,\n\t\t\treceiptCoreDigest: storeCheckReceipt(runPath, contract, {\n\t\t\t\tcheck,\n\t\t\t\texecutionId,\n\t\t\t\tresult,\n\t\t\t\ttimeoutMs,\n\t\t\t\tmanifest: candidate.manifest,\n\t\t\t}),\n\t\t});\n\t}\n\tif (\n\t\tcaptureCandidate(fixed, contract.budget).digest !== state.candidateDigest ||\n\t\tcommandEnvironmentDigest(contract, \"gated-v1\") !== state.environmentDigest\n\t)\n\t\tthrow new VerifiedRunError(\"integrity\");\n\tif (performance.now() >= deadline) throw new VerifiedRunError(\"deadline\");\n\tconst receipt = issueRunEvidence(runPath, contract, {\n\t\tgeneration: state.generation,\n\t\tcandidateDigest: state.candidateDigest,\n\t\tenvironmentDigest: state.environmentDigest,\n\t\tchecks,\n\t});\n\tif (performance.now() >= deadline || journal.state.generation !== state.generation)\n\t\tthrow new VerifiedRunError(\"deadline\");\n\treturn journal.append({ kind: \"evaluated\", receiptDigest: receipt.digest, verified: receipt.verified });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"writer-phase.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/writer-phase.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG5D,wBAAsB,aAAa,CAClC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE;IACR,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC;CACtC,GACC,OAAO,CAAC,IAAI,CAAC,CA+Df","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { performance } from \"node:perf_hooks\";\nimport { executeDag } from \"./dag-phase.ts\";\nimport { executeRunCommand, type OwnedRunCommand } from \"./owned-execution.ts\";\nimport type { RunPhaseContext } from \"./phase-context.ts\";\nimport { executeScriptedWriter } from \"./scripted-writer.ts\";\nimport type { VerifiedRunRuntime } from \"./session-port.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\nexport async function executeWriter(\n\tcontext: RunPhaseContext,\n\toptions: {\n\t\treadonly workspace: string;\n\t\treadonly deadline: number;\n\t\treadonly runtime?: VerifiedRunRuntime;\n\t},\n): Promise<void> {\n\tconst { contract, journal } = context;\n\tconst execute = (request: OwnedRunCommand, toolSignal?: AbortSignal) => {\n\t\tconst signals = [context.signal, toolSignal].filter((signal): signal is AbortSignal => signal !== undefined);\n\t\treturn executeRunCommand(journal, request, {\n\t\t\t...contract.budget,\n\t\t\t...(signals.length ? { signal: AbortSignal.any(signals) } : {}),\n\t\t});\n\t};\n\tswitch (contract.profile) {\n\t\tcase \"linux-command-dag-v1\":\n\t\t\treturn executeDag(context, options);\n\t\tcase \"linux-command-v1\": {\n\t\t\tconst writer = await execute({\n\t\t\t\trole: \"writer\",\n\t\t\t\targv: contract.writer,\n\t\t\t\tworkspace: options.workspace,\n\t\t\t\tdeadline: options.deadline,\n\t\t\t\tclaimId: null,\n\t\t\t});\n\t\t\tif (writer.result.failure) throw new VerifiedRunError(writer.result.failure);\n\t\t\treturn;\n\t\t}\n\t\tcase \"linux-scripted-agent-v1\": {\n\t\t\tconst runtime = options.runtime;\n\t\t\tif (!runtime) throw new VerifiedRunError(\"writer_backend_missing\");\n\t\t\tconst writer = contract.writer;\n\t\t\tconst requestLimit = writer.maxRequests - journal.state.modelRequests;\n\t\t\tif (requestLimit <= 0) throw new VerifiedRunError(\"model_request_limit\");\n\t\t\tjournal.append({ kind: \"writer_opened\" });\n\t\t\tlet completed = false;\n\t\t\ttry {\n\t\t\t\tawait executeScriptedWriter(writer, contract.goal, {\n\t\t\t\t\truntime,\n\t\t\t\t\tworkspace: options.workspace,\n\t\t\t\t\tdeadline: options.deadline,\n\t\t\t\t\trequestLimit,\n\t\t\t\t\t...(context.signal ? { signal: context.signal } : {}),\n\t\t\t\t\tbeforeRequest: () => {\n\t\t\t\t\t\tif (performance.now() >= options.deadline) throw new VerifiedRunError(\"deadline\");\n\t\t\t\t\t\tjournal.append({ kind: \"model_request\", requestId: randomUUID() });\n\t\t\t\t\t\tif (performance.now() >= options.deadline) throw new VerifiedRunError(\"deadline\");\n\t\t\t\t\t},\n\t\t\t\t\texecuteStep: (index, signal) => {\n\t\t\t\t\t\tconst argv = writer.steps[index];\n\t\t\t\t\t\tif (!argv) throw new VerifiedRunError(\"writer_step\");\n\t\t\t\t\t\treturn execute(\n\t\t\t\t\t\t\t{ role: \"writer\", argv, workspace: options.workspace, deadline: options.deadline, claimId: null },\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tcompleted = true;\n\t\t\t} finally {\n\t\t\t\tif (journal.state.activeExecutionIds.length === 0) journal.append({ kind: \"writer_closed\", completed });\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tdefault: {\n\t\t\tconst exhaustive: never = contract;\n\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"writer-phase.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/writer-phase.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG5D,wBAAsB,aAAa,CAClC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE;IACR,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC;CACtC,GACC,OAAO,CAAC,IAAI,CAAC,CAgEf","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { performance } from \"node:perf_hooks\";\nimport { executeDag } from \"./dag-phase.ts\";\nimport { executeRunCommand, type OwnedRunCommand } from \"./owned-execution.ts\";\nimport type { RunPhaseContext } from \"./phase-context.ts\";\nimport { executeScriptedWriter } from \"./scripted-writer.ts\";\nimport type { VerifiedRunRuntime } from \"./session-port.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\nexport async function executeWriter(\n\tcontext: RunPhaseContext,\n\toptions: {\n\t\treadonly workspace: string;\n\t\treadonly deadline: number;\n\t\treadonly runtime?: VerifiedRunRuntime;\n\t},\n): Promise<void> {\n\tconst { contract, journal } = context;\n\tconst execute = (request: OwnedRunCommand, toolSignal?: AbortSignal) => {\n\t\tconst signals = [context.signal, toolSignal].filter((signal): signal is AbortSignal => signal !== undefined);\n\t\treturn executeRunCommand(journal, request, {\n\t\t\t...contract.budget,\n\t\t\tauthority: context.authority,\n\t\t\t...(signals.length ? { signal: AbortSignal.any(signals) } : {}),\n\t\t});\n\t};\n\tswitch (contract.profile) {\n\t\tcase \"linux-command-dag-v1\":\n\t\t\treturn executeDag(context, options);\n\t\tcase \"linux-command-v1\": {\n\t\t\tconst writer = await execute({\n\t\t\t\trole: \"writer\",\n\t\t\t\targv: contract.writer,\n\t\t\t\tworkspace: options.workspace,\n\t\t\t\tdeadline: options.deadline,\n\t\t\t\tclaimId: null,\n\t\t\t});\n\t\t\tif (writer.result.failure) throw new VerifiedRunError(writer.result.failure);\n\t\t\treturn;\n\t\t}\n\t\tcase \"linux-scripted-agent-v1\": {\n\t\t\tconst runtime = options.runtime;\n\t\t\tif (!runtime) throw new VerifiedRunError(\"writer_backend_missing\");\n\t\t\tconst writer = contract.writer;\n\t\t\tconst requestLimit = writer.maxRequests - journal.state.modelRequests;\n\t\t\tif (requestLimit <= 0) throw new VerifiedRunError(\"model_request_limit\");\n\t\t\tjournal.append({ kind: \"writer_opened\" });\n\t\t\tlet completed = false;\n\t\t\ttry {\n\t\t\t\tawait executeScriptedWriter(writer, contract.goal, {\n\t\t\t\t\truntime,\n\t\t\t\t\tworkspace: options.workspace,\n\t\t\t\t\tdeadline: options.deadline,\n\t\t\t\t\trequestLimit,\n\t\t\t\t\t...(context.signal ? { signal: context.signal } : {}),\n\t\t\t\t\tbeforeRequest: () => {\n\t\t\t\t\t\tif (performance.now() >= options.deadline) throw new VerifiedRunError(\"deadline\");\n\t\t\t\t\t\tjournal.append({ kind: \"model_request\", requestId: randomUUID() });\n\t\t\t\t\t\tif (performance.now() >= options.deadline) throw new VerifiedRunError(\"deadline\");\n\t\t\t\t\t},\n\t\t\t\t\texecuteStep: (index, signal) => {\n\t\t\t\t\t\tconst argv = writer.steps[index];\n\t\t\t\t\t\tif (!argv) throw new VerifiedRunError(\"writer_step\");\n\t\t\t\t\t\treturn execute(\n\t\t\t\t\t\t\t{ role: \"writer\", argv, workspace: options.workspace, deadline: options.deadline, claimId: null },\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tcompleted = true;\n\t\t\t} finally {\n\t\t\t\tif (journal.state.activeExecutionIds.length === 0) journal.append({ kind: \"writer_closed\", completed });\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tdefault: {\n\t\t\tconst exhaustive: never = contract;\n\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t}\n\t}\n}\n"]}
@@ -10,6 +10,7 @@ export async function executeWriter(context, options) {
10
10
  const signals = [context.signal, toolSignal].filter((signal) => signal !== undefined);
11
11
  return executeRunCommand(journal, request, {
12
12
  ...contract.budget,
13
+ authority: context.authority,
13
14
  ...(signals.length ? { signal: AbortSignal.any(signals) } : {}),
14
15
  });
15
16
  };
@@ -1 +1 @@
1
- {"version":3,"file":"writer-phase.js","sourceRoot":"","sources":["../../../src/core/verified-run/writer-phase.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { performance } from \"node:perf_hooks\";\nimport { executeDag } from \"./dag-phase.ts\";\nimport { executeRunCommand, type OwnedRunCommand } from \"./owned-execution.ts\";\nimport type { RunPhaseContext } from \"./phase-context.ts\";\nimport { executeScriptedWriter } from \"./scripted-writer.ts\";\nimport type { VerifiedRunRuntime } from \"./session-port.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\nexport async function executeWriter(\n\tcontext: RunPhaseContext,\n\toptions: {\n\t\treadonly workspace: string;\n\t\treadonly deadline: number;\n\t\treadonly runtime?: VerifiedRunRuntime;\n\t},\n): Promise<void> {\n\tconst { contract, journal } = context;\n\tconst execute = (request: OwnedRunCommand, toolSignal?: AbortSignal) => {\n\t\tconst signals = [context.signal, toolSignal].filter((signal): signal is AbortSignal => signal !== undefined);\n\t\treturn executeRunCommand(journal, request, {\n\t\t\t...contract.budget,\n\t\t\t...(signals.length ? { signal: AbortSignal.any(signals) } : {}),\n\t\t});\n\t};\n\tswitch (contract.profile) {\n\t\tcase \"linux-command-dag-v1\":\n\t\t\treturn executeDag(context, options);\n\t\tcase \"linux-command-v1\": {\n\t\t\tconst writer = await execute({\n\t\t\t\trole: \"writer\",\n\t\t\t\targv: contract.writer,\n\t\t\t\tworkspace: options.workspace,\n\t\t\t\tdeadline: options.deadline,\n\t\t\t\tclaimId: null,\n\t\t\t});\n\t\t\tif (writer.result.failure) throw new VerifiedRunError(writer.result.failure);\n\t\t\treturn;\n\t\t}\n\t\tcase \"linux-scripted-agent-v1\": {\n\t\t\tconst runtime = options.runtime;\n\t\t\tif (!runtime) throw new VerifiedRunError(\"writer_backend_missing\");\n\t\t\tconst writer = contract.writer;\n\t\t\tconst requestLimit = writer.maxRequests - journal.state.modelRequests;\n\t\t\tif (requestLimit <= 0) throw new VerifiedRunError(\"model_request_limit\");\n\t\t\tjournal.append({ kind: \"writer_opened\" });\n\t\t\tlet completed = false;\n\t\t\ttry {\n\t\t\t\tawait executeScriptedWriter(writer, contract.goal, {\n\t\t\t\t\truntime,\n\t\t\t\t\tworkspace: options.workspace,\n\t\t\t\t\tdeadline: options.deadline,\n\t\t\t\t\trequestLimit,\n\t\t\t\t\t...(context.signal ? { signal: context.signal } : {}),\n\t\t\t\t\tbeforeRequest: () => {\n\t\t\t\t\t\tif (performance.now() >= options.deadline) throw new VerifiedRunError(\"deadline\");\n\t\t\t\t\t\tjournal.append({ kind: \"model_request\", requestId: randomUUID() });\n\t\t\t\t\t\tif (performance.now() >= options.deadline) throw new VerifiedRunError(\"deadline\");\n\t\t\t\t\t},\n\t\t\t\t\texecuteStep: (index, signal) => {\n\t\t\t\t\t\tconst argv = writer.steps[index];\n\t\t\t\t\t\tif (!argv) throw new VerifiedRunError(\"writer_step\");\n\t\t\t\t\t\treturn execute(\n\t\t\t\t\t\t\t{ role: \"writer\", argv, workspace: options.workspace, deadline: options.deadline, claimId: null },\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tcompleted = true;\n\t\t\t} finally {\n\t\t\t\tif (journal.state.activeExecutionIds.length === 0) journal.append({ kind: \"writer_closed\", completed });\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tdefault: {\n\t\t\tconst exhaustive: never = contract;\n\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"writer-phase.js","sourceRoot":"","sources":["../../../src/core/verified-run/writer-phase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAwB,MAAM,sBAAsB,CAAC;AAE/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,OAAwB,EACxB,OAIC,EACe;IAChB,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACtC,MAAM,OAAO,GAAG,CAAC,OAAwB,EAAE,UAAwB,EAAE,EAAE,CAAC;QACvE,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAAyB,EAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;QAC7G,OAAO,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE;YAC1C,GAAG,QAAQ,CAAC,MAAM;YAClB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC/D,CAAC,CAAC;IAAA,CACH,CAAC;IACF,QAAQ,QAAQ,CAAC,OAAO,EAAE,CAAC;QAC1B,KAAK,sBAAsB;YAC1B,OAAO,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACrC,KAAK,kBAAkB,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;gBAC5B,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ,CAAC,MAAM;gBACrB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,OAAO,EAAE,IAAI;aACb,CAAC,CAAC;YACH,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO;gBAAE,MAAM,IAAI,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC7E,OAAO;QACR,CAAC;QACD,KAAK,yBAAyB,EAAE,CAAC;YAChC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;YAChC,IAAI,CAAC,OAAO;gBAAE,MAAM,IAAI,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;YACnE,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;YAC/B,MAAM,YAAY,GAAG,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC;YACtE,IAAI,YAAY,IAAI,CAAC;gBAAE,MAAM,IAAI,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;YACzE,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC;YAC1C,IAAI,SAAS,GAAG,KAAK,CAAC;YACtB,IAAI,CAAC;gBACJ,MAAM,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE;oBAClD,OAAO;oBACP,SAAS,EAAE,OAAO,CAAC,SAAS;oBAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,YAAY;oBACZ,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACrD,aAAa,EAAE,GAAG,EAAE,CAAC;wBACpB,IAAI,WAAW,CAAC,GAAG,EAAE,IAAI,OAAO,CAAC,QAAQ;4BAAE,MAAM,IAAI,gBAAgB,CAAC,UAAU,CAAC,CAAC;wBAClF,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;wBACnE,IAAI,WAAW,CAAC,GAAG,EAAE,IAAI,OAAO,CAAC,QAAQ;4BAAE,MAAM,IAAI,gBAAgB,CAAC,UAAU,CAAC,CAAC;oBAAA,CAClF;oBACD,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;wBAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;wBACjC,IAAI,CAAC,IAAI;4BAAE,MAAM,IAAI,gBAAgB,CAAC,aAAa,CAAC,CAAC;wBACrD,OAAO,OAAO,CACb,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,EACjG,MAAM,CACN,CAAC;oBAAA,CACF;iBACD,CAAC,CAAC;gBACH,SAAS,GAAG,IAAI,CAAC;YAClB,CAAC;oBAAS,CAAC;gBACV,IAAI,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,KAAK,CAAC;oBAAE,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC,CAAC;YACzG,CAAC;YACD,OAAO;QACR,CAAC;QACD,SAAS,CAAC;YACT,MAAM,UAAU,GAAU,QAAQ,CAAC;YACnC,MAAM,IAAI,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;QAChD,CAAC;IACF,CAAC;AAAA,CACD","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { performance } from \"node:perf_hooks\";\nimport { executeDag } from \"./dag-phase.ts\";\nimport { executeRunCommand, type OwnedRunCommand } from \"./owned-execution.ts\";\nimport type { RunPhaseContext } from \"./phase-context.ts\";\nimport { executeScriptedWriter } from \"./scripted-writer.ts\";\nimport type { VerifiedRunRuntime } from \"./session-port.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\nexport async function executeWriter(\n\tcontext: RunPhaseContext,\n\toptions: {\n\t\treadonly workspace: string;\n\t\treadonly deadline: number;\n\t\treadonly runtime?: VerifiedRunRuntime;\n\t},\n): Promise<void> {\n\tconst { contract, journal } = context;\n\tconst execute = (request: OwnedRunCommand, toolSignal?: AbortSignal) => {\n\t\tconst signals = [context.signal, toolSignal].filter((signal): signal is AbortSignal => signal !== undefined);\n\t\treturn executeRunCommand(journal, request, {\n\t\t\t...contract.budget,\n\t\t\tauthority: context.authority,\n\t\t\t...(signals.length ? { signal: AbortSignal.any(signals) } : {}),\n\t\t});\n\t};\n\tswitch (contract.profile) {\n\t\tcase \"linux-command-dag-v1\":\n\t\t\treturn executeDag(context, options);\n\t\tcase \"linux-command-v1\": {\n\t\t\tconst writer = await execute({\n\t\t\t\trole: \"writer\",\n\t\t\t\targv: contract.writer,\n\t\t\t\tworkspace: options.workspace,\n\t\t\t\tdeadline: options.deadline,\n\t\t\t\tclaimId: null,\n\t\t\t});\n\t\t\tif (writer.result.failure) throw new VerifiedRunError(writer.result.failure);\n\t\t\treturn;\n\t\t}\n\t\tcase \"linux-scripted-agent-v1\": {\n\t\t\tconst runtime = options.runtime;\n\t\t\tif (!runtime) throw new VerifiedRunError(\"writer_backend_missing\");\n\t\t\tconst writer = contract.writer;\n\t\t\tconst requestLimit = writer.maxRequests - journal.state.modelRequests;\n\t\t\tif (requestLimit <= 0) throw new VerifiedRunError(\"model_request_limit\");\n\t\t\tjournal.append({ kind: \"writer_opened\" });\n\t\t\tlet completed = false;\n\t\t\ttry {\n\t\t\t\tawait executeScriptedWriter(writer, contract.goal, {\n\t\t\t\t\truntime,\n\t\t\t\t\tworkspace: options.workspace,\n\t\t\t\t\tdeadline: options.deadline,\n\t\t\t\t\trequestLimit,\n\t\t\t\t\t...(context.signal ? { signal: context.signal } : {}),\n\t\t\t\t\tbeforeRequest: () => {\n\t\t\t\t\t\tif (performance.now() >= options.deadline) throw new VerifiedRunError(\"deadline\");\n\t\t\t\t\t\tjournal.append({ kind: \"model_request\", requestId: randomUUID() });\n\t\t\t\t\t\tif (performance.now() >= options.deadline) throw new VerifiedRunError(\"deadline\");\n\t\t\t\t\t},\n\t\t\t\t\texecuteStep: (index, signal) => {\n\t\t\t\t\t\tconst argv = writer.steps[index];\n\t\t\t\t\t\tif (!argv) throw new VerifiedRunError(\"writer_step\");\n\t\t\t\t\t\treturn execute(\n\t\t\t\t\t\t\t{ role: \"writer\", argv, workspace: options.workspace, deadline: options.deadline, claimId: null },\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tcompleted = true;\n\t\t\t} finally {\n\t\t\t\tif (journal.state.activeExecutionIds.length === 0) journal.append({ kind: \"writer_closed\", completed });\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tdefault: {\n\t\t\tconst exhaustive: never = contract;\n\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t}\n\t}\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  import type { RunWriterRestartCommand } from "omk-protocol";
2
+ import type { RunAuthority } from "./authority-runtime.ts";
2
3
  import type { RunProjection } from "./run-types.ts";
3
4
  import type { VerifiedRunRuntime } from "./session-port.ts";
4
5
  export interface WriterRecoveryInspection {
@@ -12,5 +13,6 @@ export declare function inspectWriterRecovery(runPath: string): WriterRecoveryIn
12
13
  export declare function restartIsolatedWriter(runPath: string, command: RunWriterRestartCommand, options: {
13
14
  readonly runtime?: VerifiedRunRuntime;
14
15
  readonly signal?: AbortSignal;
16
+ readonly authority: RunAuthority;
15
17
  }): Promise<RunProjection>;
16
18
  //# sourceMappingURL=writer-recovery.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"writer-recovery.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/writer-recovery.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAO5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAO5D,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,SAAS,EACf,OAAO,GACP,UAAU,GACV,0BAA0B,GAC1B,mBAAmB,GACnB,WAAW,GACX,SAAS,GACT,eAAe,GACf,gBAAgB,GAChB,gBAAgB,GAChB,qBAAqB,GACrB,WAAW,CAAC;IACf,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;CACrC;AAaD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,wBAAwB,CA0C/E;AAED,4GAA4G;AAC5G,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,uBAAuB,EAChC,OAAO,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,GAC/E,OAAO,CAAC,aAAa,CAAC,CAkCxB","sourcesContent":["import { join } from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport type { RunWriterRestartCommand } from \"omk-protocol\";\nimport { probeVerifiedSandbox } from \"./broker.ts\";\nimport { loadCandidate, materializeCandidate } from \"./candidate.ts\";\nimport { preflightCheckReceipts } from \"./check-receipt.ts\";\nimport type { JournalSnapshot } from \"./journal.ts\";\nimport { readRunClock, remainingRunTime } from \"./recovery-clock.ts\";\nimport { requireRunJournal, withRecoveryLease } from \"./recovery-command.ts\";\nimport type { RunProjection } from \"./run-types.ts\";\nimport type { VerifiedRunRuntime } from \"./session-port.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\nimport { verifyCandidate } from \"./verification-phase.ts\";\nimport { assertWorkRecoverable } from \"./work-recovery.ts\";\nimport { publishWriterCandidate } from \"./writer-completion.ts\";\nimport { executeWriter } from \"./writer-phase.ts\";\n\nexport interface WriterRecoveryInspection {\n\treadonly state: RunProjection;\n\treadonly readiness:\n\t\t| \"ready\"\n\t\t| \"terminal\"\n\t\t| \"input_checkpoint_missing\"\n\t\t| \"candidate_present\"\n\t\t| \"unsettled\"\n\t\t| \"expired\"\n\t\t| \"clock_changed\"\n\t\t| \"clock_rollback\"\n\t\t| \"recovery_limit\"\n\t\t| \"model_request_limit\"\n\t\t| \"integrity\";\n\treadonly remainingWorkMs: number | null;\n\treadonly ownership: \"lease_required\";\n}\n\nfunction assertWriterRecoverable(runPath: string, snapshot: JournalSnapshot): number {\n\tconst { contract, remainingMs } = assertWorkRecoverable(runPath, snapshot);\n\tif (contract.profile === \"linux-command-dag-v1\") throw new VerifiedRunError(\"task_recovery_required\");\n\tif (\n\t\tcontract.profile === \"linux-scripted-agent-v1\" &&\n\t\tcontract.writer.maxRequests - snapshot.state.modelRequests < contract.writer.steps.length + 1\n\t)\n\t\tthrow new VerifiedRunError(\"model_request_limit\");\n\treturn remainingMs;\n}\n\nexport function inspectWriterRecovery(runPath: string): WriterRecoveryInspection {\n\tconst snapshot = requireRunJournal(runPath);\n\tlet readiness: WriterRecoveryInspection[\"readiness\"] = \"ready\";\n\tlet remainingWorkMs: number | null = null;\n\ttry {\n\t\tremainingWorkMs = assertWriterRecoverable(runPath, snapshot);\n\t} catch (error) {\n\t\tif (!(error instanceof Error)) throw error;\n\t\tswitch (error instanceof VerifiedRunError ? error.code : \"integrity\") {\n\t\t\tcase \"resume_terminal\":\n\t\t\t\treadiness = \"terminal\";\n\t\t\t\tbreak;\n\t\t\tcase \"deadline\":\n\t\t\t\treadiness = \"expired\";\n\t\t\t\tremainingWorkMs = 0;\n\t\t\t\tbreak;\n\t\t\tcase \"input_checkpoint_missing\":\n\t\t\t\treadiness = \"input_checkpoint_missing\";\n\t\t\t\tbreak;\n\t\t\tcase \"candidate_present\":\n\t\t\t\treadiness = \"candidate_present\";\n\t\t\t\tbreak;\n\t\t\tcase \"unsettled\":\n\t\t\t\treadiness = \"unsettled\";\n\t\t\t\tbreak;\n\t\t\tcase \"clock_changed\":\n\t\t\t\treadiness = \"clock_changed\";\n\t\t\t\tbreak;\n\t\t\tcase \"clock_rollback\":\n\t\t\t\treadiness = \"clock_rollback\";\n\t\t\t\tbreak;\n\t\t\tcase \"recovery_limit\":\n\t\t\t\treadiness = \"recovery_limit\";\n\t\t\t\tbreak;\n\t\t\tcase \"model_request_limit\":\n\t\t\t\treadiness = \"model_request_limit\";\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treadiness = \"integrity\";\n\t\t}\n\t}\n\treturn Object.freeze({ state: snapshot.state, readiness, remainingWorkMs, ownership: \"lease_required\" });\n}\n\n/** Re-run isolated local work in a new copy. Never reuse an interrupted workspace or replenish a budget. */\nexport async function restartIsolatedWriter(\n\trunPath: string,\n\tcommand: RunWriterRestartCommand,\n\toptions: { readonly runtime?: VerifiedRunRuntime; readonly signal?: AbortSignal },\n): Promise<RunProjection> {\n\tif (options.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\treturn withRecoveryLease(runPath, command, async ({ snapshot, journal }) => {\n\t\tassertWriterRecoverable(runPath, snapshot);\n\t\tconst first = snapshot.records[0]?.event;\n\t\tif (first?.kind !== \"created\") throw new VerifiedRunError(\"integrity\");\n\t\tif (first.contract.profile === \"linux-scripted-agent-v1\" && !options.runtime)\n\t\t\tthrow new VerifiedRunError(\"writer_backend_missing\");\n\t\tpreflightCheckReceipts(first.contract);\n\t\tprobeVerifiedSandbox();\n\t\tassertWriterRecoverable(runPath, snapshot);\n\t\tif (options.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\t\tjournal.append({\n\t\t\tkind: \"writer_restarted\",\n\t\t\tcommand,\n\t\t\tobservedMs: readRunClock().nowMs,\n\t\t\treconciledExecutionIds: snapshot.state.activeExecutionIds,\n\t\t});\n\t\tconst state = journal.state;\n\t\tif (!state.budget || !state.inputDigest) throw new VerifiedRunError(\"integrity\");\n\t\tconst deadline = performance.now() + remainingRunTime(state.budget, state.budget.workDeadlineMs);\n\t\tconst base = loadCandidate(runPath, state.inputDigest, first.contract.budget);\n\t\tconst workspace = join(runPath, `writer-${state.generation}`);\n\t\tmaterializeCandidate(base, workspace);\n\t\tconst context = {\n\t\t\trunPath,\n\t\t\tcontract: first.contract,\n\t\t\tjournal,\n\t\t\t...(options.signal ? { signal: options.signal } : {}),\n\t\t};\n\t\tawait executeWriter(context, { workspace, deadline, ...(options.runtime ? { runtime: options.runtime } : {}) });\n\t\tpublishWriterCandidate(context, workspace, deadline);\n\t\treturn verifyCandidate(context);\n\t});\n}\n"]}
1
+ {"version":3,"file":"writer-recovery.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/writer-recovery.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAO3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAO5D,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,SAAS,EACf,OAAO,GACP,UAAU,GACV,0BAA0B,GAC1B,mBAAmB,GACnB,WAAW,GACX,SAAS,GACT,eAAe,GACf,gBAAgB,GAChB,gBAAgB,GAChB,qBAAqB,GACrB,WAAW,CAAC;IACf,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;CACrC;AAaD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,wBAAwB,CA0C/E;AAED,4GAA4G;AAC5G,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,uBAAuB,EAChC,OAAO,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAA;CAAE,GACjH,OAAO,CAAC,aAAa,CAAC,CAmCxB","sourcesContent":["import { join } from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport type { RunWriterRestartCommand } from \"omk-protocol\";\nimport type { RunAuthority } from \"./authority-runtime.ts\";\nimport { probeVerifiedSandbox } from \"./broker.ts\";\nimport { loadCandidate, materializeCandidate } from \"./candidate.ts\";\nimport { preflightCheckReceipts } from \"./check-receipt.ts\";\nimport type { JournalSnapshot } from \"./journal.ts\";\nimport { readRunClock, remainingRunTime } from \"./recovery-clock.ts\";\nimport { requireRunJournal, withRecoveryLease } from \"./recovery-command.ts\";\nimport type { RunProjection } from \"./run-types.ts\";\nimport type { VerifiedRunRuntime } from \"./session-port.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\nimport { verifyCandidate } from \"./verification-phase.ts\";\nimport { assertWorkRecoverable } from \"./work-recovery.ts\";\nimport { publishWriterCandidate } from \"./writer-completion.ts\";\nimport { executeWriter } from \"./writer-phase.ts\";\n\nexport interface WriterRecoveryInspection {\n\treadonly state: RunProjection;\n\treadonly readiness:\n\t\t| \"ready\"\n\t\t| \"terminal\"\n\t\t| \"input_checkpoint_missing\"\n\t\t| \"candidate_present\"\n\t\t| \"unsettled\"\n\t\t| \"expired\"\n\t\t| \"clock_changed\"\n\t\t| \"clock_rollback\"\n\t\t| \"recovery_limit\"\n\t\t| \"model_request_limit\"\n\t\t| \"integrity\";\n\treadonly remainingWorkMs: number | null;\n\treadonly ownership: \"lease_required\";\n}\n\nfunction assertWriterRecoverable(runPath: string, snapshot: JournalSnapshot): number {\n\tconst { contract, remainingMs } = assertWorkRecoverable(runPath, snapshot);\n\tif (contract.profile === \"linux-command-dag-v1\") throw new VerifiedRunError(\"task_recovery_required\");\n\tif (\n\t\tcontract.profile === \"linux-scripted-agent-v1\" &&\n\t\tcontract.writer.maxRequests - snapshot.state.modelRequests < contract.writer.steps.length + 1\n\t)\n\t\tthrow new VerifiedRunError(\"model_request_limit\");\n\treturn remainingMs;\n}\n\nexport function inspectWriterRecovery(runPath: string): WriterRecoveryInspection {\n\tconst snapshot = requireRunJournal(runPath);\n\tlet readiness: WriterRecoveryInspection[\"readiness\"] = \"ready\";\n\tlet remainingWorkMs: number | null = null;\n\ttry {\n\t\tremainingWorkMs = assertWriterRecoverable(runPath, snapshot);\n\t} catch (error) {\n\t\tif (!(error instanceof Error)) throw error;\n\t\tswitch (error instanceof VerifiedRunError ? error.code : \"integrity\") {\n\t\t\tcase \"resume_terminal\":\n\t\t\t\treadiness = \"terminal\";\n\t\t\t\tbreak;\n\t\t\tcase \"deadline\":\n\t\t\t\treadiness = \"expired\";\n\t\t\t\tremainingWorkMs = 0;\n\t\t\t\tbreak;\n\t\t\tcase \"input_checkpoint_missing\":\n\t\t\t\treadiness = \"input_checkpoint_missing\";\n\t\t\t\tbreak;\n\t\t\tcase \"candidate_present\":\n\t\t\t\treadiness = \"candidate_present\";\n\t\t\t\tbreak;\n\t\t\tcase \"unsettled\":\n\t\t\t\treadiness = \"unsettled\";\n\t\t\t\tbreak;\n\t\t\tcase \"clock_changed\":\n\t\t\t\treadiness = \"clock_changed\";\n\t\t\t\tbreak;\n\t\t\tcase \"clock_rollback\":\n\t\t\t\treadiness = \"clock_rollback\";\n\t\t\t\tbreak;\n\t\t\tcase \"recovery_limit\":\n\t\t\t\treadiness = \"recovery_limit\";\n\t\t\t\tbreak;\n\t\t\tcase \"model_request_limit\":\n\t\t\t\treadiness = \"model_request_limit\";\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treadiness = \"integrity\";\n\t\t}\n\t}\n\treturn Object.freeze({ state: snapshot.state, readiness, remainingWorkMs, ownership: \"lease_required\" });\n}\n\n/** Re-run isolated local work in a new copy. Never reuse an interrupted workspace or replenish a budget. */\nexport async function restartIsolatedWriter(\n\trunPath: string,\n\tcommand: RunWriterRestartCommand,\n\toptions: { readonly runtime?: VerifiedRunRuntime; readonly signal?: AbortSignal; readonly authority: RunAuthority },\n): Promise<RunProjection> {\n\tif (options.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\treturn withRecoveryLease(runPath, command, async ({ snapshot, journal }) => {\n\t\tassertWriterRecoverable(runPath, snapshot);\n\t\tconst first = snapshot.records[0]?.event;\n\t\tif (first?.kind !== \"created\") throw new VerifiedRunError(\"integrity\");\n\t\tif (first.contract.profile === \"linux-scripted-agent-v1\" && !options.runtime)\n\t\t\tthrow new VerifiedRunError(\"writer_backend_missing\");\n\t\tpreflightCheckReceipts(first.contract);\n\t\tprobeVerifiedSandbox();\n\t\tassertWriterRecoverable(runPath, snapshot);\n\t\tif (options.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\t\tjournal.append({\n\t\t\tkind: \"writer_restarted\",\n\t\t\tcommand,\n\t\t\tobservedMs: readRunClock().nowMs,\n\t\t\treconciledExecutionIds: snapshot.state.activeExecutionIds,\n\t\t});\n\t\tconst state = journal.state;\n\t\tif (!state.budget || !state.inputDigest) throw new VerifiedRunError(\"integrity\");\n\t\tconst deadline = performance.now() + remainingRunTime(state.budget, state.budget.workDeadlineMs);\n\t\tconst base = loadCandidate(runPath, state.inputDigest, first.contract.budget);\n\t\tconst workspace = join(runPath, `writer-${state.generation}`);\n\t\tmaterializeCandidate(base, workspace);\n\t\tconst context = {\n\t\t\trunPath,\n\t\t\tcontract: first.contract,\n\t\t\tjournal,\n\t\t\tauthority: options.authority,\n\t\t\t...(options.signal ? { signal: options.signal } : {}),\n\t\t};\n\t\tawait executeWriter(context, { workspace, deadline, ...(options.runtime ? { runtime: options.runtime } : {}) });\n\t\tpublishWriterCandidate(context, workspace, deadline);\n\t\treturn verifyCandidate(context);\n\t});\n}\n"]}
@@ -97,6 +97,7 @@ export async function restartIsolatedWriter(runPath, command, options) {
97
97
  runPath,
98
98
  contract: first.contract,
99
99
  journal,
100
+ authority: options.authority,
100
101
  ...(options.signal ? { signal: options.signal } : {}),
101
102
  };
102
103
  await executeWriter(context, { workspace, deadline, ...(options.runtime ? { runtime: options.runtime } : {}) });
@@ -1 +1 @@
1
- {"version":3,"file":"writer-recovery.js","sourceRoot":"","sources":["../../../src/core/verified-run/writer-recovery.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport type { RunWriterRestartCommand } from \"omk-protocol\";\nimport { probeVerifiedSandbox } from \"./broker.ts\";\nimport { loadCandidate, materializeCandidate } from \"./candidate.ts\";\nimport { preflightCheckReceipts } from \"./check-receipt.ts\";\nimport type { JournalSnapshot } from \"./journal.ts\";\nimport { readRunClock, remainingRunTime } from \"./recovery-clock.ts\";\nimport { requireRunJournal, withRecoveryLease } from \"./recovery-command.ts\";\nimport type { RunProjection } from \"./run-types.ts\";\nimport type { VerifiedRunRuntime } from \"./session-port.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\nimport { verifyCandidate } from \"./verification-phase.ts\";\nimport { assertWorkRecoverable } from \"./work-recovery.ts\";\nimport { publishWriterCandidate } from \"./writer-completion.ts\";\nimport { executeWriter } from \"./writer-phase.ts\";\n\nexport interface WriterRecoveryInspection {\n\treadonly state: RunProjection;\n\treadonly readiness:\n\t\t| \"ready\"\n\t\t| \"terminal\"\n\t\t| \"input_checkpoint_missing\"\n\t\t| \"candidate_present\"\n\t\t| \"unsettled\"\n\t\t| \"expired\"\n\t\t| \"clock_changed\"\n\t\t| \"clock_rollback\"\n\t\t| \"recovery_limit\"\n\t\t| \"model_request_limit\"\n\t\t| \"integrity\";\n\treadonly remainingWorkMs: number | null;\n\treadonly ownership: \"lease_required\";\n}\n\nfunction assertWriterRecoverable(runPath: string, snapshot: JournalSnapshot): number {\n\tconst { contract, remainingMs } = assertWorkRecoverable(runPath, snapshot);\n\tif (contract.profile === \"linux-command-dag-v1\") throw new VerifiedRunError(\"task_recovery_required\");\n\tif (\n\t\tcontract.profile === \"linux-scripted-agent-v1\" &&\n\t\tcontract.writer.maxRequests - snapshot.state.modelRequests < contract.writer.steps.length + 1\n\t)\n\t\tthrow new VerifiedRunError(\"model_request_limit\");\n\treturn remainingMs;\n}\n\nexport function inspectWriterRecovery(runPath: string): WriterRecoveryInspection {\n\tconst snapshot = requireRunJournal(runPath);\n\tlet readiness: WriterRecoveryInspection[\"readiness\"] = \"ready\";\n\tlet remainingWorkMs: number | null = null;\n\ttry {\n\t\tremainingWorkMs = assertWriterRecoverable(runPath, snapshot);\n\t} catch (error) {\n\t\tif (!(error instanceof Error)) throw error;\n\t\tswitch (error instanceof VerifiedRunError ? error.code : \"integrity\") {\n\t\t\tcase \"resume_terminal\":\n\t\t\t\treadiness = \"terminal\";\n\t\t\t\tbreak;\n\t\t\tcase \"deadline\":\n\t\t\t\treadiness = \"expired\";\n\t\t\t\tremainingWorkMs = 0;\n\t\t\t\tbreak;\n\t\t\tcase \"input_checkpoint_missing\":\n\t\t\t\treadiness = \"input_checkpoint_missing\";\n\t\t\t\tbreak;\n\t\t\tcase \"candidate_present\":\n\t\t\t\treadiness = \"candidate_present\";\n\t\t\t\tbreak;\n\t\t\tcase \"unsettled\":\n\t\t\t\treadiness = \"unsettled\";\n\t\t\t\tbreak;\n\t\t\tcase \"clock_changed\":\n\t\t\t\treadiness = \"clock_changed\";\n\t\t\t\tbreak;\n\t\t\tcase \"clock_rollback\":\n\t\t\t\treadiness = \"clock_rollback\";\n\t\t\t\tbreak;\n\t\t\tcase \"recovery_limit\":\n\t\t\t\treadiness = \"recovery_limit\";\n\t\t\t\tbreak;\n\t\t\tcase \"model_request_limit\":\n\t\t\t\treadiness = \"model_request_limit\";\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treadiness = \"integrity\";\n\t\t}\n\t}\n\treturn Object.freeze({ state: snapshot.state, readiness, remainingWorkMs, ownership: \"lease_required\" });\n}\n\n/** Re-run isolated local work in a new copy. Never reuse an interrupted workspace or replenish a budget. */\nexport async function restartIsolatedWriter(\n\trunPath: string,\n\tcommand: RunWriterRestartCommand,\n\toptions: { readonly runtime?: VerifiedRunRuntime; readonly signal?: AbortSignal },\n): Promise<RunProjection> {\n\tif (options.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\treturn withRecoveryLease(runPath, command, async ({ snapshot, journal }) => {\n\t\tassertWriterRecoverable(runPath, snapshot);\n\t\tconst first = snapshot.records[0]?.event;\n\t\tif (first?.kind !== \"created\") throw new VerifiedRunError(\"integrity\");\n\t\tif (first.contract.profile === \"linux-scripted-agent-v1\" && !options.runtime)\n\t\t\tthrow new VerifiedRunError(\"writer_backend_missing\");\n\t\tpreflightCheckReceipts(first.contract);\n\t\tprobeVerifiedSandbox();\n\t\tassertWriterRecoverable(runPath, snapshot);\n\t\tif (options.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\t\tjournal.append({\n\t\t\tkind: \"writer_restarted\",\n\t\t\tcommand,\n\t\t\tobservedMs: readRunClock().nowMs,\n\t\t\treconciledExecutionIds: snapshot.state.activeExecutionIds,\n\t\t});\n\t\tconst state = journal.state;\n\t\tif (!state.budget || !state.inputDigest) throw new VerifiedRunError(\"integrity\");\n\t\tconst deadline = performance.now() + remainingRunTime(state.budget, state.budget.workDeadlineMs);\n\t\tconst base = loadCandidate(runPath, state.inputDigest, first.contract.budget);\n\t\tconst workspace = join(runPath, `writer-${state.generation}`);\n\t\tmaterializeCandidate(base, workspace);\n\t\tconst context = {\n\t\t\trunPath,\n\t\t\tcontract: first.contract,\n\t\t\tjournal,\n\t\t\t...(options.signal ? { signal: options.signal } : {}),\n\t\t};\n\t\tawait executeWriter(context, { workspace, deadline, ...(options.runtime ? { runtime: options.runtime } : {}) });\n\t\tpublishWriterCandidate(context, workspace, deadline);\n\t\treturn verifyCandidate(context);\n\t});\n}\n"]}
1
+ {"version":3,"file":"writer-recovery.js","sourceRoot":"","sources":["../../../src/core/verified-run/writer-recovery.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport type { RunWriterRestartCommand } from \"omk-protocol\";\nimport type { RunAuthority } from \"./authority-runtime.ts\";\nimport { probeVerifiedSandbox } from \"./broker.ts\";\nimport { loadCandidate, materializeCandidate } from \"./candidate.ts\";\nimport { preflightCheckReceipts } from \"./check-receipt.ts\";\nimport type { JournalSnapshot } from \"./journal.ts\";\nimport { readRunClock, remainingRunTime } from \"./recovery-clock.ts\";\nimport { requireRunJournal, withRecoveryLease } from \"./recovery-command.ts\";\nimport type { RunProjection } from \"./run-types.ts\";\nimport type { VerifiedRunRuntime } from \"./session-port.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\nimport { verifyCandidate } from \"./verification-phase.ts\";\nimport { assertWorkRecoverable } from \"./work-recovery.ts\";\nimport { publishWriterCandidate } from \"./writer-completion.ts\";\nimport { executeWriter } from \"./writer-phase.ts\";\n\nexport interface WriterRecoveryInspection {\n\treadonly state: RunProjection;\n\treadonly readiness:\n\t\t| \"ready\"\n\t\t| \"terminal\"\n\t\t| \"input_checkpoint_missing\"\n\t\t| \"candidate_present\"\n\t\t| \"unsettled\"\n\t\t| \"expired\"\n\t\t| \"clock_changed\"\n\t\t| \"clock_rollback\"\n\t\t| \"recovery_limit\"\n\t\t| \"model_request_limit\"\n\t\t| \"integrity\";\n\treadonly remainingWorkMs: number | null;\n\treadonly ownership: \"lease_required\";\n}\n\nfunction assertWriterRecoverable(runPath: string, snapshot: JournalSnapshot): number {\n\tconst { contract, remainingMs } = assertWorkRecoverable(runPath, snapshot);\n\tif (contract.profile === \"linux-command-dag-v1\") throw new VerifiedRunError(\"task_recovery_required\");\n\tif (\n\t\tcontract.profile === \"linux-scripted-agent-v1\" &&\n\t\tcontract.writer.maxRequests - snapshot.state.modelRequests < contract.writer.steps.length + 1\n\t)\n\t\tthrow new VerifiedRunError(\"model_request_limit\");\n\treturn remainingMs;\n}\n\nexport function inspectWriterRecovery(runPath: string): WriterRecoveryInspection {\n\tconst snapshot = requireRunJournal(runPath);\n\tlet readiness: WriterRecoveryInspection[\"readiness\"] = \"ready\";\n\tlet remainingWorkMs: number | null = null;\n\ttry {\n\t\tremainingWorkMs = assertWriterRecoverable(runPath, snapshot);\n\t} catch (error) {\n\t\tif (!(error instanceof Error)) throw error;\n\t\tswitch (error instanceof VerifiedRunError ? error.code : \"integrity\") {\n\t\t\tcase \"resume_terminal\":\n\t\t\t\treadiness = \"terminal\";\n\t\t\t\tbreak;\n\t\t\tcase \"deadline\":\n\t\t\t\treadiness = \"expired\";\n\t\t\t\tremainingWorkMs = 0;\n\t\t\t\tbreak;\n\t\t\tcase \"input_checkpoint_missing\":\n\t\t\t\treadiness = \"input_checkpoint_missing\";\n\t\t\t\tbreak;\n\t\t\tcase \"candidate_present\":\n\t\t\t\treadiness = \"candidate_present\";\n\t\t\t\tbreak;\n\t\t\tcase \"unsettled\":\n\t\t\t\treadiness = \"unsettled\";\n\t\t\t\tbreak;\n\t\t\tcase \"clock_changed\":\n\t\t\t\treadiness = \"clock_changed\";\n\t\t\t\tbreak;\n\t\t\tcase \"clock_rollback\":\n\t\t\t\treadiness = \"clock_rollback\";\n\t\t\t\tbreak;\n\t\t\tcase \"recovery_limit\":\n\t\t\t\treadiness = \"recovery_limit\";\n\t\t\t\tbreak;\n\t\t\tcase \"model_request_limit\":\n\t\t\t\treadiness = \"model_request_limit\";\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treadiness = \"integrity\";\n\t\t}\n\t}\n\treturn Object.freeze({ state: snapshot.state, readiness, remainingWorkMs, ownership: \"lease_required\" });\n}\n\n/** Re-run isolated local work in a new copy. Never reuse an interrupted workspace or replenish a budget. */\nexport async function restartIsolatedWriter(\n\trunPath: string,\n\tcommand: RunWriterRestartCommand,\n\toptions: { readonly runtime?: VerifiedRunRuntime; readonly signal?: AbortSignal; readonly authority: RunAuthority },\n): Promise<RunProjection> {\n\tif (options.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\treturn withRecoveryLease(runPath, command, async ({ snapshot, journal }) => {\n\t\tassertWriterRecoverable(runPath, snapshot);\n\t\tconst first = snapshot.records[0]?.event;\n\t\tif (first?.kind !== \"created\") throw new VerifiedRunError(\"integrity\");\n\t\tif (first.contract.profile === \"linux-scripted-agent-v1\" && !options.runtime)\n\t\t\tthrow new VerifiedRunError(\"writer_backend_missing\");\n\t\tpreflightCheckReceipts(first.contract);\n\t\tprobeVerifiedSandbox();\n\t\tassertWriterRecoverable(runPath, snapshot);\n\t\tif (options.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\t\tjournal.append({\n\t\t\tkind: \"writer_restarted\",\n\t\t\tcommand,\n\t\t\tobservedMs: readRunClock().nowMs,\n\t\t\treconciledExecutionIds: snapshot.state.activeExecutionIds,\n\t\t});\n\t\tconst state = journal.state;\n\t\tif (!state.budget || !state.inputDigest) throw new VerifiedRunError(\"integrity\");\n\t\tconst deadline = performance.now() + remainingRunTime(state.budget, state.budget.workDeadlineMs);\n\t\tconst base = loadCandidate(runPath, state.inputDigest, first.contract.budget);\n\t\tconst workspace = join(runPath, `writer-${state.generation}`);\n\t\tmaterializeCandidate(base, workspace);\n\t\tconst context = {\n\t\t\trunPath,\n\t\t\tcontract: first.contract,\n\t\t\tjournal,\n\t\t\tauthority: options.authority,\n\t\t\t...(options.signal ? { signal: options.signal } : {}),\n\t\t};\n\t\tawait executeWriter(context, { workspace, deadline, ...(options.runtime ? { runtime: options.runtime } : {}) });\n\t\tpublishWriterCandidate(context, workspace, deadline);\n\t\treturn verifyCandidate(context);\n\t});\n}\n"]}
@@ -12,13 +12,14 @@
12
12
  */
13
13
  import type { ResourceAdmissionDecision } from "./resource-admission.ts";
14
14
  import type { WorkloadPermitPool } from "./workload-permit-pool.ts";
15
- import type { WorkloadShardPlan, WorkloadShardSpec } from "./workload-shard-plan.ts";
15
+ import type { WorkloadShardPlan, WorkloadShardProjection, WorkloadShardSpec } from "./workload-shard-plan.ts";
16
16
  import type { WorkloadShardStore } from "./workload-shard-store.ts";
17
17
  export interface ShardRunContext {
18
18
  readonly shard: WorkloadShardSpec;
19
19
  readonly attempt: number;
20
20
  readonly signal?: AbortSignal;
21
21
  }
22
+ /** Resolves only after its owned execution boundary terminates; rejection is unproven. */
22
23
  export type ShardRunner = (context: ShardRunContext) => Promise<{
23
24
  readonly exitCode: number;
24
25
  readonly evidenceRefs?: readonly string[];
@@ -34,6 +35,8 @@ export interface ExecuteWorkloadShardPlanInput {
34
35
  readonly retryFailed?: boolean;
35
36
  /** §13.4: aborted -> pending needs an explicit resume; this call is that act. Default true. */
36
37
  readonly resumeAborted?: boolean;
38
+ /** Trusted recovery witness for this exact shard attempt. Missing or unknown never rearms. */
39
+ readonly observeTermination?: (shard: WorkloadShardProjection) => "terminated" | "unknown" | Promise<"terminated" | "unknown">;
37
40
  readonly permitWaitTimeoutMs?: number;
38
41
  readonly now?: () => Date;
39
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"workload-shard-execution-types.d.ts","sourceRoot":"","sources":["../../src/core/workload-shard-execution-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACrF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC9B;AAED,MAAM,MAAM,WAAW,GAAG,CACzB,OAAO,EAAE,eAAe,KACpB,OAAO,CAAC;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC;AAEvF,MAAM,WAAW,6BAA6B;IAC7C,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAC;IAC7C,QAAQ,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC;IACzC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,kFAAiF;IACjF,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,gGAA+F;IAC/F,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B","sourcesContent":["/**\n * Shard execution contract.\n *\n * These declarations describe the call the executor makes and the input it\n * takes. They lived in the executor, so the runner — which the executor calls\n * to advance one shard — had to import the executor back to name its own\n * parameter type. Moving the contract below both leaves the executor free to\n * depend on the runner without the runner depending on the executor.\n *\n * Types only. Imports stay on the plan, store, admission, and permit modules,\n * none of which reach the executor or the runner.\n */\n\nimport type { ResourceAdmissionDecision } from \"./resource-admission.ts\";\nimport type { WorkloadPermitPool } from \"./workload-permit-pool.ts\";\nimport type { WorkloadShardPlan, WorkloadShardSpec } from \"./workload-shard-plan.ts\";\nimport type { WorkloadShardStore } from \"./workload-shard-store.ts\";\n\nexport interface ShardRunContext {\n\treadonly shard: WorkloadShardSpec;\n\treadonly attempt: number;\n\treadonly signal?: AbortSignal;\n}\n\nexport type ShardRunner = (\n\tcontext: ShardRunContext,\n) => Promise<{ readonly exitCode: number; readonly evidenceRefs?: readonly string[] }>;\n\nexport interface ExecuteWorkloadShardPlanInput {\n\treadonly plan: WorkloadShardPlan;\n\treadonly store: WorkloadShardStore;\n\treadonly runner: ShardRunner;\n\treadonly decision: ResourceAdmissionDecision;\n\treadonly permitPool?: WorkloadPermitPool;\n\treadonly signal?: AbortSignal;\n\t/** §13.5 step 4 retry policy: re-arm previously failed shards. Default false. */\n\treadonly retryFailed?: boolean;\n\t/** §13.4: aborted -> pending needs an explicit resume; this call is that act. Default true. */\n\treadonly resumeAborted?: boolean;\n\treadonly permitWaitTimeoutMs?: number;\n\treadonly now?: () => Date;\n}\n"]}
1
+ {"version":3,"file":"workload-shard-execution-types.d.ts","sourceRoot":"","sources":["../../src/core/workload-shard-execution-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC9G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC9B;AAED,0FAA0F;AAC1F,MAAM,MAAM,WAAW,GAAG,CACzB,OAAO,EAAE,eAAe,KACpB,OAAO,CAAC;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC;AAEvF,MAAM,WAAW,6BAA6B;IAC7C,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAC;IAC7C,QAAQ,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC;IACzC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,kFAAiF;IACjF,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,gGAA+F;IAC/F,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,8FAA8F;IAC9F,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAC7B,KAAK,EAAE,uBAAuB,KAC1B,YAAY,GAAG,SAAS,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;IAClE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B","sourcesContent":["/**\n * Shard execution contract.\n *\n * These declarations describe the call the executor makes and the input it\n * takes. They lived in the executor, so the runner — which the executor calls\n * to advance one shard — had to import the executor back to name its own\n * parameter type. Moving the contract below both leaves the executor free to\n * depend on the runner without the runner depending on the executor.\n *\n * Types only. Imports stay on the plan, store, admission, and permit modules,\n * none of which reach the executor or the runner.\n */\n\nimport type { ResourceAdmissionDecision } from \"./resource-admission.ts\";\nimport type { WorkloadPermitPool } from \"./workload-permit-pool.ts\";\nimport type { WorkloadShardPlan, WorkloadShardProjection, WorkloadShardSpec } from \"./workload-shard-plan.ts\";\nimport type { WorkloadShardStore } from \"./workload-shard-store.ts\";\n\nexport interface ShardRunContext {\n\treadonly shard: WorkloadShardSpec;\n\treadonly attempt: number;\n\treadonly signal?: AbortSignal;\n}\n\n/** Resolves only after its owned execution boundary terminates; rejection is unproven. */\nexport type ShardRunner = (\n\tcontext: ShardRunContext,\n) => Promise<{ readonly exitCode: number; readonly evidenceRefs?: readonly string[] }>;\n\nexport interface ExecuteWorkloadShardPlanInput {\n\treadonly plan: WorkloadShardPlan;\n\treadonly store: WorkloadShardStore;\n\treadonly runner: ShardRunner;\n\treadonly decision: ResourceAdmissionDecision;\n\treadonly permitPool?: WorkloadPermitPool;\n\treadonly signal?: AbortSignal;\n\t/** §13.5 step 4 retry policy: re-arm previously failed shards. Default false. */\n\treadonly retryFailed?: boolean;\n\t/** §13.4: aborted -> pending needs an explicit resume; this call is that act. Default true. */\n\treadonly resumeAborted?: boolean;\n\t/** Trusted recovery witness for this exact shard attempt. Missing or unknown never rearms. */\n\treadonly observeTermination?: (\n\t\tshard: WorkloadShardProjection,\n\t) => \"terminated\" | \"unknown\" | Promise<\"terminated\" | \"unknown\">;\n\treadonly permitWaitTimeoutMs?: number;\n\treadonly now?: () => Date;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"workload-shard-execution-types.js","sourceRoot":"","sources":["../../src/core/workload-shard-execution-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG","sourcesContent":["/**\n * Shard execution contract.\n *\n * These declarations describe the call the executor makes and the input it\n * takes. They lived in the executor, so the runner — which the executor calls\n * to advance one shard — had to import the executor back to name its own\n * parameter type. Moving the contract below both leaves the executor free to\n * depend on the runner without the runner depending on the executor.\n *\n * Types only. Imports stay on the plan, store, admission, and permit modules,\n * none of which reach the executor or the runner.\n */\n\nimport type { ResourceAdmissionDecision } from \"./resource-admission.ts\";\nimport type { WorkloadPermitPool } from \"./workload-permit-pool.ts\";\nimport type { WorkloadShardPlan, WorkloadShardSpec } from \"./workload-shard-plan.ts\";\nimport type { WorkloadShardStore } from \"./workload-shard-store.ts\";\n\nexport interface ShardRunContext {\n\treadonly shard: WorkloadShardSpec;\n\treadonly attempt: number;\n\treadonly signal?: AbortSignal;\n}\n\nexport type ShardRunner = (\n\tcontext: ShardRunContext,\n) => Promise<{ readonly exitCode: number; readonly evidenceRefs?: readonly string[] }>;\n\nexport interface ExecuteWorkloadShardPlanInput {\n\treadonly plan: WorkloadShardPlan;\n\treadonly store: WorkloadShardStore;\n\treadonly runner: ShardRunner;\n\treadonly decision: ResourceAdmissionDecision;\n\treadonly permitPool?: WorkloadPermitPool;\n\treadonly signal?: AbortSignal;\n\t/** §13.5 step 4 retry policy: re-arm previously failed shards. Default false. */\n\treadonly retryFailed?: boolean;\n\t/** §13.4: aborted -> pending needs an explicit resume; this call is that act. Default true. */\n\treadonly resumeAborted?: boolean;\n\treadonly permitWaitTimeoutMs?: number;\n\treadonly now?: () => Date;\n}\n"]}
1
+ {"version":3,"file":"workload-shard-execution-types.js","sourceRoot":"","sources":["../../src/core/workload-shard-execution-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG","sourcesContent":["/**\n * Shard execution contract.\n *\n * These declarations describe the call the executor makes and the input it\n * takes. They lived in the executor, so the runner — which the executor calls\n * to advance one shard — had to import the executor back to name its own\n * parameter type. Moving the contract below both leaves the executor free to\n * depend on the runner without the runner depending on the executor.\n *\n * Types only. Imports stay on the plan, store, admission, and permit modules,\n * none of which reach the executor or the runner.\n */\n\nimport type { ResourceAdmissionDecision } from \"./resource-admission.ts\";\nimport type { WorkloadPermitPool } from \"./workload-permit-pool.ts\";\nimport type { WorkloadShardPlan, WorkloadShardProjection, WorkloadShardSpec } from \"./workload-shard-plan.ts\";\nimport type { WorkloadShardStore } from \"./workload-shard-store.ts\";\n\nexport interface ShardRunContext {\n\treadonly shard: WorkloadShardSpec;\n\treadonly attempt: number;\n\treadonly signal?: AbortSignal;\n}\n\n/** Resolves only after its owned execution boundary terminates; rejection is unproven. */\nexport type ShardRunner = (\n\tcontext: ShardRunContext,\n) => Promise<{ readonly exitCode: number; readonly evidenceRefs?: readonly string[] }>;\n\nexport interface ExecuteWorkloadShardPlanInput {\n\treadonly plan: WorkloadShardPlan;\n\treadonly store: WorkloadShardStore;\n\treadonly runner: ShardRunner;\n\treadonly decision: ResourceAdmissionDecision;\n\treadonly permitPool?: WorkloadPermitPool;\n\treadonly signal?: AbortSignal;\n\t/** §13.5 step 4 retry policy: re-arm previously failed shards. Default false. */\n\treadonly retryFailed?: boolean;\n\t/** §13.4: aborted -> pending needs an explicit resume; this call is that act. Default true. */\n\treadonly resumeAborted?: boolean;\n\t/** Trusted recovery witness for this exact shard attempt. Missing or unknown never rearms. */\n\treadonly observeTermination?: (\n\t\tshard: WorkloadShardProjection,\n\t) => \"terminated\" | \"unknown\" | Promise<\"terminated\" | \"unknown\">;\n\treadonly permitWaitTimeoutMs?: number;\n\treadonly now?: () => Date;\n}\n"]}
@@ -6,8 +6,8 @@ export type { ExecuteWorkloadShardPlanInput, ShardRunContext, ShardRunner };
6
6
  *
7
7
  * Drives a validated `WorkloadShardPlan` through the journalled §13.4 state
8
8
  * machine: passed shards are terminal and never re-run (§13.5 step 3),
9
- * crash-orphaned `running` shards are recovered through `pending` re-arm
10
- * records, concurrency is recomputed from the CURRENT admission decision
9
+ * crash-orphaned `running` shards require a trusted termination witness before
10
+ * re-arm; concurrency is recomputed from the CURRENT admission decision
11
11
  * (§13.5 step 6) plus the shared permit pool, and completion produces an
12
12
  * aggregate evidence receipt (§13.6) — an observation input for
13
13
  * `evaluateTask()`, never a task verdict by itself.
@@ -1 +1 @@
1
- {"version":3,"file":"workload-shard-executor.d.ts","sourceRoot":"","sources":["../../src/core/workload-shard-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AACvH,OAAO,EAKN,KAAK,kBAAkB,EACvB,MAAM,0BAA0B,CAAC;AAMlC,YAAY,EAAE,6BAA6B,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC;AAE5E;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,kEAAgE;AAChE,MAAM,WAAW,8BAA8B;IAC9C,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IAC9D,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9D,QAAQ,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC/C,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAsB,wBAAwB,CAC7C,KAAK,EAAE,6BAA6B,GAClC,OAAO,CAAC,8BAA8B,CAAC,CAoFzC","sourcesContent":["import type { ExecuteWorkloadShardPlanInput, ShardRunContext, ShardRunner } from \"./workload-shard-execution-types.ts\";\nimport {\n\tplanShardResume,\n\treduceShardRecords,\n\tvalidateWorkloadShardPlan,\n\ttype WorkloadShardProjection,\n\ttype WorkloadShardState,\n} from \"./workload-shard-plan.ts\";\nimport { applyTransition, runOneShard, shardById } from \"./workload-shard-runner.ts\";\nimport { WorkloadShardJournalError, type WorkloadShardStore } from \"./workload-shard-store.ts\";\n\n// The contract lives in `workload-shard-execution-types.ts` so the runner can\n// name its own parameter type without importing this module back.\nexport type { ExecuteWorkloadShardPlanInput, ShardRunContext, ShardRunner };\n\n/**\n * Workload shard executor (OMK v0.97.x roadmap §13, M5 completion slice).\n *\n * Drives a validated `WorkloadShardPlan` through the journalled §13.4 state\n * machine: passed shards are terminal and never re-run (§13.5 step 3),\n * crash-orphaned `running` shards are recovered through `pending` re-arm\n * records, concurrency is recomputed from the CURRENT admission decision\n * (§13.5 step 6) plus the shared permit pool, and completion produces an\n * aggregate evidence receipt (§13.6) — an observation input for\n * `evaluateTask()`, never a task verdict by itself.\n *\n * Fail-closed rules (§21): a corrupt journal is quarantined and the run is\n * `blocked`; a journal written for a different plan is `blocked`; an invalid\n * plan never starts. The executor never rewrites shard commands (§12.3) —\n * it only runs what the plan's descriptors already describe via the\n * injected runner.\n */\n\nexport interface ShardResultSummary {\n\treadonly shardId: string;\n\treadonly state: WorkloadShardState;\n\treadonly attempt: number;\n\treadonly evidenceRefs: readonly string[];\n\treadonly reasonCode?: string;\n}\n\n/** §13.6 aggregate evidence receipt; §15.1 observation kind. */\nexport interface WorkloadShardAggregateEvidence {\n\treadonly kind: \"workload_shard_result.v1\";\n\treadonly planId: string;\n\treadonly promptRunId: string;\n\treadonly commandDigest: string;\n\treadonly strategy: string;\n\treadonly verdict: \"passed\" | \"failed\" | \"aborted\" | \"blocked\";\n\treadonly reasonCodes: readonly string[];\n\treadonly shardCount: number;\n\treadonly counts: Readonly<Record<WorkloadShardState, number>>;\n\treadonly shards: readonly ShardResultSummary[];\n\treadonly effectiveConcurrency: number;\n\treadonly completedAt: string;\n}\n\nexport async function executeWorkloadShardPlan(\n\tinput: ExecuteWorkloadShardPlanInput,\n): Promise<WorkloadShardAggregateEvidence> {\n\tconst now = input.now ?? (() => new Date());\n\tconst planErrors = validateWorkloadShardPlan(input.plan);\n\tif (planErrors.length > 0) {\n\t\treturn blockedEvidence(input, now, [\"plan.invalid\", ...planErrors.slice(0, 3)]);\n\t}\n\n\tlet journal: ReturnType<WorkloadShardStore[\"load\"]>;\n\ttry {\n\t\tjournal = input.store.load();\n\t} catch (error) {\n\t\t// §21 fail closed: corrupt evidence is quarantined, never silently rebuilt.\n\t\tif (error instanceof WorkloadShardJournalError) {\n\t\t\tinput.store.quarantine();\n\t\t\treturn blockedEvidence(input, now, [`journal.${error.code}`]);\n\t\t}\n\t\tthrow error;\n\t}\n\tif (journal.plan === null) {\n\t\tinput.store.appendPlan(input.plan);\n\t} else if (journal.plan.planId !== input.plan.planId || journal.plan.commandDigest !== input.plan.commandDigest) {\n\t\treturn blockedEvidence(input, now, [\"plan.mismatch\"]);\n\t}\n\n\tconst projections = new Map<string, WorkloadShardProjection>(\n\t\tjournal.projections ?? reduceShardRecords(input.plan, []),\n\t);\n\tconst effectiveConcurrency = Math.max(1, Math.min(input.plan.maxConcurrency, input.decision.maxHeavyProcesses));\n\n\t// §13.5 steps 2-4: re-arm recoverable shards through explicit pending records.\n\tconst resume = planShardResume(input.plan, projections);\n\tconst rearm = [\n\t\t...resume.interrupted,\n\t\t...(input.retryFailed ? resume.retryable : []),\n\t\t...((input.resumeAborted ?? true) ? resume.resumable : []),\n\t];\n\tfor (const shardId of rearm) {\n\t\t// §13.5 step 2: a crash-orphaned `running` shard is first projected as\n\t\t// interrupted (running -> pending is illegal in §13.4), then re-armed.\n\t\tif (projections.get(shardId)?.state === \"running\") {\n\t\t\tapplyTransition(input, projections, shardId, \"interrupted\", { reasonCode: \"recovery.orphaned\", now });\n\t\t}\n\t\tapplyTransition(input, projections, shardId, \"pending\", { reasonCode: \"recovery.rearm\", now });\n\t}\n\n\t// Dependency-wave scheduler: launch ready shards up to the recomputed width.\n\tconst remaining = new Set(\n\t\tinput.plan.shards.map((shard) => shard.shardId).filter((id) => projections.get(id)?.state !== \"passed\"),\n\t);\n\tlet active = 0;\n\tlet wake: (() => void) | undefined;\n\tconst waitTurn = () =>\n\t\tnew Promise<void>((resolve) => {\n\t\t\twake = resolve;\n\t\t});\n\tconst running = new Map<string, Promise<void>>();\n\n\twhile (remaining.size > 0 && !input.signal?.aborted) {\n\t\tconst ready = [...remaining].filter((id) => {\n\t\t\tconst projection = projections.get(id);\n\t\t\tif (projection?.state !== \"pending\") return false;\n\t\t\tconst spec = shardById(input.plan, id);\n\t\t\treturn spec.dependencyIds.every((dep) => projections.get(dep)?.state === \"passed\");\n\t\t});\n\t\tconst launchable = ready.slice(0, Math.max(0, effectiveConcurrency - active));\n\t\tif (launchable.length === 0) {\n\t\t\tif (running.size === 0) break; // deadlock = blocked dependents; aggregate reports them\n\t\t\tawait Promise.race([...running.values(), waitTurn()]);\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const shardId of launchable) {\n\t\t\tremaining.delete(shardId);\n\t\t\tactive += 1;\n\t\t\tconst task = runOneShard(input, projections, shardId, now).finally(() => {\n\t\t\t\tactive -= 1;\n\t\t\t\trunning.delete(shardId);\n\t\t\t\twake?.();\n\t\t\t});\n\t\t\trunning.set(shardId, task);\n\t\t}\n\t}\n\tawait Promise.all(running.values());\n\n\treturn aggregate(input, projections, effectiveConcurrency, now, input.signal?.aborted ? [\"run.aborted\"] : []);\n}\n\nfunction aggregate(\n\tinput: ExecuteWorkloadShardPlanInput,\n\tprojections: ReadonlyMap<string, WorkloadShardProjection>,\n\teffectiveConcurrency: number,\n\tnow: () => Date,\n\textraReasons: readonly string[],\n): WorkloadShardAggregateEvidence {\n\tconst counts: Record<WorkloadShardState, number> = {\n\t\tpending: 0,\n\t\trunning: 0,\n\t\tpassed: 0,\n\t\tfailed: 0,\n\t\taborted: 0,\n\t\tinterrupted: 0,\n\t};\n\tconst shards: ShardResultSummary[] = input.plan.shards.map((shard) => {\n\t\tconst projection = projections.get(shard.shardId);\n\t\tconst state = projection?.state ?? \"pending\";\n\t\tcounts[state] += 1;\n\t\treturn {\n\t\t\tshardId: shard.shardId,\n\t\t\tstate,\n\t\t\tattempt: projection?.attempt ?? 0,\n\t\t\tevidenceRefs: projection?.evidenceRefs ?? [],\n\t\t\t...(projection?.reasonCode !== undefined ? { reasonCode: projection.reasonCode } : {}),\n\t\t};\n\t});\n\tconst verdict = aggregateVerdict(counts, input.plan.shards.length, extraReasons);\n\treturn {\n\t\tkind: \"workload_shard_result.v1\",\n\t\tplanId: input.plan.planId,\n\t\tpromptRunId: input.plan.promptRunId,\n\t\tcommandDigest: input.plan.commandDigest,\n\t\tstrategy: input.plan.strategy,\n\t\tverdict,\n\t\treasonCodes: extraReasons,\n\t\tshardCount: input.plan.shards.length,\n\t\tcounts,\n\t\tshards,\n\t\teffectiveConcurrency,\n\t\tcompletedAt: now().toISOString(),\n\t};\n}\n\nfunction blockedEvidence(\n\tinput: ExecuteWorkloadShardPlanInput,\n\tnow: () => Date,\n\treasonCodes: readonly string[],\n): WorkloadShardAggregateEvidence {\n\tconst counts: Record<WorkloadShardState, number> = {\n\t\tpending: input.plan.shards.length,\n\t\trunning: 0,\n\t\tpassed: 0,\n\t\tfailed: 0,\n\t\taborted: 0,\n\t\tinterrupted: 0,\n\t};\n\treturn {\n\t\tkind: \"workload_shard_result.v1\",\n\t\tplanId: input.plan.planId,\n\t\tpromptRunId: input.plan.promptRunId,\n\t\tcommandDigest: input.plan.commandDigest,\n\t\tstrategy: input.plan.strategy,\n\t\tverdict: \"blocked\",\n\t\treasonCodes,\n\t\tshardCount: input.plan.shards.length,\n\t\tcounts,\n\t\tshards: input.plan.shards.map((shard) => ({\n\t\t\tshardId: shard.shardId,\n\t\t\tstate: \"pending\" as const,\n\t\t\tattempt: 0,\n\t\t\tevidenceRefs: [],\n\t\t})),\n\t\teffectiveConcurrency: 0,\n\t\tcompletedAt: now().toISOString(),\n\t};\n}\n\n/** §13.6: \"passed\" requires EVERY shard to hold terminal passed evidence. */\nfunction aggregateVerdict(\n\tcounts: Readonly<Record<WorkloadShardState, number>>,\n\tshardCount: number,\n\textraReasons: readonly string[],\n): WorkloadShardAggregateEvidence[\"verdict\"] {\n\tif (counts.passed === shardCount) return \"passed\";\n\tif (counts.aborted > 0 || extraReasons.includes(\"run.aborted\")) return \"aborted\";\n\treturn \"failed\";\n}\n"]}
1
+ {"version":3,"file":"workload-shard-executor.d.ts","sourceRoot":"","sources":["../../src/core/workload-shard-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAEvH,OAAO,EAKN,KAAK,kBAAkB,EACvB,MAAM,0BAA0B,CAAC;AAMlC,YAAY,EAAE,6BAA6B,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC;AAE5E;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,kEAAgE;AAChE,MAAM,WAAW,8BAA8B;IAC9C,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IAC9D,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9D,QAAQ,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC/C,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAsB,wBAAwB,CAC7C,KAAK,EAAE,6BAA6B,GAClC,OAAO,CAAC,8BAA8B,CAAC,CAwDzC","sourcesContent":["import type { ExecuteWorkloadShardPlanInput, ShardRunContext, ShardRunner } from \"./workload-shard-execution-types.ts\";\nimport { runShardFrontier } from \"./workload-shard-frontier.ts\";\nimport {\n\tplanShardResume,\n\treduceShardRecords,\n\tvalidateWorkloadShardPlan,\n\ttype WorkloadShardProjection,\n\ttype WorkloadShardState,\n} from \"./workload-shard-plan.ts\";\nimport { applyTransition } from \"./workload-shard-runner.ts\";\nimport { WorkloadShardJournalError, type WorkloadShardStore } from \"./workload-shard-store.ts\";\n\n// The contract lives in `workload-shard-execution-types.ts` so the runner can\n// name its own parameter type without importing this module back.\nexport type { ExecuteWorkloadShardPlanInput, ShardRunContext, ShardRunner };\n\n/**\n * Workload shard executor (OMK v0.97.x roadmap §13, M5 completion slice).\n *\n * Drives a validated `WorkloadShardPlan` through the journalled §13.4 state\n * machine: passed shards are terminal and never re-run (§13.5 step 3),\n * crash-orphaned `running` shards require a trusted termination witness before\n * re-arm; concurrency is recomputed from the CURRENT admission decision\n * (§13.5 step 6) plus the shared permit pool, and completion produces an\n * aggregate evidence receipt (§13.6) — an observation input for\n * `evaluateTask()`, never a task verdict by itself.\n *\n * Fail-closed rules (§21): a corrupt journal is quarantined and the run is\n * `blocked`; a journal written for a different plan is `blocked`; an invalid\n * plan never starts. The executor never rewrites shard commands (§12.3) —\n * it only runs what the plan's descriptors already describe via the\n * injected runner.\n */\n\nexport interface ShardResultSummary {\n\treadonly shardId: string;\n\treadonly state: WorkloadShardState;\n\treadonly attempt: number;\n\treadonly evidenceRefs: readonly string[];\n\treadonly reasonCode?: string;\n}\n\n/** §13.6 aggregate evidence receipt; §15.1 observation kind. */\nexport interface WorkloadShardAggregateEvidence {\n\treadonly kind: \"workload_shard_result.v1\";\n\treadonly planId: string;\n\treadonly promptRunId: string;\n\treadonly commandDigest: string;\n\treadonly strategy: string;\n\treadonly verdict: \"passed\" | \"failed\" | \"aborted\" | \"blocked\";\n\treadonly reasonCodes: readonly string[];\n\treadonly shardCount: number;\n\treadonly counts: Readonly<Record<WorkloadShardState, number>>;\n\treadonly shards: readonly ShardResultSummary[];\n\treadonly effectiveConcurrency: number;\n\treadonly completedAt: string;\n}\n\nexport async function executeWorkloadShardPlan(\n\tinput: ExecuteWorkloadShardPlanInput,\n): Promise<WorkloadShardAggregateEvidence> {\n\tconst now = input.now ?? (() => new Date());\n\tconst planErrors = validateWorkloadShardPlan(input.plan);\n\tif (planErrors.length > 0) {\n\t\treturn blockedEvidence(input, now, [\"plan.invalid\", ...planErrors.slice(0, 3)]);\n\t}\n\n\tlet journal: ReturnType<WorkloadShardStore[\"load\"]>;\n\ttry {\n\t\tjournal = input.store.load();\n\t} catch (error) {\n\t\t// §21 fail closed: corrupt evidence is quarantined, never silently rebuilt.\n\t\tif (error instanceof WorkloadShardJournalError) {\n\t\t\tinput.store.quarantine();\n\t\t\treturn blockedEvidence(input, now, [`journal.${error.code}`]);\n\t\t}\n\t\tthrow error;\n\t}\n\tif (journal.plan === null) {\n\t\tinput.store.appendPlan(input.plan);\n\t} else if (journal.plan.planId !== input.plan.planId || journal.plan.commandDigest !== input.plan.commandDigest) {\n\t\treturn blockedEvidence(input, now, [\"plan.mismatch\"]);\n\t}\n\n\tconst projections = new Map<string, WorkloadShardProjection>(\n\t\tjournal.projections ?? reduceShardRecords(input.plan, []),\n\t);\n\tconst cap = input.decision.maxHeavyProcesses;\n\tif (!Number.isSafeInteger(cap) || cap < 0) return blockedEvidence(input, now, [\"resource.invalid_capacity\"]);\n\tconst effectiveConcurrency = Math.min(input.plan.maxConcurrency, cap);\n\tif (effectiveConcurrency === 0) return aggregate(input, projections, 0, now, [\"resource.capacity_zero\"]);\n\n\t// §13.5 steps 2-4: re-arm recoverable shards through explicit pending records.\n\tconst resume = planShardResume(input.plan, projections);\n\tfor (const id of resume.interrupted) {\n\t\tconst shard = projections.get(id);\n\t\tif (!shard || (await input.observeTermination?.(shard)) !== \"terminated\")\n\t\t\treturn aggregate(input, projections, effectiveConcurrency, now, [\"recovery.termination_unproven\"]);\n\t}\n\tconst rearm = [\n\t\t...resume.interrupted,\n\t\t...(input.retryFailed ? resume.retryable : []),\n\t\t...((input.resumeAborted ?? true) ? resume.resumable : []),\n\t];\n\tfor (const shardId of rearm) {\n\t\t// §13.5 step 2: a crash-orphaned `running` shard is first projected as\n\t\t// interrupted (running -> pending is illegal in §13.4), then re-armed.\n\t\tif (projections.get(shardId)?.state === \"running\") {\n\t\t\tapplyTransition(input, projections, shardId, \"interrupted\", { reasonCode: \"recovery.orphaned\", now });\n\t\t}\n\t\tapplyTransition(input, projections, shardId, \"pending\", { reasonCode: \"recovery.rearm\", now });\n\t}\n\n\tawait runShardFrontier(input, projections, effectiveConcurrency, now);\n\n\treturn aggregate(input, projections, effectiveConcurrency, now, input.signal?.aborted ? [\"run.aborted\"] : []);\n}\n\nfunction aggregate(\n\tinput: ExecuteWorkloadShardPlanInput,\n\tprojections: ReadonlyMap<string, WorkloadShardProjection>,\n\teffectiveConcurrency: number,\n\tnow: () => Date,\n\textraReasons: readonly string[],\n): WorkloadShardAggregateEvidence {\n\tconst counts: Record<WorkloadShardState, number> = {\n\t\tpending: 0,\n\t\trunning: 0,\n\t\tpassed: 0,\n\t\tfailed: 0,\n\t\taborted: 0,\n\t\tinterrupted: 0,\n\t};\n\tconst shards: ShardResultSummary[] = input.plan.shards.map((shard) => {\n\t\tconst projection = projections.get(shard.shardId);\n\t\tconst state = projection?.state ?? \"pending\";\n\t\tcounts[state] += 1;\n\t\treturn {\n\t\t\tshardId: shard.shardId,\n\t\t\tstate,\n\t\t\tattempt: projection?.attempt ?? 0,\n\t\t\tevidenceRefs: projection?.evidenceRefs ?? [],\n\t\t\t...(projection?.reasonCode !== undefined ? { reasonCode: projection.reasonCode } : {}),\n\t\t};\n\t});\n\tconst verdict = aggregateVerdict(counts, input.plan.shards.length, extraReasons);\n\treturn {\n\t\tkind: \"workload_shard_result.v1\",\n\t\tplanId: input.plan.planId,\n\t\tpromptRunId: input.plan.promptRunId,\n\t\tcommandDigest: input.plan.commandDigest,\n\t\tstrategy: input.plan.strategy,\n\t\tverdict,\n\t\treasonCodes: extraReasons,\n\t\tshardCount: input.plan.shards.length,\n\t\tcounts,\n\t\tshards,\n\t\teffectiveConcurrency,\n\t\tcompletedAt: now().toISOString(),\n\t};\n}\n\nfunction blockedEvidence(\n\tinput: ExecuteWorkloadShardPlanInput,\n\tnow: () => Date,\n\treasonCodes: readonly string[],\n): WorkloadShardAggregateEvidence {\n\tconst counts: Record<WorkloadShardState, number> = {\n\t\tpending: input.plan.shards.length,\n\t\trunning: 0,\n\t\tpassed: 0,\n\t\tfailed: 0,\n\t\taborted: 0,\n\t\tinterrupted: 0,\n\t};\n\treturn {\n\t\tkind: \"workload_shard_result.v1\",\n\t\tplanId: input.plan.planId,\n\t\tpromptRunId: input.plan.promptRunId,\n\t\tcommandDigest: input.plan.commandDigest,\n\t\tstrategy: input.plan.strategy,\n\t\tverdict: \"blocked\",\n\t\treasonCodes,\n\t\tshardCount: input.plan.shards.length,\n\t\tcounts,\n\t\tshards: input.plan.shards.map((shard) => ({\n\t\t\tshardId: shard.shardId,\n\t\t\tstate: \"pending\" as const,\n\t\t\tattempt: 0,\n\t\t\tevidenceRefs: [],\n\t\t})),\n\t\teffectiveConcurrency: 0,\n\t\tcompletedAt: now().toISOString(),\n\t};\n}\n\n/** §13.6: \"passed\" requires EVERY shard to hold terminal passed evidence. */\nfunction aggregateVerdict(\n\tcounts: Readonly<Record<WorkloadShardState, number>>,\n\tshardCount: number,\n\textraReasons: readonly string[],\n): WorkloadShardAggregateEvidence[\"verdict\"] {\n\tif (counts.passed === shardCount) return \"passed\";\n\tif (extraReasons.some((reason) => reason.startsWith(\"resource.\") || reason.startsWith(\"recovery.\")))\n\t\treturn \"blocked\";\n\tif (counts.aborted > 0 || extraReasons.includes(\"run.aborted\")) return \"aborted\";\n\treturn \"failed\";\n}\n"]}