@blxzer/pactile 0.6.0-beta.2 → 0.6.0-beta.4

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 (703) hide show
  1. package/README.md +93 -84
  2. package/README.zh-CN.md +90 -81
  3. package/dist/bin/compat-warning.d.ts +2 -0
  4. package/dist/bin/compat-warning.d.ts.map +1 -0
  5. package/dist/bin/compat-warning.js +8 -0
  6. package/dist/bin/compat-warning.js.map +1 -0
  7. package/dist/bin/cstl.d.ts +3 -0
  8. package/dist/bin/cstl.d.ts.map +1 -0
  9. package/{bin → dist/bin}/cstl.js +2 -3
  10. package/dist/bin/cstl.js.map +1 -0
  11. package/dist/bin/pactile.d.ts +3 -0
  12. package/dist/bin/pactile.d.ts.map +1 -0
  13. package/dist/bin/pactile.js +4 -0
  14. package/dist/bin/pactile.js.map +1 -0
  15. package/dist/cli/index.d.ts.map +1 -1
  16. package/dist/cli/index.js +77 -17
  17. package/dist/cli/index.js.map +1 -1
  18. package/dist/commands/capability.d.ts +3 -0
  19. package/dist/commands/capability.d.ts.map +1 -0
  20. package/dist/commands/capability.js +129 -0
  21. package/dist/commands/capability.js.map +1 -0
  22. package/dist/commands/codex.d.ts.map +1 -1
  23. package/dist/commands/codex.js +54 -6
  24. package/dist/commands/codex.js.map +1 -1
  25. package/dist/commands/context.d.ts +2 -0
  26. package/dist/commands/context.d.ts.map +1 -1
  27. package/dist/commands/context.js +367 -41
  28. package/dist/commands/context.js.map +1 -1
  29. package/dist/commands/detach.d.ts.map +1 -1
  30. package/dist/commands/detach.js +5 -4
  31. package/dist/commands/detach.js.map +1 -1
  32. package/dist/commands/init.d.ts.map +1 -1
  33. package/dist/commands/init.js +615 -259
  34. package/dist/commands/init.js.map +1 -1
  35. package/dist/commands/legacy-task.d.ts +3 -0
  36. package/dist/commands/legacy-task.d.ts.map +1 -0
  37. package/dist/commands/legacy-task.js +295 -0
  38. package/dist/commands/legacy-task.js.map +1 -0
  39. package/dist/commands/pi.d.ts +3 -2
  40. package/dist/commands/pi.d.ts.map +1 -1
  41. package/dist/commands/pi.js +333 -10
  42. package/dist/commands/pi.js.map +1 -1
  43. package/dist/commands/session.d.ts.map +1 -1
  44. package/dist/commands/session.js +148 -24
  45. package/dist/commands/session.js.map +1 -1
  46. package/dist/commands/task-schedule.d.ts +17 -0
  47. package/dist/commands/task-schedule.d.ts.map +1 -0
  48. package/dist/commands/task-schedule.js +395 -0
  49. package/dist/commands/task-schedule.js.map +1 -0
  50. package/dist/commands/task-verify-plan.d.ts +3 -0
  51. package/dist/commands/task-verify-plan.d.ts.map +1 -0
  52. package/dist/commands/task-verify-plan.js +503 -0
  53. package/dist/commands/task-verify-plan.js.map +1 -0
  54. package/dist/commands/task-worktree-close.d.ts +4 -0
  55. package/dist/commands/task-worktree-close.d.ts.map +1 -0
  56. package/dist/commands/task-worktree-close.js +81 -0
  57. package/dist/commands/task-worktree-close.js.map +1 -0
  58. package/dist/commands/task.d.ts +3 -0
  59. package/dist/commands/task.d.ts.map +1 -1
  60. package/dist/commands/task.js +1373 -184
  61. package/dist/commands/task.js.map +1 -1
  62. package/dist/commands/tile-selection.d.ts +3 -0
  63. package/dist/commands/tile-selection.d.ts.map +1 -0
  64. package/dist/commands/tile-selection.js +174 -0
  65. package/dist/commands/tile-selection.js.map +1 -0
  66. package/dist/commands/update.d.ts +1 -1
  67. package/dist/commands/update.d.ts.map +1 -1
  68. package/dist/commands/update.js +80 -55
  69. package/dist/commands/update.js.map +1 -1
  70. package/dist/commands/worktree.d.ts +4 -0
  71. package/dist/commands/worktree.d.ts.map +1 -0
  72. package/dist/commands/worktree.js +198 -0
  73. package/dist/commands/worktree.js.map +1 -0
  74. package/dist/configurators/shared.js +1 -1
  75. package/dist/configurators/shared.js.map +1 -1
  76. package/dist/core/compat/environment.d.ts +0 -1
  77. package/dist/core/compat/environment.d.ts.map +1 -1
  78. package/dist/core/compat/environment.js +1 -9
  79. package/dist/core/compat/environment.js.map +1 -1
  80. package/dist/core/pactile/bounded-capabilities.d.ts +127 -0
  81. package/dist/core/pactile/bounded-capabilities.d.ts.map +1 -0
  82. package/dist/core/pactile/bounded-capabilities.js +188 -0
  83. package/dist/core/pactile/bounded-capabilities.js.map +1 -0
  84. package/dist/core/pactile/index.d.ts +1 -0
  85. package/dist/core/pactile/index.d.ts.map +1 -1
  86. package/dist/core/pactile/index.js +1 -0
  87. package/dist/core/pactile/index.js.map +1 -1
  88. package/dist/core/task/index.d.ts +4 -2
  89. package/dist/core/task/index.d.ts.map +1 -1
  90. package/dist/core/task/index.js +2 -1
  91. package/dist/core/task/index.js.map +1 -1
  92. package/dist/core/task/kernel-cli.d.ts +14 -1
  93. package/dist/core/task/kernel-cli.d.ts.map +1 -1
  94. package/dist/core/task/kernel-cli.js +128 -0
  95. package/dist/core/task/kernel-cli.js.map +1 -1
  96. package/dist/core/task/kernel-contract.d.ts +6 -3
  97. package/dist/core/task/kernel-contract.d.ts.map +1 -1
  98. package/dist/core/task/kernel-contract.js +71 -23
  99. package/dist/core/task/kernel-contract.js.map +1 -1
  100. package/dist/core/task/kernel-store.d.ts +6 -0
  101. package/dist/core/task/kernel-store.d.ts.map +1 -1
  102. package/dist/core/task/kernel-store.js +54 -2
  103. package/dist/core/task/kernel-store.js.map +1 -1
  104. package/dist/core/task/legacy-task-migration-reader.d.ts +137 -0
  105. package/dist/core/task/legacy-task-migration-reader.d.ts.map +1 -0
  106. package/dist/core/task/legacy-task-migration-reader.js +512 -0
  107. package/dist/core/task/legacy-task-migration-reader.js.map +1 -0
  108. package/dist/core/task/legacy-task-migration.d.ts +105 -0
  109. package/dist/core/task/legacy-task-migration.d.ts.map +1 -0
  110. package/dist/core/task/legacy-task-migration.js +562 -0
  111. package/dist/core/task/legacy-task-migration.js.map +1 -0
  112. package/dist/core/task/legacy-task-overlay-durable-io.d.ts +18 -0
  113. package/dist/core/task/legacy-task-overlay-durable-io.d.ts.map +1 -0
  114. package/dist/core/task/legacy-task-overlay-durable-io.js +66 -0
  115. package/dist/core/task/legacy-task-overlay-durable-io.js.map +1 -0
  116. package/dist/core/task/legacy-task-reconciliation-reader.d.ts +26 -0
  117. package/dist/core/task/legacy-task-reconciliation-reader.d.ts.map +1 -0
  118. package/dist/core/task/legacy-task-reconciliation-reader.js +324 -0
  119. package/dist/core/task/legacy-task-reconciliation-reader.js.map +1 -0
  120. package/dist/core/task/legacy-task-v2-import.d.ts +67 -0
  121. package/dist/core/task/legacy-task-v2-import.d.ts.map +1 -0
  122. package/dist/core/task/legacy-task-v2-import.js +1046 -0
  123. package/dist/core/task/legacy-task-v2-import.js.map +1 -0
  124. package/dist/core/task/project-file-observer.d.ts +46 -0
  125. package/dist/core/task/project-file-observer.d.ts.map +1 -0
  126. package/dist/core/task/project-file-observer.js +618 -0
  127. package/dist/core/task/project-file-observer.js.map +1 -0
  128. package/dist/core/task/start-authority.d.ts +14 -0
  129. package/dist/core/task/start-authority.d.ts.map +1 -0
  130. package/dist/core/task/start-authority.js +146 -0
  131. package/dist/core/task/start-authority.js.map +1 -0
  132. package/dist/core/task/strategy.d.ts +24 -0
  133. package/dist/core/task/strategy.d.ts.map +1 -0
  134. package/dist/core/task/strategy.js +136 -0
  135. package/dist/core/task/strategy.js.map +1 -0
  136. package/dist/core/task/task-candidate-observer.d.ts +111 -0
  137. package/dist/core/task/task-candidate-observer.d.ts.map +1 -0
  138. package/dist/core/task/task-candidate-observer.js +762 -0
  139. package/dist/core/task/task-candidate-observer.js.map +1 -0
  140. package/dist/core/task/task-kernel-close.d.ts +5 -0
  141. package/dist/core/task/task-kernel-close.d.ts.map +1 -0
  142. package/dist/core/task/task-kernel-close.js +367 -0
  143. package/dist/core/task/task-kernel-close.js.map +1 -0
  144. package/dist/core/task/task-kernel-dependencies.d.ts +3 -0
  145. package/dist/core/task/task-kernel-dependencies.d.ts.map +1 -0
  146. package/dist/core/task/task-kernel-dependencies.js +24 -0
  147. package/dist/core/task/task-kernel-dependencies.js.map +1 -0
  148. package/dist/core/task/task-kernel-host.d.ts +5 -0
  149. package/dist/core/task/task-kernel-host.d.ts.map +1 -0
  150. package/dist/core/task/task-kernel-host.js +136 -0
  151. package/dist/core/task/task-kernel-host.js.map +1 -0
  152. package/dist/core/task/task-kernel-paths.d.ts +19 -0
  153. package/dist/core/task/task-kernel-paths.d.ts.map +1 -0
  154. package/dist/core/task/task-kernel-paths.js +237 -0
  155. package/dist/core/task/task-kernel-paths.js.map +1 -0
  156. package/dist/core/task/task-kernel-reviews.d.ts +3 -0
  157. package/dist/core/task/task-kernel-reviews.d.ts.map +1 -0
  158. package/dist/core/task/task-kernel-reviews.js +100 -0
  159. package/dist/core/task/task-kernel-reviews.js.map +1 -0
  160. package/dist/core/task/task-kernel-runs.d.ts +5 -0
  161. package/dist/core/task/task-kernel-runs.d.ts.map +1 -0
  162. package/dist/core/task/task-kernel-runs.js +196 -0
  163. package/dist/core/task/task-kernel-runs.js.map +1 -0
  164. package/dist/core/task/task-kernel-schema.d.ts +29 -0
  165. package/dist/core/task/task-kernel-schema.d.ts.map +1 -0
  166. package/dist/core/task/task-kernel-schema.js +1169 -0
  167. package/dist/core/task/task-kernel-schema.js.map +1 -0
  168. package/dist/core/task/task-kernel-store-v2.d.ts +33 -0
  169. package/dist/core/task/task-kernel-store-v2.d.ts.map +1 -0
  170. package/dist/core/task/task-kernel-store-v2.js +574 -0
  171. package/dist/core/task/task-kernel-store-v2.js.map +1 -0
  172. package/dist/core/task/task-kernel-types.d.ts +585 -0
  173. package/dist/core/task/task-kernel-types.d.ts.map +1 -0
  174. package/dist/core/task/task-kernel-types.js +31 -0
  175. package/dist/core/task/task-kernel-types.js.map +1 -0
  176. package/dist/core/task/task-kernel-workspaces.d.ts +10 -0
  177. package/dist/core/task/task-kernel-workspaces.d.ts.map +1 -0
  178. package/dist/core/task/task-kernel-workspaces.js +250 -0
  179. package/dist/core/task/task-kernel-workspaces.js.map +1 -0
  180. package/dist/core/task/task-kernel-write-set.d.ts +3 -0
  181. package/dist/core/task/task-kernel-write-set.d.ts.map +1 -0
  182. package/dist/core/task/task-kernel-write-set.js +12 -0
  183. package/dist/core/task/task-kernel-write-set.js.map +1 -0
  184. package/dist/core/task/task-kernel.d.ts +19 -0
  185. package/dist/core/task/task-kernel.d.ts.map +1 -0
  186. package/dist/core/task/task-kernel.js +17 -0
  187. package/dist/core/task/task-kernel.js.map +1 -0
  188. package/dist/core/task/task-pull-request-observer.d.ts +25 -0
  189. package/dist/core/task/task-pull-request-observer.d.ts.map +1 -0
  190. package/dist/core/task/task-pull-request-observer.js +187 -0
  191. package/dist/core/task/task-pull-request-observer.js.map +1 -0
  192. package/dist/core/task/task-review-evidence.d.ts +27 -0
  193. package/dist/core/task/task-review-evidence.d.ts.map +1 -0
  194. package/dist/core/task/task-review-evidence.js +383 -0
  195. package/dist/core/task/task-review-evidence.js.map +1 -0
  196. package/dist/migrations/index.d.ts +1 -1
  197. package/dist/migrations/index.d.ts.map +1 -1
  198. package/dist/migrations/index.js +5 -3
  199. package/dist/migrations/index.js.map +1 -1
  200. package/dist/migrations/manifests/0.6.0-beta.3.json +9 -0
  201. package/dist/migrations/manifests/0.6.0-beta.4.json +9 -0
  202. package/dist/pactile/artifacts/documents.d.ts +72 -0
  203. package/dist/pactile/artifacts/documents.d.ts.map +1 -0
  204. package/dist/pactile/artifacts/documents.js +406 -0
  205. package/dist/pactile/artifacts/documents.js.map +1 -0
  206. package/dist/pactile/artifacts/index.d.ts +6 -0
  207. package/dist/pactile/artifacts/index.d.ts.map +1 -0
  208. package/dist/pactile/artifacts/index.js +6 -0
  209. package/dist/pactile/artifacts/index.js.map +1 -0
  210. package/dist/pactile/artifacts/projection.d.ts +50 -0
  211. package/dist/pactile/artifacts/projection.d.ts.map +1 -0
  212. package/dist/pactile/artifacts/projection.js +139 -0
  213. package/dist/pactile/artifacts/projection.js.map +1 -0
  214. package/dist/pactile/artifacts/reader.d.ts +20 -0
  215. package/dist/pactile/artifacts/reader.d.ts.map +1 -0
  216. package/dist/pactile/artifacts/reader.js +559 -0
  217. package/dist/pactile/artifacts/reader.js.map +1 -0
  218. package/dist/pactile/artifacts/schema.d.ts +4 -0
  219. package/dist/pactile/artifacts/schema.d.ts.map +1 -0
  220. package/dist/pactile/artifacts/schema.js +217 -0
  221. package/dist/pactile/artifacts/schema.js.map +1 -0
  222. package/dist/pactile/artifacts/types.d.ts +66 -0
  223. package/dist/pactile/artifacts/types.d.ts.map +1 -0
  224. package/dist/pactile/artifacts/types.js +45 -0
  225. package/dist/pactile/artifacts/types.js.map +1 -0
  226. package/dist/pactile/capabilities/claim.d.ts +3 -0
  227. package/dist/pactile/capabilities/claim.d.ts.map +1 -0
  228. package/dist/pactile/capabilities/claim.js +97 -0
  229. package/dist/pactile/capabilities/claim.js.map +1 -0
  230. package/dist/pactile/capabilities/command.d.ts +6 -0
  231. package/dist/pactile/capabilities/command.d.ts.map +1 -0
  232. package/dist/pactile/capabilities/command.js +253 -0
  233. package/dist/pactile/capabilities/command.js.map +1 -0
  234. package/dist/pactile/capabilities/discover.d.ts +6 -0
  235. package/dist/pactile/capabilities/discover.d.ts.map +1 -0
  236. package/dist/pactile/capabilities/discover.js +48 -0
  237. package/dist/pactile/capabilities/discover.js.map +1 -0
  238. package/dist/pactile/capabilities/node.d.ts +15 -0
  239. package/dist/pactile/capabilities/node.d.ts.map +1 -0
  240. package/dist/pactile/capabilities/node.js +292 -0
  241. package/dist/pactile/capabilities/node.js.map +1 -0
  242. package/dist/pactile/capabilities/read.d.ts +6 -0
  243. package/dist/pactile/capabilities/read.d.ts.map +1 -0
  244. package/dist/pactile/capabilities/read.js +100 -0
  245. package/dist/pactile/capabilities/read.js.map +1 -0
  246. package/dist/pactile/capabilities/receipts.d.ts +17 -0
  247. package/dist/pactile/capabilities/receipts.d.ts.map +1 -0
  248. package/dist/pactile/capabilities/receipts.js +90 -0
  249. package/dist/pactile/capabilities/receipts.js.map +1 -0
  250. package/dist/pactile/capabilities/search.d.ts +6 -0
  251. package/dist/pactile/capabilities/search.d.ts.map +1 -0
  252. package/dist/pactile/capabilities/search.js +181 -0
  253. package/dist/pactile/capabilities/search.js.map +1 -0
  254. package/dist/pactile/capabilities/shared.d.ts +29 -0
  255. package/dist/pactile/capabilities/shared.d.ts.map +1 -0
  256. package/dist/pactile/capabilities/shared.js +134 -0
  257. package/dist/pactile/capabilities/shared.js.map +1 -0
  258. package/dist/pactile/capabilities/workspace.d.ts +19 -0
  259. package/dist/pactile/capabilities/workspace.d.ts.map +1 -0
  260. package/dist/pactile/capabilities/workspace.js +273 -0
  261. package/dist/pactile/capabilities/workspace.js.map +1 -0
  262. package/dist/pactile/codex/bridge.d.ts +105 -2
  263. package/dist/pactile/codex/bridge.d.ts.map +1 -1
  264. package/dist/pactile/codex/bridge.js +1266 -92
  265. package/dist/pactile/codex/bridge.js.map +1 -1
  266. package/dist/pactile/codex/dispatch-stop-proof.d.ts +43 -0
  267. package/dist/pactile/codex/dispatch-stop-proof.d.ts.map +1 -0
  268. package/dist/pactile/codex/dispatch-stop-proof.js +177 -0
  269. package/dist/pactile/codex/dispatch-stop-proof.js.map +1 -0
  270. package/dist/pactile/codex/host-stop.d.ts +47 -0
  271. package/dist/pactile/codex/host-stop.d.ts.map +1 -0
  272. package/dist/pactile/codex/host-stop.js +344 -0
  273. package/dist/pactile/codex/host-stop.js.map +1 -0
  274. package/dist/pactile/coordination/index.d.ts +4 -0
  275. package/dist/pactile/coordination/index.d.ts.map +1 -0
  276. package/dist/pactile/coordination/index.js +4 -0
  277. package/dist/pactile/coordination/index.js.map +1 -0
  278. package/dist/pactile/coordination/journal.d.ts +10 -0
  279. package/dist/pactile/coordination/journal.d.ts.map +1 -0
  280. package/dist/pactile/coordination/journal.js +255 -0
  281. package/dist/pactile/coordination/journal.js.map +1 -0
  282. package/dist/pactile/coordination/kernel-resume.d.ts +8 -0
  283. package/dist/pactile/coordination/kernel-resume.d.ts.map +1 -0
  284. package/dist/pactile/coordination/kernel-resume.js +87 -0
  285. package/dist/pactile/coordination/kernel-resume.js.map +1 -0
  286. package/dist/pactile/coordination/model.d.ts +553 -0
  287. package/dist/pactile/coordination/model.d.ts.map +1 -0
  288. package/dist/pactile/coordination/model.js +239 -0
  289. package/dist/pactile/coordination/model.js.map +1 -0
  290. package/dist/pactile/coordination/state.d.ts +46 -0
  291. package/dist/pactile/coordination/state.d.ts.map +1 -0
  292. package/dist/pactile/coordination/state.js +301 -0
  293. package/dist/pactile/coordination/state.js.map +1 -0
  294. package/dist/pactile/coordination/store.d.ts +94 -0
  295. package/dist/pactile/coordination/store.d.ts.map +1 -0
  296. package/dist/pactile/coordination/store.js +396 -0
  297. package/dist/pactile/coordination/store.js.map +1 -0
  298. package/dist/pactile/index.d.ts +7 -1
  299. package/dist/pactile/index.d.ts.map +1 -1
  300. package/dist/pactile/index.js +7 -1
  301. package/dist/pactile/index.js.map +1 -1
  302. package/dist/pactile/jev/contracts.d.ts +104 -0
  303. package/dist/pactile/jev/contracts.d.ts.map +1 -0
  304. package/dist/pactile/jev/contracts.js +53 -0
  305. package/dist/pactile/jev/contracts.js.map +1 -0
  306. package/dist/pactile/jev/decision.d.ts +58 -0
  307. package/dist/pactile/jev/decision.d.ts.map +1 -0
  308. package/dist/pactile/jev/decision.js +149 -0
  309. package/dist/pactile/jev/decision.js.map +1 -0
  310. package/dist/pactile/jev/http.d.ts +25 -0
  311. package/dist/pactile/jev/http.d.ts.map +1 -0
  312. package/dist/pactile/jev/http.js +234 -0
  313. package/dist/pactile/jev/http.js.map +1 -0
  314. package/dist/pactile/jev/index.d.ts +8 -0
  315. package/dist/pactile/jev/index.d.ts.map +1 -0
  316. package/dist/pactile/jev/index.js +4 -0
  317. package/dist/pactile/jev/index.js.map +1 -0
  318. package/dist/pactile/jev/outbound.d.ts +15 -0
  319. package/dist/pactile/jev/outbound.d.ts.map +1 -0
  320. package/dist/pactile/jev/outbound.js +264 -0
  321. package/dist/pactile/jev/outbound.js.map +1 -0
  322. package/dist/pactile/jev/project-policy.d.ts +10 -0
  323. package/dist/pactile/jev/project-policy.d.ts.map +1 -0
  324. package/dist/pactile/jev/project-policy.js +53 -0
  325. package/dist/pactile/jev/project-policy.js.map +1 -0
  326. package/dist/pactile/jev/response.d.ts +17 -0
  327. package/dist/pactile/jev/response.d.ts.map +1 -0
  328. package/dist/pactile/jev/response.js +280 -0
  329. package/dist/pactile/jev/response.js.map +1 -0
  330. package/dist/pactile/jev/scheduler-advice.d.ts +92 -0
  331. package/dist/pactile/jev/scheduler-advice.d.ts.map +1 -0
  332. package/dist/pactile/jev/scheduler-advice.js +323 -0
  333. package/dist/pactile/jev/scheduler-advice.js.map +1 -0
  334. package/dist/pactile/jev/transport.d.ts +6 -0
  335. package/dist/pactile/jev/transport.d.ts.map +1 -0
  336. package/dist/pactile/jev/transport.js +87 -0
  337. package/dist/pactile/jev/transport.js.map +1 -0
  338. package/dist/pactile/lifecycle/deferred-live.d.ts +17 -0
  339. package/dist/pactile/lifecycle/deferred-live.d.ts.map +1 -0
  340. package/dist/pactile/lifecycle/deferred-live.js +173 -0
  341. package/dist/pactile/lifecycle/deferred-live.js.map +1 -0
  342. package/dist/pactile/lifecycle/legacy-import.d.ts +1 -1
  343. package/dist/pactile/lifecycle/legacy-import.js +3 -3
  344. package/dist/pactile/lifecycle/legacy-import.js.map +1 -1
  345. package/dist/pactile/lifecycle/project-files.d.ts.map +1 -1
  346. package/dist/pactile/lifecycle/project-files.js +1 -0
  347. package/dist/pactile/lifecycle/project-files.js.map +1 -1
  348. package/dist/pactile/migration/legacy-task-batch-generation.d.ts +23 -0
  349. package/dist/pactile/migration/legacy-task-batch-generation.d.ts.map +1 -0
  350. package/dist/pactile/migration/legacy-task-batch-generation.js +102 -0
  351. package/dist/pactile/migration/legacy-task-batch-generation.js.map +1 -0
  352. package/dist/pactile/migration/legacy-task-batch-io.d.ts +9 -0
  353. package/dist/pactile/migration/legacy-task-batch-io.d.ts.map +1 -0
  354. package/dist/pactile/migration/legacy-task-batch-io.js +208 -0
  355. package/dist/pactile/migration/legacy-task-batch-io.js.map +1 -0
  356. package/dist/pactile/migration/legacy-task-batch-journal.d.ts +6 -0
  357. package/dist/pactile/migration/legacy-task-batch-journal.d.ts.map +1 -0
  358. package/dist/pactile/migration/legacy-task-batch-journal.js +121 -0
  359. package/dist/pactile/migration/legacy-task-batch-journal.js.map +1 -0
  360. package/dist/pactile/migration/legacy-task-batch-orchestrator.d.ts +18 -0
  361. package/dist/pactile/migration/legacy-task-batch-orchestrator.d.ts.map +1 -0
  362. package/dist/pactile/migration/legacy-task-batch-orchestrator.js +634 -0
  363. package/dist/pactile/migration/legacy-task-batch-orchestrator.js.map +1 -0
  364. package/dist/pactile/migration/legacy-task-batch-source.d.ts +8 -0
  365. package/dist/pactile/migration/legacy-task-batch-source.d.ts.map +1 -0
  366. package/dist/pactile/migration/legacy-task-batch-source.js +158 -0
  367. package/dist/pactile/migration/legacy-task-batch-source.js.map +1 -0
  368. package/dist/pactile/migration/legacy-task-batch-types.d.ts +127 -0
  369. package/dist/pactile/migration/legacy-task-batch-types.d.ts.map +1 -0
  370. package/dist/pactile/migration/legacy-task-batch-types.js +127 -0
  371. package/dist/pactile/migration/legacy-task-batch-types.js.map +1 -0
  372. package/dist/pactile/migration/legacy-task-batch.d.ts +3 -0
  373. package/dist/pactile/migration/legacy-task-batch.d.ts.map +1 -0
  374. package/dist/pactile/migration/legacy-task-batch.js +2 -0
  375. package/dist/pactile/migration/legacy-task-batch.js.map +1 -0
  376. package/dist/pactile/migration/legacy-task-held-source-reader.d.ts +27 -0
  377. package/dist/pactile/migration/legacy-task-held-source-reader.d.ts.map +1 -0
  378. package/dist/pactile/migration/legacy-task-held-source-reader.js +261 -0
  379. package/dist/pactile/migration/legacy-task-held-source-reader.js.map +1 -0
  380. package/dist/pactile/migration/legacy-task-reconciliation.d.ts +46 -0
  381. package/dist/pactile/migration/legacy-task-reconciliation.d.ts.map +1 -0
  382. package/dist/pactile/migration/legacy-task-reconciliation.js +589 -0
  383. package/dist/pactile/migration/legacy-task-reconciliation.js.map +1 -0
  384. package/dist/pactile/migration/legacy-task-update.d.ts +19 -0
  385. package/dist/pactile/migration/legacy-task-update.d.ts.map +1 -0
  386. package/dist/pactile/migration/legacy-task-update.js +164 -0
  387. package/dist/pactile/migration/legacy-task-update.js.map +1 -0
  388. package/dist/pactile/parallel/batch.d.ts +21 -2
  389. package/dist/pactile/parallel/batch.d.ts.map +1 -1
  390. package/dist/pactile/parallel/batch.js +271 -50
  391. package/dist/pactile/parallel/batch.js.map +1 -1
  392. package/dist/pactile/parallel/policy.d.ts +1 -1
  393. package/dist/pactile/parallel/policy.d.ts.map +1 -1
  394. package/dist/pactile/parallel/policy.js +130 -102
  395. package/dist/pactile/parallel/policy.js.map +1 -1
  396. package/dist/pactile/pi/bridge.d.ts +139 -2
  397. package/dist/pactile/pi/bridge.d.ts.map +1 -1
  398. package/dist/pactile/pi/bridge.js +1317 -106
  399. package/dist/pactile/pi/bridge.js.map +1 -1
  400. package/dist/pactile/pi/rpc.d.ts +23 -4
  401. package/dist/pactile/pi/rpc.d.ts.map +1 -1
  402. package/dist/pactile/pi/rpc.js +243 -42
  403. package/dist/pactile/pi/rpc.js.map +1 -1
  404. package/dist/pactile/pi/v2-dispatch.d.ts +113 -0
  405. package/dist/pactile/pi/v2-dispatch.d.ts.map +1 -0
  406. package/dist/pactile/pi/v2-dispatch.js +919 -0
  407. package/dist/pactile/pi/v2-dispatch.js.map +1 -0
  408. package/dist/pactile/projection/planner.js +1 -1
  409. package/dist/pactile/projection/planner.js.map +1 -1
  410. package/dist/pactile/registry.d.ts +63 -1
  411. package/dist/pactile/registry.d.ts.map +1 -1
  412. package/dist/pactile/registry.js +633 -4
  413. package/dist/pactile/registry.js.map +1 -1
  414. package/dist/pactile/retrieval/index.d.ts +1 -0
  415. package/dist/pactile/retrieval/index.d.ts.map +1 -1
  416. package/dist/pactile/retrieval/index.js +1 -0
  417. package/dist/pactile/retrieval/index.js.map +1 -1
  418. package/dist/pactile/retrieval/jev-planning.d.ts +28 -0
  419. package/dist/pactile/retrieval/jev-planning.d.ts.map +1 -0
  420. package/dist/pactile/retrieval/jev-planning.js +96 -0
  421. package/dist/pactile/retrieval/jev-planning.js.map +1 -0
  422. package/dist/pactile/review/contract.d.ts +232 -0
  423. package/dist/pactile/review/contract.d.ts.map +1 -0
  424. package/dist/pactile/review/contract.js +695 -0
  425. package/dist/pactile/review/contract.js.map +1 -0
  426. package/dist/pactile/review/escalation-artifacts.d.ts +41 -0
  427. package/dist/pactile/review/escalation-artifacts.d.ts.map +1 -0
  428. package/dist/pactile/review/escalation-artifacts.js +415 -0
  429. package/dist/pactile/review/escalation-artifacts.js.map +1 -0
  430. package/dist/pactile/review/escalation-contract.d.ts +115 -0
  431. package/dist/pactile/review/escalation-contract.d.ts.map +1 -0
  432. package/dist/pactile/review/escalation-contract.js +151 -0
  433. package/dist/pactile/review/escalation-contract.js.map +1 -0
  434. package/dist/pactile/review/escalation-finalize.d.ts +14 -0
  435. package/dist/pactile/review/escalation-finalize.d.ts.map +1 -0
  436. package/dist/pactile/review/escalation-finalize.js +319 -0
  437. package/dist/pactile/review/escalation-finalize.js.map +1 -0
  438. package/dist/pactile/review/escalation-reply.d.ts +10 -0
  439. package/dist/pactile/review/escalation-reply.d.ts.map +1 -0
  440. package/dist/pactile/review/escalation-reply.js +61 -0
  441. package/dist/pactile/review/escalation-reply.js.map +1 -0
  442. package/dist/pactile/review/escalation-transport.d.ts +32 -0
  443. package/dist/pactile/review/escalation-transport.d.ts.map +1 -0
  444. package/dist/pactile/review/escalation-transport.js +216 -0
  445. package/dist/pactile/review/escalation-transport.js.map +1 -0
  446. package/dist/pactile/review/escalation.d.ts +7 -0
  447. package/dist/pactile/review/escalation.d.ts.map +1 -0
  448. package/dist/pactile/review/escalation.js +6 -0
  449. package/dist/pactile/review/escalation.js.map +1 -0
  450. package/dist/pactile/review/evidence.d.ts +25 -0
  451. package/dist/pactile/review/evidence.d.ts.map +1 -0
  452. package/dist/pactile/review/evidence.js +58 -0
  453. package/dist/pactile/review/evidence.js.map +1 -0
  454. package/dist/pactile/review/jev-escalation-advice.d.ts +77 -0
  455. package/dist/pactile/review/jev-escalation-advice.d.ts.map +1 -0
  456. package/dist/pactile/review/jev-escalation-advice.js +358 -0
  457. package/dist/pactile/review/jev-escalation-advice.js.map +1 -0
  458. package/dist/pactile/scheduler/index.d.ts +6 -0
  459. package/dist/pactile/scheduler/index.d.ts.map +1 -0
  460. package/dist/pactile/scheduler/index.js +5 -0
  461. package/dist/pactile/scheduler/index.js.map +1 -0
  462. package/dist/pactile/scheduler/project-lease-store.d.ts +35 -0
  463. package/dist/pactile/scheduler/project-lease-store.d.ts.map +1 -0
  464. package/dist/pactile/scheduler/project-lease-store.js +189 -0
  465. package/dist/pactile/scheduler/project-lease-store.js.map +1 -0
  466. package/dist/pactile/scheduler/scheduler.d.ts +91 -0
  467. package/dist/pactile/scheduler/scheduler.d.ts.map +1 -0
  468. package/dist/pactile/scheduler/scheduler.js +589 -0
  469. package/dist/pactile/scheduler/scheduler.js.map +1 -0
  470. package/dist/pactile/scheduler/task-kernel-admission.d.ts +173 -0
  471. package/dist/pactile/scheduler/task-kernel-admission.d.ts.map +1 -0
  472. package/dist/pactile/scheduler/task-kernel-admission.js +1560 -0
  473. package/dist/pactile/scheduler/task-kernel-admission.js.map +1 -0
  474. package/dist/pactile/scheduler/task-kernel-wave-dispatch.d.ts +184 -0
  475. package/dist/pactile/scheduler/task-kernel-wave-dispatch.d.ts.map +1 -0
  476. package/dist/pactile/scheduler/task-kernel-wave-dispatch.js +952 -0
  477. package/dist/pactile/scheduler/task-kernel-wave-dispatch.js.map +1 -0
  478. package/dist/pactile/scheduler/task-map-scheduler.d.ts +116 -0
  479. package/dist/pactile/scheduler/task-map-scheduler.d.ts.map +1 -0
  480. package/dist/pactile/scheduler/task-map-scheduler.js +1448 -0
  481. package/dist/pactile/scheduler/task-map-scheduler.js.map +1 -0
  482. package/dist/pactile/scheduler/task-run-dispatch-state.d.ts +7 -0
  483. package/dist/pactile/scheduler/task-run-dispatch-state.d.ts.map +1 -0
  484. package/dist/pactile/scheduler/task-run-dispatch-state.js +69 -0
  485. package/dist/pactile/scheduler/task-run-dispatch-state.js.map +1 -0
  486. package/dist/pactile/task/authorization.d.ts +3 -0
  487. package/dist/pactile/task/authorization.d.ts.map +1 -0
  488. package/dist/pactile/task/authorization.js +43 -0
  489. package/dist/pactile/task/authorization.js.map +1 -0
  490. package/dist/pactile/task/creation.d.ts +22 -0
  491. package/dist/pactile/task/creation.d.ts.map +1 -0
  492. package/dist/pactile/task/creation.js +95 -0
  493. package/dist/pactile/task/creation.js.map +1 -0
  494. package/dist/pactile/task/guards.d.ts +1 -4
  495. package/dist/pactile/task/guards.d.ts.map +1 -1
  496. package/dist/pactile/task/guards.js +5 -57
  497. package/dist/pactile/task/guards.js.map +1 -1
  498. package/dist/pactile/task/session-jev-receipt.d.ts +58 -0
  499. package/dist/pactile/task/session-jev-receipt.d.ts.map +1 -0
  500. package/dist/pactile/task/session-jev-receipt.js +375 -0
  501. package/dist/pactile/task/session-jev-receipt.js.map +1 -0
  502. package/dist/pactile/task/session-jev.d.ts +7 -0
  503. package/dist/pactile/task/session-jev.d.ts.map +1 -0
  504. package/dist/pactile/task/session-jev.js +217 -0
  505. package/dist/pactile/task/session-jev.js.map +1 -0
  506. package/dist/pactile/task/session-pack.d.ts.map +1 -1
  507. package/dist/pactile/task/session-pack.js +155 -16
  508. package/dist/pactile/task/session-pack.js.map +1 -1
  509. package/dist/pactile/task/session-retrieval-jev-receipt.d.ts +49 -0
  510. package/dist/pactile/task/session-retrieval-jev-receipt.d.ts.map +1 -0
  511. package/dist/pactile/task/session-retrieval-jev-receipt.js +97 -0
  512. package/dist/pactile/task/session-retrieval-jev-receipt.js.map +1 -0
  513. package/dist/pactile/task/session-retrieval-jev.d.ts +8 -0
  514. package/dist/pactile/task/session-retrieval-jev.d.ts.map +1 -0
  515. package/dist/pactile/task/session-retrieval-jev.js +352 -0
  516. package/dist/pactile/task/session-retrieval-jev.js.map +1 -0
  517. package/dist/pactile/task/strategy.d.ts +1 -23
  518. package/dist/pactile/task/strategy.d.ts.map +1 -1
  519. package/dist/pactile/task/strategy.js +2 -135
  520. package/dist/pactile/task/strategy.js.map +1 -1
  521. package/dist/pactile/tiles/jev-selection.d.ts +44 -0
  522. package/dist/pactile/tiles/jev-selection.d.ts.map +1 -0
  523. package/dist/pactile/tiles/jev-selection.js +210 -0
  524. package/dist/pactile/tiles/jev-selection.js.map +1 -0
  525. package/dist/pactile/tiles/safe-yaml.d.ts +5 -1
  526. package/dist/pactile/tiles/safe-yaml.d.ts.map +1 -1
  527. package/dist/pactile/tiles/safe-yaml.js +8 -8
  528. package/dist/pactile/tiles/safe-yaml.js.map +1 -1
  529. package/dist/pactile/tiles/selection-receipts.d.ts +71 -0
  530. package/dist/pactile/tiles/selection-receipts.d.ts.map +1 -0
  531. package/dist/pactile/tiles/selection-receipts.js +319 -0
  532. package/dist/pactile/tiles/selection-receipts.js.map +1 -0
  533. package/dist/pactile/tiles/selection.d.ts +185 -0
  534. package/dist/pactile/tiles/selection.d.ts.map +1 -0
  535. package/dist/pactile/tiles/selection.js +985 -0
  536. package/dist/pactile/tiles/selection.js.map +1 -0
  537. package/dist/pactile/verification/git-observer.d.ts +3 -0
  538. package/dist/pactile/verification/git-observer.d.ts.map +1 -0
  539. package/dist/pactile/verification/git-observer.js +3 -0
  540. package/dist/pactile/verification/git-observer.js.map +1 -0
  541. package/dist/pactile/verification/index.d.ts +11 -0
  542. package/dist/pactile/verification/index.d.ts.map +1 -0
  543. package/dist/pactile/verification/index.js +6 -0
  544. package/dist/pactile/verification/index.js.map +1 -0
  545. package/dist/pactile/verification/jev-advice.d.ts +78 -0
  546. package/dist/pactile/verification/jev-advice.d.ts.map +1 -0
  547. package/dist/pactile/verification/jev-advice.js +397 -0
  548. package/dist/pactile/verification/jev-advice.js.map +1 -0
  549. package/dist/pactile/verification/planner.d.ts +15 -0
  550. package/dist/pactile/verification/planner.d.ts.map +1 -0
  551. package/dist/pactile/verification/planner.js +412 -0
  552. package/dist/pactile/verification/planner.js.map +1 -0
  553. package/dist/pactile/verification/receipt.d.ts +101 -0
  554. package/dist/pactile/verification/receipt.d.ts.map +1 -0
  555. package/dist/pactile/verification/receipt.js +400 -0
  556. package/dist/pactile/verification/receipt.js.map +1 -0
  557. package/dist/pactile/verification/types.d.ts +72 -0
  558. package/dist/pactile/verification/types.d.ts.map +1 -0
  559. package/dist/pactile/verification/types.js +21 -0
  560. package/dist/pactile/verification/types.js.map +1 -0
  561. package/dist/pactile/worktree/git-probe.d.ts +32 -0
  562. package/dist/pactile/worktree/git-probe.d.ts.map +1 -0
  563. package/dist/pactile/worktree/git-probe.js +336 -0
  564. package/dist/pactile/worktree/git-probe.js.map +1 -0
  565. package/dist/pactile/worktree/git-removal.d.ts +3 -0
  566. package/dist/pactile/worktree/git-removal.d.ts.map +1 -0
  567. package/dist/pactile/worktree/git-removal.js +11 -0
  568. package/dist/pactile/worktree/git-removal.js.map +1 -0
  569. package/dist/pactile/worktree/index.d.ts +2 -0
  570. package/dist/pactile/worktree/index.d.ts.map +1 -0
  571. package/dist/pactile/worktree/index.js +2 -0
  572. package/dist/pactile/worktree/index.js.map +1 -0
  573. package/dist/pactile/worktree/integration-evidence.d.ts +80 -0
  574. package/dist/pactile/worktree/integration-evidence.d.ts.map +1 -0
  575. package/dist/pactile/worktree/integration-evidence.js +166 -0
  576. package/dist/pactile/worktree/integration-evidence.js.map +1 -0
  577. package/dist/pactile/worktree/manager-core.d.ts +50 -0
  578. package/dist/pactile/worktree/manager-core.d.ts.map +1 -0
  579. package/dist/pactile/worktree/manager-core.js +359 -0
  580. package/dist/pactile/worktree/manager-core.js.map +1 -0
  581. package/dist/pactile/worktree/manager-provenance.d.ts +32 -0
  582. package/dist/pactile/worktree/manager-provenance.d.ts.map +1 -0
  583. package/dist/pactile/worktree/manager-provenance.js +409 -0
  584. package/dist/pactile/worktree/manager-provenance.js.map +1 -0
  585. package/dist/pactile/worktree/manager-types.d.ts +84 -0
  586. package/dist/pactile/worktree/manager-types.d.ts.map +1 -0
  587. package/dist/pactile/worktree/manager-types.js +11 -0
  588. package/dist/pactile/worktree/manager-types.js.map +1 -0
  589. package/dist/pactile/worktree/manager.d.ts +10 -0
  590. package/dist/pactile/worktree/manager.d.ts.map +1 -0
  591. package/dist/pactile/worktree/manager.js +6 -0
  592. package/dist/pactile/worktree/manager.js.map +1 -0
  593. package/dist/pactile/worktree/run-workspace-cleanup.d.ts +10 -0
  594. package/dist/pactile/worktree/run-workspace-cleanup.d.ts.map +1 -0
  595. package/dist/pactile/worktree/run-workspace-cleanup.js +695 -0
  596. package/dist/pactile/worktree/run-workspace-cleanup.js.map +1 -0
  597. package/dist/pactile/worktree/run-workspace-lifecycle.d.ts +65 -0
  598. package/dist/pactile/worktree/run-workspace-lifecycle.d.ts.map +1 -0
  599. package/dist/pactile/worktree/run-workspace-lifecycle.js +276 -0
  600. package/dist/pactile/worktree/run-workspace-lifecycle.js.map +1 -0
  601. package/dist/templates/common/bundled-skills/pactile-meta/references/customize-local/change-hooks.md +1 -1
  602. package/dist/templates/common/bundled-skills/pactile-meta/references/local-architecture/generated-files.md +1 -1
  603. package/dist/templates/common/bundled-skills/pactile-meta/references/platform-files/hooks-and-settings.md +1 -1
  604. package/dist/templates/common/bundled-skills/pactile-meta/references/platform-files/overview.md +1 -1
  605. package/dist/templates/common/bundled-skills/pactile-meta/references/platform-files/platform-map.md +1 -1
  606. package/dist/templates/common/bundled-skills/smart-search-cli/SKILL.md +2 -0
  607. package/dist/templates/common/skills/brainstorm.md +19 -13
  608. package/dist/templates/markdown/agents.md +2 -2
  609. package/dist/templates/markdown/framework/execution-strategy.md.txt +1 -1
  610. package/dist/templates/markdown/framework/index.md.txt +1 -1
  611. package/dist/templates/markdown/framework/parallel-first-execution.md.txt +17 -105
  612. package/dist/templates/markdown/framework/prd-grill-frontier.md.txt +3 -3
  613. package/dist/templates/markdown/framework/release-boundary.md.txt +9 -10
  614. package/dist/templates/markdown/framework/retrieval-daily-guide.md.txt +1 -1
  615. package/dist/templates/pactile/CONTEXT.md +48 -36
  616. package/dist/templates/pactile/modules/approval-personal/contract.md +12 -24
  617. package/dist/templates/pactile/modules/close-basic/contract.md +15 -18
  618. package/dist/templates/pactile/modules/debug-recovery/contract.md +4 -4
  619. package/dist/templates/pactile/modules/define-basic/contract.md +15 -19
  620. package/dist/templates/pactile/modules/define-extended/contract.md +3 -3
  621. package/dist/templates/pactile/modules/execute-agent/contract.md +11 -19
  622. package/dist/templates/pactile/modules/intake-basic/contract.md +16 -13
  623. package/dist/templates/pactile/modules/verify-basic/contract.md +11 -20
  624. package/dist/templates/pactile/tasks/templates/release-execution/design.md +5 -5
  625. package/dist/templates/pactile/tasks/templates/release-readiness/design.md +6 -6
  626. package/dist/templates/pactile/tasks/templates/release-readiness/handoff-template.md +8 -2
  627. package/dist/templates/pactile/workflow.md +37 -41
  628. package/dist/templates/template-utils.d.ts +1 -2
  629. package/dist/templates/template-utils.d.ts.map +1 -1
  630. package/dist/templates/template-utils.js +2 -13
  631. package/dist/templates/template-utils.js.map +1 -1
  632. package/dist/types/ai-tools.d.ts +1 -1
  633. package/dist/types/ai-tools.js +1 -1
  634. package/dist/utils/manifest-prune.js +1 -1
  635. package/dist/utils/manifest-prune.js.map +1 -1
  636. package/dist/utils/p36-upgrade.d.ts +2 -2
  637. package/dist/utils/p36-upgrade.d.ts.map +1 -1
  638. package/dist/utils/p36-upgrade.js +2 -10
  639. package/dist/utils/p36-upgrade.js.map +1 -1
  640. package/dist/utils/post-update-smoke.js +1 -1
  641. package/dist/utils/post-update-smoke.js.map +1 -1
  642. package/dist/utils/readiness.d.ts +2 -2
  643. package/dist/utils/readiness.js +2 -2
  644. package/dist/utils/uninstall-scrubbers.js +1 -1
  645. package/dist/utils/workflow-dir.d.ts +1 -1
  646. package/dist/utils/workflow-dir.d.ts.map +1 -1
  647. package/dist/utils/workflow-dir.js +1 -1
  648. package/dist/utils/workflow-dir.js.map +1 -1
  649. package/package.json +42 -37
  650. package/CHANGELOG.md +0 -651
  651. package/bin/compat-warning.js +0 -11
  652. package/bin/pactile.js +0 -3
  653. package/bin/smart-search.js +0 -38
  654. package/dist/migrations/manifests/0.1.0.json +0 -9
  655. package/dist/migrations/manifests/0.1.1.json +0 -9
  656. package/dist/migrations/manifests/0.1.2.json +0 -9
  657. package/dist/migrations/manifests/0.1.3.json +0 -9
  658. package/dist/migrations/manifests/0.1.4.json +0 -9
  659. package/dist/migrations/manifests/0.2.1.json +0 -9
  660. package/dist/migrations/manifests/0.2.10.json +0 -374
  661. package/dist/migrations/manifests/0.2.2.json +0 -9
  662. package/dist/migrations/manifests/0.2.3.json +0 -9
  663. package/dist/migrations/manifests/0.2.4.json +0 -9
  664. package/dist/migrations/manifests/0.2.5.json +0 -9
  665. package/dist/migrations/manifests/0.2.6.json +0 -9
  666. package/dist/migrations/manifests/0.2.7.json +0 -9
  667. package/dist/migrations/manifests/0.2.8.json +0 -9
  668. package/dist/migrations/manifests/0.2.9.json +0 -9
  669. package/dist/migrations/manifests/0.3.0.json +0 -89
  670. package/dist/migrations/manifests/0.3.1.json +0 -32
  671. package/dist/migrations/manifests/0.3.2.json +0 -16
  672. package/dist/migrations/manifests/0.3.3.json +0 -9
  673. package/dist/migrations/manifests/0.3.4.json +0 -9
  674. package/dist/migrations/manifests/0.3.5.json +0 -9
  675. package/dist/migrations/manifests/0.3.6.json +0 -9
  676. package/dist/migrations/manifests/0.4.0.json +0 -9
  677. package/dist/migrations/manifests/0.4.1.json +0 -9
  678. package/dist/migrations/manifests/0.4.2.json +0 -9
  679. package/dist/migrations/manifests/0.4.3.json +0 -9
  680. package/dist/migrations/manifests/0.5.0-beta.0.json +0 -9
  681. package/dist/migrations/manifests/0.5.0-beta.1.json +0 -9
  682. package/dist/migrations/manifests/0.5.0-beta.2.json +0 -9
  683. package/dist/migrations/manifests/0.5.0-beta.3.json +0 -9
  684. package/dist/migrations/manifests/0.5.0-beta.4.json +0 -9
  685. package/dist/migrations/manifests/0.5.0-beta.5.json +0 -9
  686. package/dist/migrations/manifests/0.5.0.json +0 -9
  687. package/dist/pactile/compat/retired-alternate-client.d.ts +0 -42
  688. package/dist/pactile/compat/retired-alternate-client.d.ts.map +0 -1
  689. package/dist/pactile/compat/retired-alternate-client.js +0 -153
  690. package/dist/pactile/compat/retired-alternate-client.js.map +0 -1
  691. package/dist/pactile/compat/update-residue.d.ts +0 -4
  692. package/dist/pactile/compat/update-residue.d.ts.map +0 -1
  693. package/dist/pactile/compat/update-residue.js +0 -55
  694. package/dist/pactile/compat/update-residue.js.map +0 -1
  695. package/dist/utils/cursor-retrieval-env.d.ts +0 -17
  696. package/dist/utils/cursor-retrieval-env.d.ts.map +0 -1
  697. package/dist/utils/cursor-retrieval-env.js +0 -19
  698. package/dist/utils/cursor-retrieval-env.js.map +0 -1
  699. package/dist/utils/proxy.d.ts +0 -25
  700. package/dist/utils/proxy.d.ts.map +0 -1
  701. package/dist/utils/proxy.js +0 -60
  702. package/dist/utils/proxy.js.map +0 -1
  703. package/scripts/postinstall.js +0 -6
@@ -1,20 +1,58 @@
1
1
  import { createHash, randomUUID } from "node:crypto";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
- import { readKernel } from "../../core/task/index.js";
4
+ import { fingerprintTaskValue, readTaskKernel, } from "../../core/task/index.js";
5
5
  import { resolveTaskDir } from "../task/session.js";
6
- import { approvedTask } from "../pi/bridge.js";
7
- import { parallelChild, releaseParallelChild, reserveParallelChild } from "../parallel/policy.js";
6
+ import { approvedExecuteTask } from "../task/authorization.js";
7
+ import { readStrategyContract } from "../task/strategy.js";
8
+ import { parallelChild, releaseParallelChild, reserveParallelChild, } from "../parallel/policy.js";
9
+ import { CoordinationStore, } from "../coordination/index.js";
10
+ import { assertCurrentPiReviewEscalationV1, assertCodexEscalationSendPromptV1, buildCodexEscalationPromptV1, readCodexEscalationSendV1, readPiReviewEscalationV1, } from "../review/escalation.js";
11
+ import { withProjectSchedulerMutex } from "../scheduler/project-lease-store.js";
12
+ export { readCodexHostStopReceipts, } from "./host-stop.js";
8
13
  const idPattern = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;
9
14
  const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
15
+ const escalationIdPattern = /^pi-escalation:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
16
+ const transportIdentifierPattern = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$/;
17
+ const escalationSecretPattern = /\b(?:bearer\s+[a-z0-9._~+/-]{12,}|(?:sk[-_]|gh[pousr]_|glpat-|plane_api_)[a-z0-9_-]{12,}|(?:api[_-]?key|token|password|secret)\s*[:=]\s*\S+)/iu;
18
+ function taskContextFromDirectory(root, dir, archived) {
19
+ const read = readTaskKernel({ root, taskDir: dir, cwd: root });
20
+ if (read.kind === "task-kernel-v2") {
21
+ const kernel = read.kernel;
22
+ return {
23
+ dir,
24
+ task: path.relative(root, dir).replaceAll("\\", "/"),
25
+ taskId: kernel.identity.taskId,
26
+ phase: kernel.phase,
27
+ revision: kernel.revision,
28
+ kernelKind: read.kind,
29
+ contractFingerprint: fingerprintTaskValue(kernel.definition),
30
+ events: kernel.events,
31
+ runs: kernel.runs,
32
+ reviews: kernel.reviews,
33
+ archived,
34
+ };
35
+ }
36
+ const kernel = read.kernel.kernel;
37
+ return {
38
+ dir,
39
+ task: path.relative(root, dir).replaceAll("\\", "/"),
40
+ taskId: kernel.identity.taskId,
41
+ phase: kernel.phase,
42
+ revision: kernel.revision,
43
+ kernelKind: read.kind,
44
+ contractFingerprint: null,
45
+ events: [],
46
+ runs: [],
47
+ reviews: [],
48
+ archived,
49
+ };
50
+ }
10
51
  function taskContext(root, reference) {
11
52
  const dir = resolveTaskDir(root, reference);
12
53
  if (!fs.statSync(dir, { throwIfNoEntry: false })?.isDirectory())
13
54
  throw new Error(`Task not found: ${reference}`);
14
- const { kernel } = readKernel({ taskDir: dir, cwd: root });
15
- if (!kernel.projection)
16
- throw new Error("Task has no canonical Kernel projection");
17
- return { dir, task: path.relative(root, dir).replaceAll("\\", "/"), phase: kernel.phase, revision: kernel.revision };
55
+ return taskContextFromDirectory(root, dir, false);
18
56
  }
19
57
  function archivedTaskContext(root, reference) {
20
58
  if (!/^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/.test(reference))
@@ -22,28 +60,191 @@ function archivedTaskContext(root, reference) {
22
60
  const archive = path.join(root, ".pactile", "tasks", "archive");
23
61
  if (!fs.statSync(archive, { throwIfNoEntry: false })?.isDirectory())
24
62
  throw new Error(`Task not found: ${reference}`);
25
- const matches = fs.readdirSync(archive, { withFileTypes: true })
63
+ const matches = fs
64
+ .readdirSync(archive, { withFileTypes: true })
26
65
  .filter((entry) => entry.isDirectory() && /^\d{4}-\d{2}$/.test(entry.name))
27
- .flatMap((entry) => fs.readdirSync(path.join(archive, entry.name), { withFileTypes: true })
28
- .filter((task) => task.isDirectory() && (task.name === reference || task.name.endsWith(`-${reference}`)))
66
+ .flatMap((entry) => fs
67
+ .readdirSync(path.join(archive, entry.name), { withFileTypes: true })
68
+ .filter((task) => task.isDirectory() &&
69
+ (task.name === reference || task.name.endsWith(`-${reference}`)))
29
70
  .map((task) => path.join(archive, entry.name, task.name)));
30
71
  if (matches.length !== 1)
31
- throw new Error(matches.length ? `Archived task reference is ambiguous: ${reference}` : `Task not found: ${reference}`);
72
+ throw new Error(matches.length
73
+ ? `Archived task reference is ambiguous: ${reference}`
74
+ : `Task not found: ${reference}`);
32
75
  const dir = matches[0];
33
76
  const realArchive = fs.realpathSync(archive);
34
77
  const relative = path.relative(realArchive, fs.realpathSync(dir));
35
78
  if (relative.startsWith("..") || path.isAbsolute(relative))
36
79
  throw new Error("Archived task resolves outside the task archive");
37
- const { kernel } = readKernel({ taskDir: dir, cwd: root });
38
- return { dir, task: path.relative(root, dir).replaceAll("\\", "/"), phase: kernel.phase, revision: kernel.revision };
80
+ return taskContextFromDirectory(root, dir, true);
81
+ }
82
+ function taskContextIncludingArchive(root, reference) {
83
+ try {
84
+ return taskContext(root, reference);
85
+ }
86
+ catch (error) {
87
+ if (!(error instanceof Error) ||
88
+ !error.message.startsWith("Task not found:")) {
89
+ throw error;
90
+ }
91
+ return archivedTaskContext(root, reference);
92
+ }
93
+ }
94
+ function selectRun(context, role, requestedRunId, requireRunning = false) {
95
+ if (context.kernelKind !== "task-kernel-v2") {
96
+ if (requestedRunId)
97
+ throw new Error("--run-id requires a Task Kernel v2 task");
98
+ return {
99
+ runId: null,
100
+ candidateSnapshotId: null,
101
+ candidateFingerprint: null,
102
+ run: null,
103
+ };
104
+ }
105
+ const run = requestedRunId
106
+ ? context.runs.find((candidate) => candidate.id === requestedRunId)
107
+ : role === "review"
108
+ ? [...context.runs]
109
+ .reverse()
110
+ .find((candidate) => candidate.candidateSnapshot)
111
+ : [...context.runs]
112
+ .reverse()
113
+ .find((candidate) => candidate.state === "running" || candidate.state === "waiting");
114
+ if (requestedRunId && !run)
115
+ throw new Error(`Run not found on Task ${context.taskId}: ${requestedRunId}`);
116
+ if (role === "execute" &&
117
+ requireRunning &&
118
+ run?.state !== "running" &&
119
+ run?.state !== "waiting") {
120
+ throw new Error("Codex Execute dispatch requires a running or waiting Task Kernel v2 Run");
121
+ }
122
+ if (role === "review" &&
123
+ context.phase === "verify" &&
124
+ !run?.candidateSnapshot) {
125
+ throw new Error("Codex Review requires the latest Run candidate snapshot");
126
+ }
127
+ return {
128
+ runId: run?.id ?? null,
129
+ candidateSnapshotId: run?.candidateSnapshot?.id ?? null,
130
+ candidateFingerprint: run?.candidateSnapshot?.fingerprint ?? null,
131
+ run: run ?? null,
132
+ };
133
+ }
134
+ function bridgeDir(dir) {
135
+ return path.join(dir, "codex-bridge");
136
+ }
137
+ function requestFile(dir, id) {
138
+ return path.join(bridgeDir(dir), "requests", `${id}.json`);
139
+ }
140
+ function receiptFile(dir, id) {
141
+ return path.join(bridgeDir(dir), "receipts", `${id}.json`);
142
+ }
143
+ function queuedFile(dir, id) {
144
+ return path.join(bridgeDir(dir), "queued", `${id}.json`);
39
145
  }
40
- function bridgeDir(dir) { return path.join(dir, "codex-bridge"); }
41
- function requestFile(dir, id) { return path.join(bridgeDir(dir), "requests", `${id}.json`); }
42
- function receiptFile(dir, id) { return path.join(bridgeDir(dir), "receipts", `${id}.json`); }
43
- function queuedFile(dir, id) { return path.join(bridgeDir(dir), "queued", `${id}.json`); }
44
146
  function writeNew(file, value) {
45
147
  fs.mkdirSync(path.dirname(file), { recursive: true });
46
- fs.writeFileSync(file, `${JSON.stringify(value, null, 2)}\n`, { encoding: "utf8", flag: "wx", mode: 0o600 });
148
+ fs.writeFileSync(file, `${JSON.stringify(value, null, 2)}\n`, {
149
+ encoding: "utf8",
150
+ flag: "wx",
151
+ mode: 0o600,
152
+ });
153
+ }
154
+ function codexRequestFingerprint(request) {
155
+ const { request_fingerprint: _stored, ...payload } = request;
156
+ return fingerprintTaskValue(payload);
157
+ }
158
+ function verifyFreshCoordinationMessage(root, entry, destinationContext, requireNative) {
159
+ const message = entry.message;
160
+ const requestId = message.request_id;
161
+ if (!requestId ||
162
+ !uuidPattern.test(requestId) ||
163
+ !new Set(["sent", "delivered", "acknowledged"]).has(entry.status)) {
164
+ throw new Error("Coordination message has no successful bound request");
165
+ }
166
+ const sourceContext = taskContext(root, message.from_task_id);
167
+ const request = readJson(requestFile(sourceContext.dir, requestId));
168
+ const receipt = readJson(receiptFile(sourceContext.dir, requestId));
169
+ const sendReceipt = entry.receipts.find((candidate) => candidate.receipt_id === requestId);
170
+ const evidenceLevel = receipt.evidence_level;
171
+ const requestFingerprint = codexRequestFingerprint(request);
172
+ const sourceBound = !sourceContext.archived &&
173
+ request.request_id === requestId &&
174
+ request.request_fingerprint === requestFingerprint &&
175
+ request.task === sourceContext.task &&
176
+ request.task_id === sourceContext.taskId &&
177
+ request.task_kernel_kind === sourceContext.kernelKind &&
178
+ request.kernel_revision === sourceContext.revision &&
179
+ (request.contract_fingerprint ?? null) ===
180
+ sourceContext.contractFingerprint &&
181
+ (request.run_id ?? null) === message.from_run_id &&
182
+ isRunBoundToContext(sourceContext, request.run_id, request.candidate_snapshot_id, request.candidate_fingerprint);
183
+ const destinationBound = !destinationContext.archived &&
184
+ request.to_task === path.basename(destinationContext.dir) &&
185
+ request.to_task_id === destinationContext.taskId &&
186
+ request.to_task_kernel_kind === destinationContext.kernelKind &&
187
+ request.to_kernel_revision === destinationContext.revision &&
188
+ (request.to_contract_fingerprint ?? null) ===
189
+ destinationContext.contractFingerprint &&
190
+ (request.to_run_id ?? null) === message.to_run_id &&
191
+ isRunBoundToContext(destinationContext, request.to_run_id, request.to_candidate_snapshot_id, request.to_candidate_fingerprint);
192
+ if (!sourceBound ||
193
+ !destinationBound ||
194
+ message.message_id !== request.coordination_message_id ||
195
+ message.message_id !== requestId ||
196
+ message.host_ref !== request.thread_id ||
197
+ request.tool !== "send_message_to_thread" ||
198
+ !request.thread_id ||
199
+ !request.host_id ||
200
+ receipt.schema_version !== 1 ||
201
+ receipt.request_id !== requestId ||
202
+ receipt.request_fingerprint !== requestFingerprint ||
203
+ receipt.task_id !== sourceContext.taskId ||
204
+ (receipt.run_id ?? null) !== (request.run_id ?? null) ||
205
+ (receipt.candidate_snapshot_id ?? null) !==
206
+ (request.candidate_snapshot_id ?? null) ||
207
+ (receipt.candidate_fingerprint ?? null) !==
208
+ (request.candidate_fingerprint ?? null) ||
209
+ (receipt.to_task_id ?? null) !== destinationContext.taskId ||
210
+ (receipt.to_run_id ?? null) !== (request.to_run_id ?? null) ||
211
+ (receipt.to_candidate_snapshot_id ?? null) !==
212
+ (request.to_candidate_snapshot_id ?? null) ||
213
+ (receipt.to_candidate_fingerprint ?? null) !==
214
+ (request.to_candidate_fingerprint ?? null) ||
215
+ receipt.destination_kernel_revision_at_receipt !==
216
+ request.to_kernel_revision ||
217
+ receipt.kernel_revision_at_receipt !== request.kernel_revision ||
218
+ receipt.thread_id !== request.thread_id ||
219
+ receipt.host_id !== request.host_id ||
220
+ receipt.tool !== request.tool ||
221
+ receipt.outcome !== "ok" ||
222
+ receipt.contract_stale !== false ||
223
+ !sendReceipt ||
224
+ !new Set(["sent", "delivered", "acknowledged"]).has(sendReceipt.status) ||
225
+ sendReceipt.evidence_level !== evidenceLevel ||
226
+ (evidenceLevel !== "simulated" && evidenceLevel !== "desktop-native") ||
227
+ (requireNative && evidenceLevel !== "desktop-native")) {
228
+ throw new Error("Coordination message request or receipt is stale, misbound, or not authoritative");
229
+ }
230
+ return { evidenceLevel, sourceContext };
231
+ }
232
+ function coordinationKernelBarrier(context) {
233
+ if (context.kernelKind !== "task-kernel-v2") {
234
+ return { runId: null, kernelRevision: null, kernelEventId: null };
235
+ }
236
+ const lastEvent = context.events.at(-1);
237
+ if (lastEvent?.revision !== context.revision) {
238
+ throw new Error("Cannot bind coordination unblock to the current Kernel event");
239
+ }
240
+ const activeRun = [...context.runs]
241
+ .reverse()
242
+ .find((run) => run.state === "running" || run.state === "waiting");
243
+ return {
244
+ runId: activeRun?.id ?? null,
245
+ kernelRevision: context.revision,
246
+ kernelEventId: lastEvent.id,
247
+ };
47
248
  }
48
249
  function readJson(file) {
49
250
  const value = JSON.parse(fs.readFileSync(file, "utf8"));
@@ -55,9 +256,12 @@ function requests(dir) {
55
256
  const folder = path.join(bridgeDir(dir), "requests");
56
257
  if (!fs.existsSync(folder))
57
258
  return [];
58
- return fs.readdirSync(folder).filter((file) => uuidPattern.test(file.replace(/\.json$/, "")) && file.endsWith(".json"))
259
+ return fs
260
+ .readdirSync(folder)
261
+ .filter((file) => uuidPattern.test(file.replace(/\.json$/, "")) && file.endsWith(".json"))
59
262
  .map((file) => readJson(path.join(folder, file)))
60
- .sort((left, right) => left.created_at.localeCompare(right.created_at) || left.request_id.localeCompare(right.request_id));
263
+ .sort((left, right) => left.created_at.localeCompare(right.created_at) ||
264
+ left.request_id.localeCompare(right.request_id));
61
265
  }
62
266
  function boundThreads(dir) {
63
267
  const bound = new Map();
@@ -68,12 +272,72 @@ function boundThreads(dir) {
68
272
  if (!fs.existsSync(file))
69
273
  continue;
70
274
  const receipt = readJson(file);
71
- if (receipt.outcome === "ok" && typeof receipt.thread_id === "string" && typeof receipt.host_id === "string") {
72
- bound.set(receipt.thread_id, { threadId: receipt.thread_id, hostId: receipt.host_id, role: request.role });
275
+ if (receipt.outcome === "ok" &&
276
+ receipt.contract_stale !== true &&
277
+ typeof receipt.thread_id === "string" &&
278
+ typeof receipt.host_id === "string") {
279
+ bound.set(receipt.thread_id, {
280
+ threadId: receipt.thread_id,
281
+ hostId: receipt.host_id,
282
+ role: request.role,
283
+ runId: request.run_id ?? null,
284
+ dispatchLeaseId: request.dispatch_lease_id ?? null,
285
+ });
73
286
  }
74
287
  }
75
288
  return bound;
76
289
  }
290
+ /**
291
+ * A Plan thread can outlive the Kernel revision that created it. Reuse that
292
+ * thread only for a coordination message, and only when its original request
293
+ * still matches this V2 Task's identity and contract. The outgoing message is
294
+ * separately bound to the current Kernel revision and active Run.
295
+ */
296
+ function coordinationBoundThread(context, threadId) {
297
+ if (context.archived || context.kernelKind !== "task-kernel-v2")
298
+ return undefined;
299
+ for (const request of requests(context.dir).reverse()) {
300
+ if (request.tool !== "create_thread" ||
301
+ request.role !== "plan" ||
302
+ request.task !== context.task ||
303
+ request.task_id !== context.taskId ||
304
+ request.task_kernel_kind !== "task-kernel-v2" ||
305
+ (request.contract_fingerprint ?? null) !== context.contractFingerprint ||
306
+ !Number.isInteger(request.kernel_revision) ||
307
+ request.kernel_revision > context.revision) {
308
+ continue;
309
+ }
310
+ const receiptPath = receiptFile(context.dir, request.request_id);
311
+ if (!fs.existsSync(receiptPath))
312
+ continue;
313
+ const receipt = readJson(receiptPath);
314
+ const requestFingerprint = codexRequestFingerprint(request);
315
+ if (request.request_fingerprint !== requestFingerprint ||
316
+ receipt.schema_version !== 1 ||
317
+ receipt.request_id !== request.request_id ||
318
+ receipt.request_fingerprint !== requestFingerprint ||
319
+ receipt.task_id !== context.taskId ||
320
+ receipt.run_id !== (request.run_id ?? null) ||
321
+ receipt.tool !== "create_thread" ||
322
+ receipt.outcome !== "ok" ||
323
+ (request.kernel_revision === context.revision &&
324
+ receipt.contract_stale === true) ||
325
+ receipt.kernel_revision_at_receipt !== request.kernel_revision ||
326
+ receipt.thread_id !== threadId ||
327
+ !receipt.host_id ||
328
+ !idPattern.test(receipt.host_id)) {
329
+ continue;
330
+ }
331
+ return {
332
+ threadId,
333
+ hostId: receipt.host_id,
334
+ role: "plan",
335
+ runId: request.run_id ?? null,
336
+ dispatchLeaseId: request.dispatch_lease_id ?? null,
337
+ };
338
+ }
339
+ return undefined;
340
+ }
77
341
  function latestWaitCursor(dir, threadId) {
78
342
  const waits = requests(dir).filter((request) => request.tool === "wait_threads" && request.thread_id === threadId);
79
343
  for (const request of waits.reverse()) {
@@ -81,7 +345,9 @@ function latestWaitCursor(dir, threadId) {
81
345
  if (!fs.existsSync(file))
82
346
  continue;
83
347
  const receipt = readJson(file);
84
- if (receipt.outcome === "ok" && typeof receipt.cursor === "string")
348
+ if (receipt.outcome === "ok" &&
349
+ receipt.contract_stale !== true &&
350
+ typeof receipt.cursor === "string")
85
351
  return receipt.cursor;
86
352
  }
87
353
  return null;
@@ -107,28 +373,348 @@ function roleBoundary(role) {
107
373
  return "Review is read-only: inspect the change set and evidence, report findings, and do not alter code or declare acceptance.";
108
374
  return "Implement only the approved Execute contract and write set. Do not commit, integrate, archive, change Kernel approval, or declare acceptance.";
109
375
  }
376
+ function recordRunBinding(store, context, selected) {
377
+ if (context.kernelKind !== "task-kernel-v2" || !selected.runId)
378
+ return;
379
+ store.startRun({
380
+ taskId: context.taskId,
381
+ runId: selected.runId,
382
+ role: null,
383
+ workspaceId: null,
384
+ providerRunId: null,
385
+ actor: { platform: "pactile", id: "codex-bridge" },
386
+ evidenceLevel: "local",
387
+ });
388
+ }
389
+ function runContextLine(context, selected, includeAuthorization = true) {
390
+ const parts = [
391
+ `Task ID: ${context.taskId}`,
392
+ `Task Kernel: ${context.kernelKind}`,
393
+ `Kernel revision: ${context.revision}`,
394
+ ];
395
+ if (selected.runId)
396
+ parts.push(`Run ID: ${selected.runId}`);
397
+ if (selected.candidateSnapshotId && selected.candidateFingerprint) {
398
+ parts.push(`Candidate snapshot: ${selected.candidateSnapshotId} (${selected.candidateFingerprint})`);
399
+ }
400
+ if (includeAuthorization &&
401
+ selected.run &&
402
+ context.kernelKind === "task-kernel-v2") {
403
+ parts.push(`Run authorization: ${selected.run.authorization.scope}`);
404
+ if (selected.run.writeSetSnapshot.length) {
405
+ parts.push(`Run write set: ${selected.run.writeSetSnapshot.join(", ")}`);
406
+ }
407
+ }
408
+ return parts.join("\n");
409
+ }
410
+ function isRunBoundToContext(context, runId, candidateSnapshotId, candidateFingerprint) {
411
+ if (!runId) {
412
+ return candidateSnapshotId == null && candidateFingerprint == null;
413
+ }
414
+ if (context.kernelKind !== "task-kernel-v2")
415
+ return false;
416
+ const run = context.runs.find((candidate) => candidate.id === runId);
417
+ return Boolean(run &&
418
+ (run.candidateSnapshot?.id ?? null) === (candidateSnapshotId ?? null) &&
419
+ (run.candidateSnapshot?.fingerprint ?? null) ===
420
+ (candidateFingerprint ?? null));
421
+ }
422
+ function coordinationReceiptEvidence(value) {
423
+ if (value === undefined || value === "simulated")
424
+ return "simulated";
425
+ if (value === "desktop-native")
426
+ return value;
427
+ throw new Error("--evidence-level must be simulated or desktop-native");
428
+ }
429
+ function normalizeReplyEvidence(value, escalationId) {
430
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
431
+ throw new Error("Native read reply requires structured reply_evidence");
432
+ }
433
+ const evidence = value;
434
+ const body = evidence.body;
435
+ const responseTurnId = evidence.response_turn_id;
436
+ const bodySha256 = evidence.body_sha256;
437
+ if (evidence.reply_to_escalation_id !== escalationId ||
438
+ typeof responseTurnId !== "string" ||
439
+ !transportIdentifierPattern.test(responseTurnId) ||
440
+ typeof body !== "string" ||
441
+ body.trim() !== body ||
442
+ Buffer.byteLength(body, "utf8") < 1 ||
443
+ Buffer.byteLength(body, "utf8") > 8_192 ||
444
+ escalationSecretPattern.test(body) ||
445
+ typeof bodySha256 !== "string" ||
446
+ !/^[a-f0-9]{64}$/.test(bodySha256) ||
447
+ createHash("sha256").update(body, "utf8").digest("hex") !== bodySha256) {
448
+ throw new Error("Native read reply evidence must match the escalation and bounded body hash");
449
+ }
450
+ return {
451
+ reply_to_escalation_id: escalationId,
452
+ response_turn_id: responseTurnId,
453
+ body,
454
+ body_sha256: bodySha256,
455
+ };
456
+ }
110
457
  export function prepareCodexRequest(input) {
111
458
  const context = taskContext(input.root, input.task);
112
- const bound = input.threadId ? boundThreads(context.dir).get(input.threadId) : undefined;
459
+ if (input.escalationId !== undefined &&
460
+ !escalationIdPattern.test(input.escalationId)) {
461
+ throw new Error("--escalation-id must be pi-escalation:<Pi Run UUID>");
462
+ }
463
+ if (input.replyToEscalationId !== undefined &&
464
+ !escalationIdPattern.test(input.replyToEscalationId)) {
465
+ throw new Error("--reply-to-escalation-id must be pi-escalation:<Pi Run UUID>");
466
+ }
467
+ if (input.escalationId && input.replyToEscalationId) {
468
+ throw new Error("A Codex request cannot send and reply to an escalation");
469
+ }
470
+ if (input.sourceTask && !input.replyToEscalationId) {
471
+ throw new Error("--source-task is only valid with --reply-to-escalation-id");
472
+ }
473
+ if (input.replyToEscalationId && !input.sourceTask) {
474
+ throw new Error("--reply-to-escalation-id requires --source-task");
475
+ }
476
+ if (input.replyToEscalationId && !input.sendRequestId) {
477
+ throw new Error("--reply-to-escalation-id requires --send-request-id");
478
+ }
479
+ if (input.sendRequestId && !input.replyToEscalationId) {
480
+ throw new Error("--send-request-id is only valid with --reply-to-escalation-id");
481
+ }
482
+ if (input.escalationId && input.promptFile) {
483
+ throw new Error("P40 Codex escalation uses its bound Review prompt; additional prompt files are not accepted");
484
+ }
485
+ if (input.escalationId && input.tool !== "send_message_to_thread") {
486
+ throw new Error("--escalation-id is only valid for a Codex message");
487
+ }
488
+ if (input.replyToEscalationId && input.tool !== "read_thread") {
489
+ throw new Error("--reply-to-escalation-id is only valid for a Codex read");
490
+ }
491
+ if (input.toTask && input.tool === "create_thread") {
492
+ throw new Error("--to-task is only valid for cross-task message");
493
+ }
494
+ if (input.toRunId && !input.toTask) {
495
+ throw new Error("--to-run-id requires --to-task");
496
+ }
497
+ if (input.toTask && !input.threadId) {
498
+ throw new Error("cross-task requests require --thread-id");
499
+ }
500
+ const targetContext = input.toTask
501
+ ? taskContext(input.root, input.toTask)
502
+ : context;
503
+ const crossTask = targetContext.taskId !== context.taskId;
504
+ if (input.toTask && !crossTask) {
505
+ throw new Error("--to-task must identify a different Pactile Task");
506
+ }
507
+ if (crossTask && input.tool !== "send_message_to_thread") {
508
+ throw new Error("--to-task is currently supported only for cross-task messages");
509
+ }
510
+ if (input.resumeExecute &&
511
+ (!crossTask || input.tool !== "send_message_to_thread")) {
512
+ throw new Error("--resume-execute is only valid for a cross-task message");
513
+ }
514
+ if (input.resumeExecute && targetContext.kernelKind !== "task-kernel-v2") {
515
+ throw new Error("--resume-execute requires a Task Kernel v2 destination Run");
516
+ }
517
+ if (input.resumeExecute && targetContext.kernelKind === "task-kernel-v2") {
518
+ throw new Error("Task Kernel v2 --resume-execute dispatch is disabled until P37 admission, lease and Resume/block validation are connected");
519
+ }
520
+ const coordinationToExecutingV2Task = crossTask &&
521
+ input.tool === "send_message_to_thread" &&
522
+ targetContext.kernelKind === "task-kernel-v2" &&
523
+ targetContext.phase === "execute";
524
+ const bound = input.threadId
525
+ ? coordinationToExecutingV2Task
526
+ ? coordinationBoundThread(targetContext, input.threadId)
527
+ : boundThreads(targetContext.dir).get(input.threadId)
528
+ : undefined;
113
529
  const role = input.tool === "create_thread" ? input.role : bound?.role;
114
530
  if (!role)
115
- throw new Error(input.tool === "create_thread" ? "--role plan|review|execute is required" : "Thread is not bound to this Pactile task");
531
+ throw new Error(input.tool === "create_thread"
532
+ ? "--role plan|review|execute is required"
533
+ : "Thread is not bound to this Pactile task");
116
534
  if (role !== "plan" && role !== "review" && role !== "execute")
117
535
  throw new Error("Codex role must be plan, review or execute");
118
- if (input.tool === "create_thread" || input.tool === "send_message_to_thread")
119
- checkPhase(role, context.phase);
120
- if (role === "execute" && (input.tool === "create_thread" || input.tool === "send_message_to_thread"))
121
- approvedTask(input.root, input.task, "implement");
122
- if ((input.tool === "wait_threads" || input.tool === "read_thread") && input.promptFile) {
536
+ if (input.tool === "send_message_to_thread" &&
537
+ input.role &&
538
+ input.role !== bound?.role) {
539
+ throw new Error("--role must match the bound Codex thread role");
540
+ }
541
+ if (!coordinationToExecutingV2Task &&
542
+ (input.tool === "create_thread" || input.tool === "send_message_to_thread")) {
543
+ checkPhase(role, crossTask ? targetContext.phase : context.phase);
544
+ }
545
+ if ((input.tool === "wait_threads" || input.tool === "read_thread") &&
546
+ input.promptFile) {
123
547
  throw new Error("wait/read do not accept --prompt-file");
124
548
  }
125
- const prompt = input.promptFile ? textFile(input.promptFile) : null;
126
- const executeScope = role === "execute" && (input.tool === "create_thread" || input.tool === "send_message_to_thread")
127
- ? parallelChild(input.root, context.dir) : null;
128
- const scopeLine = executeScope ? `Parent-approved write set: ${executeScope.touches.join(", ")}. Integration owner: Parent.` : "";
129
- const record = JSON.parse(fs.readFileSync(path.join(context.dir, "task.json"), "utf8"));
130
- const baseBranch = record && typeof record === "object" && "base_branch" in record ? record.base_branch : null;
131
- if (role === "execute" && baseBranch && (typeof baseBranch !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._/-]{0,127}$/.test(baseBranch) || baseBranch.includes(".."))) {
549
+ let prompt = input.promptFile ? textFile(input.promptFile) : null;
550
+ if (crossTask && prompt && Buffer.byteLength(prompt, "utf8") > 4_096) {
551
+ throw new Error("cross-task message body must be at most 4096 bytes for the coordination journal");
552
+ }
553
+ const executionDispatch = role === "execute" &&
554
+ (input.tool === "create_thread" ||
555
+ (input.tool === "send_message_to_thread" &&
556
+ (!crossTask || input.resumeExecute === true)));
557
+ const executionContext = crossTask ? targetContext : context;
558
+ if (executionDispatch &&
559
+ role === "execute" &&
560
+ executionContext.kernelKind === "task-kernel-v2") {
561
+ throw new Error("Task Kernel v2 Execute dispatch is disabled until P37 admission, lease and Resume/block validation are connected");
562
+ }
563
+ const selectedRun = selectRun(context, role, input.runId, executionDispatch && !crossTask);
564
+ const targetRun = crossTask
565
+ ? selectRun(targetContext, role, input.toRunId, executionDispatch)
566
+ : selectedRun;
567
+ if (coordinationToExecutingV2Task &&
568
+ (!targetRun.runId ||
569
+ (targetRun.run?.state !== "running" &&
570
+ targetRun.run?.state !== "waiting") ||
571
+ (bound?.runId && bound.runId !== targetRun.runId))) {
572
+ throw new Error("Coordination to an executing Task requires its current active Run and a Plan thread bound to that Task");
573
+ }
574
+ if (input.escalationId) {
575
+ const prepared = readPiReviewEscalationV1(input.root, context.task, input.escalationId);
576
+ const current = assertCurrentPiReviewEscalationV1(input.root, context.task, prepared);
577
+ const sourceRun = context.runs.at(-1);
578
+ if (!crossTask ||
579
+ context.kernelKind !== "task-kernel-v2" ||
580
+ context.phase !== "verify" ||
581
+ role !== "review" ||
582
+ bound?.role !== "review" ||
583
+ targetContext.kernelKind !== "task-kernel-v2" ||
584
+ targetRun.run?.state !== "completed" ||
585
+ !targetRun.run.candidateSnapshot ||
586
+ !input.runId ||
587
+ sourceRun?.id !== input.runId ||
588
+ sourceRun.state !== "completed" ||
589
+ !sourceRun.candidateSnapshot ||
590
+ selectedRun.runId !== sourceRun.id ||
591
+ selectedRun.candidateSnapshotId !== sourceRun.candidateSnapshot.id ||
592
+ selectedRun.candidateFingerprint !==
593
+ sourceRun.candidateSnapshot.fingerprint ||
594
+ current.run.id !== sourceRun.id ||
595
+ current.kernel.reviews.at(-1)?.id !== prepared.request.reviewId ||
596
+ current.kernel.reviews.at(-1)?.decision === "pass") {
597
+ throw new Error("Codex escalation send requires its current prepared non-passing Pi Review, source candidate and bound Review thread");
598
+ }
599
+ prompt = buildCodexEscalationPromptV1({
600
+ prepared,
601
+ hostId: bound.hostId,
602
+ threadId: bound.threadId,
603
+ });
604
+ }
605
+ let escalationBinding = null;
606
+ let escalationSendBinding = null;
607
+ if (input.escalationId) {
608
+ const prepared = readPiReviewEscalationV1(input.root, context.task, input.escalationId);
609
+ escalationBinding = {
610
+ sourceTask: context.task,
611
+ sourceTaskId: prepared.request.taskId,
612
+ preparedRequestRef: prepared.ref,
613
+ preparedFingerprint: prepared.request.preparedFingerprint,
614
+ };
615
+ }
616
+ if (input.replyToEscalationId) {
617
+ if (role !== "review" || bound?.role !== "review") {
618
+ throw new Error("Pi escalation replies require a bound Codex Review thread");
619
+ }
620
+ const prepared = readPiReviewEscalationV1(input.root, input.sourceTask, input.replyToEscalationId);
621
+ assertCurrentPiReviewEscalationV1(input.root, input.sourceTask, prepared);
622
+ const send = readCodexEscalationSendV1({
623
+ root: input.root,
624
+ sourceTask: input.sourceTask,
625
+ escalationId: input.replyToEscalationId,
626
+ sendRequestId: input.sendRequestId,
627
+ });
628
+ if (send.request["to_task"] !== path.basename(context.dir) ||
629
+ send.request["to_task_id"] !== context.taskId ||
630
+ send.request["thread_id"] !== bound.threadId ||
631
+ send.request["host_id"] !== bound.hostId ||
632
+ send.request["to_run_id"] !== selectedRun.runId ||
633
+ send.request["to_candidate_snapshot_id"] !== selectedRun.candidateSnapshotId ||
634
+ send.request["to_candidate_fingerprint"] !== selectedRun.candidateFingerprint) {
635
+ throw new Error("Escalation reply read must follow the selected send to this exact Review Task and thread");
636
+ }
637
+ escalationSendBinding = {
638
+ requestId: input.sendRequestId,
639
+ requestFingerprint: send.requestFingerprint,
640
+ receiptSha256: send.receiptSha256,
641
+ receiptRecordedAt: send.receiptRecordedAt,
642
+ };
643
+ const sourceDir = prepared.taskDir;
644
+ escalationBinding = {
645
+ sourceTask: path.relative(input.root, sourceDir).replaceAll("\\", "/"),
646
+ sourceTaskId: prepared.request.taskId,
647
+ preparedRequestRef: prepared.ref,
648
+ preparedFingerprint: prepared.request.preparedFingerprint,
649
+ };
650
+ if (context.kernelKind !== "task-kernel-v2" ||
651
+ selectedRun.run?.state !== "completed" ||
652
+ !selectedRun.run.candidateSnapshot) {
653
+ throw new Error("Pi escalation reply read requires the current completed Review Task candidate");
654
+ }
655
+ }
656
+ if (executionDispatch &&
657
+ role === "execute" &&
658
+ input.tool !== "wait_threads" &&
659
+ (crossTask ? targetContext.kernelKind : context.kernelKind) ===
660
+ "task-kernel-v2" &&
661
+ !(crossTask ? input.toRunId : input.runId)) {
662
+ throw new Error(crossTask
663
+ ? "Task Kernel v2 cross-task Execute dispatch requires an explicit --to-run-id"
664
+ : "Task Kernel v2 Execute dispatch requires an explicit --run-id");
665
+ }
666
+ if (executionDispatch &&
667
+ role === "execute" &&
668
+ (input.tool === "create_thread" || input.tool === "send_message_to_thread")) {
669
+ const dispatchContext = crossTask ? targetContext : context;
670
+ const dispatchRun = crossTask ? targetRun.run : selectedRun.run;
671
+ if (dispatchContext.kernelKind === "legacy-task-kernel-v1") {
672
+ const dir = approvedExecuteTask(input.root, dispatchContext.task);
673
+ if (fs.existsSync(path.join(dir, "implement.md"))) {
674
+ const parsed = readStrategyContract(dir);
675
+ if (parsed.errors.length)
676
+ throw new Error(`Invalid execution contract: ${parsed.errors.join("; ")}`);
677
+ }
678
+ }
679
+ else if (!dispatchRun?.authorization.scope.trim() ||
680
+ !dispatchRun.writeSetSnapshot.length) {
681
+ throw new Error("Codex Execute dispatch requires a Task Kernel v2 Run with a scope and non-empty write set");
682
+ }
683
+ }
684
+ const executeScope = executionDispatch &&
685
+ role === "execute" &&
686
+ context.kernelKind === "legacy-task-kernel-v1" &&
687
+ (input.tool === "create_thread" || input.tool === "send_message_to_thread")
688
+ ? parallelChild(input.root, context.dir)
689
+ : null;
690
+ const runScope = executionDispatch &&
691
+ role === "execute" &&
692
+ (crossTask ? targetContext.kernelKind : context.kernelKind) ===
693
+ "task-kernel-v2"
694
+ ? crossTask
695
+ ? targetRun.run
696
+ : selectedRun.run
697
+ : null;
698
+ const scopeLine = executeScope
699
+ ? `Parent-approved write set: ${executeScope.touches.join(", ")}. Integration owner: Parent.`
700
+ : runScope
701
+ ? `Task Run authorized scope: ${runScope.authorization.scope}. Approved write set: ${runScope.writeSetSnapshot.join(", ")}.`
702
+ : "";
703
+ let baseBranch = null;
704
+ if (input.tool === "create_thread" &&
705
+ context.kernelKind === "legacy-task-kernel-v1") {
706
+ const record = JSON.parse(fs.readFileSync(path.join(context.dir, "task.json"), "utf8"));
707
+ baseBranch =
708
+ record && typeof record === "object" && "base_branch" in record
709
+ ? record.base_branch
710
+ : null;
711
+ }
712
+ if (executionDispatch &&
713
+ role === "execute" &&
714
+ baseBranch &&
715
+ (typeof baseBranch !== "string" ||
716
+ !/^[A-Za-z0-9][A-Za-z0-9._/-]{0,127}$/.test(baseBranch) ||
717
+ baseBranch.includes(".."))) {
132
718
  throw new Error("Invalid approved base_branch for Codex Execute");
133
719
  }
134
720
  let args;
@@ -138,16 +724,34 @@ export function prepareCodexRequest(input) {
138
724
  const targetType = input.targetType ?? "project";
139
725
  if (targetType !== "project" && targetType !== "projectless")
140
726
  throw new Error("--target must be project or projectless");
141
- if (targetType === "project" && (!input.projectId || !idPattern.test(input.projectId) || !["local", "worktree"].includes(input.environment ?? ""))) {
727
+ if (targetType === "project" &&
728
+ (!input.projectId ||
729
+ !idPattern.test(input.projectId) ||
730
+ !["local", "worktree"].includes(input.environment ?? ""))) {
142
731
  throw new Error("project create requires --project-id and --environment local|worktree");
143
732
  }
144
- if (role === "execute" && (targetType !== "project" || input.environment !== "worktree"))
733
+ if (role === "execute" &&
734
+ (targetType !== "project" || input.environment !== "worktree"))
145
735
  throw new Error("Codex Execute requires a project worktree");
146
- const target = targetType === "projectless" ? { type: "projectless" } :
147
- { type: "project", projectId: input.projectId, environment: { type: input.environment,
148
- ...(role === "execute" && typeof baseBranch === "string" && baseBranch ? { startingState: { type: "branch", branchName: baseBranch } } : {}) } };
149
- args = { prompt: `Pactile task: ${context.task}\nCanonical Pactile task directory: ${context.dir}\nCodex role: ${role}\nKernel revision: ${context.revision}\nUse Pactile as the task lifecycle and evidence source. ${roleBoundary(role)} ${scopeLine} Do not change Kernel approval or claim acceptance from a message alone. Do not dispatch Codex subagents.\n\n${prompt}`,
150
- target, ...(input.title ? { title: input.title } : {}) };
736
+ const target = targetType === "projectless"
737
+ ? { type: "projectless" }
738
+ : {
739
+ type: "project",
740
+ projectId: input.projectId,
741
+ environment: {
742
+ type: input.environment,
743
+ ...(role === "execute" &&
744
+ typeof baseBranch === "string" &&
745
+ baseBranch
746
+ ? { startingState: { type: "branch", branchName: baseBranch } }
747
+ : {}),
748
+ },
749
+ };
750
+ args = {
751
+ prompt: `Pactile task: ${context.task}\nCanonical Pactile task directory: ${context.dir}\nCodex role: ${role}\n${runContextLine(context, selectedRun)}\nUse Pactile as the task lifecycle and evidence source. ${roleBoundary(role)} ${scopeLine} Do not change Kernel approval or claim acceptance from a message alone. Do not dispatch Codex subagents.\n\n${prompt}`,
752
+ target,
753
+ ...(input.title ? { title: input.title } : {}),
754
+ };
151
755
  }
152
756
  else {
153
757
  if (!bound)
@@ -155,29 +759,110 @@ export function prepareCodexRequest(input) {
155
759
  if (input.tool === "send_message_to_thread") {
156
760
  if (!prompt)
157
761
  throw new Error("message requires --prompt-file");
158
- args = { threadId: bound.threadId, hostId: bound.hostId,
159
- prompt: `Pactile task: ${context.task}\nCanonical Pactile task directory: ${context.dir}\nKernel revision: ${context.revision}\n${roleBoundary(role)} ${scopeLine}\n\n${prompt}` };
762
+ if (executionDispatch &&
763
+ role === "execute" &&
764
+ bound.runId &&
765
+ bound.runId !== (crossTask ? targetRun.runId : selectedRun.runId)) {
766
+ throw new Error("Codex Execute thread is bound to a different Task Run");
767
+ }
768
+ args = {
769
+ threadId: bound.threadId,
770
+ hostId: bound.hostId,
771
+ prompt: input.escalationId
772
+ ? prompt
773
+ : crossTask
774
+ ? input.resumeExecute
775
+ ? `Pactile cross-task Execute dispatch from ${context.taskId} to ${targetContext.taskId}.\n${runContextLine(context, selectedRun, false)}\nRecipient ${runContextLine(targetContext, targetRun)}\n${roleBoundary(role)} ${scopeLine}\nDo not change Kernel approval or claim acceptance from this message. Do not dispatch Codex subagents.\n\n${prompt}`
776
+ : `Pactile coordination-only message from ${context.taskId} to ${targetContext.taskId}. This message and any send receipt do not resume a Run, change Task state, grant Execute permission, or authorize file writes. Preserve any blocked or waiting state. Do not edit files, change approval, or dispatch Codex subagents; wait for an explicit Kernel Resume and P37 dispatch admission before executing.\n${runContextLine(context, selectedRun, false)}\nRecipient ${runContextLine(targetContext, targetRun, false)}\n\n${prompt}`
777
+ : `Pactile task: ${context.task}\nCanonical Pactile task directory: ${context.dir}\n${runContextLine(context, selectedRun)}\n${roleBoundary(role)} ${scopeLine}\n\n${prompt}`,
778
+ };
160
779
  }
161
780
  else if (input.tool === "wait_threads") {
162
781
  const timeoutMs = input.timeoutMs ?? 120_000;
163
782
  if (!Number.isInteger(timeoutMs) || timeoutMs < 0 || timeoutMs > 120_000)
164
783
  throw new Error("wait timeout must be 0 to 120000 ms");
165
784
  const afterCursor = latestWaitCursor(context.dir, bound.threadId);
166
- args = { targets: [{ threadId: bound.threadId, hostId: bound.hostId,
167
- ...(afterCursor ? { afterCursor } : {}) }], timeoutMs };
785
+ args = {
786
+ targets: [
787
+ {
788
+ threadId: bound.threadId,
789
+ hostId: bound.hostId,
790
+ ...(afterCursor ? { afterCursor } : {}),
791
+ },
792
+ ],
793
+ timeoutMs,
794
+ };
168
795
  }
169
796
  else {
170
797
  args = { threadId: bound.threadId, hostId: bound.hostId, turnLimit: 1 };
171
798
  }
172
799
  }
800
+ const requestId = randomUUID();
173
801
  const request = {
174
- schema_version: 1, request_id: randomUUID(), task: context.task, kernel_revision: context.revision,
175
- created_at: new Date().toISOString(), tool: input.tool, role,
176
- thread_id: bound?.threadId ?? null, host_id: bound?.hostId ?? null,
177
- arguments: args, prompt_sha256: prompt ? createHash("sha256").update(prompt).digest("hex") : null,
802
+ schema_version: 1,
803
+ request_id: requestId,
804
+ task: context.task,
805
+ task_id: context.taskId,
806
+ task_kernel_kind: context.kernelKind,
807
+ kernel_revision: context.revision,
808
+ contract_fingerprint: context.contractFingerprint,
809
+ run_id: selectedRun.runId,
810
+ candidate_snapshot_id: selectedRun.candidateSnapshotId,
811
+ candidate_fingerprint: selectedRun.candidateFingerprint,
812
+ to_task: crossTask ? path.basename(targetContext.dir) : null,
813
+ to_task_id: crossTask ? targetContext.taskId : null,
814
+ to_kernel_revision: crossTask ? targetContext.revision : null,
815
+ to_task_kernel_kind: crossTask ? targetContext.kernelKind : null,
816
+ to_contract_fingerprint: crossTask
817
+ ? targetContext.contractFingerprint
818
+ : null,
819
+ to_run_id: crossTask ? targetRun.runId : null,
820
+ to_candidate_snapshot_id: crossTask ? targetRun.candidateSnapshotId : null,
821
+ to_candidate_fingerprint: crossTask ? targetRun.candidateFingerprint : null,
822
+ coordination_message_id: crossTask && input.tool === "send_message_to_thread" ? requestId : null,
823
+ ...(input.escalationId ? { escalation_id: input.escalationId } : {}),
824
+ ...(input.replyToEscalationId
825
+ ? { reply_to_escalation_id: input.replyToEscalationId }
826
+ : {}),
827
+ ...(escalationBinding
828
+ ? {
829
+ escalation_source_task: escalationBinding.sourceTask,
830
+ escalation_source_task_id: escalationBinding.sourceTaskId,
831
+ escalation_prepared_request_ref: escalationBinding.preparedRequestRef,
832
+ escalation_prepared_fingerprint: escalationBinding.preparedFingerprint,
833
+ }
834
+ : {}),
835
+ ...(escalationSendBinding
836
+ ? {
837
+ escalation_send_request_id: escalationSendBinding.requestId,
838
+ escalation_send_request_fingerprint: escalationSendBinding.requestFingerprint,
839
+ escalation_send_receipt_sha256: escalationSendBinding.receiptSha256,
840
+ escalation_send_receipt_recorded_at: escalationSendBinding.receiptRecordedAt,
841
+ }
842
+ : {}),
843
+ created_at: new Date().toISOString(),
844
+ tool: input.tool,
845
+ role,
846
+ thread_id: bound?.threadId ?? null,
847
+ host_id: bound?.hostId ?? null,
848
+ arguments: args,
849
+ prompt_sha256: prompt
850
+ ? createHash("sha256").update(prompt).digest("hex")
851
+ : null,
178
852
  };
179
- const release = role === "execute" && input.tool === "create_thread"
180
- ? reserveParallelChild(input.root, context.dir, { id: request.request_id, durable: true }) : null;
853
+ request.request_fingerprint = codexRequestFingerprint(request);
854
+ const release = context.kernelKind === "legacy-task-kernel-v1" &&
855
+ role === "execute" &&
856
+ input.tool === "create_thread"
857
+ ? reserveParallelChild(input.root, context.dir, {
858
+ id: request.request_id,
859
+ durable: true,
860
+ })
861
+ : null;
862
+ const coordination = new CoordinationStore(input.root);
863
+ recordRunBinding(coordination, context, selectedRun);
864
+ if (crossTask)
865
+ recordRunBinding(coordination, targetContext, targetRun);
181
866
  try {
182
867
  writeNew(requestFile(context.dir, request.request_id), request);
183
868
  }
@@ -185,87 +870,576 @@ export function prepareCodexRequest(input) {
185
870
  release?.();
186
871
  throw error;
187
872
  }
873
+ if (request.coordination_message_id && prompt) {
874
+ coordination.createMessage({
875
+ messageId: request.request_id,
876
+ fromTaskId: context.taskId,
877
+ toTaskId: targetContext.taskId,
878
+ fromRunId: selectedRun.runId,
879
+ toRunId: targetRun.runId,
880
+ sender: { platform: "codex", id: "node-bridge" },
881
+ evidenceLevel: "local",
882
+ body: prompt,
883
+ requestId: request.request_id,
884
+ hostRef: bound?.threadId ?? null,
885
+ });
886
+ }
188
887
  return request;
189
888
  }
190
- export function recordCodexReceipt(root, task, requestId, resultFile) {
889
+ export function recordCodexReceipt(root, task, requestId, resultFile, evidenceLevelInput) {
191
890
  if (!uuidPattern.test(requestId))
192
891
  throw new Error("Invalid request id");
193
- const context = taskContext(root, task);
892
+ const initialContext = taskContextIncludingArchive(root, task);
893
+ if (initialContext.archived) {
894
+ throw new Error("Cannot record a new Codex receipt for an archived Task");
895
+ }
896
+ const initialRequest = readJson(requestFile(initialContext.dir, requestId));
897
+ const initialFingerprint = codexRequestFingerprint(initialRequest);
898
+ const record = () => recordCodexReceiptUnlocked(root, task, requestId, resultFile, evidenceLevelInput, initialRequest.tool, initialFingerprint);
899
+ if (initialRequest.tool !== "send_message_to_thread")
900
+ return record();
901
+ return withProjectSchedulerMutex(root, () => {
902
+ const lockedContext = taskContextIncludingArchive(root, task);
903
+ const lockedRequest = readJson(requestFile(lockedContext.dir, requestId));
904
+ if (codexRequestFingerprint(lockedRequest) !== initialFingerprint) {
905
+ throw new Error("Codex send request changed while acquiring the receipt lock");
906
+ }
907
+ return record();
908
+ });
909
+ }
910
+ function recordCodexReceiptUnlocked(root, task, requestId, resultFile, evidenceLevelInput, expectedTool, expectedFingerprint) {
911
+ if (!uuidPattern.test(requestId))
912
+ throw new Error("Invalid request id");
913
+ const context = taskContextIncludingArchive(root, task);
914
+ if (context.archived) {
915
+ throw new Error("Cannot record a new Codex receipt for an archived Task");
916
+ }
194
917
  const request = readJson(requestFile(context.dir, requestId));
195
- if (request.task !== context.task || request.request_id !== requestId)
918
+ if (request.tool !== expectedTool || codexRequestFingerprint(request) !== expectedFingerprint) {
919
+ throw new Error("Codex request changed before its receipt was recorded");
920
+ }
921
+ if (request.request_id !== requestId ||
922
+ (request.task_id && request.task_id !== context.taskId) ||
923
+ request.task !== context.task) {
196
924
  throw new Error("Request belongs to another task");
925
+ }
926
+ const requestFingerprint = codexRequestFingerprint(request);
927
+ if (request.request_fingerprint !== undefined &&
928
+ request.request_fingerprint !== requestFingerprint) {
929
+ throw new Error("Request fingerprint does not match its persisted content");
930
+ }
197
931
  const result = readJson(resultFile);
198
932
  if (result.request_id !== requestId || result.tool !== request.tool)
199
933
  throw new Error("Receipt does not match the request");
934
+ const evidenceLevel = coordinationReceiptEvidence(evidenceLevelInput);
200
935
  if (!["ok", "failed", "queued"].includes(String(result.outcome)) ||
201
936
  (result.outcome === "queued" && request.tool !== "create_thread")) {
202
937
  throw new Error("Receipt outcome must be ok, failed or queued for create");
203
938
  }
204
939
  const successful = result.outcome === "ok";
205
- const threadId = typeof result.thread_id === "string" && idPattern.test(result.thread_id) ? result.thread_id : request.thread_id;
206
- const hostId = typeof result.host_id === "string" && idPattern.test(result.host_id) ? result.host_id : request.host_id;
207
- const clientThreadId = typeof result.client_thread_id === "string" && idPattern.test(result.client_thread_id) ? result.client_thread_id : null;
940
+ const threadId = typeof result.thread_id === "string" && idPattern.test(result.thread_id)
941
+ ? result.thread_id
942
+ : request.thread_id;
943
+ const hostId = typeof result.host_id === "string" && idPattern.test(result.host_id)
944
+ ? result.host_id
945
+ : request.host_id;
946
+ const clientThreadId = typeof result.client_thread_id === "string" &&
947
+ idPattern.test(result.client_thread_id)
948
+ ? result.client_thread_id
949
+ : null;
950
+ let threadCreationState;
951
+ if (request.tool === "create_thread") {
952
+ const suppliedState = result.thread_creation_state;
953
+ if (suppliedState !== undefined &&
954
+ suppliedState !== "created" &&
955
+ suppliedState !== "not_created" &&
956
+ suppliedState !== "unknown") {
957
+ throw new Error("thread_creation_state must be created, not_created or unknown");
958
+ }
959
+ if (successful) {
960
+ if (suppliedState === "not_created" || suppliedState === "unknown") {
961
+ throw new Error("Successful create receipt cannot report thread_creation_state as not created or unknown");
962
+ }
963
+ threadCreationState = "created";
964
+ }
965
+ else if (result.outcome === "queued") {
966
+ if (suppliedState === "created" || suppliedState === "not_created") {
967
+ throw new Error("Queued create cannot establish whether a thread was created");
968
+ }
969
+ threadCreationState = "unknown";
970
+ }
971
+ else {
972
+ if (suppliedState === "created") {
973
+ throw new Error("Failed create receipt cannot report thread_creation_state as created");
974
+ }
975
+ threadCreationState = suppliedState ?? "unknown";
976
+ if (threadCreationState === "not_created" &&
977
+ (threadId !== null ||
978
+ clientThreadId !== null ||
979
+ result.thread_id != null ||
980
+ result.client_thread_id != null)) {
981
+ throw new Error("not_created requires no thread_id or client_thread_id");
982
+ }
983
+ }
984
+ }
208
985
  if (successful && (!threadId || !hostId))
209
986
  throw new Error("Successful receipt requires thread_id and host_id");
987
+ if (evidenceLevel === "desktop-native" &&
988
+ successful &&
989
+ (request.tool === "create_thread" || request.tool === "wait_threads") &&
990
+ (result.thread_id !== threadId || result.host_id !== hostId)) {
991
+ throw new Error("Desktop-native create/wait receipt must echo the native thread_id and host_id");
992
+ }
993
+ if (evidenceLevel === "desktop-native" &&
994
+ request.task_kernel_kind === "task-kernel-v2" &&
995
+ request.role === "execute" &&
996
+ request.tool === "wait_threads" &&
997
+ !request.run_id) {
998
+ throw new Error("Desktop-native Execute wait receipts require an explicit --run-id");
999
+ }
210
1000
  if (result.outcome === "queued" && (!clientThreadId || threadId))
211
1001
  throw new Error("Queued create requires client_thread_id without thread_id");
212
- if (request.thread_id && (threadId !== request.thread_id || hostId !== request.host_id))
1002
+ if (request.thread_id &&
1003
+ (threadId !== request.thread_id || hostId !== request.host_id))
213
1004
  throw new Error("Receipt thread identity changed");
214
1005
  const queuedPath = queuedFile(context.dir, requestId);
215
- if (fs.existsSync(queuedPath) && result.outcome !== "queued" && readJson(queuedPath).client_thread_id !== clientThreadId) {
1006
+ if (fs.existsSync(queuedPath) &&
1007
+ result.outcome !== "queued" &&
1008
+ readJson(queuedPath).client_thread_id !== clientThreadId) {
216
1009
  throw new Error("Ready receipt must match the queued client_thread_id");
217
1010
  }
218
- const status = typeof result.status === "string" && result.status.length <= 80 ? result.status : null;
219
- if (successful && request.tool === "wait_threads" && !["completed", "needs_attention", "timeout"].includes(status ?? "")) {
1011
+ const status = typeof result.status === "string" && result.status.length <= 80
1012
+ ? result.status
1013
+ : null;
1014
+ if (request.escalation_id) {
1015
+ const prepared = readPiReviewEscalationV1(root, context.task, request.escalation_id);
1016
+ const currentPiReview = assertCurrentPiReviewEscalationV1(root, context.task, prepared);
1017
+ assertCodexEscalationSendPromptV1(prepared, request);
1018
+ if (request.tool !== "send_message_to_thread" ||
1019
+ request.reply_to_escalation_id ||
1020
+ evidenceLevel !== "desktop-native" ||
1021
+ (successful && currentPiReview.kernel.reviews.at(-1)?.id !== prepared.request.reviewId) ||
1022
+ request.role !== "review" ||
1023
+ request.escalation_source_task !== context.task ||
1024
+ request.escalation_source_task_id !== prepared.request.taskId ||
1025
+ request.escalation_prepared_request_ref !== prepared.ref ||
1026
+ request.escalation_prepared_fingerprint !==
1027
+ prepared.request.preparedFingerprint ||
1028
+ request.escalation_id !== prepared.request.escalationId ||
1029
+ !request.to_task_id ||
1030
+ !request.thread_id ||
1031
+ !request.host_id ||
1032
+ (successful &&
1033
+ (result.thread_id !== request.thread_id ||
1034
+ result.host_id !== request.host_id))) {
1035
+ throw new Error("Pi escalation send requires a desktop-native cross-task message receipt bound to its Task and thread");
1036
+ }
1037
+ }
1038
+ let replyEvidence;
1039
+ if (request.reply_to_escalation_id) {
1040
+ if (!request.escalation_source_task) {
1041
+ throw new Error("P40 reply read is missing its source Task binding");
1042
+ }
1043
+ const prepared = readPiReviewEscalationV1(root, request.escalation_source_task, request.reply_to_escalation_id);
1044
+ assertCurrentPiReviewEscalationV1(root, request.escalation_source_task, prepared);
1045
+ const send = readCodexEscalationSendV1({
1046
+ root,
1047
+ sourceTask: request.escalation_source_task,
1048
+ escalationId: request.reply_to_escalation_id,
1049
+ sendRequestId: request.escalation_send_request_id ?? "",
1050
+ });
1051
+ if (request.escalation_send_request_fingerprint !== send.requestFingerprint ||
1052
+ request.escalation_send_receipt_sha256 !== send.receiptSha256 ||
1053
+ request.escalation_send_receipt_recorded_at !== send.receiptRecordedAt ||
1054
+ Date.parse(request.created_at) < Date.parse(send.receiptRecordedAt)) {
1055
+ throw new Error("Escalation reply read request is not causally bound to the latest successful native send");
1056
+ }
1057
+ if (request.tool !== "read_thread" ||
1058
+ request.escalation_id ||
1059
+ evidenceLevel !== "desktop-native" ||
1060
+ request.role !== "review" ||
1061
+ request.escalation_source_task_id !== prepared.request.taskId ||
1062
+ request.escalation_prepared_request_ref !== prepared.ref ||
1063
+ request.escalation_prepared_fingerprint !==
1064
+ prepared.request.preparedFingerprint ||
1065
+ !request.escalation_send_request_id ||
1066
+ !request.escalation_send_request_fingerprint ||
1067
+ !request.escalation_send_receipt_sha256 ||
1068
+ !request.escalation_send_receipt_recorded_at ||
1069
+ !request.thread_id ||
1070
+ !request.host_id) {
1071
+ throw new Error("Escalation reply requires a desktop-native read_thread request bound to its Task and thread");
1072
+ }
1073
+ if (successful) {
1074
+ if (status !== "completed" ||
1075
+ result.reply_to_escalation_id !== request.reply_to_escalation_id ||
1076
+ result.thread_id !== request.thread_id ||
1077
+ result.host_id !== request.host_id) {
1078
+ throw new Error("Native escalation reply read must complete on the bound thread with exact escalation correlation");
1079
+ }
1080
+ replyEvidence = normalizeReplyEvidence(result.reply_evidence, request.reply_to_escalation_id);
1081
+ }
1082
+ }
1083
+ if (successful &&
1084
+ request.tool === "wait_threads" &&
1085
+ !["completed", "needs_attention", "timeout"].includes(status ?? "")) {
220
1086
  throw new Error("Wait receipt requires completed, needs_attention or timeout status");
221
1087
  }
222
- const reason = typeof result.reason === "string" && result.reason.length <= 500 ? result.reason : null;
1088
+ const reason = typeof result.reason === "string" && result.reason.length <= 500
1089
+ ? result.reason
1090
+ : null;
223
1091
  if (result.outcome === "failed" && !reason)
224
1092
  throw new Error("Failed receipt requires a short reason");
225
- const cursor = typeof result.cursor === "string" && result.cursor.length <= 2048 ? result.cursor : null;
1093
+ const cursor = typeof result.cursor === "string" && result.cursor.length <= 2048
1094
+ ? result.cursor
1095
+ : null;
1096
+ let destinationContext = null;
1097
+ if (request.to_task) {
1098
+ try {
1099
+ destinationContext = taskContextIncludingArchive(root, request.to_task);
1100
+ }
1101
+ catch {
1102
+ destinationContext = null;
1103
+ }
1104
+ }
1105
+ const sourceStale = context.archived ||
1106
+ context.revision !== request.kernel_revision ||
1107
+ (request.task_id !== undefined && request.task_id !== context.taskId) ||
1108
+ (request.task_kernel_kind !== undefined &&
1109
+ request.task_kernel_kind !== context.kernelKind) ||
1110
+ (request.contract_fingerprint !== undefined &&
1111
+ request.contract_fingerprint !== context.contractFingerprint) ||
1112
+ !isRunBoundToContext(context, request.run_id, request.candidate_snapshot_id, request.candidate_fingerprint);
1113
+ const destinationStale = Boolean(request.to_task) &&
1114
+ (!destinationContext ||
1115
+ destinationContext.archived ||
1116
+ destinationContext.taskId !== request.to_task_id ||
1117
+ destinationContext.revision !== request.to_kernel_revision ||
1118
+ destinationContext.kernelKind !== request.to_task_kernel_kind ||
1119
+ destinationContext.contractFingerprint !==
1120
+ request.to_contract_fingerprint ||
1121
+ !isRunBoundToContext(destinationContext, request.to_run_id, request.to_candidate_snapshot_id, request.to_candidate_fingerprint));
1122
+ const contractStale = sourceStale || destinationStale;
226
1123
  const receipt = {
227
- schema_version: 1, request_id: requestId, tool: request.tool, outcome: result.outcome,
228
- thread_id: threadId, client_thread_id: clientThreadId, host_id: hostId, status, cursor, reason,
229
- kernel_revision_at_receipt: context.revision, contract_stale: context.revision !== request.kernel_revision,
230
- recorded_at: new Date().toISOString(), assurance: "host-reported",
1124
+ schema_version: 1,
1125
+ request_id: requestId,
1126
+ task_id: context.taskId,
1127
+ run_id: request.run_id ?? null,
1128
+ candidate_snapshot_id: request.candidate_snapshot_id ?? null,
1129
+ candidate_fingerprint: request.candidate_fingerprint ?? null,
1130
+ to_task_id: request.to_task_id ?? null,
1131
+ to_run_id: request.to_run_id ?? null,
1132
+ to_candidate_snapshot_id: request.to_candidate_snapshot_id ?? null,
1133
+ to_candidate_fingerprint: request.to_candidate_fingerprint ?? null,
1134
+ destination_kernel_revision_at_receipt: destinationContext?.revision ?? null,
1135
+ request_fingerprint: requestFingerprint,
1136
+ evidence_level: evidenceLevel,
1137
+ ...(request.escalation_id ? { escalation_id: request.escalation_id } : {}),
1138
+ ...(request.reply_to_escalation_id
1139
+ ? { reply_to_escalation_id: request.reply_to_escalation_id }
1140
+ : {}),
1141
+ ...(request.escalation_source_task
1142
+ ? { escalation_source_task: request.escalation_source_task }
1143
+ : {}),
1144
+ ...(request.escalation_source_task_id
1145
+ ? { escalation_source_task_id: request.escalation_source_task_id }
1146
+ : {}),
1147
+ ...(request.escalation_prepared_request_ref
1148
+ ? {
1149
+ escalation_prepared_request_ref: request.escalation_prepared_request_ref,
1150
+ }
1151
+ : {}),
1152
+ ...(request.escalation_prepared_fingerprint
1153
+ ? {
1154
+ escalation_prepared_fingerprint: request.escalation_prepared_fingerprint,
1155
+ }
1156
+ : {}),
1157
+ ...(request.escalation_send_request_id
1158
+ ? {
1159
+ escalation_send_request_id: request.escalation_send_request_id,
1160
+ escalation_send_request_fingerprint: request.escalation_send_request_fingerprint,
1161
+ escalation_send_receipt_sha256: request.escalation_send_receipt_sha256,
1162
+ escalation_send_receipt_recorded_at: request.escalation_send_receipt_recorded_at,
1163
+ }
1164
+ : {}),
1165
+ ...(replyEvidence ? { reply_evidence: replyEvidence } : {}),
1166
+ ...(threadCreationState
1167
+ ? { thread_creation_state: threadCreationState }
1168
+ : {}),
1169
+ tool: request.tool,
1170
+ outcome: result.outcome,
1171
+ thread_id: threadId,
1172
+ client_thread_id: clientThreadId,
1173
+ host_id: hostId,
1174
+ status,
1175
+ cursor,
1176
+ reason,
1177
+ kernel_revision_at_receipt: context.revision,
1178
+ contract_stale: contractStale,
1179
+ recorded_at: new Date().toISOString(),
1180
+ assurance: "host-reported",
231
1181
  };
232
- writeNew(result.outcome === "queued" ? queuedPath : receiptFile(context.dir, requestId), receipt);
233
- if (request.role === "execute" && request.tool === "create_thread" && result.outcome === "failed") {
1182
+ writeNew(result.outcome === "queued"
1183
+ ? queuedPath
1184
+ : receiptFile(context.dir, requestId), receipt);
1185
+ if (request.task_kernel_kind !== "task-kernel-v2" &&
1186
+ request.role === "execute" &&
1187
+ request.tool === "create_thread" &&
1188
+ result.outcome === "failed") {
234
1189
  releaseParallelChild(root, context.dir, requestId);
235
1190
  }
236
- if (request.role === "execute" && request.tool === "wait_threads" && result.outcome === "ok" && status === "completed") {
237
- const create = requests(context.dir).find((candidate) => candidate.tool === "create_thread" && candidate.role === "execute"
238
- && fs.existsSync(receiptFile(context.dir, candidate.request_id))
239
- && readJson(receiptFile(context.dir, candidate.request_id)).thread_id === threadId);
1191
+ if (request.task_kernel_kind !== "task-kernel-v2" &&
1192
+ request.role === "execute" &&
1193
+ request.tool === "wait_threads" &&
1194
+ result.outcome === "ok" &&
1195
+ status === "completed") {
1196
+ const create = requests(context.dir).find((candidate) => candidate.tool === "create_thread" &&
1197
+ candidate.role === "execute" &&
1198
+ fs.existsSync(receiptFile(context.dir, candidate.request_id)) &&
1199
+ readJson(receiptFile(context.dir, candidate.request_id)).thread_id ===
1200
+ threadId);
240
1201
  if (create)
241
1202
  releaseParallelChild(root, context.dir, create.request_id);
242
1203
  }
1204
+ if (!contractStale) {
1205
+ const coordination = new CoordinationStore(root);
1206
+ if (request.coordination_message_id &&
1207
+ request.tool === "send_message_to_thread") {
1208
+ coordination.recordMessageReceipt({
1209
+ messageId: request.coordination_message_id,
1210
+ receiptId: requestId,
1211
+ status: result.outcome === "ok" ? "sent" : "failed",
1212
+ actor: { platform: "codex", id: hostId ?? "desktop" },
1213
+ evidenceLevel,
1214
+ externalRef: threadId,
1215
+ note: result.outcome === "failed"
1216
+ ? reason
1217
+ : "Host reported send accepted; recipient delivery is not confirmed.",
1218
+ });
1219
+ }
1220
+ if (request.task_kernel_kind === "task-kernel-v2" && request.run_id) {
1221
+ const coordinatedRun = coordination
1222
+ .snapshot()
1223
+ .runs.find((run) => run.started.task_id === context.taskId &&
1224
+ run.started.run_id === request.run_id);
1225
+ if (coordinatedRun && !coordinatedRun.result) {
1226
+ const requestRef = path
1227
+ .relative(root, requestFile(context.dir, requestId))
1228
+ .replaceAll("\\", "/");
1229
+ const receiptRef = path
1230
+ .relative(root, receiptFile(context.dir, requestId))
1231
+ .replaceAll("\\", "/");
1232
+ const sequence = (coordinatedRun.progress.at(-1)?.sequence ?? -1) + 1;
1233
+ coordination.recordRunProgress({
1234
+ taskId: context.taskId,
1235
+ runId: request.run_id,
1236
+ sequence,
1237
+ name: `codex.${request.tool.replaceAll("_", ".")}.${receipt.outcome}`,
1238
+ summary: `Codex bridge host-reported ${request.tool} receipt: ${receipt.outcome}${status ? ` (${status})` : ""}${reason ? `: ${reason}` : ""}`,
1239
+ evidenceRefs: [requestRef, receiptRef],
1240
+ actor: { platform: "codex", id: hostId ?? "desktop" },
1241
+ evidenceLevel,
1242
+ });
1243
+ }
1244
+ }
1245
+ }
243
1246
  return receipt;
244
1247
  }
245
1248
  export function codexBridgeStatus(root, task) {
246
- let context;
247
- let archived = false;
248
- try {
249
- context = taskContext(root, task);
250
- }
251
- catch (error) {
252
- if (!(error instanceof Error) || !error.message.startsWith("Task not found:"))
253
- throw error;
254
- context = archivedTaskContext(root, task);
255
- archived = true;
256
- }
1249
+ const context = taskContextIncludingArchive(root, task);
257
1250
  const all = requests(context.dir);
258
1251
  const receipts = all.flatMap((request) => {
259
1252
  const file = receiptFile(context.dir, request.request_id);
260
- return fs.existsSync(file) ? [readJson(file)] : [];
1253
+ return fs.existsSync(file)
1254
+ ? [readJson(file)]
1255
+ : [];
261
1256
  });
262
1257
  const completed = new Set(receipts.map((receipt) => receipt.request_id));
263
1258
  const queued = all.flatMap((request) => {
264
1259
  const file = queuedFile(context.dir, request.request_id);
265
- return fs.existsSync(file) && !completed.has(request.request_id) ? [readJson(file)] : [];
1260
+ return fs.existsSync(file) && !completed.has(request.request_id)
1261
+ ? [readJson(file)]
1262
+ : [];
1263
+ });
1264
+ const coordinated = new CoordinationStore(root).snapshot();
1265
+ const taskEvents = coordinated.events.filter((event) => (event.type === "task.blocked" || event.type === "task.unblocked") &&
1266
+ event.task_id === context.taskId);
1267
+ return {
1268
+ task: context.task,
1269
+ task_id: context.taskId,
1270
+ task_kernel_kind: context.kernelKind,
1271
+ archived: context.archived,
1272
+ phase: context.phase,
1273
+ kernel_revision: context.revision,
1274
+ threads: [...boundThreads(context.dir).values()],
1275
+ pending: all
1276
+ .filter((request) => !completed.has(request.request_id))
1277
+ .map(({ request_id, tool, role, thread_id, kernel_revision, created_at, prompt_sha256, }) => ({
1278
+ request_id,
1279
+ tool,
1280
+ role,
1281
+ thread_id,
1282
+ kernel_revision,
1283
+ created_at,
1284
+ prompt_sha256,
1285
+ })),
1286
+ queued,
1287
+ receipts,
1288
+ coordination: {
1289
+ messages: coordinated.messages
1290
+ .filter(({ message }) => message.from_task_id === context.taskId ||
1291
+ message.to_task_id === context.taskId)
1292
+ .map(({ message, status, receipts: messageReceipts }) => ({
1293
+ message_id: message.message_id,
1294
+ from_task_id: message.from_task_id,
1295
+ to_task_id: message.to_task_id,
1296
+ from_run_id: message.from_run_id,
1297
+ to_run_id: message.to_run_id,
1298
+ status,
1299
+ request_id: message.request_id,
1300
+ host_ref: message.host_ref,
1301
+ evidence_level: messageReceipts.at(-1)?.evidence_level ?? message.evidence_level,
1302
+ recorded_at: message.recorded_at,
1303
+ })),
1304
+ blocked_tasks: coordinated.blocked_tasks.filter((event) => event.task_id === context.taskId),
1305
+ task_events: taskEvents,
1306
+ runs: coordinated.runs.filter(({ started }) => started.task_id === context.taskId),
1307
+ },
1308
+ };
1309
+ }
1310
+ export function blockCodexTask(root, task, input) {
1311
+ const context = taskContext(root, task);
1312
+ const coordination = new CoordinationStore(root);
1313
+ let blockedByTaskId = input.blockedByTaskId ?? null;
1314
+ let evidenceLevel = "local";
1315
+ if (input.messageId) {
1316
+ const messageEntry = coordination
1317
+ .snapshot()
1318
+ .messages.find((candidate) => candidate.message.message_id === input.messageId);
1319
+ if (messageEntry?.message.to_task_id !== context.taskId) {
1320
+ throw new Error("block message must be addressed to this Task");
1321
+ }
1322
+ const sendReceipt = messageEntry.receipts.at(-1);
1323
+ if (!sendReceipt ||
1324
+ !new Set(["sent", "delivered", "acknowledged"]).has(sendReceipt.status)) {
1325
+ throw new Error("block message requires a non-stale successful send receipt");
1326
+ }
1327
+ const verified = verifyFreshCoordinationMessage(root, messageEntry, context, false);
1328
+ evidenceLevel = verified.evidenceLevel;
1329
+ if (messageEntry.message.to_run_id &&
1330
+ context.kernelKind === "task-kernel-v2") {
1331
+ const run = context.runs.find((candidate) => candidate.id === messageEntry.message.to_run_id);
1332
+ if (!run || (run.state !== "running" && run.state !== "waiting")) {
1333
+ throw new Error("block message Run is no longer active on this Task");
1334
+ }
1335
+ }
1336
+ blockedByTaskId ??= messageEntry.message.from_task_id;
1337
+ }
1338
+ return coordination.blockTaskWithPrecondition({
1339
+ taskId: context.taskId,
1340
+ blockedByTaskId,
1341
+ messageId: input.messageId ?? null,
1342
+ reason: input.reason,
1343
+ actor: { platform: "user", id: input.actorId ?? null },
1344
+ evidenceLevel,
1345
+ }, (_event, snapshot) => {
1346
+ const currentContext = taskContext(root, task);
1347
+ if (currentContext.taskId !== context.taskId ||
1348
+ currentContext.revision !== context.revision) {
1349
+ throw new Error("Task changed while the coordination block was added");
1350
+ }
1351
+ if (!input.messageId)
1352
+ return;
1353
+ const messageEntry = snapshot.messages.find((candidate) => candidate.message.message_id === input.messageId);
1354
+ if (messageEntry?.message.to_task_id !== context.taskId) {
1355
+ throw new Error("block message must be addressed to this Task");
1356
+ }
1357
+ const verified = verifyFreshCoordinationMessage(root, messageEntry, currentContext, false);
1358
+ if (verified.evidenceLevel !== evidenceLevel) {
1359
+ throw new Error("block message receipt changed while adding the block");
1360
+ }
1361
+ if (messageEntry.message.from_task_id !== blockedByTaskId ||
1362
+ (messageEntry.message.to_run_id &&
1363
+ currentContext.kernelKind === "task-kernel-v2" &&
1364
+ !currentContext.runs.some((run) => run.id === messageEntry.message.to_run_id &&
1365
+ (run.state === "running" || run.state === "waiting")))) {
1366
+ throw new Error("block message Run is no longer active on this Task");
1367
+ }
1368
+ });
1369
+ }
1370
+ export function unblockCodexTask(root, task, input) {
1371
+ const context = taskContext(root, task);
1372
+ const coordination = new CoordinationStore(root);
1373
+ let unblockedByTaskId = input.unblockedByTaskId ?? null;
1374
+ let evidenceLevel = "local";
1375
+ let resolutionEntry;
1376
+ let resolutionSourceTaskId = null;
1377
+ if (input.resolutionMessageId) {
1378
+ resolutionEntry = coordination
1379
+ .snapshot()
1380
+ .messages.find((candidate) => candidate.message.message_id === input.resolutionMessageId);
1381
+ if (resolutionEntry?.message.to_task_id !== context.taskId) {
1382
+ throw new Error("resolution message must be addressed to this Task");
1383
+ }
1384
+ if (!resolutionEntry)
1385
+ throw new Error("Resolution message disappeared");
1386
+ const sendReceipt = resolutionEntry.receipts.at(-1);
1387
+ if (!sendReceipt ||
1388
+ !new Set(["sent", "delivered", "acknowledged"]).has(sendReceipt.status)) {
1389
+ throw new Error("unblock requires a non-stale successful resolution receipt");
1390
+ }
1391
+ if (sendReceipt.evidence_level !== "desktop-native") {
1392
+ throw new Error("unblock requires a successful desktop-native resolution receipt");
1393
+ }
1394
+ const verified = verifyFreshCoordinationMessage(root, resolutionEntry, context, true);
1395
+ evidenceLevel = verified.evidenceLevel;
1396
+ resolutionSourceTaskId = resolutionEntry.message.from_task_id;
1397
+ unblockedByTaskId ??= resolutionSourceTaskId;
1398
+ }
1399
+ const barrier = coordinationKernelBarrier(context);
1400
+ return coordination.unblockTaskWithPostcondition({
1401
+ taskId: context.taskId,
1402
+ blockId: input.blockId,
1403
+ unblockedByTaskId,
1404
+ resolutionMessageId: input.resolutionMessageId ?? null,
1405
+ runId: barrier.runId,
1406
+ kernelRevisionAtUnblock: barrier.kernelRevision,
1407
+ kernelEventIdAtUnblock: barrier.kernelEventId,
1408
+ reason: input.reason,
1409
+ actor: { platform: "user", id: input.actorId ?? null },
1410
+ evidenceLevel,
1411
+ }, () => {
1412
+ const afterContext = taskContext(root, task);
1413
+ if (afterContext.taskId !== context.taskId ||
1414
+ afterContext.revision !== context.revision) {
1415
+ throw new Error("Task Kernel changed while the coordination block was cleared");
1416
+ }
1417
+ if (input.resolutionMessageId) {
1418
+ const afterEntry = coordination
1419
+ .snapshot()
1420
+ .messages.find((candidate) => candidate.message.message_id === input.resolutionMessageId);
1421
+ if (!afterEntry)
1422
+ throw new Error("Resolution message disappeared");
1423
+ const beforeEntry = resolutionEntry;
1424
+ if (!beforeEntry)
1425
+ throw new Error("Resolution message disappeared");
1426
+ const afterVerified = verifyFreshCoordinationMessage(root, afterEntry, afterContext, true);
1427
+ const beforeVerified = verifyFreshCoordinationMessage(root, beforeEntry, context, true);
1428
+ if (afterVerified.sourceContext.revision !==
1429
+ beforeVerified.sourceContext.revision ||
1430
+ afterVerified.sourceContext.taskId !==
1431
+ beforeVerified.sourceContext.taskId) {
1432
+ throw new Error("Resolution source Task changed while the block was cleared");
1433
+ }
1434
+ }
1435
+ }, {
1436
+ taskId: context.taskId,
1437
+ blockId: randomUUID(),
1438
+ blockedByTaskId: resolutionSourceTaskId,
1439
+ messageId: null,
1440
+ reason: "Task or Run state changed while clearing the coordination block; obtain a fresh resolution.",
1441
+ actor: { platform: "user", id: input.actorId ?? null },
1442
+ evidenceLevel: "local",
266
1443
  });
267
- return { task: context.task, archived, phase: context.phase, kernel_revision: context.revision,
268
- threads: [...boundThreads(context.dir).values()], pending: all.filter((request) => !completed.has(request.request_id))
269
- .map(({ request_id, tool, role, thread_id, kernel_revision, created_at, prompt_sha256 }) => ({ request_id, tool, role, thread_id, kernel_revision, created_at, prompt_sha256 })), queued, receipts };
270
1444
  }
271
1445
  //# sourceMappingURL=bridge.js.map