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

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 (704) 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/migrations/manifests/0.6.0-beta.5.json +9 -0
  203. package/dist/pactile/artifacts/documents.d.ts +72 -0
  204. package/dist/pactile/artifacts/documents.d.ts.map +1 -0
  205. package/dist/pactile/artifacts/documents.js +406 -0
  206. package/dist/pactile/artifacts/documents.js.map +1 -0
  207. package/dist/pactile/artifacts/index.d.ts +6 -0
  208. package/dist/pactile/artifacts/index.d.ts.map +1 -0
  209. package/dist/pactile/artifacts/index.js +6 -0
  210. package/dist/pactile/artifacts/index.js.map +1 -0
  211. package/dist/pactile/artifacts/projection.d.ts +50 -0
  212. package/dist/pactile/artifacts/projection.d.ts.map +1 -0
  213. package/dist/pactile/artifacts/projection.js +139 -0
  214. package/dist/pactile/artifacts/projection.js.map +1 -0
  215. package/dist/pactile/artifacts/reader.d.ts +20 -0
  216. package/dist/pactile/artifacts/reader.d.ts.map +1 -0
  217. package/dist/pactile/artifacts/reader.js +559 -0
  218. package/dist/pactile/artifacts/reader.js.map +1 -0
  219. package/dist/pactile/artifacts/schema.d.ts +4 -0
  220. package/dist/pactile/artifacts/schema.d.ts.map +1 -0
  221. package/dist/pactile/artifacts/schema.js +217 -0
  222. package/dist/pactile/artifacts/schema.js.map +1 -0
  223. package/dist/pactile/artifacts/types.d.ts +66 -0
  224. package/dist/pactile/artifacts/types.d.ts.map +1 -0
  225. package/dist/pactile/artifacts/types.js +45 -0
  226. package/dist/pactile/artifacts/types.js.map +1 -0
  227. package/dist/pactile/capabilities/claim.d.ts +3 -0
  228. package/dist/pactile/capabilities/claim.d.ts.map +1 -0
  229. package/dist/pactile/capabilities/claim.js +97 -0
  230. package/dist/pactile/capabilities/claim.js.map +1 -0
  231. package/dist/pactile/capabilities/command.d.ts +6 -0
  232. package/dist/pactile/capabilities/command.d.ts.map +1 -0
  233. package/dist/pactile/capabilities/command.js +253 -0
  234. package/dist/pactile/capabilities/command.js.map +1 -0
  235. package/dist/pactile/capabilities/discover.d.ts +6 -0
  236. package/dist/pactile/capabilities/discover.d.ts.map +1 -0
  237. package/dist/pactile/capabilities/discover.js +48 -0
  238. package/dist/pactile/capabilities/discover.js.map +1 -0
  239. package/dist/pactile/capabilities/node.d.ts +15 -0
  240. package/dist/pactile/capabilities/node.d.ts.map +1 -0
  241. package/dist/pactile/capabilities/node.js +292 -0
  242. package/dist/pactile/capabilities/node.js.map +1 -0
  243. package/dist/pactile/capabilities/read.d.ts +6 -0
  244. package/dist/pactile/capabilities/read.d.ts.map +1 -0
  245. package/dist/pactile/capabilities/read.js +100 -0
  246. package/dist/pactile/capabilities/read.js.map +1 -0
  247. package/dist/pactile/capabilities/receipts.d.ts +17 -0
  248. package/dist/pactile/capabilities/receipts.d.ts.map +1 -0
  249. package/dist/pactile/capabilities/receipts.js +90 -0
  250. package/dist/pactile/capabilities/receipts.js.map +1 -0
  251. package/dist/pactile/capabilities/search.d.ts +6 -0
  252. package/dist/pactile/capabilities/search.d.ts.map +1 -0
  253. package/dist/pactile/capabilities/search.js +181 -0
  254. package/dist/pactile/capabilities/search.js.map +1 -0
  255. package/dist/pactile/capabilities/shared.d.ts +29 -0
  256. package/dist/pactile/capabilities/shared.d.ts.map +1 -0
  257. package/dist/pactile/capabilities/shared.js +134 -0
  258. package/dist/pactile/capabilities/shared.js.map +1 -0
  259. package/dist/pactile/capabilities/workspace.d.ts +19 -0
  260. package/dist/pactile/capabilities/workspace.d.ts.map +1 -0
  261. package/dist/pactile/capabilities/workspace.js +273 -0
  262. package/dist/pactile/capabilities/workspace.js.map +1 -0
  263. package/dist/pactile/codex/bridge.d.ts +105 -2
  264. package/dist/pactile/codex/bridge.d.ts.map +1 -1
  265. package/dist/pactile/codex/bridge.js +1266 -92
  266. package/dist/pactile/codex/bridge.js.map +1 -1
  267. package/dist/pactile/codex/dispatch-stop-proof.d.ts +43 -0
  268. package/dist/pactile/codex/dispatch-stop-proof.d.ts.map +1 -0
  269. package/dist/pactile/codex/dispatch-stop-proof.js +177 -0
  270. package/dist/pactile/codex/dispatch-stop-proof.js.map +1 -0
  271. package/dist/pactile/codex/host-stop.d.ts +47 -0
  272. package/dist/pactile/codex/host-stop.d.ts.map +1 -0
  273. package/dist/pactile/codex/host-stop.js +344 -0
  274. package/dist/pactile/codex/host-stop.js.map +1 -0
  275. package/dist/pactile/coordination/index.d.ts +4 -0
  276. package/dist/pactile/coordination/index.d.ts.map +1 -0
  277. package/dist/pactile/coordination/index.js +4 -0
  278. package/dist/pactile/coordination/index.js.map +1 -0
  279. package/dist/pactile/coordination/journal.d.ts +10 -0
  280. package/dist/pactile/coordination/journal.d.ts.map +1 -0
  281. package/dist/pactile/coordination/journal.js +255 -0
  282. package/dist/pactile/coordination/journal.js.map +1 -0
  283. package/dist/pactile/coordination/kernel-resume.d.ts +8 -0
  284. package/dist/pactile/coordination/kernel-resume.d.ts.map +1 -0
  285. package/dist/pactile/coordination/kernel-resume.js +87 -0
  286. package/dist/pactile/coordination/kernel-resume.js.map +1 -0
  287. package/dist/pactile/coordination/model.d.ts +553 -0
  288. package/dist/pactile/coordination/model.d.ts.map +1 -0
  289. package/dist/pactile/coordination/model.js +239 -0
  290. package/dist/pactile/coordination/model.js.map +1 -0
  291. package/dist/pactile/coordination/state.d.ts +46 -0
  292. package/dist/pactile/coordination/state.d.ts.map +1 -0
  293. package/dist/pactile/coordination/state.js +301 -0
  294. package/dist/pactile/coordination/state.js.map +1 -0
  295. package/dist/pactile/coordination/store.d.ts +94 -0
  296. package/dist/pactile/coordination/store.d.ts.map +1 -0
  297. package/dist/pactile/coordination/store.js +396 -0
  298. package/dist/pactile/coordination/store.js.map +1 -0
  299. package/dist/pactile/index.d.ts +7 -1
  300. package/dist/pactile/index.d.ts.map +1 -1
  301. package/dist/pactile/index.js +7 -1
  302. package/dist/pactile/index.js.map +1 -1
  303. package/dist/pactile/jev/contracts.d.ts +104 -0
  304. package/dist/pactile/jev/contracts.d.ts.map +1 -0
  305. package/dist/pactile/jev/contracts.js +53 -0
  306. package/dist/pactile/jev/contracts.js.map +1 -0
  307. package/dist/pactile/jev/decision.d.ts +58 -0
  308. package/dist/pactile/jev/decision.d.ts.map +1 -0
  309. package/dist/pactile/jev/decision.js +149 -0
  310. package/dist/pactile/jev/decision.js.map +1 -0
  311. package/dist/pactile/jev/http.d.ts +25 -0
  312. package/dist/pactile/jev/http.d.ts.map +1 -0
  313. package/dist/pactile/jev/http.js +234 -0
  314. package/dist/pactile/jev/http.js.map +1 -0
  315. package/dist/pactile/jev/index.d.ts +8 -0
  316. package/dist/pactile/jev/index.d.ts.map +1 -0
  317. package/dist/pactile/jev/index.js +4 -0
  318. package/dist/pactile/jev/index.js.map +1 -0
  319. package/dist/pactile/jev/outbound.d.ts +15 -0
  320. package/dist/pactile/jev/outbound.d.ts.map +1 -0
  321. package/dist/pactile/jev/outbound.js +264 -0
  322. package/dist/pactile/jev/outbound.js.map +1 -0
  323. package/dist/pactile/jev/project-policy.d.ts +10 -0
  324. package/dist/pactile/jev/project-policy.d.ts.map +1 -0
  325. package/dist/pactile/jev/project-policy.js +53 -0
  326. package/dist/pactile/jev/project-policy.js.map +1 -0
  327. package/dist/pactile/jev/response.d.ts +17 -0
  328. package/dist/pactile/jev/response.d.ts.map +1 -0
  329. package/dist/pactile/jev/response.js +280 -0
  330. package/dist/pactile/jev/response.js.map +1 -0
  331. package/dist/pactile/jev/scheduler-advice.d.ts +92 -0
  332. package/dist/pactile/jev/scheduler-advice.d.ts.map +1 -0
  333. package/dist/pactile/jev/scheduler-advice.js +323 -0
  334. package/dist/pactile/jev/scheduler-advice.js.map +1 -0
  335. package/dist/pactile/jev/transport.d.ts +6 -0
  336. package/dist/pactile/jev/transport.d.ts.map +1 -0
  337. package/dist/pactile/jev/transport.js +87 -0
  338. package/dist/pactile/jev/transport.js.map +1 -0
  339. package/dist/pactile/lifecycle/deferred-live.d.ts +17 -0
  340. package/dist/pactile/lifecycle/deferred-live.d.ts.map +1 -0
  341. package/dist/pactile/lifecycle/deferred-live.js +173 -0
  342. package/dist/pactile/lifecycle/deferred-live.js.map +1 -0
  343. package/dist/pactile/lifecycle/legacy-import.d.ts +1 -1
  344. package/dist/pactile/lifecycle/legacy-import.js +3 -3
  345. package/dist/pactile/lifecycle/legacy-import.js.map +1 -1
  346. package/dist/pactile/lifecycle/project-files.d.ts.map +1 -1
  347. package/dist/pactile/lifecycle/project-files.js +1 -0
  348. package/dist/pactile/lifecycle/project-files.js.map +1 -1
  349. package/dist/pactile/migration/legacy-task-batch-generation.d.ts +23 -0
  350. package/dist/pactile/migration/legacy-task-batch-generation.d.ts.map +1 -0
  351. package/dist/pactile/migration/legacy-task-batch-generation.js +102 -0
  352. package/dist/pactile/migration/legacy-task-batch-generation.js.map +1 -0
  353. package/dist/pactile/migration/legacy-task-batch-io.d.ts +9 -0
  354. package/dist/pactile/migration/legacy-task-batch-io.d.ts.map +1 -0
  355. package/dist/pactile/migration/legacy-task-batch-io.js +208 -0
  356. package/dist/pactile/migration/legacy-task-batch-io.js.map +1 -0
  357. package/dist/pactile/migration/legacy-task-batch-journal.d.ts +6 -0
  358. package/dist/pactile/migration/legacy-task-batch-journal.d.ts.map +1 -0
  359. package/dist/pactile/migration/legacy-task-batch-journal.js +121 -0
  360. package/dist/pactile/migration/legacy-task-batch-journal.js.map +1 -0
  361. package/dist/pactile/migration/legacy-task-batch-orchestrator.d.ts +18 -0
  362. package/dist/pactile/migration/legacy-task-batch-orchestrator.d.ts.map +1 -0
  363. package/dist/pactile/migration/legacy-task-batch-orchestrator.js +634 -0
  364. package/dist/pactile/migration/legacy-task-batch-orchestrator.js.map +1 -0
  365. package/dist/pactile/migration/legacy-task-batch-source.d.ts +8 -0
  366. package/dist/pactile/migration/legacy-task-batch-source.d.ts.map +1 -0
  367. package/dist/pactile/migration/legacy-task-batch-source.js +158 -0
  368. package/dist/pactile/migration/legacy-task-batch-source.js.map +1 -0
  369. package/dist/pactile/migration/legacy-task-batch-types.d.ts +127 -0
  370. package/dist/pactile/migration/legacy-task-batch-types.d.ts.map +1 -0
  371. package/dist/pactile/migration/legacy-task-batch-types.js +127 -0
  372. package/dist/pactile/migration/legacy-task-batch-types.js.map +1 -0
  373. package/dist/pactile/migration/legacy-task-batch.d.ts +3 -0
  374. package/dist/pactile/migration/legacy-task-batch.d.ts.map +1 -0
  375. package/dist/pactile/migration/legacy-task-batch.js +2 -0
  376. package/dist/pactile/migration/legacy-task-batch.js.map +1 -0
  377. package/dist/pactile/migration/legacy-task-held-source-reader.d.ts +27 -0
  378. package/dist/pactile/migration/legacy-task-held-source-reader.d.ts.map +1 -0
  379. package/dist/pactile/migration/legacy-task-held-source-reader.js +261 -0
  380. package/dist/pactile/migration/legacy-task-held-source-reader.js.map +1 -0
  381. package/dist/pactile/migration/legacy-task-reconciliation.d.ts +46 -0
  382. package/dist/pactile/migration/legacy-task-reconciliation.d.ts.map +1 -0
  383. package/dist/pactile/migration/legacy-task-reconciliation.js +589 -0
  384. package/dist/pactile/migration/legacy-task-reconciliation.js.map +1 -0
  385. package/dist/pactile/migration/legacy-task-update.d.ts +19 -0
  386. package/dist/pactile/migration/legacy-task-update.d.ts.map +1 -0
  387. package/dist/pactile/migration/legacy-task-update.js +164 -0
  388. package/dist/pactile/migration/legacy-task-update.js.map +1 -0
  389. package/dist/pactile/parallel/batch.d.ts +21 -2
  390. package/dist/pactile/parallel/batch.d.ts.map +1 -1
  391. package/dist/pactile/parallel/batch.js +271 -50
  392. package/dist/pactile/parallel/batch.js.map +1 -1
  393. package/dist/pactile/parallel/policy.d.ts +1 -1
  394. package/dist/pactile/parallel/policy.d.ts.map +1 -1
  395. package/dist/pactile/parallel/policy.js +130 -102
  396. package/dist/pactile/parallel/policy.js.map +1 -1
  397. package/dist/pactile/pi/bridge.d.ts +139 -2
  398. package/dist/pactile/pi/bridge.d.ts.map +1 -1
  399. package/dist/pactile/pi/bridge.js +1317 -106
  400. package/dist/pactile/pi/bridge.js.map +1 -1
  401. package/dist/pactile/pi/rpc.d.ts +23 -4
  402. package/dist/pactile/pi/rpc.d.ts.map +1 -1
  403. package/dist/pactile/pi/rpc.js +243 -42
  404. package/dist/pactile/pi/rpc.js.map +1 -1
  405. package/dist/pactile/pi/v2-dispatch.d.ts +113 -0
  406. package/dist/pactile/pi/v2-dispatch.d.ts.map +1 -0
  407. package/dist/pactile/pi/v2-dispatch.js +919 -0
  408. package/dist/pactile/pi/v2-dispatch.js.map +1 -0
  409. package/dist/pactile/projection/planner.js +1 -1
  410. package/dist/pactile/projection/planner.js.map +1 -1
  411. package/dist/pactile/registry.d.ts +63 -1
  412. package/dist/pactile/registry.d.ts.map +1 -1
  413. package/dist/pactile/registry.js +633 -4
  414. package/dist/pactile/registry.js.map +1 -1
  415. package/dist/pactile/retrieval/index.d.ts +1 -0
  416. package/dist/pactile/retrieval/index.d.ts.map +1 -1
  417. package/dist/pactile/retrieval/index.js +1 -0
  418. package/dist/pactile/retrieval/index.js.map +1 -1
  419. package/dist/pactile/retrieval/jev-planning.d.ts +28 -0
  420. package/dist/pactile/retrieval/jev-planning.d.ts.map +1 -0
  421. package/dist/pactile/retrieval/jev-planning.js +96 -0
  422. package/dist/pactile/retrieval/jev-planning.js.map +1 -0
  423. package/dist/pactile/review/contract.d.ts +232 -0
  424. package/dist/pactile/review/contract.d.ts.map +1 -0
  425. package/dist/pactile/review/contract.js +695 -0
  426. package/dist/pactile/review/contract.js.map +1 -0
  427. package/dist/pactile/review/escalation-artifacts.d.ts +41 -0
  428. package/dist/pactile/review/escalation-artifacts.d.ts.map +1 -0
  429. package/dist/pactile/review/escalation-artifacts.js +415 -0
  430. package/dist/pactile/review/escalation-artifacts.js.map +1 -0
  431. package/dist/pactile/review/escalation-contract.d.ts +115 -0
  432. package/dist/pactile/review/escalation-contract.d.ts.map +1 -0
  433. package/dist/pactile/review/escalation-contract.js +151 -0
  434. package/dist/pactile/review/escalation-contract.js.map +1 -0
  435. package/dist/pactile/review/escalation-finalize.d.ts +14 -0
  436. package/dist/pactile/review/escalation-finalize.d.ts.map +1 -0
  437. package/dist/pactile/review/escalation-finalize.js +319 -0
  438. package/dist/pactile/review/escalation-finalize.js.map +1 -0
  439. package/dist/pactile/review/escalation-reply.d.ts +10 -0
  440. package/dist/pactile/review/escalation-reply.d.ts.map +1 -0
  441. package/dist/pactile/review/escalation-reply.js +61 -0
  442. package/dist/pactile/review/escalation-reply.js.map +1 -0
  443. package/dist/pactile/review/escalation-transport.d.ts +32 -0
  444. package/dist/pactile/review/escalation-transport.d.ts.map +1 -0
  445. package/dist/pactile/review/escalation-transport.js +216 -0
  446. package/dist/pactile/review/escalation-transport.js.map +1 -0
  447. package/dist/pactile/review/escalation.d.ts +7 -0
  448. package/dist/pactile/review/escalation.d.ts.map +1 -0
  449. package/dist/pactile/review/escalation.js +6 -0
  450. package/dist/pactile/review/escalation.js.map +1 -0
  451. package/dist/pactile/review/evidence.d.ts +25 -0
  452. package/dist/pactile/review/evidence.d.ts.map +1 -0
  453. package/dist/pactile/review/evidence.js +58 -0
  454. package/dist/pactile/review/evidence.js.map +1 -0
  455. package/dist/pactile/review/jev-escalation-advice.d.ts +77 -0
  456. package/dist/pactile/review/jev-escalation-advice.d.ts.map +1 -0
  457. package/dist/pactile/review/jev-escalation-advice.js +358 -0
  458. package/dist/pactile/review/jev-escalation-advice.js.map +1 -0
  459. package/dist/pactile/scheduler/index.d.ts +6 -0
  460. package/dist/pactile/scheduler/index.d.ts.map +1 -0
  461. package/dist/pactile/scheduler/index.js +5 -0
  462. package/dist/pactile/scheduler/index.js.map +1 -0
  463. package/dist/pactile/scheduler/project-lease-store.d.ts +35 -0
  464. package/dist/pactile/scheduler/project-lease-store.d.ts.map +1 -0
  465. package/dist/pactile/scheduler/project-lease-store.js +189 -0
  466. package/dist/pactile/scheduler/project-lease-store.js.map +1 -0
  467. package/dist/pactile/scheduler/scheduler.d.ts +91 -0
  468. package/dist/pactile/scheduler/scheduler.d.ts.map +1 -0
  469. package/dist/pactile/scheduler/scheduler.js +589 -0
  470. package/dist/pactile/scheduler/scheduler.js.map +1 -0
  471. package/dist/pactile/scheduler/task-kernel-admission.d.ts +173 -0
  472. package/dist/pactile/scheduler/task-kernel-admission.d.ts.map +1 -0
  473. package/dist/pactile/scheduler/task-kernel-admission.js +1560 -0
  474. package/dist/pactile/scheduler/task-kernel-admission.js.map +1 -0
  475. package/dist/pactile/scheduler/task-kernel-wave-dispatch.d.ts +184 -0
  476. package/dist/pactile/scheduler/task-kernel-wave-dispatch.d.ts.map +1 -0
  477. package/dist/pactile/scheduler/task-kernel-wave-dispatch.js +952 -0
  478. package/dist/pactile/scheduler/task-kernel-wave-dispatch.js.map +1 -0
  479. package/dist/pactile/scheduler/task-map-scheduler.d.ts +116 -0
  480. package/dist/pactile/scheduler/task-map-scheduler.d.ts.map +1 -0
  481. package/dist/pactile/scheduler/task-map-scheduler.js +1448 -0
  482. package/dist/pactile/scheduler/task-map-scheduler.js.map +1 -0
  483. package/dist/pactile/scheduler/task-run-dispatch-state.d.ts +7 -0
  484. package/dist/pactile/scheduler/task-run-dispatch-state.d.ts.map +1 -0
  485. package/dist/pactile/scheduler/task-run-dispatch-state.js +69 -0
  486. package/dist/pactile/scheduler/task-run-dispatch-state.js.map +1 -0
  487. package/dist/pactile/task/authorization.d.ts +3 -0
  488. package/dist/pactile/task/authorization.d.ts.map +1 -0
  489. package/dist/pactile/task/authorization.js +43 -0
  490. package/dist/pactile/task/authorization.js.map +1 -0
  491. package/dist/pactile/task/creation.d.ts +22 -0
  492. package/dist/pactile/task/creation.d.ts.map +1 -0
  493. package/dist/pactile/task/creation.js +95 -0
  494. package/dist/pactile/task/creation.js.map +1 -0
  495. package/dist/pactile/task/guards.d.ts +1 -4
  496. package/dist/pactile/task/guards.d.ts.map +1 -1
  497. package/dist/pactile/task/guards.js +5 -57
  498. package/dist/pactile/task/guards.js.map +1 -1
  499. package/dist/pactile/task/session-jev-receipt.d.ts +58 -0
  500. package/dist/pactile/task/session-jev-receipt.d.ts.map +1 -0
  501. package/dist/pactile/task/session-jev-receipt.js +375 -0
  502. package/dist/pactile/task/session-jev-receipt.js.map +1 -0
  503. package/dist/pactile/task/session-jev.d.ts +7 -0
  504. package/dist/pactile/task/session-jev.d.ts.map +1 -0
  505. package/dist/pactile/task/session-jev.js +217 -0
  506. package/dist/pactile/task/session-jev.js.map +1 -0
  507. package/dist/pactile/task/session-pack.d.ts.map +1 -1
  508. package/dist/pactile/task/session-pack.js +155 -16
  509. package/dist/pactile/task/session-pack.js.map +1 -1
  510. package/dist/pactile/task/session-retrieval-jev-receipt.d.ts +49 -0
  511. package/dist/pactile/task/session-retrieval-jev-receipt.d.ts.map +1 -0
  512. package/dist/pactile/task/session-retrieval-jev-receipt.js +97 -0
  513. package/dist/pactile/task/session-retrieval-jev-receipt.js.map +1 -0
  514. package/dist/pactile/task/session-retrieval-jev.d.ts +8 -0
  515. package/dist/pactile/task/session-retrieval-jev.d.ts.map +1 -0
  516. package/dist/pactile/task/session-retrieval-jev.js +352 -0
  517. package/dist/pactile/task/session-retrieval-jev.js.map +1 -0
  518. package/dist/pactile/task/strategy.d.ts +1 -23
  519. package/dist/pactile/task/strategy.d.ts.map +1 -1
  520. package/dist/pactile/task/strategy.js +2 -135
  521. package/dist/pactile/task/strategy.js.map +1 -1
  522. package/dist/pactile/tiles/jev-selection.d.ts +44 -0
  523. package/dist/pactile/tiles/jev-selection.d.ts.map +1 -0
  524. package/dist/pactile/tiles/jev-selection.js +210 -0
  525. package/dist/pactile/tiles/jev-selection.js.map +1 -0
  526. package/dist/pactile/tiles/safe-yaml.d.ts +5 -1
  527. package/dist/pactile/tiles/safe-yaml.d.ts.map +1 -1
  528. package/dist/pactile/tiles/safe-yaml.js +8 -8
  529. package/dist/pactile/tiles/safe-yaml.js.map +1 -1
  530. package/dist/pactile/tiles/selection-receipts.d.ts +71 -0
  531. package/dist/pactile/tiles/selection-receipts.d.ts.map +1 -0
  532. package/dist/pactile/tiles/selection-receipts.js +319 -0
  533. package/dist/pactile/tiles/selection-receipts.js.map +1 -0
  534. package/dist/pactile/tiles/selection.d.ts +185 -0
  535. package/dist/pactile/tiles/selection.d.ts.map +1 -0
  536. package/dist/pactile/tiles/selection.js +985 -0
  537. package/dist/pactile/tiles/selection.js.map +1 -0
  538. package/dist/pactile/verification/git-observer.d.ts +3 -0
  539. package/dist/pactile/verification/git-observer.d.ts.map +1 -0
  540. package/dist/pactile/verification/git-observer.js +3 -0
  541. package/dist/pactile/verification/git-observer.js.map +1 -0
  542. package/dist/pactile/verification/index.d.ts +11 -0
  543. package/dist/pactile/verification/index.d.ts.map +1 -0
  544. package/dist/pactile/verification/index.js +6 -0
  545. package/dist/pactile/verification/index.js.map +1 -0
  546. package/dist/pactile/verification/jev-advice.d.ts +78 -0
  547. package/dist/pactile/verification/jev-advice.d.ts.map +1 -0
  548. package/dist/pactile/verification/jev-advice.js +397 -0
  549. package/dist/pactile/verification/jev-advice.js.map +1 -0
  550. package/dist/pactile/verification/planner.d.ts +15 -0
  551. package/dist/pactile/verification/planner.d.ts.map +1 -0
  552. package/dist/pactile/verification/planner.js +412 -0
  553. package/dist/pactile/verification/planner.js.map +1 -0
  554. package/dist/pactile/verification/receipt.d.ts +101 -0
  555. package/dist/pactile/verification/receipt.d.ts.map +1 -0
  556. package/dist/pactile/verification/receipt.js +400 -0
  557. package/dist/pactile/verification/receipt.js.map +1 -0
  558. package/dist/pactile/verification/types.d.ts +72 -0
  559. package/dist/pactile/verification/types.d.ts.map +1 -0
  560. package/dist/pactile/verification/types.js +21 -0
  561. package/dist/pactile/verification/types.js.map +1 -0
  562. package/dist/pactile/worktree/git-probe.d.ts +32 -0
  563. package/dist/pactile/worktree/git-probe.d.ts.map +1 -0
  564. package/dist/pactile/worktree/git-probe.js +336 -0
  565. package/dist/pactile/worktree/git-probe.js.map +1 -0
  566. package/dist/pactile/worktree/git-removal.d.ts +3 -0
  567. package/dist/pactile/worktree/git-removal.d.ts.map +1 -0
  568. package/dist/pactile/worktree/git-removal.js +11 -0
  569. package/dist/pactile/worktree/git-removal.js.map +1 -0
  570. package/dist/pactile/worktree/index.d.ts +2 -0
  571. package/dist/pactile/worktree/index.d.ts.map +1 -0
  572. package/dist/pactile/worktree/index.js +2 -0
  573. package/dist/pactile/worktree/index.js.map +1 -0
  574. package/dist/pactile/worktree/integration-evidence.d.ts +80 -0
  575. package/dist/pactile/worktree/integration-evidence.d.ts.map +1 -0
  576. package/dist/pactile/worktree/integration-evidence.js +166 -0
  577. package/dist/pactile/worktree/integration-evidence.js.map +1 -0
  578. package/dist/pactile/worktree/manager-core.d.ts +50 -0
  579. package/dist/pactile/worktree/manager-core.d.ts.map +1 -0
  580. package/dist/pactile/worktree/manager-core.js +359 -0
  581. package/dist/pactile/worktree/manager-core.js.map +1 -0
  582. package/dist/pactile/worktree/manager-provenance.d.ts +32 -0
  583. package/dist/pactile/worktree/manager-provenance.d.ts.map +1 -0
  584. package/dist/pactile/worktree/manager-provenance.js +409 -0
  585. package/dist/pactile/worktree/manager-provenance.js.map +1 -0
  586. package/dist/pactile/worktree/manager-types.d.ts +84 -0
  587. package/dist/pactile/worktree/manager-types.d.ts.map +1 -0
  588. package/dist/pactile/worktree/manager-types.js +11 -0
  589. package/dist/pactile/worktree/manager-types.js.map +1 -0
  590. package/dist/pactile/worktree/manager.d.ts +10 -0
  591. package/dist/pactile/worktree/manager.d.ts.map +1 -0
  592. package/dist/pactile/worktree/manager.js +6 -0
  593. package/dist/pactile/worktree/manager.js.map +1 -0
  594. package/dist/pactile/worktree/run-workspace-cleanup.d.ts +10 -0
  595. package/dist/pactile/worktree/run-workspace-cleanup.d.ts.map +1 -0
  596. package/dist/pactile/worktree/run-workspace-cleanup.js +695 -0
  597. package/dist/pactile/worktree/run-workspace-cleanup.js.map +1 -0
  598. package/dist/pactile/worktree/run-workspace-lifecycle.d.ts +65 -0
  599. package/dist/pactile/worktree/run-workspace-lifecycle.d.ts.map +1 -0
  600. package/dist/pactile/worktree/run-workspace-lifecycle.js +276 -0
  601. package/dist/pactile/worktree/run-workspace-lifecycle.js.map +1 -0
  602. package/dist/templates/common/bundled-skills/pactile-meta/references/customize-local/change-hooks.md +1 -1
  603. package/dist/templates/common/bundled-skills/pactile-meta/references/local-architecture/generated-files.md +1 -1
  604. package/dist/templates/common/bundled-skills/pactile-meta/references/platform-files/hooks-and-settings.md +1 -1
  605. package/dist/templates/common/bundled-skills/pactile-meta/references/platform-files/overview.md +1 -1
  606. package/dist/templates/common/bundled-skills/pactile-meta/references/platform-files/platform-map.md +1 -1
  607. package/dist/templates/common/bundled-skills/smart-search-cli/SKILL.md +2 -0
  608. package/dist/templates/common/skills/brainstorm.md +19 -13
  609. package/dist/templates/markdown/agents.md +2 -2
  610. package/dist/templates/markdown/framework/execution-strategy.md.txt +1 -1
  611. package/dist/templates/markdown/framework/index.md.txt +1 -1
  612. package/dist/templates/markdown/framework/parallel-first-execution.md.txt +17 -105
  613. package/dist/templates/markdown/framework/prd-grill-frontier.md.txt +3 -3
  614. package/dist/templates/markdown/framework/release-boundary.md.txt +9 -10
  615. package/dist/templates/markdown/framework/retrieval-daily-guide.md.txt +1 -1
  616. package/dist/templates/pactile/CONTEXT.md +48 -36
  617. package/dist/templates/pactile/modules/approval-personal/contract.md +12 -24
  618. package/dist/templates/pactile/modules/close-basic/contract.md +15 -18
  619. package/dist/templates/pactile/modules/debug-recovery/contract.md +4 -4
  620. package/dist/templates/pactile/modules/define-basic/contract.md +15 -19
  621. package/dist/templates/pactile/modules/define-extended/contract.md +3 -3
  622. package/dist/templates/pactile/modules/execute-agent/contract.md +11 -19
  623. package/dist/templates/pactile/modules/intake-basic/contract.md +16 -13
  624. package/dist/templates/pactile/modules/verify-basic/contract.md +11 -20
  625. package/dist/templates/pactile/tasks/templates/release-execution/design.md +5 -5
  626. package/dist/templates/pactile/tasks/templates/release-readiness/design.md +6 -6
  627. package/dist/templates/pactile/tasks/templates/release-readiness/handoff-template.md +8 -2
  628. package/dist/templates/pactile/workflow.md +37 -41
  629. package/dist/templates/template-utils.d.ts +1 -2
  630. package/dist/templates/template-utils.d.ts.map +1 -1
  631. package/dist/templates/template-utils.js +2 -13
  632. package/dist/templates/template-utils.js.map +1 -1
  633. package/dist/types/ai-tools.d.ts +1 -1
  634. package/dist/types/ai-tools.js +1 -1
  635. package/dist/utils/manifest-prune.js +1 -1
  636. package/dist/utils/manifest-prune.js.map +1 -1
  637. package/dist/utils/p36-upgrade.d.ts +2 -2
  638. package/dist/utils/p36-upgrade.d.ts.map +1 -1
  639. package/dist/utils/p36-upgrade.js +2 -10
  640. package/dist/utils/p36-upgrade.js.map +1 -1
  641. package/dist/utils/post-update-smoke.js +1 -1
  642. package/dist/utils/post-update-smoke.js.map +1 -1
  643. package/dist/utils/readiness.d.ts +2 -2
  644. package/dist/utils/readiness.js +2 -2
  645. package/dist/utils/uninstall-scrubbers.js +1 -1
  646. package/dist/utils/workflow-dir.d.ts +1 -1
  647. package/dist/utils/workflow-dir.d.ts.map +1 -1
  648. package/dist/utils/workflow-dir.js +1 -1
  649. package/dist/utils/workflow-dir.js.map +1 -1
  650. package/package.json +42 -37
  651. package/CHANGELOG.md +0 -651
  652. package/bin/compat-warning.js +0 -11
  653. package/bin/pactile.js +0 -3
  654. package/bin/smart-search.js +0 -38
  655. package/dist/migrations/manifests/0.1.0.json +0 -9
  656. package/dist/migrations/manifests/0.1.1.json +0 -9
  657. package/dist/migrations/manifests/0.1.2.json +0 -9
  658. package/dist/migrations/manifests/0.1.3.json +0 -9
  659. package/dist/migrations/manifests/0.1.4.json +0 -9
  660. package/dist/migrations/manifests/0.2.1.json +0 -9
  661. package/dist/migrations/manifests/0.2.10.json +0 -374
  662. package/dist/migrations/manifests/0.2.2.json +0 -9
  663. package/dist/migrations/manifests/0.2.3.json +0 -9
  664. package/dist/migrations/manifests/0.2.4.json +0 -9
  665. package/dist/migrations/manifests/0.2.5.json +0 -9
  666. package/dist/migrations/manifests/0.2.6.json +0 -9
  667. package/dist/migrations/manifests/0.2.7.json +0 -9
  668. package/dist/migrations/manifests/0.2.8.json +0 -9
  669. package/dist/migrations/manifests/0.2.9.json +0 -9
  670. package/dist/migrations/manifests/0.3.0.json +0 -89
  671. package/dist/migrations/manifests/0.3.1.json +0 -32
  672. package/dist/migrations/manifests/0.3.2.json +0 -16
  673. package/dist/migrations/manifests/0.3.3.json +0 -9
  674. package/dist/migrations/manifests/0.3.4.json +0 -9
  675. package/dist/migrations/manifests/0.3.5.json +0 -9
  676. package/dist/migrations/manifests/0.3.6.json +0 -9
  677. package/dist/migrations/manifests/0.4.0.json +0 -9
  678. package/dist/migrations/manifests/0.4.1.json +0 -9
  679. package/dist/migrations/manifests/0.4.2.json +0 -9
  680. package/dist/migrations/manifests/0.4.3.json +0 -9
  681. package/dist/migrations/manifests/0.5.0-beta.0.json +0 -9
  682. package/dist/migrations/manifests/0.5.0-beta.1.json +0 -9
  683. package/dist/migrations/manifests/0.5.0-beta.2.json +0 -9
  684. package/dist/migrations/manifests/0.5.0-beta.3.json +0 -9
  685. package/dist/migrations/manifests/0.5.0-beta.4.json +0 -9
  686. package/dist/migrations/manifests/0.5.0-beta.5.json +0 -9
  687. package/dist/migrations/manifests/0.5.0.json +0 -9
  688. package/dist/pactile/compat/retired-alternate-client.d.ts +0 -42
  689. package/dist/pactile/compat/retired-alternate-client.d.ts.map +0 -1
  690. package/dist/pactile/compat/retired-alternate-client.js +0 -153
  691. package/dist/pactile/compat/retired-alternate-client.js.map +0 -1
  692. package/dist/pactile/compat/update-residue.d.ts +0 -4
  693. package/dist/pactile/compat/update-residue.d.ts.map +0 -1
  694. package/dist/pactile/compat/update-residue.js +0 -55
  695. package/dist/pactile/compat/update-residue.js.map +0 -1
  696. package/dist/utils/cursor-retrieval-env.d.ts +0 -17
  697. package/dist/utils/cursor-retrieval-env.d.ts.map +0 -1
  698. package/dist/utils/cursor-retrieval-env.js +0 -19
  699. package/dist/utils/cursor-retrieval-env.js.map +0 -1
  700. package/dist/utils/proxy.d.ts +0 -25
  701. package/dist/utils/proxy.d.ts.map +0 -1
  702. package/dist/utils/proxy.js +0 -60
  703. package/dist/utils/proxy.js.map +0 -1
  704. package/scripts/postinstall.js +0 -6
@@ -1,27 +1,54 @@
1
1
  import { execFileSync, execSync } from "node:child_process";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
- import { applyKernelArchive, applyKernelCreate, applyKernelPatch, applyKernelRecordGate, applyKernelStart, assertFullQualityForPhase, buildAcEvidenceLedger, emptyTaskRecord, parseAcceptanceItems, qualityFingerprint, readDependencyGraph, readKernel, readTopology, resolveRequiredControls, unmetRequires } from "../core/task/index.js";
5
- import { addContextEntry, CONTEXT_FILES, readContextEntries, validateContextFile } from "../pactile/task/context.js";
4
+ import { addTaskDependency, applyKernelArchive, applyKernelPatch, applyKernelRecordGate, applyKernelStart, assertFullQualityForPhase, buildAcEvidenceLedger, checkTaskClose, closeTaskKernel, createTaskKernel, emptyTaskRecord, fingerprintTaskValue, isTaskDeliveryLevel, listTaskKernelSnapshots, parseAcceptanceItems, qualityFingerprint, readDependencyGraph, readKernel, readTaskKernel, readTopology, recordTaskReview, recordTaskRunResult, resolveRequiredControls, startTaskRun, taskRecordSchema, unmetRequires, } from "../core/task/index.js";
5
+ import { createTaskCandidateEntry, isRunCandidateObservationEntry, observeTaskRunCandidate, } from "../core/task/task-candidate-observer.js";
6
+ import { addContextEntry, CONTEXT_FILES, readContextEntries, validateContextFile, } from "../pactile/task/context.js";
7
+ import * as piBridge from "../pactile/pi/bridge.js";
8
+ import { approvedExecuteTask } from "../pactile/task/authorization.js";
9
+ import { createTaskWithArtifacts } from "../pactile/task/creation.js";
6
10
  import { readPactileConfig } from "../pactile/task/config.js";
7
- import { checkArchive, checkStartExecution, dependencyStatus } from "../pactile/task/guards.js";
8
- import { exitTask, resolveSelectedTask, resolveTaskDir, selectTask } from "../pactile/task/session.js";
9
- import { artifactFingerprint, contractFingerprint, currentGateErrors, readStrategyContract, requiredGates } from "../pactile/task/strategy.js";
10
- import { CHILD_STATES, childStateErrors, ensureTaskMap, readTaskMap, writeTaskMap } from "../pactile/task/task-map.js";
11
+ import { resumeTaskRunWithCoordinationBarrier } from "../pactile/coordination/index.js";
12
+ import { runTaskScheduleCli, runTaskScheduleCliAsync, runTaskScheduleDispatchCli, } from "./task-schedule.js";
13
+ import { checkArchive, checkStartExecution, dependencyStatus, } from "../pactile/task/guards.js";
14
+ import { exitTask, resolveSelectedTask, resolveTaskDir, selectTask, } from "../pactile/task/session.js";
15
+ import { artifactFingerprint, contractFingerprint, currentGateErrors, readStrategyContract, requiredGates, } from "../pactile/task/strategy.js";
16
+ import { CHILD_STATES, childStateErrors, ensureTaskMap, readTaskMap, writeTaskMap, } from "../pactile/task/task-map.js";
11
17
  import { readDeveloper } from "../utils/developer.js";
12
18
  import { sameGitRoot } from "../utils/git-root.js";
13
19
  import { localDate } from "../utils/local-date.js";
14
20
  import { getAllTaskTemplates } from "../templates/pactile/index.js";
15
- import { learningScaffold, prepareArchiveEvidence } from "../pactile/task/scaffold.js";
21
+ import { learningScaffold, prepareArchiveEvidence, } from "../pactile/task/scaffold.js";
22
+ import { listLegacyTaskImportRecords, readLegacyTaskImportRecord, } from "../core/task/legacy-task-migration-reader.js";
23
+ import { TASK_ARTIFACT_STAGES_V1, projectTaskArtifactsForAgentV1, projectTaskArtifactsForHumanV1, projectTaskKernelArtifactsV1, readSelectedTaskArtifactDocumentSectionsV1, readSelectedTaskArtifactDocumentsV1, readSelectedTaskArtifactSourcesV1, readTaskArtifactDocumentIndexV1, renderTaskPrdScaffoldV1, } from "../pactile/artifacts/index.js";
16
24
  function option(args, name) {
17
25
  const index = args.indexOf(name);
18
26
  return index >= 0 ? args[index + 1] : undefined;
19
27
  }
28
+ function options(args, name) {
29
+ const values = [];
30
+ for (let index = 0; index < args.length; index++) {
31
+ if (args[index] !== name)
32
+ continue;
33
+ const value = args[index + 1];
34
+ if (!value || value.startsWith("--"))
35
+ throw new Error(`${name} requires a value`);
36
+ values.push(value);
37
+ index++;
38
+ }
39
+ return values;
40
+ }
20
41
  function requireArgument(value, label) {
21
42
  if (!value || value.startsWith("--"))
22
43
  throw new Error(`${label} is required`);
23
44
  return value;
24
45
  }
46
+ function requireLast(values, label) {
47
+ const value = values.at(-1);
48
+ if (value === undefined)
49
+ throw new Error(`${label} was not recorded`);
50
+ return value;
51
+ }
25
52
  function taskDir(root, reference) {
26
53
  const dir = resolveTaskDir(root, reference);
27
54
  if (!fs.statSync(dir, { throwIfNoEntry: false })?.isDirectory())
@@ -31,7 +58,11 @@ function taskDir(root, reference) {
31
58
  function taskRecord(dir) {
32
59
  try {
33
60
  const value = JSON.parse(fs.readFileSync(path.join(dir, "task.json"), "utf8"));
34
- return value && typeof value === "object" ? value : null;
61
+ const parsed = taskRecordSchema.safeParse(value);
62
+ // Keep the validated source object intact. Legacy task.json files may carry
63
+ // fields outside the current schema; stripping them here changes V1
64
+ // dependency/quality behavior when subsequent commands patch the record.
65
+ return parsed.success ? value : null;
35
66
  }
36
67
  catch {
37
68
  return null;
@@ -39,14 +70,22 @@ function taskRecord(dir) {
39
70
  }
40
71
  function runTaskHooks(root, event, taskJson) {
41
72
  const hooks = readPactileConfig(root).hooks;
42
- const entries = hooks && typeof hooks === "object" && !Array.isArray(hooks) ? hooks[event] : undefined;
73
+ const entries = hooks && typeof hooks === "object" && !Array.isArray(hooks)
74
+ ? hooks[event]
75
+ : undefined;
43
76
  if (!Array.isArray(entries))
44
77
  return;
45
78
  for (const command of entries) {
46
79
  if (typeof command !== "string" || !command.trim())
47
80
  continue;
48
81
  try {
49
- execSync(command, { cwd: root, env: { ...process.env, TASK_JSON_PATH: taskJson }, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], timeout: 60_000 });
82
+ execSync(command, {
83
+ cwd: root,
84
+ env: { ...process.env, TASK_JSON_PATH: taskJson },
85
+ encoding: "utf8",
86
+ stdio: ["ignore", "pipe", "pipe"],
87
+ timeout: 60_000,
88
+ });
50
89
  }
51
90
  catch (error) {
52
91
  console.warn(`[WARN] Hook failed (${event}): ${command} — ${error instanceof Error ? error.message : String(error)}`);
@@ -73,9 +112,16 @@ function activeTasks(root) {
73
112
  const tasks = path.join(root, ".pactile", "tasks");
74
113
  if (!fs.existsSync(tasks))
75
114
  return [];
76
- return fs.readdirSync(tasks, { withFileTypes: true })
77
- .filter((entry) => entry.isDirectory() && entry.name !== "archive" && entry.name !== "locale" && entry.name !== "templates")
78
- .map((entry) => ({ dir: entry.name, record: taskRecord(path.join(tasks, entry.name)) }))
115
+ return fs
116
+ .readdirSync(tasks, { withFileTypes: true })
117
+ .filter((entry) => entry.isDirectory() &&
118
+ entry.name !== "archive" &&
119
+ entry.name !== "locale" &&
120
+ entry.name !== "templates")
121
+ .map((entry) => ({
122
+ dir: entry.name,
123
+ record: taskRecord(path.join(tasks, entry.name)),
124
+ }))
79
125
  .filter((item) => item.record !== null)
80
126
  .sort((left, right) => left.dir.localeCompare(right.dir));
81
127
  }
@@ -93,9 +139,597 @@ function verifySeed(taskLocale) {
93
139
  ? "# 验证证据\n\n## Planning check\n\n_可选(Full 任务)— 记录规划阶段审查结果。_\n\n## Execution evidence\n\n### Validation commands\n\n<!-- 示例:Validation commands: <命令> — <结果> -->\n\n### Acceptance\n\n<!-- 示例:Final acceptance evidence: <验收标准达成说明> -->\n\n### Durable learning\n\n<!-- 示例:Durable learning decision: no durable learning -->\n"
94
140
  : "# Verification Evidence\n\n## Planning check\n\n_Optional for Full tasks — record planning review outcomes._\n\n## Execution evidence\n\n### Validation commands\n\n<!-- Example: Validation commands: <command> — <outcome> -->\n\n### Acceptance\n\n<!-- Example: Final acceptance evidence: <criteria met> -->\n\n### Durable learning\n\n<!-- Example: Durable learning decision: no durable learning -->\n";
95
141
  }
142
+ function parseAcceptanceCriteria(args) {
143
+ const raw = options(args, "--accept");
144
+ if (!raw.length)
145
+ throw new Error("at least one --accept <criterion> is required");
146
+ const parsed = raw.map((value, index) => {
147
+ const separator = value.indexOf("=");
148
+ if (separator > 0)
149
+ return {
150
+ id: value.slice(0, separator).trim(),
151
+ description: value.slice(separator + 1).trim(),
152
+ };
153
+ return { id: `AC-${index + 1}`, description: value.trim() };
154
+ });
155
+ if (parsed.some((item) => !item.id || !item.description))
156
+ throw new Error("--accept must be <criterion> or <id>=<criterion>");
157
+ return parsed;
158
+ }
159
+ function taskV2(root, reference) {
160
+ const dir = taskDir(root, reference);
161
+ const result = readTaskKernel({ root, taskDir: dir, cwd: root });
162
+ if (result.kind !== "task-kernel-v2")
163
+ throw new Error(`Task ${reference} uses legacy Kernel v1. It remains readable; automatic migration is reserved for P36.`);
164
+ return { dir, kernel: result.kernel };
165
+ }
166
+ function parseTaskArtifactDocumentSelection(value) {
167
+ const separator = value.lastIndexOf("@");
168
+ if (separator <= 0 || separator === value.length - 1) {
169
+ throw new Error("--document must be <document-id>@<sha256-fingerprint|absent> copied from a current artifact index");
170
+ }
171
+ const id = value.slice(0, separator);
172
+ const expectedFingerprint = value.slice(separator + 1);
173
+ if (expectedFingerprint !== "absent" &&
174
+ !/^sha256:[a-f0-9]{64}$/u.test(expectedFingerprint)) {
175
+ throw new Error("--document fingerprint must be a lowercase sha256 digest or absent");
176
+ }
177
+ return { id, expectedFingerprint };
178
+ }
179
+ function parseTaskArtifactSectionSelection(value) {
180
+ const separator = value.lastIndexOf("@");
181
+ if (separator <= 0 || separator === value.length - 1) {
182
+ throw new Error("--section must be <section-id>@<sha256-fingerprint> copied from a current artifact index");
183
+ }
184
+ const id = value.slice(0, separator);
185
+ const expectedFingerprint = value.slice(separator + 1);
186
+ if (!id.startsWith("section:") ||
187
+ !/^sha256:[a-f0-9]{64}$/u.test(expectedFingerprint)) {
188
+ throw new Error("--section requires a stable section ID and lowercase sha256 fingerprint");
189
+ }
190
+ return { id, expectedFingerprint };
191
+ }
192
+ function taskArtifacts(root, args) {
193
+ const reference = requireArgument(args[0], "task");
194
+ const { dir, kernel } = taskV2(root, reference);
195
+ const requestedStages = [...new Set(options(args, "--stage"))].map((value) => {
196
+ if (!TASK_ARTIFACT_STAGES_V1.includes(value)) {
197
+ throw new Error(`--stage must be one of: ${TASK_ARTIFACT_STAGES_V1.join(", ")}`);
198
+ }
199
+ return value;
200
+ });
201
+ const envelope = projectTaskKernelArtifactsV1(kernel);
202
+ const documents = readTaskArtifactDocumentIndexV1(dir, kernel.identity.taskId);
203
+ const projectionOptions = {
204
+ ...(requestedStages.length ? { stages: requestedStages } : {}),
205
+ documents,
206
+ };
207
+ const requestedFactRefs = options(args, "--fact");
208
+ const selectedFactIds = requestedFactRefs.map((reference) => {
209
+ const fact = envelope.facts.find((candidate) => candidate.id === reference ||
210
+ `${candidate.ref.uri}#${candidate.ref.selector}` === reference);
211
+ if (!fact) {
212
+ throw new Error(`Unknown task artifact fact ID or locator: ${reference}`);
213
+ }
214
+ return fact.id;
215
+ });
216
+ const selectedDocuments = options(args, "--document").map(parseTaskArtifactDocumentSelection);
217
+ const selectedSections = options(args, "--section").map(parseTaskArtifactSectionSelection);
218
+ const agent = args.includes("--agent");
219
+ if (selectedDocuments.length) {
220
+ const visibleDocumentIds = new Set(requestedStages.length
221
+ ? documents
222
+ .filter((document) => requestedStages.includes(document.stage))
223
+ .map(({ id }) => id)
224
+ : documents.map(({ id }) => id));
225
+ const outsideStage = selectedDocuments.find(({ id }) => !visibleDocumentIds.has(id));
226
+ if (outsideStage) {
227
+ throw new Error(`Task artifact document '${outsideStage.id}' is not present in the requested stage view`);
228
+ }
229
+ }
230
+ const selectedDocumentContents = selectedDocuments.length
231
+ ? readSelectedTaskArtifactDocumentsV1(dir, kernel.identity.taskId, selectedDocuments)
232
+ : undefined;
233
+ if (selectedSections.length) {
234
+ const visibleSectionIds = new Set(documents
235
+ .filter((document) => !requestedStages.length || requestedStages.includes(document.stage))
236
+ .flatMap((document) => (document.sections ?? []).map(({ id }) => id)));
237
+ const outsideStage = selectedSections.find(({ id }) => !visibleSectionIds.has(id));
238
+ if (outsideStage) {
239
+ throw new Error(`Task artifact document section '${outsideStage.id}' is not present in the requested stage view`);
240
+ }
241
+ }
242
+ const selectedSectionContents = selectedSections.length
243
+ ? readSelectedTaskArtifactDocumentSectionsV1(dir, kernel.identity.taskId, selectedSections)
244
+ : undefined;
245
+ if (selectedFactIds.length) {
246
+ const visibleFactIds = new Set(requestedStages.length
247
+ ? requestedStages.flatMap((stage) => envelope.stageRefs[stage] ?? [])
248
+ : envelope.facts.map((fact) => fact.id));
249
+ const outsideStage = selectedFactIds.find((id) => !visibleFactIds.has(id));
250
+ if (outsideStage) {
251
+ throw new Error(`Task artifact fact '${outsideStage}' is not present in the requested stage view`);
252
+ }
253
+ const selectedSources = readSelectedTaskArtifactSourcesV1(kernel, envelope, selectedFactIds);
254
+ if (agent) {
255
+ console.log(JSON.stringify({
256
+ index: projectTaskArtifactsForAgentV1(envelope, projectionOptions),
257
+ selectedSources,
258
+ ...(selectedDocumentContents
259
+ ? { selectedDocuments: selectedDocumentContents }
260
+ : {}),
261
+ ...(selectedSectionContents
262
+ ? { selectedSections: selectedSectionContents }
263
+ : {}),
264
+ }, null, 2));
265
+ }
266
+ else {
267
+ console.log(JSON.stringify({
268
+ taskId: kernel.identity.taskId,
269
+ selectedSources,
270
+ ...(selectedDocumentContents
271
+ ? { selectedDocuments: selectedDocumentContents }
272
+ : {}),
273
+ ...(selectedSectionContents
274
+ ? { selectedSections: selectedSectionContents }
275
+ : {}),
276
+ }, null, 2));
277
+ }
278
+ return 0;
279
+ }
280
+ if (selectedDocumentContents || selectedSectionContents) {
281
+ console.log(JSON.stringify({
282
+ ...(agent
283
+ ? {
284
+ index: projectTaskArtifactsForAgentV1(envelope, projectionOptions),
285
+ }
286
+ : { taskId: kernel.identity.taskId }),
287
+ ...(selectedDocumentContents
288
+ ? { selectedDocuments: selectedDocumentContents }
289
+ : {}),
290
+ ...(selectedSectionContents
291
+ ? { selectedSections: selectedSectionContents }
292
+ : {}),
293
+ }, null, 2));
294
+ return 0;
295
+ }
296
+ if (agent) {
297
+ console.log(JSON.stringify(projectTaskArtifactsForAgentV1(envelope, projectionOptions), null, 2));
298
+ }
299
+ else {
300
+ console.log(projectTaskArtifactsForHumanV1(envelope, projectionOptions));
301
+ }
302
+ return 0;
303
+ }
304
+ function actor(root, args) {
305
+ return option(args, "--actor") ?? readDeveloper(root) ?? "user";
306
+ }
96
307
  function createTask(args, root) {
308
+ if (args.includes("--legacy")) {
309
+ createLegacyTask(args.filter((value) => value !== "--legacy"), root);
310
+ return;
311
+ }
312
+ if (args.includes("--rigor") || args.includes("--parent")) {
313
+ throw new Error("--rigor and --parent are legacy task presets. Use `pactile task legacy-create --legacy` for existing 0.5.x workflows, or create a Task with --deliverable, --delivery-level, and --accept.");
314
+ }
97
315
  const title = requireArgument(args[0], "title");
98
- const slug = (option(args, "--slug") ?? title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, ""));
316
+ const slug = option(args, "--slug") ??
317
+ title
318
+ .toLowerCase()
319
+ .replace(/[^a-z0-9]+/g, "-")
320
+ .replace(/^-|-$/g, "");
321
+ if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(slug))
322
+ throw new Error("slug must contain lowercase letters, digits and hyphens");
323
+ const deliverable = requireArgument(option(args, "--deliverable"), "--deliverable");
324
+ const deliveryLevel = option(args, "--delivery-level");
325
+ if (!isTaskDeliveryLevel(deliveryLevel))
326
+ throw new Error("--delivery-level must be local-result, pull-request, merged-result, or documentation");
327
+ const dependencies = [...new Set(options(args, "--depends-on"))];
328
+ const directoryName = `${localDate(new Date()).slice(5)}-${slug}`;
329
+ const dir = path.resolve(root, ".pactile", "tasks", directoryName);
330
+ const result = createTaskKernel({
331
+ root,
332
+ taskDir: dir,
333
+ actor: actor(root, args),
334
+ idempotencyKey: option(args, "--idempotency-key") ?? `task-create:${slug}`,
335
+ definition: {
336
+ taskId: slug,
337
+ title,
338
+ description: option(args, "--description") ?? "",
339
+ deliverable,
340
+ deliveryLevel,
341
+ acceptanceCriteria: parseAcceptanceCriteria(args),
342
+ dependencies,
343
+ },
344
+ });
345
+ if (!result.idempotent) {
346
+ const prdPath = path.join(dir, "prd.md");
347
+ if (!fs.existsSync(prdPath)) {
348
+ try {
349
+ fs.writeFileSync(prdPath, renderTaskPrdScaffoldV1(result.kernel), {
350
+ encoding: "utf8",
351
+ flag: "wx",
352
+ });
353
+ }
354
+ catch (error) {
355
+ if (!(error instanceof Error) ||
356
+ !("code" in error) ||
357
+ error.code !== "EEXIST")
358
+ throw error;
359
+ }
360
+ }
361
+ }
362
+ console.log(`${path.relative(root, dir).replaceAll("\\", "/")}\nTask Kernel schema: ${result.kernel.schemaVersion}\nTask ID: ${result.kernel.identity.taskId}\nPRD: ${path.relative(root, path.join(dir, "prd.md")).replaceAll("\\", "/")}\nLive fact view: pactile task artifacts ${result.kernel.identity.taskId}`);
363
+ }
364
+ function runStartTask(root, args) {
365
+ const reference = requireArgument(args[0], "task");
366
+ const { dir, kernel } = taskV2(root, reference);
367
+ const authorization = {
368
+ approvedBy: requireArgument(option(args, "--approved-by"), "--approved-by"),
369
+ approvedAt: option(args, "--approved-at") ?? new Date().toISOString(),
370
+ scope: requireArgument(option(args, "--authorization-scope"), "--authorization-scope"),
371
+ evidenceRef: requireArgument(option(args, "--authorization-evidence"), "--authorization-evidence"),
372
+ };
373
+ const workspaceInputs = ["--workspace-path", "--branch", "--base-sha"].some((flag) => args.includes(flag));
374
+ const taskActor = actor(root, args);
375
+ let workspace;
376
+ if (workspaceInputs) {
377
+ workspace = {
378
+ canonicalPath: requireArgument(option(args, "--workspace-path"), "--workspace-path"),
379
+ branch: requireArgument(option(args, "--branch"), "--branch"),
380
+ baseSha: requireArgument(option(args, "--base-sha"), "--base-sha"),
381
+ writeSet: options(args, "--write-set"),
382
+ integrationState: "not-integrated",
383
+ reclamationState: "not-requested",
384
+ };
385
+ }
386
+ const hostInputs = [
387
+ "--host",
388
+ "--role",
389
+ "--session-id",
390
+ "--thread-id",
391
+ "--request-ref",
392
+ "--event-ref",
393
+ "--result-ref",
394
+ "--assurance-source",
395
+ ].some((flag) => args.includes(flag));
396
+ let host;
397
+ if (hostInputs) {
398
+ host = {
399
+ host: requireArgument(option(args, "--host"), "--host"),
400
+ role: requireArgument(option(args, "--role"), "--role"),
401
+ sessionId: option(args, "--session-id") ?? null,
402
+ threadId: option(args, "--thread-id") ?? null,
403
+ requestRefs: options(args, "--request-ref"),
404
+ eventRefs: options(args, "--event-ref"),
405
+ resultRefs: options(args, "--result-ref"),
406
+ assuranceSource: option(args, "--assurance-source") ?? null,
407
+ };
408
+ }
409
+ const durationOption = (name) => {
410
+ const value = option(args, name);
411
+ if (value === undefined)
412
+ return null;
413
+ const parsed = Number(value);
414
+ if (!Number.isSafeInteger(parsed) || parsed < 0)
415
+ throw new Error(`${name} must be a non-negative integer`);
416
+ return parsed;
417
+ };
418
+ const input = {
419
+ summary: requireArgument(option(args, "--input-summary"), "--input-summary"),
420
+ references: options(args, "--input-ref"),
421
+ };
422
+ const initialState = args.includes("--wait")
423
+ ? "waiting"
424
+ : "running";
425
+ const writeSetSnapshot = args.includes("--write-set-snapshot")
426
+ ? options(args, "--write-set-snapshot")
427
+ : options(args, "--write-set");
428
+ const estimatedDurations = {
429
+ executionMs: durationOption("--estimate-execution-ms"),
430
+ waitingMs: durationOption("--estimate-waiting-ms"),
431
+ reviewMs: durationOption("--estimate-review-ms"),
432
+ };
433
+ const requestFingerprint = fingerprintTaskValue({
434
+ actor: taskActor,
435
+ input,
436
+ authorization: {
437
+ approvedBy: authorization.approvedBy,
438
+ scope: authorization.scope,
439
+ evidenceRef: authorization.evidenceRef,
440
+ },
441
+ initialState,
442
+ writeSetSnapshot,
443
+ estimatedDurations,
444
+ workspace: workspace ?? null,
445
+ host: host ?? null,
446
+ });
447
+ const activeRun = kernel.runs.find((run) => run.state === "running" || run.state === "waiting");
448
+ const attempt = activeRun?.attempt ?? kernel.runs.length + 1;
449
+ const idempotencyKey = option(args, "--idempotency-key") ??
450
+ `run-start:${kernel.identity.taskId}:${attempt}:${requestFingerprint}`;
451
+ const priorStart = kernel.events.find((event) => event.idempotencyKey === idempotencyKey &&
452
+ (event.type === "run.started" || event.type === "run.queued"));
453
+ const priorRun = priorStart
454
+ ? kernel.runs.find((run) => run.id === priorStart.entityId)
455
+ : undefined;
456
+ if (!option(args, "--approved-at") && priorRun)
457
+ authorization.approvedAt = priorRun.authorization.approvedAt;
458
+ const result = startTaskRun({
459
+ root,
460
+ taskDir: dir,
461
+ expectedRevision: kernel.revision,
462
+ actor: taskActor,
463
+ idempotencyKey,
464
+ input,
465
+ initialState,
466
+ writeSetSnapshot,
467
+ estimatedDurations,
468
+ authorization,
469
+ ...(workspace ? { workspace } : {}),
470
+ ...(host ? { host } : {}),
471
+ });
472
+ const run = requireLast(result.kernel.runs, "Run");
473
+ console.log(`Run ${run.state === "waiting" ? "queued" : "started"}: ${run.id}\nTask: ${run.taskId}\nAttempt: ${run.attempt}\nKernel revision: ${result.kernel.revision}`);
474
+ return 0;
475
+ }
476
+ function resumeTask(root, args) {
477
+ const reference = requireArgument(args[0], "task");
478
+ const runId = requireArgument(args[1], "run ID");
479
+ const { dir, kernel } = taskV2(root, reference);
480
+ const result = resumeTaskRunWithCoordinationBarrier({
481
+ root,
482
+ taskDir: dir,
483
+ expectedRevision: kernel.revision,
484
+ runId,
485
+ actor: actor(root, args),
486
+ idempotencyKey: option(args, "--idempotency-key") ?? `run-resume:${runId}`,
487
+ });
488
+ console.log(`Run resumed: ${runId}\nKernel revision: ${result.kernel.revision}`);
489
+ return 0;
490
+ }
491
+ function parseCandidateEntries(args) {
492
+ return options(args, "--candidate").map((value) => {
493
+ const separator = value.lastIndexOf("=");
494
+ if (separator <= 0)
495
+ throw new Error("--candidate must be <reference>=<sha256-fingerprint>");
496
+ return {
497
+ ref: value.slice(0, separator),
498
+ fingerprint: value.slice(separator + 1),
499
+ };
500
+ });
501
+ }
502
+ function runResultTask(root, args) {
503
+ const reference = requireArgument(args[0], "task");
504
+ const runId = requireArgument(args[1], "run ID");
505
+ const { dir, kernel } = taskV2(root, reference);
506
+ const outcome = requireArgument(option(args, "--outcome"), "--outcome");
507
+ if (outcome !== "completed" && outcome !== "failed" && outcome !== "blocked")
508
+ throw new Error("--outcome must be completed, failed, or blocked");
509
+ const failure = outcome === "completed"
510
+ ? undefined
511
+ : {
512
+ category: requireArgument(option(args, "--failure-category"), "--failure-category"),
513
+ message: requireArgument(option(args, "--failure-message"), "--failure-message"),
514
+ ...(option(args, "--failure-evidence")
515
+ ? { evidenceRef: option(args, "--failure-evidence") }
516
+ : {}),
517
+ };
518
+ let candidateEntries = [];
519
+ let evidenceRefs = options(args, "--evidence");
520
+ let executionMeasurementRef = option(args, "--execution-measurement-ref");
521
+ if (outcome === "completed") {
522
+ const run = kernel.runs.find((item) => item.id === runId);
523
+ if (!run)
524
+ throw new Error(`Run ${runId} does not exist on Task ${kernel.identity.taskId}`);
525
+ const candidateInputs = parseCandidateEntries(args);
526
+ if (candidateInputs.some((entry) => isRunCandidateObservationEntry(entry.ref))) {
527
+ throw new Error("--candidate cannot set a reserved P41 machine-observation reference");
528
+ }
529
+ const piBound = run.host?.host === "pi";
530
+ const hostEvidenceRefs = run.host
531
+ ? [
532
+ ...run.host.requestRefs,
533
+ ...run.host.eventRefs,
534
+ ...run.host.resultRefs,
535
+ ]
536
+ : [];
537
+ if (!piBound &&
538
+ hostEvidenceRefs.some((reference) => reference.replaceAll("\\", "/").startsWith("pi-bridge/"))) {
539
+ throw new Error("Pi evidence references cannot complete a Run bound to another host");
540
+ }
541
+ let piEvidence = null;
542
+ if (piBound) {
543
+ if (run.host?.role !== "implement" ||
544
+ run.host.assuranceSource !== "manager-owned-child-exit") {
545
+ throw new Error("Pi Run completion requires implement role and manager-owned-child-exit assurance");
546
+ }
547
+ piEvidence = piBridge.readPiTaskRunEvidence(root, dir, runId);
548
+ if (!piEvidence) {
549
+ throw new Error("Pi Run has no valid settled host-stop and persisted result receipt; it cannot be recorded completed");
550
+ }
551
+ if (piEvidence.taskRunId !== run.id ||
552
+ piEvidence.taskId !== run.taskId ||
553
+ piEvidence.outcome !== "settled" ||
554
+ piEvidence.assurance !== "manager-owned-child-exit") {
555
+ throw new Error("Pi success evidence does not match the selected Task Run binding");
556
+ }
557
+ const suppliedMeasurement = executionMeasurementRef;
558
+ if (suppliedMeasurement &&
559
+ suppliedMeasurement !== piEvidence.executionMeasurementRef) {
560
+ throw new Error("--execution-measurement-ref conflicts with the verified Pi Run receipt");
561
+ }
562
+ executionMeasurementRef = piEvidence.executionMeasurementRef;
563
+ evidenceRefs = [
564
+ ...new Set([...evidenceRefs, ...piEvidence.evidenceRefs]),
565
+ ];
566
+ }
567
+ const runObservation = observeTaskRunCandidate({
568
+ run,
569
+ ...(run.workspace === null ? { repositoryRoot: root } : {}),
570
+ });
571
+ candidateEntries = [
572
+ ...candidateInputs,
573
+ createTaskCandidateEntry(runObservation),
574
+ ];
575
+ }
576
+ const result = recordTaskRunResult({
577
+ root,
578
+ taskDir: dir,
579
+ expectedRevision: kernel.revision,
580
+ runId,
581
+ outcome,
582
+ ...(option(args, "--summary")
583
+ ? { summary: option(args, "--summary") }
584
+ : {}),
585
+ evidenceRefs,
586
+ candidateEntries,
587
+ failure,
588
+ measurementRefs: {
589
+ ...(executionMeasurementRef
590
+ ? { execution: executionMeasurementRef }
591
+ : {}),
592
+ ...(option(args, "--waiting-measurement-ref")
593
+ ? { waiting: option(args, "--waiting-measurement-ref") }
594
+ : {}),
595
+ },
596
+ actor: actor(root, args),
597
+ idempotencyKey: option(args, "--idempotency-key") ?? `run-result:${runId}`,
598
+ });
599
+ console.log(`Run ${runId}: ${outcome}\nTask phase: ${result.kernel.phase}\nKernel revision: ${result.kernel.revision}`);
600
+ return 0;
601
+ }
602
+ function parseAcceptanceEvidenceArgs(args) {
603
+ const result = {};
604
+ for (const item of options(args, "--criterion")) {
605
+ const separator = item.indexOf("=");
606
+ if (separator <= 0 || separator === item.length - 1)
607
+ throw new Error("--criterion must be <criterion-id>=<evidence-reference>");
608
+ const id = item.slice(0, separator);
609
+ if (Object.prototype.hasOwnProperty.call(result, id))
610
+ result[id]?.push(item.slice(separator + 1));
611
+ else
612
+ Object.defineProperty(result, id, {
613
+ value: [item.slice(separator + 1)],
614
+ enumerable: true,
615
+ writable: true,
616
+ configurable: true,
617
+ });
618
+ }
619
+ return result;
620
+ }
621
+ function reviewTask(root, args) {
622
+ const reference = requireArgument(args[0], "task");
623
+ const { dir, kernel } = taskV2(root, reference);
624
+ const runId = requireArgument(option(args, "--run"), "--run");
625
+ const decision = requireArgument(option(args, "--decision"), "--decision");
626
+ if (decision !== "pass" &&
627
+ decision !== "fail" &&
628
+ decision !== "needs-changes")
629
+ throw new Error("--decision must be pass, fail, or needs-changes");
630
+ const candidateSnapshotId = requireArgument(option(args, "--candidate-id"), "--candidate-id");
631
+ const candidateFingerprint = requireArgument(option(args, "--candidate-fingerprint"), "--candidate-fingerprint");
632
+ const reviewer = requireArgument(option(args, "--reviewer"), "--reviewer");
633
+ const evidenceRefs = options(args, "--evidence");
634
+ const acceptanceEvidence = parseAcceptanceEvidenceArgs(args);
635
+ const unresolvedBlockers = options(args, "--blocker");
636
+ const measurementRef = option(args, "--review-measurement-ref");
637
+ const taskActor = actor(root, args);
638
+ const idempotencyKey = option(args, "--idempotency-key") ??
639
+ `review:${runId}:${fingerprintTaskValue({
640
+ actor: taskActor,
641
+ runId,
642
+ candidateSnapshotId,
643
+ candidateFingerprint,
644
+ reviewer,
645
+ decision,
646
+ evidenceRefs,
647
+ acceptanceEvidence,
648
+ unresolvedBlockers,
649
+ measurementRef: measurementRef ?? null,
650
+ })}`;
651
+ const result = recordTaskReview({
652
+ root,
653
+ taskDir: dir,
654
+ expectedRevision: kernel.revision,
655
+ runId,
656
+ candidateSnapshotId,
657
+ candidateFingerprint,
658
+ reviewer,
659
+ decision,
660
+ evidenceRefs,
661
+ acceptanceEvidence,
662
+ unresolvedBlockers,
663
+ measurementRef,
664
+ actor: taskActor,
665
+ idempotencyKey,
666
+ });
667
+ const review = requireLast(result.kernel.reviews, "Review");
668
+ console.log(`Review recorded: ${review.id}\nDecision: ${review.decision}\nCandidate: ${review.candidateFingerprint}`);
669
+ return 0;
670
+ }
671
+ function closeTask(root, args) {
672
+ const reference = requireArgument(args[0], "task");
673
+ const { dir, kernel } = taskV2(root, reference);
674
+ const runId = requireArgument(option(args, "--run"), "--run");
675
+ const reviewId = requireArgument(option(args, "--review"), "--review");
676
+ const deliveryEvidence = {
677
+ level: option(args, "--delivery-level"),
678
+ reference: requireArgument(option(args, "--delivery-ref"), "--delivery-ref"),
679
+ summary: requireArgument(option(args, "--delivery-summary"), "--delivery-summary"),
680
+ ...(option(args, "--delivery-path")
681
+ ? { path: option(args, "--delivery-path") }
682
+ : {}),
683
+ ...(option(args, "--target-branch")
684
+ ? { targetBranch: option(args, "--target-branch") }
685
+ : {}),
686
+ };
687
+ if (!isTaskDeliveryLevel(deliveryEvidence.level))
688
+ throw new Error("--delivery-level must be local-result, pull-request, merged-result, or documentation");
689
+ const candidateObservation = {
690
+ snapshotId: requireArgument(option(args, "--candidate-id"), "--candidate-id"),
691
+ fingerprint: requireArgument(option(args, "--candidate-fingerprint"), "--candidate-fingerprint"),
692
+ observedBy: requireArgument(option(args, "--candidate-observed-by"), "--candidate-observed-by"),
693
+ observedAt: option(args, "--candidate-observed-at") ?? new Date().toISOString(),
694
+ source: requireArgument(option(args, "--candidate-observation-source"), "--candidate-observation-source"),
695
+ evidenceRef: requireArgument(option(args, "--candidate-observation-ref"), "--candidate-observation-ref"),
696
+ };
697
+ if (args.includes("--check")) {
698
+ const errors = checkTaskClose({
699
+ root,
700
+ taskDir: dir,
701
+ expectedRevision: kernel.revision,
702
+ runId,
703
+ reviewId,
704
+ candidateObservation,
705
+ deliveryEvidence,
706
+ });
707
+ console.log(`Task Close check: ${errors.length ? "FAIL" : "PASS"}${errors.length ? `\n${errors.map((error) => ` - ${error}`).join("\n")}` : ""}`);
708
+ console.log("Candidate freshness: Close re-observes current project state against the frozen Run candidate.");
709
+ return errors.length ? 1 : 0;
710
+ }
711
+ const result = closeTaskKernel({
712
+ root,
713
+ taskDir: dir,
714
+ expectedRevision: kernel.revision,
715
+ runId,
716
+ reviewId,
717
+ candidateObservation,
718
+ deliveryEvidence,
719
+ actor: actor(root, args),
720
+ idempotencyKey: option(args, "--idempotency-key") ??
721
+ `task-close:${kernel.identity.taskId}`,
722
+ });
723
+ console.log(`Task closed: ${result.kernel.identity.taskId}\nDelivery level: ${deliveryEvidence.level}\nCandidate freshness: current project state re-observed\nDelivery evidence: machine-observed\nKernel revision: ${result.kernel.revision}`);
724
+ return 0;
725
+ }
726
+ function createLegacyTask(args, root) {
727
+ const title = requireArgument(args[0], "title");
728
+ const slug = option(args, "--slug") ??
729
+ title
730
+ .toLowerCase()
731
+ .replace(/[^a-z0-9]+/g, "-")
732
+ .replace(/^-|-$/g, "");
99
733
  if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(slug))
100
734
  throw new Error("slug must contain lowercase letters, digits and hyphens");
101
735
  const parentRef = option(args, "--parent");
@@ -117,7 +751,11 @@ function createTask(args, root) {
117
751
  if (fs.existsSync(path.join(dir, "task.json")))
118
752
  throw new Error(`Task already exists: ${dirName}`);
119
753
  const archive = path.join(tasks, "archive");
120
- if (fs.existsSync(archive) && fs.readdirSync(archive, { withFileTypes: true }).some((month) => month.isDirectory() && fs.existsSync(path.join(archive, month.name, dirName)))) {
754
+ if (fs.existsSync(archive) &&
755
+ fs
756
+ .readdirSync(archive, { withFileTypes: true })
757
+ .some((month) => month.isDirectory() &&
758
+ fs.existsSync(path.join(archive, month.name, dirName)))) {
121
759
  throw new Error(`Task already archived: ${dirName}`);
122
760
  }
123
761
  const taskLocale = locale(root);
@@ -128,20 +766,33 @@ function createTask(args, root) {
128
766
  if (!prdTemplate)
129
767
  throw new Error(`Task PRD template not found for locale ${taskLocale}`);
130
768
  const contextSeeds = fs.existsSync(path.join(root, ".codex"))
131
- ? [".pactile/spec/guides/index.md", ".pactile/framework/verification-strength-guide.md", ".pactile/framework/injection-budget-guide.md"]
132
- .filter((entry) => fs.existsSync(path.join(root, entry)))
769
+ ? [
770
+ ".pactile/spec/guides/index.md",
771
+ ".pactile/framework/verification-strength-guide.md",
772
+ ".pactile/framework/injection-budget-guide.md",
773
+ ].filter((entry) => fs.existsSync(path.join(root, entry)))
133
774
  : [];
134
775
  if (fs.existsSync(path.join(root, ".codex")) && contextSeeds.length < 2) {
135
776
  throw new Error("task create requires at least two existing spec guide paths for JSONL seed");
136
777
  }
137
778
  let baseBranch = "main";
138
779
  try {
139
- baseBranch = execFileSync("git", ["branch", "--show-current"], { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim() || "main";
780
+ baseBranch =
781
+ execFileSync("git", ["branch", "--show-current"], {
782
+ cwd: root,
783
+ encoding: "utf8",
784
+ stdio: ["ignore", "pipe", "pipe"],
785
+ }).trim() || "main";
786
+ }
787
+ catch {
788
+ /* A non-Git project still has a valid default base branch. */
140
789
  }
141
- catch { /* A non-Git project still has a valid default base branch. */ }
142
790
  const description = option(args, "--description") ?? "";
143
791
  const record = emptyTaskRecord({
144
- id: slug, name: slug, title, description,
792
+ id: slug,
793
+ name: slug,
794
+ title,
795
+ description,
145
796
  priority: option(args, "--priority") ?? "P2",
146
797
  package: option(args, "--package") ?? null,
147
798
  creator: developer ?? assignee,
@@ -152,23 +803,31 @@ function createTask(args, root) {
152
803
  const rigor = option(args, "--rigor") ?? "lite";
153
804
  if (rigor !== "lite" && rigor !== "full")
154
805
  throw new Error("--rigor must be lite or full");
155
- fs.mkdirSync(dir, { recursive: true });
156
- applyKernelCreate({ taskDir: dir, record, actor: "pactile task create", idempotencyKey: `create:${slug}`, evidence: "pactile task create", cwd: root,
157
- extras: { required_controls: resolveRequiredControls({ rigor }) } });
158
- const prd = path.join(dir, "prd.md");
159
- const verify = path.join(dir, "verify.md");
160
- if (!fs.existsSync(prd)) {
161
- fs.writeFileSync(prd, prdTemplate.replaceAll("{title}", title).replaceAll("{goal}", description || (taskLocale === "zh" ? "待补充。" : "TBD.")), "utf8");
162
- }
163
- if (!fs.existsSync(verify))
164
- fs.writeFileSync(verify, verifySeed(taskLocale), "utf8");
806
+ const artifacts = new Map([
807
+ [
808
+ "prd.md",
809
+ prdTemplate
810
+ .replaceAll("{title}", title)
811
+ .replaceAll("{goal}", description || (taskLocale === "zh" ? "待补充。" : "TBD.")),
812
+ ],
813
+ ["verify.md", verifySeed(taskLocale)],
814
+ ]);
165
815
  if (fs.existsSync(path.join(root, ".codex"))) {
166
816
  for (const name of CONTEXT_FILES) {
167
- const file = path.join(dir, name);
168
- if (!fs.existsSync(file))
169
- fs.writeFileSync(file, `${contextSeeds.map((entry) => JSON.stringify({ file: entry, reason: "default spec seed — curate entries for this task" })).join("\n")}\n`, "utf8");
817
+ artifacts.set(name, `${contextSeeds.map((entry) => JSON.stringify({ file: entry, reason: "default spec seed — curate entries for this task" })).join("\n")}\n`);
170
818
  }
171
819
  }
820
+ createTaskWithArtifacts({
821
+ root,
822
+ dirName,
823
+ record,
824
+ artifacts,
825
+ actor: "pactile task create",
826
+ idempotencyKey: `create:${slug}`,
827
+ evidence: "pactile task create",
828
+ ifExists: "error",
829
+ extras: { required_controls: resolveRequiredControls({ rigor }) },
830
+ });
172
831
  if (parentRef)
173
832
  linkChild(root, parentRef, dirName);
174
833
  runTaskHooks(root, "after_create", path.join(dir, "task.json"));
@@ -185,19 +844,29 @@ function linkChild(root, parentRef, childRef) {
185
844
  throw new Error("parent and child need task.json");
186
845
  if (child.parent && child.parent !== path.basename(parentDir))
187
846
  throw new Error(`single-parent tree: child already belongs to ${child.parent}`);
188
- if (parent.parent === path.basename(childDir) || child.children.includes(path.basename(parentDir)))
847
+ if (parent.parent === path.basename(childDir) ||
848
+ child.children.includes(path.basename(parentDir)))
189
849
  throw new Error("parent-child cycle rejected");
190
850
  if (parent.status !== "planning" || child.status !== "planning")
191
851
  throw new Error("link children while both tasks are planning");
192
- if (parent.children.includes(path.basename(childDir)) && child.parent === path.basename(parentDir))
852
+ if (parent.children.includes(path.basename(childDir)) &&
853
+ child.parent === path.basename(parentDir))
193
854
  return;
194
- const nextChildren = [...new Set([...parent.children, path.basename(childDir)])];
855
+ const nextChildren = [
856
+ ...new Set([...parent.children, path.basename(childDir)]),
857
+ ];
195
858
  patchTask(root, path.basename(parentDir), { children: nextChildren }, "add-subtask");
196
859
  try {
197
860
  patchTask(root, path.basename(childDir), { parent: path.basename(parentDir) }, "add-subtask");
198
861
  }
199
862
  catch (error) {
200
- patchTask(root, path.basename(parentDir), { children: parent.children }, "add-subtask-rollback", { topology: { ...readTopology(readKernel({ taskDir: parentDir, cwd: root }).kernel.projection?.extras ?? {}), children: parent.children } });
863
+ patchTask(root, path.basename(parentDir), { children: parent.children }, "add-subtask-rollback", {
864
+ topology: {
865
+ ...readTopology(readKernel({ taskDir: parentDir, cwd: root }).kernel.projection
866
+ ?.extras ?? {}),
867
+ children: parent.children,
868
+ },
869
+ });
201
870
  throw error;
202
871
  }
203
872
  const nextParent = taskRecord(parentDir);
@@ -212,16 +881,23 @@ function unlinkChild(root, parentRef, childRef) {
212
881
  const child = taskRecord(childDir);
213
882
  if (!parent || !child)
214
883
  throw new Error("parent and child need task.json");
215
- if (!parent.children.includes(path.basename(childDir)) || child.parent !== path.basename(parentDir))
884
+ if (!parent.children.includes(path.basename(childDir)) ||
885
+ child.parent !== path.basename(parentDir))
216
886
  throw new Error("parent-child link not found");
217
887
  const map = readTaskMap(parentDir).data;
218
888
  const entry = map?.children.find((item) => item.id === path.basename(childDir));
219
- if (parent.status !== "planning" || child.status !== "planning" || (entry && entry.state !== "open"))
889
+ if (parent.status !== "planning" ||
890
+ child.status !== "planning" ||
891
+ (entry && entry.state !== "open"))
220
892
  throw new Error("unlink only an open Child while both tasks are planning");
221
893
  const nextChildren = parent.children.filter((id) => id !== path.basename(childDir));
222
- const parentTopology = readTopology(readKernel({ taskDir: parentDir, cwd: root }).kernel.projection?.extras ?? {});
223
- const childTopology = readTopology(readKernel({ taskDir: childDir, cwd: root }).kernel.projection?.extras ?? {});
224
- patchTask(root, path.basename(childDir), { parent: null }, "remove-subtask", { topology: { ...childTopology, parent_id: null } });
894
+ const parentTopology = readTopology(readKernel({ taskDir: parentDir, cwd: root }).kernel.projection?.extras ??
895
+ {});
896
+ const childTopology = readTopology(readKernel({ taskDir: childDir, cwd: root }).kernel.projection?.extras ??
897
+ {});
898
+ patchTask(root, path.basename(childDir), { parent: null }, "remove-subtask", {
899
+ topology: { ...childTopology, parent_id: null },
900
+ });
225
901
  patchTask(root, path.basename(parentDir), { children: nextChildren }, "remove-subtask", { topology: { ...parentTopology, children: nextChildren } });
226
902
  const nextParent = taskRecord(parentDir);
227
903
  if (nextParent)
@@ -235,7 +911,8 @@ function prepareChildWorktree(root, args) {
235
911
  const child = taskRecord(childDir);
236
912
  if (!parent || !child)
237
913
  throw new Error("Parent and Child need task.json");
238
- if (child.parent !== path.basename(parentDir) || !parent.children.includes(path.basename(childDir)))
914
+ if (child.parent !== path.basename(parentDir) ||
915
+ !parent.children.includes(path.basename(childDir)))
239
916
  throw new Error("Child must be linked to the Parent");
240
917
  const map = readTaskMap(parentDir);
241
918
  if (!map.data?.children.some((entry) => entry.id === path.basename(childDir)))
@@ -245,9 +922,14 @@ function prepareChildWorktree(root, args) {
245
922
  const destination = path.resolve(root, option(args, "--path") ?? path.join(worktreeRoot, path.basename(childDir)));
246
923
  const relative = path.relative(worktreeRoot, destination);
247
924
  const errors = [];
248
- if (!relative || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative))
925
+ if (!relative ||
926
+ relative === ".." ||
927
+ relative.startsWith(`..${path.sep}`) ||
928
+ path.isAbsolute(relative))
249
929
  errors.push("worktree path must stay under .pactile/worktrees");
250
- if (fs.lstatSync(path.join(root, ".pactile"), { throwIfNoEntry: false })?.isSymbolicLink())
930
+ if (fs
931
+ .lstatSync(path.join(root, ".pactile"), { throwIfNoEntry: false })
932
+ ?.isSymbolicLink())
251
933
  errors.push(".pactile must not be a symlink");
252
934
  if (fs.lstatSync(worktreeRoot, { throwIfNoEntry: false })?.isSymbolicLink())
253
935
  errors.push(".pactile/worktrees must not be a symlink");
@@ -263,7 +945,11 @@ function prepareChildWorktree(root, args) {
263
945
  errors.push("invalid branch name");
264
946
  if (typeof base !== "string" || base.startsWith("-") || /[\r\n]/.test(base))
265
947
  errors.push("invalid base ref");
266
- const git = (...gitArgs) => execFileSync("git", gitArgs, { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
948
+ const git = (...gitArgs) => execFileSync("git", gitArgs, {
949
+ cwd: root,
950
+ encoding: "utf8",
951
+ stdio: ["ignore", "pipe", "pipe"],
952
+ }).trim();
267
953
  try {
268
954
  if (!sameGitRoot(git("rev-parse", "--show-toplevel"), root))
269
955
  errors.push("prepare-child-worktree requires the project Git root");
@@ -289,7 +975,9 @@ function prepareChildWorktree(root, args) {
289
975
  git("rev-parse", "--verify", `refs/heads/${branch}`);
290
976
  branchExists = true;
291
977
  }
292
- catch { /* New local branch. */ }
978
+ catch {
979
+ /* New local branch. */
980
+ }
293
981
  try {
294
982
  git("worktree", "add", ...(branchExists ? [] : ["-b", branch]), destination, ...(branchExists ? [branch] : [base]));
295
983
  }
@@ -301,7 +989,13 @@ function prepareChildWorktree(root, args) {
301
989
  const entry = map.data?.children.find((item) => item.id === path.basename(childDir));
302
990
  if (!map.data || !entry)
303
991
  throw new Error("Child vanished from Parent task-map.md after worktree creation");
304
- Object.assign(entry, { isolation: "git-worktree", branch, worktree_path: worktreePath, base_ref: base, ref: `refs/heads/${branch}` });
992
+ Object.assign(entry, {
993
+ isolation: "git-worktree",
994
+ branch,
995
+ worktree_path: worktreePath,
996
+ base_ref: base,
997
+ ref: `refs/heads/${branch}`,
998
+ });
305
999
  writeTaskMap(parentDir, map.data, map.body, `Prepared Child ${entry.id} git worktree at ${worktreePath} from ${base}.`);
306
1000
  console.log(`Child worktree prepared: ${entry.id}\nBranch: ${branch}\nPath: ${worktreePath}`);
307
1001
  return 0;
@@ -312,8 +1006,11 @@ function updateChildState(root, args, integrated) {
312
1006
  const state = requireArgument(args[2], "state");
313
1007
  if (!CHILD_STATES.includes(state))
314
1008
  throw new Error(`unknown child state: ${state}`);
315
- if (integrated !== ["changes", "accepted", "integrating", "integrated", "cancelled"].includes(state))
316
- throw new Error(integrated ? "use a Parent-controlled integration state" : "use integrate-child for Parent-controlled states");
1009
+ if (integrated !==
1010
+ ["changes", "accepted", "integrating", "integrated", "cancelled"].includes(state))
1011
+ throw new Error(integrated
1012
+ ? "use a Parent-controlled integration state"
1013
+ : "use integrate-child for Parent-controlled states");
317
1014
  const parent = taskRecord(parentDir);
318
1015
  const child = taskRecord(childDir);
319
1016
  if (!parent || !child)
@@ -325,12 +1022,15 @@ function updateChildState(root, args, integrated) {
325
1022
  const reason = option(args, "--reason");
326
1023
  const errors = childStateErrors(parentDir, parent, childDir, state, evidence, { ref, reason });
327
1024
  if (integrated && ["accepted", "integrating", "integrated"].includes(state)) {
328
- const extras = readKernel({ taskDir: childDir, cwd: root }).kernel.projection?.extras ?? {};
329
- if (extras.required_controls?.rigor === "full") {
1025
+ const extras = readKernel({ taskDir: childDir, cwd: root }).kernel.projection?.extras ??
1026
+ {};
1027
+ if (extras.required_controls
1028
+ ?.rigor === "full") {
330
1029
  const parsed = readStrategyContract(childDir);
331
1030
  errors.push(...parsed.errors);
332
1031
  if (parsed.contract)
333
- errors.push(...currentGateErrors(childDir, child, "child-review", requiredGates("child-review", parsed.contract), parsed.contract, readKernel({ taskDir: childDir, cwd: root }).kernel.gates));
1032
+ errors.push(...currentGateErrors(childDir, child, "child-review", requiredGates("child-review", parsed.contract), parsed.contract, readKernel({ taskDir: childDir, cwd: root }).kernel
1033
+ .gates));
334
1034
  try {
335
1035
  assertFullQualityForPhase(childDir, extras, "archive");
336
1036
  }
@@ -345,7 +1045,11 @@ function updateChildState(root, args, integrated) {
345
1045
  errors.push("--execute-merge is only valid with integrate-child ... integrated");
346
1046
  if (!ref || ref.startsWith("-") || /[\r\n]/.test(ref))
347
1047
  errors.push("--execute-merge requires a valid --ref");
348
- const git = (...gitArgs) => execFileSync("git", gitArgs, { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
1048
+ const git = (...gitArgs) => execFileSync("git", gitArgs, {
1049
+ cwd: root,
1050
+ encoding: "utf8",
1051
+ stdio: ["ignore", "pipe", "pipe"],
1052
+ }).trim();
349
1053
  try {
350
1054
  if (!sameGitRoot(git("rev-parse", "--show-toplevel"), root))
351
1055
  errors.push("merge execution requires the project Git root");
@@ -356,7 +1060,9 @@ function updateChildState(root, args, integrated) {
356
1060
  errors.push(`merge ref does not resolve to a commit: ${ref ?? "(missing)"}`);
357
1061
  }
358
1062
  try {
359
- const dirty = git("status", "--porcelain", "--untracked-files=all").split(/\r?\n/).filter(Boolean)
1063
+ const dirty = git("status", "--porcelain", "--untracked-files=all")
1064
+ .split(/\r?\n/)
1065
+ .filter(Boolean)
360
1066
  .map((line) => line.slice(3).trim().replaceAll("\\", "/").replace(/^"|"$/g, ""))
361
1067
  .filter((file) => file !== ".pactile" && !file.startsWith(".pactile/"));
362
1068
  if (dirty.length)
@@ -376,7 +1082,10 @@ function updateChildState(root, args, integrated) {
376
1082
  }
377
1083
  if (executeMerge) {
378
1084
  try {
379
- execFileSync("git", ["merge", "--no-ff", "--no-commit", ref], { cwd: root, stdio: ["ignore", "pipe", "pipe"] });
1085
+ execFileSync("git", ["merge", "--no-ff", "--no-commit", ref], {
1086
+ cwd: root,
1087
+ stdio: ["ignore", "pipe", "pipe"],
1088
+ });
380
1089
  }
381
1090
  catch (error) {
382
1091
  console.error(`git merge failed; Parent task-map was not advanced to integrated: ${error instanceof Error ? error.message : String(error)}`);
@@ -399,9 +1108,17 @@ function updateChildState(root, args, integrated) {
399
1108
  data.integration_queue.push(entry.id);
400
1109
  else if (state !== "integrating")
401
1110
  data.integration_queue = data.integration_queue.filter((id) => id !== entry.id);
402
- const previous = readKernel({ taskDir: parentDir, cwd: root }).kernel.projection?.extras ?? {};
403
- const states = previous.task_map_states && typeof previous.task_map_states === "object" ? previous.task_map_states : {};
404
- patchTask(root, path.basename(parentDir), {}, integrated ? "integrate-child" : "set-child-state", { task_map_states: { ...states, [entry.id]: state }, ...(integrated ? { integration_action: "integrate-child", integration_actor: "parent" } : {}) });
1111
+ const previous = readKernel({ taskDir: parentDir, cwd: root }).kernel.projection?.extras ??
1112
+ {};
1113
+ const states = previous.task_map_states && typeof previous.task_map_states === "object"
1114
+ ? previous.task_map_states
1115
+ : {};
1116
+ patchTask(root, path.basename(parentDir), {}, integrated ? "integrate-child" : "set-child-state", {
1117
+ task_map_states: { ...states, [entry.id]: state },
1118
+ ...(integrated
1119
+ ? { integration_action: "integrate-child", integration_actor: "parent" }
1120
+ : {}),
1121
+ });
405
1122
  writeTaskMap(parentDir, data, body, `${integrated ? "Parent integrated" : "Child reported"} ${entry.id} as ${state}. Evidence: ${evidence}.`);
406
1123
  console.log(`${entry.id}: ${state}`);
407
1124
  return 0;
@@ -411,14 +1128,16 @@ function reviewChild(root, args) {
411
1128
  const childDir = taskDir(root, requireArgument(args[1], "child task"));
412
1129
  const parent = taskRecord(parentDir);
413
1130
  const child = taskRecord(childDir);
414
- if (child?.parent !== path.basename(parentDir) || !parent?.children.includes(path.basename(childDir)))
1131
+ if (child?.parent !== path.basename(parentDir) ||
1132
+ !parent?.children.includes(path.basename(childDir)))
415
1133
  throw new Error("linked Parent and Child task.json are required");
416
1134
  const map = readTaskMap(parentDir).data;
417
1135
  const entry = map?.children.find((item) => item.id === path.basename(childDir));
418
1136
  if (!entry)
419
1137
  throw new Error("Child missing from Parent task-map.md");
420
1138
  const decision = option(args, "--decision");
421
- if (decision && !["accept", "changes", "cancel", "integrate-through"].includes(decision))
1139
+ if (decision &&
1140
+ !["accept", "changes", "cancel", "integrate-through"].includes(decision))
422
1141
  throw new Error("--decision must be accept, changes, cancel, or integrate-through");
423
1142
  const check = args.includes("--check") || !decision;
424
1143
  const ref = option(args, "--ref");
@@ -426,40 +1145,86 @@ function reviewChild(root, args) {
426
1145
  const notes = option(args, "--notes");
427
1146
  const verifyFile = path.join(childDir, "verify.md");
428
1147
  const handoffFile = path.join(childDir, "handoff.md");
429
- const verify = fs.existsSync(verifyFile) ? fs.readFileSync(verifyFile, "utf8") : "";
430
- const handoff = fs.existsSync(handoffFile) ? fs.readFileSync(handoffFile, "utf8") : "";
431
- const excerpt = (content) => content.slice(0, 800).trim().split(/\r?\n/).map((line) => `> ${line}`).join("\n") || "> (empty)";
1148
+ const verify = fs.existsSync(verifyFile)
1149
+ ? fs.readFileSync(verifyFile, "utf8")
1150
+ : "";
1151
+ const handoff = fs.existsSync(handoffFile)
1152
+ ? fs.readFileSync(handoffFile, "utf8")
1153
+ : "";
1154
+ const excerpt = (content) => content
1155
+ .slice(0, 800)
1156
+ .trim()
1157
+ .split(/\r?\n/)
1158
+ .map((line) => `> ${line}`)
1159
+ .join("\n") || "> (empty)";
432
1160
  const report = [
433
- `# Parent review — \`${path.basename(childDir)}\``, "", `- Timestamp: ${new Date().toISOString()}`,
434
- `- Current integration state: \`${entry.state}\``, `- Decision: \`${check ? "check-only" : decision}\``, "",
435
- "## Handoff artifacts", "", `- verify.md: ${verify.trim() ? "present" : "missing"}`,
1161
+ `# Parent review — \`${path.basename(childDir)}\``,
1162
+ "",
1163
+ `- Timestamp: ${new Date().toISOString()}`,
1164
+ `- Current integration state: \`${entry.state}\``,
1165
+ `- Decision: \`${check ? "check-only" : decision}\``,
1166
+ "",
1167
+ "## Handoff artifacts",
1168
+ "",
1169
+ `- verify.md: ${verify.trim() ? "present" : "missing"}`,
436
1170
  `- handoff.md: ${handoff.trim() ? "present" : "missing"}`,
437
1171
  `- validation signal: ${/^\s*(?:[-*]\s*)?validation(?:\s+(?:commands?|results?|evidence))?\s*:\s*\S.{2,}$/im.test(verify)}`,
438
1172
  `- acceptance signal: ${/^\s*(?:[-*]\s*)?(?:(?:final|user)\s+)?acceptance(?:\s+evidence)?\s*:\s*\S.{2,}$/im.test(verify)}`,
439
- `- durable learning decision signal: ${/durable learning decision\s*:/i.test(verify)}`, "",
1173
+ `- durable learning decision signal: ${/durable learning decision\s*:/i.test(verify)}`,
1174
+ "",
440
1175
  ...(notes ? ["## Parent notes", "", excerpt(notes), ""] : []),
441
- "## verify.md excerpt", "", excerpt(verify), "",
442
- "## handoff.md excerpt", "", excerpt(handoff), "",
1176
+ "## verify.md excerpt",
1177
+ "",
1178
+ excerpt(verify),
1179
+ "",
1180
+ "## handoff.md excerpt",
1181
+ "",
1182
+ excerpt(handoff),
1183
+ "",
443
1184
  ].join("\n");
444
1185
  if (check) {
445
1186
  const errors = [
446
- ...(entry.state !== "review" ? [`Child must be in review state, got ${entry.state}`] : []),
1187
+ ...(entry.state !== "review"
1188
+ ? [`Child must be in review state, got ${entry.state}`]
1189
+ : []),
447
1190
  ...(!verify.trim() ? ["verify.md missing"] : []),
448
1191
  ...(!handoff.trim() ? ["handoff.md missing"] : []),
449
1192
  ];
450
1193
  console.log(`Review-child check: ${errors.length ? "FAIL" : "PASS"}\n${errors.map((error) => ` - ${error}`).join("\n")}\n\n${report}`);
451
1194
  return errors.length ? 1 : 0;
452
1195
  }
453
- const state = decision === "accept" || decision === "integrate-through" ? "accepted" : decision === "changes" ? "changes" : "cancelled";
454
- const transition = (target, evidence) => updateChildState(root, [path.basename(parentDir), path.basename(childDir), target, "--evidence", evidence, ...(ref ? ["--ref", ref] : []), ...(reason ? ["--reason", reason] : [])], true);
1196
+ const state = decision === "accept" || decision === "integrate-through"
1197
+ ? "accepted"
1198
+ : decision === "changes"
1199
+ ? "changes"
1200
+ : "cancelled";
1201
+ const transition = (target, evidence) => updateChildState(root, [
1202
+ path.basename(parentDir),
1203
+ path.basename(childDir),
1204
+ target,
1205
+ "--evidence",
1206
+ evidence,
1207
+ ...(ref ? ["--ref", ref] : []),
1208
+ ...(reason ? ["--reason", reason] : []),
1209
+ ], true);
455
1210
  // Validate the first transition before writing any review artifact or Parent evidence.
456
- const firstCheck = updateChildState(root, [path.basename(parentDir), path.basename(childDir), state, "--evidence", "handoff.md", ...(ref ? ["--ref", ref] : []), ...(reason ? ["--reason", reason] : []), "--check"], true);
1211
+ const firstCheck = updateChildState(root, [
1212
+ path.basename(parentDir),
1213
+ path.basename(childDir),
1214
+ state,
1215
+ "--evidence",
1216
+ "handoff.md",
1217
+ ...(ref ? ["--ref", ref] : []),
1218
+ ...(reason ? ["--reason", reason] : []),
1219
+ "--check",
1220
+ ], true);
457
1221
  if (firstCheck !== 0)
458
1222
  return firstCheck;
459
1223
  if (transition(state, "handoff.md") !== 0)
460
1224
  return 1;
461
1225
  if (decision === "integrate-through") {
462
- if (transition("integrating", "task-map.md") !== 0 || transition("integrated", "task-map.md") !== 0)
1226
+ if (transition("integrating", "task-map.md") !== 0 ||
1227
+ transition("integrated", "task-map.md") !== 0)
463
1228
  return 1;
464
1229
  }
465
1230
  const reviewFile = path.join(parentDir, `review-${path.basename(childDir)}.md`);
@@ -467,13 +1232,90 @@ function reviewChild(root, args) {
467
1232
  fs.writeFileSync(reviewFile, `${report}\n`, "utf8");
468
1233
  if (!args.includes("--no-append-parent-verify")) {
469
1234
  const parentVerify = path.join(parentDir, "verify.md");
470
- const current = fs.existsSync(parentVerify) ? fs.readFileSync(parentVerify, "utf8") : "# Verification Evidence\n";
1235
+ const current = fs.existsSync(parentVerify)
1236
+ ? fs.readFileSync(parentVerify, "utf8")
1237
+ : "# Verification Evidence\n";
471
1238
  const note = `## Parent review — \`${path.basename(childDir)}\`\n\n- Decision: ${decision}\n- Child handoff: ${path.basename(childDir)}/handoff.md\n- Child verification: ${path.basename(childDir)}/verify.md\n- Review artifact: ${args.includes("--write-artifact") ? path.basename(reviewFile) : "not written"}\n`;
472
1239
  fs.writeFileSync(parentVerify, `${current.trimEnd()}\n\n${note}`, "utf8");
473
1240
  }
474
1241
  console.log(report);
475
1242
  return 0;
476
1243
  }
1244
+ function showTask(root, args) {
1245
+ const reference = requireArgument(args[0], "task");
1246
+ const dir = taskDir(root, reference);
1247
+ const migration = readLegacyTaskImportRecord(root, dir);
1248
+ if (migration && migration.status !== "imported") {
1249
+ const status = migration.status;
1250
+ const details = {
1251
+ status,
1252
+ taskId: migration.legacyTaskId,
1253
+ missingDefinitionFields: migration.missingDefinitionFields,
1254
+ coordinationReasons: migration.coordinationReasons,
1255
+ hardDependencies: migration.dependencyFacts.hardDependencies,
1256
+ sourceFingerprint: migration.sourceFingerprint,
1257
+ };
1258
+ if (args.includes("--json"))
1259
+ console.log(JSON.stringify(details, null, 2));
1260
+ else
1261
+ console.log([
1262
+ `${migration.legacyTaskId} (legacy migration: ${status})`,
1263
+ migration.missingDefinitionFields.length
1264
+ ? `Definition fields to supply: ${migration.missingDefinitionFields.join(", ")}`
1265
+ : null,
1266
+ migration.coordinationReasons.length
1267
+ ? `Dependency coordination: ${migration.coordinationReasons.join(", ")}`
1268
+ : null,
1269
+ "No runnable V2 Task Kernel was created; original Task, Kernel, and documents remain preserved.",
1270
+ ]
1271
+ .filter((line) => line !== null)
1272
+ .join("\n"));
1273
+ return 0;
1274
+ }
1275
+ if (!fs.existsSync(path.join(dir, "kernel.json")) && !migration) {
1276
+ const record = taskRecord(dir);
1277
+ if (!record)
1278
+ throw new Error(`No readable legacy task record exists at ${dir}`);
1279
+ console.log(args.includes("--json")
1280
+ ? JSON.stringify({ schemaVersion: 0, task: record }, null, 2)
1281
+ : `${record.title || record.name} (${record.id})\nLegacy task.json record without Kernel\nStatus: ${record.status}\nAutomatic migration: reserved for P36.`);
1282
+ return 0;
1283
+ }
1284
+ const read = readTaskKernel({ root, taskDir: dir, cwd: root });
1285
+ if (args.includes("--json")) {
1286
+ console.log(JSON.stringify(read.kind === "task-kernel-v2"
1287
+ ? read.kernel
1288
+ : { ...read.kernel, task: taskRecord(dir) }, null, 2));
1289
+ return 0;
1290
+ }
1291
+ if (read.kind === "task-kernel-v2") {
1292
+ const { definition, runs, reviews, phase, condition, revision } = read.kernel;
1293
+ console.log([
1294
+ `${definition.title} (${definition.taskId})`,
1295
+ `Kernel: v2 @ revision ${revision}`,
1296
+ `Phase: ${phase} | condition: ${condition}`,
1297
+ `Deliverable: ${definition.deliverable}`,
1298
+ `Delivery level: ${definition.deliveryLevel}`,
1299
+ `Dependencies: ${definition.dependencies.length ? definition.dependencies.join(", ") : "none"}`,
1300
+ "Acceptance criteria:",
1301
+ ...definition.acceptanceCriteria.map((criterion) => ` - ${criterion.id}: ${criterion.description}`),
1302
+ `Runs: ${runs.length} | Reviews: ${reviews.length}`,
1303
+ ].join("\n"));
1304
+ return 0;
1305
+ }
1306
+ const record = taskRecord(dir);
1307
+ console.log(`${record?.title ?? record?.id ?? path.basename(dir)} (legacy Kernel v1)\nPhase: ${read.kernel.kernel.phase}\nStatus: ${record?.status ?? "unknown"}\nAutomatic migration: reserved for P36.`);
1308
+ return 0;
1309
+ }
1310
+ function activeV2Tasks(root) {
1311
+ const archivePrefix = `${path.resolve(root, ".pactile", "tasks", "archive")}${path.sep}`.toLowerCase();
1312
+ return listTaskKernelSnapshots(root)
1313
+ .filter(({ taskDir: dir }) => !path.resolve(dir).toLowerCase().startsWith(archivePrefix))
1314
+ .map(({ taskDir: dir, kernel }) => ({ dir: path.basename(dir), kernel }));
1315
+ }
1316
+ function v2DisplayStatus(kernel) {
1317
+ return kernel.phase === "close" ? "closed" : kernel.phase;
1318
+ }
477
1319
  function listTasks(args, root) {
478
1320
  const developer = readDeveloper(root);
479
1321
  const mine = args.includes("--mine") || args.includes("-m");
@@ -482,16 +1324,67 @@ function listTasks(args, root) {
482
1324
  const assignee = option(args, "--assignee") ?? (mine ? developer : undefined);
483
1325
  const status = option(args, "--status") ?? option(args, "-s");
484
1326
  const selected = resolveSelectedTask(root).taskPath;
485
- const tasks = activeTasks(root).filter(({ record }) => (!assignee || record.assignee === assignee) && (!status || record.status === status));
1327
+ const phaseForStatus = {
1328
+ planning: "define",
1329
+ in_progress: "execute",
1330
+ review: "verify",
1331
+ completed: "close",
1332
+ closed: "close",
1333
+ };
1334
+ const requiredPhase = status ? (phaseForStatus[status] ?? status) : undefined;
1335
+ const migrationRecords = listLegacyTaskImportRecords(root);
1336
+ const restoredSourcePaths = new Set(migrationRecords.flatMap(({ record }) => {
1337
+ if (record.status !== "imported")
1338
+ return [];
1339
+ const taskJsonPath = record.legacySourceMetadata?.fileReferences.taskJson?.path;
1340
+ if (!taskJsonPath?.startsWith(".pactile/tasks/") ||
1341
+ !taskJsonPath.endsWith("/task.json"))
1342
+ return [];
1343
+ const sourceTaskPath = taskJsonPath.slice(0, -"/task.json".length);
1344
+ return sourceTaskPath === record.taskPath
1345
+ ? []
1346
+ : [sourceTaskPath.slice(".pactile/tasks/".length)];
1347
+ }));
1348
+ const migrationByDirectory = new Map(migrationRecords.map((item) => [path.resolve(item.taskDir), item.record]));
1349
+ const tasks = activeTasks(root).filter(({ dir, record }) => !migrationByDirectory.has(path.resolve(root, ".pactile", "tasks", dir)) &&
1350
+ (!assignee || record.assignee === assignee) &&
1351
+ (!status || record.status === status));
1352
+ const pendingImports = migrationRecords.filter(({ taskDir, record }) => {
1353
+ if (record.status === "imported" ||
1354
+ record.status === "archived-historical-only" ||
1355
+ restoredSourcePaths.has(path
1356
+ .relative(path.join(root, ".pactile", "tasks"), taskDir)
1357
+ .replaceAll("\\", "/")))
1358
+ return false;
1359
+ const raw = taskRecord(taskDir);
1360
+ return ((!assignee || raw?.assignee === assignee) &&
1361
+ (!status || raw?.status === status));
1362
+ });
1363
+ const v2Tasks = activeV2Tasks(root).filter(({ kernel }) => (!assignee || kernel.definition.createdBy === assignee) &&
1364
+ (!requiredPhase || kernel.phase === requiredPhase));
486
1365
  console.log(assignee ? `Tasks (assignee: ${assignee}):` : "All active tasks:");
487
1366
  console.log();
488
1367
  for (const { dir, record } of tasks) {
489
1368
  const marker = `.pactile/tasks/${dir}` === selected ? " <- selected" : "";
490
1369
  console.log(` - ${dir}/ (${record.status})${record.package ? ` @${record.package}` : ""} [${record.assignee || "-"}]${marker}`);
491
1370
  }
492
- if (!tasks.length)
1371
+ for (const { dir, kernel } of v2Tasks) {
1372
+ const marker = `.pactile/tasks/${dir}` === selected ? " <- selected" : "";
1373
+ console.log(` - ${dir}/ (${v2DisplayStatus(kernel)}; Kernel v2) [${kernel.definition.createdBy}]${marker}`);
1374
+ }
1375
+ for (const { taskDir: importedDir, record } of pendingImports) {
1376
+ const dir = path
1377
+ .relative(path.join(root, ".pactile", "tasks"), importedDir)
1378
+ .replaceAll("\\", "/");
1379
+ const marker = `.pactile/tasks/${dir}` === selected ? " <- selected" : "";
1380
+ const detail = record.status === "needs-definition"
1381
+ ? `needs definition: ${record.missingDefinitionFields.join(", ")}`
1382
+ : `needs dependency coordination: ${record.coordinationReasons.join(", ")}`;
1383
+ console.log(` - ${dir}/ (${detail}; not runnable)${marker}`);
1384
+ }
1385
+ if (!tasks.length && !v2Tasks.length && !pendingImports.length)
493
1386
  console.log(" (no active tasks)");
494
- console.log(`\nTotal: ${tasks.length} task(s)`);
1387
+ console.log(`\nTotal: ${tasks.length + v2Tasks.length + pendingImports.length} task(s)`);
495
1388
  }
496
1389
  function listArchive(root, month) {
497
1390
  if (month && !/^\d{4}-(?:0[1-9]|1[0-2])$/.test(month))
@@ -500,14 +1393,24 @@ function listArchive(root, month) {
500
1393
  console.log("Archived tasks:\n");
501
1394
  if (!fs.existsSync(archive))
502
1395
  return;
503
- const months = month ? [month] : fs.readdirSync(archive, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort();
1396
+ const months = month
1397
+ ? [month]
1398
+ : fs
1399
+ .readdirSync(archive, { withFileTypes: true })
1400
+ .filter((entry) => entry.isDirectory())
1401
+ .map((entry) => entry.name)
1402
+ .sort();
504
1403
  for (const name of months) {
505
1404
  const monthDir = path.join(archive, name);
506
1405
  if (!fs.statSync(monthDir, { throwIfNoEntry: false })?.isDirectory()) {
507
1406
  console.log(` No archives for ${name}`);
508
1407
  continue;
509
1408
  }
510
- const tasks = fs.readdirSync(monthDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort();
1409
+ const tasks = fs
1410
+ .readdirSync(monthDir, { withFileTypes: true })
1411
+ .filter((entry) => entry.isDirectory())
1412
+ .map((entry) => entry.name)
1413
+ .sort();
511
1414
  console.log(`[${name}]${month ? "" : ` - ${tasks.length} task(s)`}`);
512
1415
  if (month)
513
1416
  for (const task of tasks)
@@ -519,9 +1422,14 @@ function dashboard(root) {
519
1422
  console.log("Task Dashboard\nPactile framework: active");
520
1423
  console.log(`Selected task: ${selected.taskPath ?? "none"}${selected.taskPath ? ` (${selected.source})` : ""}\n`);
521
1424
  const tasks = activeTasks(root);
1425
+ const v2Tasks = activeV2Tasks(root);
522
1426
  if (!tasks.length)
523
1427
  console.log("Tasks: none");
524
- for (const [status, heading] of [["planning", "Define"], ["in_progress", "Execute"], ["review", "Verify"]]) {
1428
+ for (const [status, heading] of [
1429
+ ["planning", "Define"],
1430
+ ["in_progress", "Execute"],
1431
+ ["review", "Verify"],
1432
+ ]) {
525
1433
  const matching = tasks.filter(({ record }) => record.status === status);
526
1434
  if (!matching.length)
527
1435
  continue;
@@ -530,10 +1438,20 @@ function dashboard(root) {
530
1438
  console.log(` - .pactile/tasks/${dir} (${heading}) [${record.assignee || "-"}]`);
531
1439
  console.log();
532
1440
  }
533
- console.log("Suggested actions:\n - Select a task: pactile task select <task>\n - Create a task: pactile task create \"<title>\" --slug <slug>\n - Inspect raw list: pactile task list");
1441
+ if (v2Tasks.length) {
1442
+ console.log("Task Kernel v2:");
1443
+ for (const { dir, kernel } of v2Tasks)
1444
+ console.log(` - .pactile/tasks/${dir} (${v2DisplayStatus(kernel)}) [${kernel.definition.deliveryLevel}]`);
1445
+ console.log();
1446
+ }
1447
+ console.log('Suggested actions:\n - Select a task: pactile task select <task>\n - Create a deliverable Task: pactile task create "<title>" --slug <slug> --deliverable <text> --delivery-level <level> --accept <criterion>\n - Inspect tasks: pactile task list | pactile task show <task>');
534
1448
  }
535
1449
  function startExecution(root, args) {
536
1450
  const dir = taskDir(root, requireArgument(args[0], "task"));
1451
+ const migration = readLegacyTaskImportRecord(root, dir);
1452
+ if (migration) {
1453
+ throw new Error(`Task ${migration.legacyTaskId} has an active V2 migration record (${migration.status}); use the Task Kernel Run command. Legacy --ignore-deps and execution approvals do not carry over.`);
1454
+ }
537
1455
  const record = taskRecord(dir);
538
1456
  if (!record)
539
1457
  throw new Error(`task.json not found at ${dir}`);
@@ -541,6 +1459,14 @@ function startExecution(root, args) {
541
1459
  const approved = args.includes("--approved");
542
1460
  if (check === approved)
543
1461
  throw new Error("choose --check or --approved");
1462
+ const existing = readKernel({ taskDir: dir, cwd: root }).kernel;
1463
+ if (approved &&
1464
+ existing.phase === "execute" &&
1465
+ existing.projection?.status === "in_progress") {
1466
+ approvedExecuteTask(root, path.basename(dir));
1467
+ console.log(`Execution already approved for: ${path.relative(root, dir).replaceAll("\\", "/")}\nStatus: in_progress`);
1468
+ return 0;
1469
+ }
544
1470
  const guard = checkStartExecution(root, dir, record, approved, args.includes("--ignore-deps"));
545
1471
  for (const warning of guard.warnings)
546
1472
  console.error(`[dependencies] WARN: ${warning}`);
@@ -554,63 +1480,58 @@ function startExecution(root, args) {
554
1480
  return 0;
555
1481
  }
556
1482
  const prior = record;
557
- const priorApproval = prior.execution_approval;
558
- if (priorApproval && typeof priorApproval === "object") {
559
- const old = priorApproval;
560
- if (old.contract_fingerprint !== guard.contractFingerprint || old.artifact_fingerprint !== guard.artifactFingerprint) {
561
- throw new Error("stale execution approval; return to Planning and ask for explicit approval again");
562
- }
563
- }
564
1483
  const checkedAt = new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
565
1484
  const baseline = {
566
- schema_version: 1, transition: "start-execution", gate: "baseline-check", result: "PASS",
567
- reviewer: "pactile-cli", evidence: "task.json", checked_at: checkedAt,
568
- contract_fingerprint: guard.contractFingerprint, artifact_fingerprint: guard.artifactFingerprint,
569
- issue_fingerprint: null, consecutive_failures: 0, approved_skip: null,
1485
+ schema_version: 1,
1486
+ transition: "start-execution",
1487
+ gate: "baseline-check",
1488
+ result: "PASS",
1489
+ reviewer: "pactile-cli",
1490
+ evidence: "task.json",
1491
+ checked_at: checkedAt,
1492
+ contract_fingerprint: guard.contractFingerprint,
1493
+ artifact_fingerprint: guard.artifactFingerprint,
1494
+ issue_fingerprint: null,
1495
+ consecutive_failures: 0,
1496
+ approved_skip: null,
570
1497
  };
571
1498
  const existingQgr = prior.quality_gate_results && typeof prior.quality_gate_results === "object"
572
- ? prior.quality_gate_results : {};
1499
+ ? prior.quality_gate_results
1500
+ : {};
573
1501
  const transitions = existingQgr.transitions && typeof existingQgr.transitions === "object"
574
- ? existingQgr.transitions : {};
1502
+ ? existingQgr.transitions
1503
+ : {};
575
1504
  const qualityGateResults = {
576
1505
  ...existingQgr,
577
1506
  schema_version: 1,
578
1507
  contract_fingerprint: guard.contractFingerprint,
579
1508
  artifact_fingerprint: guard.artifactFingerprint,
580
- transitions: { ...transitions, "start-execution": { "baseline-check": baseline } },
1509
+ transitions: {
1510
+ ...transitions,
1511
+ "start-execution": {
1512
+ ...(transitions["start-execution"] ?? {}),
1513
+ "baseline-check": baseline,
1514
+ },
1515
+ },
581
1516
  };
582
1517
  const approval = {
583
- schema_version: 1, transition: "start-execution", approved_at: checkedAt,
584
- approved_by: "user", approval_source: "pactile task start-execution --approved",
585
- contract_fingerprint: guard.contractFingerprint, artifact_fingerprint: guard.artifactFingerprint,
1518
+ schema_version: 1,
1519
+ transition: "start-execution",
1520
+ approved_at: checkedAt,
1521
+ approved_by: "user",
1522
+ task_id: record.id,
1523
+ assurance: "caller-asserted",
1524
+ approval_source: "pactile task start-execution --approved",
1525
+ contract_fingerprint: guard.contractFingerprint,
1526
+ artifact_fingerprint: guard.artifactFingerprint,
1527
+ };
1528
+ const extras = {
1529
+ quality_gate_results: qualityGateResults,
1530
+ execution_approval: approval,
586
1531
  };
587
- const extras = { quality_gate_results: qualityGateResults, execution_approval: approval };
588
1532
  const dependencyFacts = dependencyStatus(root, dir, record);
589
1533
  const priorExtras = readKernel({ taskDir: dir, cwd: root }).kernel.projection?.extras ?? {};
590
- const attestedSatisfied = Array.isArray(priorExtras.dependency_satisfied)
591
- ? priorExtras.dependency_satisfied.filter((item) => typeof item === "string") : [];
592
- extras.dependency_satisfied = [...new Set([...attestedSatisfied, ...dependencyFacts.satisfied])];
593
- const controls = readKernel({ taskDir: dir, cwd: root }).kernel.projection?.extras?.required_controls;
594
- if (controls && typeof controls === "object" && controls.rigor === "full") {
595
- const parsed = readStrategyContract(dir);
596
- if (!parsed.contract)
597
- throw new Error(parsed.errors.join("; "));
598
- const currentContract = contractFingerprint(dir, record, parsed.contract);
599
- const autoGates = requiredGates("start-execution", parsed.contract);
600
- for (const gate of autoGates) {
601
- const stamp = new Date().toISOString();
602
- const artifact = artifactFingerprint(dir, record, "start-execution", gate);
603
- const gateRecord = { schema_version: 1, transition: "start-execution", gate, result: "PASS", reviewer: "pactile-cli", evidence: gate === "requirements-review" ? "prd.md" : "design.md + implement.md",
604
- checked_at: stamp, contract_fingerprint: currentContract, artifact_fingerprint: artifact,
605
- issue_fingerprint: null, consecutive_failures: 0, approved_skip: null };
606
- const gateRevision = readKernel({ taskDir: dir, cwd: root }).kernel.revision;
607
- applyKernelRecordGate({ taskDir: dir, cwd: root, expectedRevision: gateRevision,
608
- actor: "pactile task start-execution planning review", idempotencyKey: `planning:${record.id}:${gate}:r${gateRevision}`,
609
- transition: "start-execution", gateName: gate, record: gateRecord, evidence: String(gateRecord.evidence) });
610
- const transitionRows = qualityGateResults.transitions["start-execution"];
611
- transitionRows[gate] = gateRecord;
612
- }
613
- }
1534
+ extras.dependency_satisfied = dependencyFacts.satisfied;
614
1535
  if (args.includes("--ignore-deps")) {
615
1536
  extras.dependency_override = {
616
1537
  schema_version: 1,
@@ -623,7 +1544,9 @@ function startExecution(root, args) {
623
1544
  }
624
1545
  const revision = readKernel({ taskDir: dir, cwd: root }).kernel.revision;
625
1546
  applyKernelStart({
626
- taskDir: dir, cwd: root, expectedRevision: revision,
1547
+ taskDir: dir,
1548
+ cwd: root,
1549
+ expectedRevision: revision,
627
1550
  actor: "pactile task start-execution --approved",
628
1551
  idempotencyKey: `start:${record.id || path.basename(dir)}:${checkedAt}`,
629
1552
  evidence: "pactile task start-execution --approved",
@@ -648,8 +1571,16 @@ function recordGate(root, args) {
648
1571
  throw new Error("--result must be PASS, FAIL, or SKIPPED");
649
1572
  const allowed = {
650
1573
  "start-execution": ["requirements-review", "architecture-review"],
651
- "full-task-complete": ["code-review", "architecture-review", "architecture-deep-review"],
652
- "child-review": ["code-review", "architecture-review", "architecture-deep-review"],
1574
+ "full-task-complete": [
1575
+ "code-review",
1576
+ "architecture-review",
1577
+ "architecture-deep-review",
1578
+ ],
1579
+ "child-review": [
1580
+ "code-review",
1581
+ "architecture-review",
1582
+ "architecture-deep-review",
1583
+ ],
653
1584
  "parent-integrated": ["integration-review"],
654
1585
  };
655
1586
  if (!allowed[transition]?.includes(gate))
@@ -658,34 +1589,63 @@ function recordGate(root, args) {
658
1589
  throw new Error("--reviewer must be a short identifier");
659
1590
  if (!evidence.trim() || evidence.length > 240 || /[\r\n]/.test(evidence))
660
1591
  throw new Error("--evidence must be a short single-line reference");
661
- if (result === "FAIL" && (!option(args, "--issue-fingerprint") || !option(args, "--root-cause")))
1592
+ if (result === "FAIL" &&
1593
+ (!option(args, "--issue-fingerprint") || !option(args, "--root-cause")))
662
1594
  throw new Error("FAIL requires --issue-fingerprint and --root-cause");
663
- if (result === "FAIL" && !["implementation-defect", "contract-changing-defect", "validation-environment-blocker"].includes(option(args, "--root-cause") ?? ""))
1595
+ if (result === "FAIL" &&
1596
+ ![
1597
+ "implementation-defect",
1598
+ "contract-changing-defect",
1599
+ "validation-environment-blocker",
1600
+ ].includes(option(args, "--root-cause") ?? ""))
664
1601
  throw new Error("--root-cause is not a known failure route");
665
- if (result === "SKIPPED" && (option(args, "--skip-approved-by") !== "user" || !option(args, "--skip-reason")))
1602
+ if (result === "SKIPPED" &&
1603
+ (option(args, "--skip-approved-by") !== "user" ||
1604
+ !option(args, "--skip-reason")))
666
1605
  throw new Error("SKIPPED requires --skip-approved-by user and --skip-reason");
667
- const parsed = fs.existsSync(path.join(dir, "implement.md")) ? readStrategyContract(dir) : { contract: null, errors: [] };
1606
+ const parsed = fs.existsSync(path.join(dir, "implement.md"))
1607
+ ? readStrategyContract(dir)
1608
+ : { contract: null, errors: [] };
668
1609
  if (parsed.errors.length && transition !== "parent-integrated")
669
1610
  throw new Error(parsed.errors.join("; "));
670
1611
  const currentContract = contractFingerprint(dir, task, parsed.contract);
671
1612
  const currentArtifact = artifactFingerprint(dir, task, transition, gate);
672
- if (option(args, "--contract-fingerprint") && option(args, "--contract-fingerprint") !== currentContract)
1613
+ if (option(args, "--contract-fingerprint") &&
1614
+ option(args, "--contract-fingerprint") !== currentContract)
673
1615
  throw new Error("contract fingerprint assertion is stale");
674
- if (option(args, "--artifact-fingerprint") && option(args, "--artifact-fingerprint") !== currentArtifact)
1616
+ if (option(args, "--artifact-fingerprint") &&
1617
+ option(args, "--artifact-fingerprint") !== currentArtifact)
675
1618
  throw new Error("artifact fingerprint assertion is stale");
676
1619
  const record = {
677
- schema_version: 1, transition, gate, result, reviewer, evidence, checked_at: new Date().toISOString(),
678
- contract_fingerprint: currentContract, artifact_fingerprint: currentArtifact,
1620
+ schema_version: 1,
1621
+ transition,
1622
+ gate,
1623
+ result,
1624
+ reviewer,
1625
+ evidence,
1626
+ checked_at: new Date().toISOString(),
1627
+ contract_fingerprint: currentContract,
1628
+ artifact_fingerprint: currentArtifact,
679
1629
  issue_fingerprint: result === "FAIL" ? option(args, "--issue-fingerprint") : null,
680
1630
  root_cause: result === "FAIL" ? option(args, "--root-cause") : null,
681
- issue_summary: result === "FAIL" ? option(args, "--issue-summary") ?? null : null,
1631
+ issue_summary: result === "FAIL" ? (option(args, "--issue-summary") ?? null) : null,
682
1632
  consecutive_failures: result === "FAIL" ? 1 : 0,
683
- approved_skip: result === "SKIPPED" ? { approved_by: "user", reason: option(args, "--skip-reason") } : null,
1633
+ approved_skip: result === "SKIPPED"
1634
+ ? { approved_by: "user", reason: option(args, "--skip-reason") }
1635
+ : null,
684
1636
  };
685
1637
  const revision = readKernel({ taskDir: dir, cwd: root }).kernel.revision;
686
- applyKernelRecordGate({ taskDir: dir, cwd: root, expectedRevision: revision, actor: `pactile task record-gate ${reviewer}`,
1638
+ applyKernelRecordGate({
1639
+ taskDir: dir,
1640
+ cwd: root,
1641
+ expectedRevision: revision,
1642
+ actor: `pactile task record-gate ${reviewer}`,
687
1643
  idempotencyKey: `record-gate:${task.id}:${transition}:${gate}:r${revision}`,
688
- transition, gateName: gate, record, evidence });
1644
+ transition,
1645
+ gateName: gate,
1646
+ record,
1647
+ evidence,
1648
+ });
689
1649
  console.log(`${transition}/${gate}: ${result}`);
690
1650
  return 0;
691
1651
  }
@@ -702,15 +1662,25 @@ function recordAcEvidence(root, args) {
702
1662
  const equal = assignment.indexOf("=");
703
1663
  if (equal < 0)
704
1664
  throw new Error("--map must be AC-N=reference");
705
- mappings.push({ ac_id: assignment.slice(0, equal), evidence_ref: assignment.slice(equal + 1) });
1665
+ mappings.push({
1666
+ ac_id: assignment.slice(0, equal),
1667
+ evidence_ref: assignment.slice(equal + 1),
1668
+ });
706
1669
  index += 1;
707
1670
  }
708
1671
  if (!mappings.length)
709
1672
  throw new Error("at least one --map AC-N=reference is required");
710
1673
  const codeRef = requireArgument(option(args, "--code-ref"), "--code-ref");
711
- const ledger = buildAcEvidenceLedger({ acceptanceItems: parseAcceptanceItems(prd), mappings,
712
- sourceFingerprint: qualityFingerprint(prd), evidenceFingerprint: qualityFingerprint(verify), testedCodeFingerprint: codeRef });
713
- patchTask(root, reference, {}, "record-ac-evidence", { ac_evidence_ledger: ledger });
1674
+ const ledger = buildAcEvidenceLedger({
1675
+ acceptanceItems: parseAcceptanceItems(prd),
1676
+ mappings,
1677
+ sourceFingerprint: qualityFingerprint(prd),
1678
+ evidenceFingerprint: qualityFingerprint(verify),
1679
+ testedCodeFingerprint: codeRef,
1680
+ });
1681
+ patchTask(root, reference, {}, "record-ac-evidence", {
1682
+ ac_evidence_ledger: ledger,
1683
+ });
714
1684
  console.log(`AC evidence ledger recorded: ${ledger.items.length} mapped criteria`);
715
1685
  return 0;
716
1686
  }
@@ -730,9 +1700,20 @@ function recordIndependentCheck(root, args) {
730
1700
  const reviewer = option(args, "--reviewer");
731
1701
  if (mode === "true-independent" && result === "PASS" && !reviewer)
732
1702
  throw new Error("true-independent PASS requires --reviewer");
733
- const verdict = { schema_version: 1, mode, readonly: true, result, evidence,
734
- independent_worker: independentWorker, reviewer: reviewer ?? null, code_fingerprint: codeRef, checked_at: new Date().toISOString() };
735
- patchTask(root, reference, {}, "record-independent-check", { independent_check: verdict });
1703
+ const verdict = {
1704
+ schema_version: 1,
1705
+ mode,
1706
+ readonly: true,
1707
+ result,
1708
+ evidence,
1709
+ independent_worker: independentWorker,
1710
+ reviewer: reviewer ?? null,
1711
+ code_fingerprint: codeRef,
1712
+ checked_at: new Date().toISOString(),
1713
+ };
1714
+ patchTask(root, reference, {}, "record-independent-check", {
1715
+ independent_check: verdict,
1716
+ });
736
1717
  console.log(`Independent check: ${result} (${mode})`);
737
1718
  return 0;
738
1719
  }
@@ -742,7 +1723,9 @@ function archiveTask(root, args) {
742
1723
  if (!record)
743
1724
  throw new Error(`task.json not found at ${dir}`);
744
1725
  const guard = checkArchive(dir, record);
745
- const activeChildren = record.children.map((id) => path.join(root, ".pactile", "tasks", id)).filter((candidate) => fs.existsSync(candidate));
1726
+ const activeChildren = record.children
1727
+ .map((id) => path.join(root, ".pactile", "tasks", id))
1728
+ .filter((candidate) => fs.existsSync(candidate));
746
1729
  if (activeChildren.length && !args.includes("--archive-integrated-children"))
747
1730
  guard.errors.push(`active children remain: ${activeChildren.map((candidate) => path.basename(candidate)).join(", ")}; use --archive-integrated-children after preflight`);
748
1731
  if (activeChildren.length && args.includes("--archive-integrated-children")) {
@@ -778,20 +1761,34 @@ function archiveTask(root, args) {
778
1761
  if (fs.existsSync(destination))
779
1762
  throw new Error(`Archive destination already exists: ${destination}`);
780
1763
  const revision = readKernel({ taskDir: dir, cwd: root }).kernel.revision;
781
- const archivedRelative = path.relative(root, destination).replaceAll("\\", "/");
1764
+ const archivedRelative = path
1765
+ .relative(root, destination)
1766
+ .replaceAll("\\", "/");
782
1767
  const verifyText = fs.readFileSync(path.join(dir, "verify.md"), "utf8");
783
- const acceptance = verifyText.match(/^\s*(?:[-*]\s*)?(?:(?:final|user)\s+)?acceptance(?:\s+evidence)?\s*:\s*(\S[^\r\n]*)$/im)?.[1]?.trim();
784
- const points = acceptance ? [{ text: acceptance, source: "verify.md", confidence: "low" }] : [];
1768
+ const acceptance = verifyText
1769
+ .match(/^\s*(?:[-*]\s*)?(?:(?:final|user)\s+)?acceptance(?:\s+evidence)?\s*:\s*(\S[^\r\n]*)$/im)?.[1]
1770
+ ?.trim();
1771
+ const points = acceptance
1772
+ ? [{ text: acceptance, source: "verify.md", confidence: "low" }]
1773
+ : [];
785
1774
  const notesProjection = {
786
1775
  schema_version: 1,
787
- summary: points.map((point) => point.text).join("; ").split(/\s+/).slice(0, 150).join(" "),
1776
+ summary: points
1777
+ .map((point) => point.text)
1778
+ .join("; ")
1779
+ .split(/\s+/)
1780
+ .slice(0, 150)
1781
+ .join(" "),
788
1782
  pointers: [archivedRelative, `${archivedRelative}/verify.md`],
789
1783
  source: "cmd_archive",
790
1784
  points,
791
1785
  };
792
1786
  applyKernelArchive({
793
- taskDir: dir, cwd: root, expectedRevision: revision,
794
- actor: "pactile task archive", idempotencyKey: `archive:${path.basename(dir)}:${completedAt}`,
1787
+ taskDir: dir,
1788
+ cwd: root,
1789
+ expectedRevision: revision,
1790
+ actor: "pactile task archive",
1791
+ idempotencyKey: `archive:${path.basename(dir)}:${completedAt}`,
795
1792
  evidence: "pactile task archive",
796
1793
  record: { ...record, status: "completed", completedAt },
797
1794
  extras: { notes_projection: notesProjection },
@@ -802,14 +1799,24 @@ function archiveTask(root, args) {
802
1799
  const selected = resolveSelectedTask(root);
803
1800
  if (selected.taskPath === `.pactile/tasks/${path.basename(dir)}`)
804
1801
  exitTask(root);
805
- if (!args.includes("--no-commit") && readPactileConfig(root).session_auto_commit !== "false") {
1802
+ if (!args.includes("--no-commit") &&
1803
+ readPactileConfig(root).session_auto_commit !== "false") {
806
1804
  const relativeSource = path.relative(root, dir).replaceAll("\\", "/");
807
- const relativeDestination = path.relative(root, destination).replaceAll("\\", "/");
1805
+ const relativeDestination = path
1806
+ .relative(root, destination)
1807
+ .replaceAll("\\", "/");
808
1808
  let isRepo = false;
809
1809
  try {
810
- isRepo = execFileSync("git", ["rev-parse", "--is-inside-work-tree"], { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim() === "true";
1810
+ isRepo =
1811
+ execFileSync("git", ["rev-parse", "--is-inside-work-tree"], {
1812
+ cwd: root,
1813
+ encoding: "utf8",
1814
+ stdio: ["ignore", "pipe", "ignore"],
1815
+ }).trim() === "true";
1816
+ }
1817
+ catch {
1818
+ /* Archive remains valid in a non-Git project. */
811
1819
  }
812
- catch { /* Archive remains valid in a non-Git project. */ }
813
1820
  try {
814
1821
  if (isRepo) {
815
1822
  let ignored = false;
@@ -817,11 +1824,21 @@ function archiveTask(root, args) {
817
1824
  execFileSync("git", ["check-ignore", "-q", "--", relativeDestination], { cwd: root, stdio: ["ignore", "pipe", "ignore"] });
818
1825
  ignored = true;
819
1826
  }
820
- catch { /* The archive path is not ignored. */ }
1827
+ catch {
1828
+ /* The archive path is not ignored. */
1829
+ }
821
1830
  if (!ignored) {
822
1831
  execFileSync("git", ["add", "-A", "--", relativeSource, relativeDestination], { cwd: root, stdio: ["ignore", "pipe", "pipe"] });
823
1832
  const message = `chore(task): archive ${path.basename(dir)}`;
824
- execFileSync("git", ["commit", "--only", "-m", message, "--", relativeSource, relativeDestination], { cwd: root, stdio: ["ignore", "pipe", "pipe"] });
1833
+ execFileSync("git", [
1834
+ "commit",
1835
+ "--only",
1836
+ "-m",
1837
+ message,
1838
+ "--",
1839
+ relativeSource,
1840
+ relativeDestination,
1841
+ ], { cwd: root, stdio: ["ignore", "pipe", "pipe"] });
825
1842
  }
826
1843
  }
827
1844
  }
@@ -837,32 +1854,80 @@ export function runTaskCli(argv, root = process.cwd()) {
837
1854
  const [command, ...args] = argv;
838
1855
  try {
839
1856
  switch (command) {
1857
+ case "schedule":
1858
+ return runTaskScheduleCli(args, root);
840
1859
  case "create":
841
1860
  createTask(args, root);
842
1861
  return 0;
843
- case "start-execution": return startExecution(root, args);
844
- case "record-gate": return recordGate(root, args);
845
- case "record-ac-evidence": return recordAcEvidence(root, args);
846
- case "record-independent-check": return recordIndependentCheck(root, args);
1862
+ case "legacy-create":
1863
+ createLegacyTask(args, root);
1864
+ return 0;
1865
+ case "show":
1866
+ return showTask(root, args);
1867
+ case "artifacts":
1868
+ return taskArtifacts(root, args);
1869
+ case "add-dependency": {
1870
+ const reference = requireArgument(args[0], "task");
1871
+ const dependencyId = requireArgument(args[1], "dependency task ID");
1872
+ const { dir, kernel } = taskV2(root, reference);
1873
+ const result = addTaskDependency({
1874
+ root,
1875
+ taskDir: dir,
1876
+ expectedRevision: kernel.revision,
1877
+ dependencyId,
1878
+ actor: actor(root, args),
1879
+ idempotencyKey: option(args, "--idempotency-key") ??
1880
+ `dependency:${kernel.identity.taskId}:${dependencyId}`,
1881
+ });
1882
+ console.log(`Hard dependency added: ${result.kernel.identity.taskId} -> ${dependencyId}\nKernel revision: ${result.kernel.revision}`);
1883
+ return 0;
1884
+ }
1885
+ case "run-start":
1886
+ return runStartTask(root, args);
1887
+ case "run-resume":
1888
+ return resumeTask(root, args);
1889
+ case "run-result":
1890
+ return runResultTask(root, args);
1891
+ case "review":
1892
+ return reviewTask(root, args);
1893
+ case "close":
1894
+ return closeTask(root, args);
1895
+ case "start-execution":
1896
+ return startExecution(root, args);
1897
+ case "record-gate":
1898
+ return recordGate(root, args);
1899
+ case "record-ac-evidence":
1900
+ return recordAcEvidence(root, args);
1901
+ case "record-independent-check":
1902
+ return recordIndependentCheck(root, args);
847
1903
  case "add-subtask":
848
1904
  linkChild(root, requireArgument(args[0], "parent task"), requireArgument(args[1], "child task"));
849
1905
  return 0;
850
1906
  case "remove-subtask":
851
1907
  unlinkChild(root, requireArgument(args[0], "parent task"), requireArgument(args[1], "child task"));
852
1908
  return 0;
853
- case "prepare-child-worktree": return prepareChildWorktree(root, args);
854
- case "set-child-state": return updateChildState(root, args, false);
855
- case "integrate-child": return updateChildState(root, args, true);
856
- case "review-child": return reviewChild(root, args);
1909
+ case "prepare-child-worktree":
1910
+ return prepareChildWorktree(root, args);
1911
+ case "set-child-state":
1912
+ return updateChildState(root, args, false);
1913
+ case "integrate-child":
1914
+ return updateChildState(root, args, true);
1915
+ case "review-child":
1916
+ return reviewChild(root, args);
857
1917
  case "parent-status": {
858
1918
  const dir = taskDir(root, requireArgument(args[0], "parent task"));
859
1919
  const snapshot = readTaskMap(dir).data;
860
1920
  if (!snapshot)
861
1921
  throw new Error("task-map.md missing");
862
- console.log(args.includes("--json") ? JSON.stringify(snapshot, null, 2) : snapshot.children.map((child) => `${child.id}: ${child.state}`).join("\n"));
1922
+ console.log(args.includes("--json")
1923
+ ? JSON.stringify(snapshot, null, 2)
1924
+ : snapshot.children
1925
+ .map((child) => `${child.id}: ${child.state}`)
1926
+ .join("\n"));
863
1927
  return 0;
864
1928
  }
865
- case "archive": return archiveTask(root, args);
1929
+ case "archive":
1930
+ return archiveTask(root, args);
866
1931
  case "prepare-archive-evidence": {
867
1932
  const dir = taskDir(root, requireArgument(args[0], "task"));
868
1933
  const record = taskRecord(dir);
@@ -896,10 +1961,83 @@ export function runTaskCli(argv, root = process.cwd()) {
896
1961
  }
897
1962
  case "selected": {
898
1963
  const chosen = resolveSelectedTask(root);
1964
+ if (args.includes("--json")) {
1965
+ if (!chosen.taskPath || chosen.stale) {
1966
+ console.log(JSON.stringify({
1967
+ selectedTask: chosen.taskPath,
1968
+ source: chosen.source,
1969
+ stale: chosen.stale,
1970
+ }, null, 2));
1971
+ return chosen.taskPath ? 0 : 1;
1972
+ }
1973
+ const dir = resolveTaskDir(root, chosen.taskPath);
1974
+ const imported = readLegacyTaskImportRecord(root, dir);
1975
+ if (imported && imported.status !== "imported") {
1976
+ console.log(JSON.stringify({
1977
+ taskPath: chosen.taskPath,
1978
+ source: chosen.source,
1979
+ taskId: imported.legacyTaskId,
1980
+ migrationStatus: imported.status,
1981
+ runnable: false,
1982
+ missingDefinitionFields: imported.missingDefinitionFields,
1983
+ coordinationReasons: imported.coordinationReasons,
1984
+ kernelVersion: null,
1985
+ }, null, 2));
1986
+ return 0;
1987
+ }
1988
+ if (!fs.existsSync(path.join(dir, "kernel.json")) && !imported) {
1989
+ const record = taskRecord(dir);
1990
+ console.log(JSON.stringify({
1991
+ taskPath: chosen.taskPath,
1992
+ source: chosen.source,
1993
+ taskId: record?.id ?? null,
1994
+ title: record?.title ?? record?.name ?? null,
1995
+ status: record?.status ?? null,
1996
+ kernelVersion: 0,
1997
+ }, null, 2));
1998
+ return 0;
1999
+ }
2000
+ const read = readTaskKernel({ root, taskDir: dir, cwd: root });
2001
+ const summary = read.kind === "task-kernel-v2"
2002
+ ? {
2003
+ taskId: read.kernel.identity.taskId,
2004
+ title: read.kernel.definition.title,
2005
+ phase: read.kernel.phase,
2006
+ condition: read.kernel.condition,
2007
+ revision: read.kernel.revision,
2008
+ kernelVersion: 2,
2009
+ }
2010
+ : {
2011
+ taskId: read.kernel.kernel.identity.taskId,
2012
+ phase: read.kernel.kernel.phase,
2013
+ condition: read.kernel.kernel.condition,
2014
+ revision: read.kernel.kernel.revision,
2015
+ kernelVersion: 1,
2016
+ };
2017
+ console.log(JSON.stringify({ taskPath: chosen.taskPath, source: chosen.source, ...summary }, null, 2));
2018
+ return 0;
2019
+ }
899
2020
  if (args.includes("--source")) {
900
2021
  console.log(`Selected task: ${chosen.taskPath ?? "(none)"}\nSource: ${chosen.source}`);
901
2022
  if (chosen.stale)
902
2023
  console.log("State: stale");
2024
+ else if (chosen.taskPath) {
2025
+ const dir = resolveTaskDir(root, chosen.taskPath);
2026
+ const imported = readLegacyTaskImportRecord(root, dir);
2027
+ if (imported && imported.status !== "imported") {
2028
+ console.log(`Migration: ${imported.status}; Run unavailable`);
2029
+ }
2030
+ else if (fs.existsSync(path.join(dir, "kernel.json")) ||
2031
+ imported) {
2032
+ const read = readTaskKernel({ root, taskDir: dir, cwd: root });
2033
+ const kernel = read.kind === "task-kernel-v2"
2034
+ ? read.kernel
2035
+ : read.kernel.kernel;
2036
+ console.log(`Kernel: ${read.kind === "task-kernel-v2" ? "v2" : "v1"}\nPhase: ${kernel.phase}\nKernel revision: ${kernel.revision}`);
2037
+ }
2038
+ else
2039
+ console.log("Kernel: unavailable (legacy task.json only)");
2040
+ }
903
2041
  }
904
2042
  else if (chosen.taskPath)
905
2043
  console.log(chosen.taskPath);
@@ -909,7 +2047,9 @@ export function runTaskCli(argv, root = process.cwd()) {
909
2047
  }
910
2048
  case "exit": {
911
2049
  const previous = exitTask(root);
912
- console.log(previous.taskPath ? `Cleared selected task (was: ${previous.taskPath})\nTask status unchanged.` : "No selected task set");
2050
+ console.log(previous.taskPath
2051
+ ? `Cleared selected task (was: ${previous.taskPath})\nTask status unchanged.`
2052
+ : "No selected task set");
913
2053
  return 0;
914
2054
  }
915
2055
  case "add-context": {
@@ -925,26 +2065,46 @@ export function runTaskCli(argv, root = process.cwd()) {
925
2065
  case "set-scope": {
926
2066
  const reference = requireArgument(args[0], "task");
927
2067
  const value = requireArgument(args[1], command === "set-scope" ? "scope" : "branch");
928
- const key = command === "set-branch" ? "branch" : command === "set-base-branch" ? "base_branch" : "scope";
2068
+ const key = command === "set-branch"
2069
+ ? "branch"
2070
+ : command === "set-base-branch"
2071
+ ? "base_branch"
2072
+ : "scope";
929
2073
  patchTask(root, reference, { [key]: value }, command);
930
2074
  console.log(`${key} set to: ${value}`);
931
2075
  return 0;
932
2076
  }
933
2077
  case "set-deps": {
934
2078
  const reference = requireArgument(args[0], "task");
935
- const dependencies = [...new Set(args.slice(1).filter((item) => item.trim()))];
2079
+ const dependencies = [
2080
+ ...new Set(args.slice(1).filter((item) => item.trim())),
2081
+ ];
936
2082
  const dir = taskDir(root, reference);
937
2083
  const record = taskRecord(dir);
938
2084
  if (!record)
939
2085
  throw new Error(`task.json not found at ${dir}`);
940
- const projection = readKernel({ taskDir: dir, cwd: root }).kernel.projection?.extras ?? {};
941
- const rawDeps = record.depends_on;
942
- const oldDeps = Array.isArray(rawDeps) ? rawDeps.filter((item) => typeof item === "string") : [];
2086
+ const projection = readKernel({ taskDir: dir, cwd: root }).kernel.projection?.extras ??
2087
+ {};
2088
+ const rawDeps = record
2089
+ .depends_on;
2090
+ const oldDeps = Array.isArray(rawDeps)
2091
+ ? rawDeps.filter((item) => typeof item === "string")
2092
+ : [];
943
2093
  const graph = readDependencyGraph(projection);
944
- const edges = graph.edges.filter((edge) => !(edge.from === record.id && edge.type === "requires" && oldDeps.includes(edge.to)));
945
- const satisfied = Array.isArray(projection.dependency_satisfied) ? projection.dependency_satisfied.filter((item) => typeof item === "string" && !oldDeps.includes(item)) : [];
946
- patchTask(root, reference, {}, command, { depends_on: dependencies, dependency_graph: { ...graph, edges }, dependency_satisfied: satisfied });
947
- console.log(dependencies.length ? `depends_on set: ${dependencies.join(", ")}` : "depends_on cleared to []");
2094
+ const edges = graph.edges.filter((edge) => !(edge.from === record.id &&
2095
+ edge.type === "requires" &&
2096
+ oldDeps.includes(edge.to)));
2097
+ const satisfied = Array.isArray(projection.dependency_satisfied)
2098
+ ? projection.dependency_satisfied.filter((item) => typeof item === "string" && !oldDeps.includes(item))
2099
+ : [];
2100
+ patchTask(root, reference, {}, command, {
2101
+ depends_on: dependencies,
2102
+ dependency_graph: { ...graph, edges },
2103
+ dependency_satisfied: satisfied,
2104
+ });
2105
+ console.log(dependencies.length
2106
+ ? `depends_on set: ${dependencies.join(", ")}`
2107
+ : "depends_on cleared to []");
948
2108
  return 0;
949
2109
  }
950
2110
  case "set-depends-mode": {
@@ -964,8 +2124,12 @@ export function runTaskCli(argv, root = process.cwd()) {
964
2124
  const reference = option(args, "--task");
965
2125
  if (operation === "get") {
966
2126
  const task = reference ? taskRecord(taskDir(root, reference)) : null;
967
- const taskLocale = task?.meta && typeof task.meta === "object" ? task.meta.artifact_locale : undefined;
968
- console.log(taskLocale === "en" || taskLocale === "zh" ? taskLocale : locale(root));
2127
+ const taskLocale = task?.meta && typeof task.meta === "object"
2128
+ ? task.meta.artifact_locale
2129
+ : undefined;
2130
+ console.log(taskLocale === "en" || taskLocale === "zh"
2131
+ ? taskLocale
2132
+ : locale(root));
969
2133
  return 0;
970
2134
  }
971
2135
  if (operation !== "set")
@@ -982,7 +2146,9 @@ export function runTaskCli(argv, root = process.cwd()) {
982
2146
  return 0;
983
2147
  }
984
2148
  const configFile = path.join(root, ".pactile", "config.yaml");
985
- const content = fs.existsSync(configFile) ? fs.readFileSync(configFile, "utf8") : "# Pactile Configuration\n";
2149
+ const content = fs.existsSync(configFile)
2150
+ ? fs.readFileSync(configFile, "utf8")
2151
+ : "# Pactile Configuration\n";
986
2152
  const replacement = `artifact_locale: ${value}`;
987
2153
  fs.mkdirSync(path.dirname(configFile), { recursive: true });
988
2154
  fs.writeFileSync(configFile, /^\s*artifact_locale:\s*[^\r\n]*/m.test(content)
@@ -1014,7 +2180,7 @@ export function runTaskCli(argv, root = process.cwd()) {
1014
2180
  return 0;
1015
2181
  }
1016
2182
  default:
1017
- console.error("Usage: pactile task <create|start-execution|archive|prepare-archive-evidence|prepare-learning-scaffold|review-child|dashboard|list|select|selected|exit|add-context|validate|list-context|set-branch|set-base-branch|set-scope|set-deps|set-depends-mode> ...");
2183
+ console.error("Usage: pactile task <create|legacy-create|show|artifacts|schedule|add-dependency|run-start|run-resume|run-result|review|close|start-execution|archive|prepare-archive-evidence|prepare-learning-scaffold|review-child|dashboard|list|select|selected|exit|add-context|validate|list-context|set-branch|set-base-branch|set-scope|set-deps|set-depends-mode> ...");
1018
2184
  return 1;
1019
2185
  }
1020
2186
  }
@@ -1023,4 +2189,27 @@ export function runTaskCli(argv, root = process.cwd()) {
1023
2189
  return 1;
1024
2190
  }
1025
2191
  }
2192
+ /** Promise-aware task entry for the existing CLI wrapper's async operations. */
2193
+ export async function runTaskCliAsync(argv, root = process.cwd(), scheduleDispatchOptions = {}) {
2194
+ const [command, operation, ...args] = argv;
2195
+ if (command === "schedule" && operation === "dispatch") {
2196
+ try {
2197
+ return await runTaskScheduleDispatchCli(args, root, scheduleDispatchOptions);
2198
+ }
2199
+ catch (error) {
2200
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
2201
+ return 1;
2202
+ }
2203
+ }
2204
+ if (command === "schedule") {
2205
+ try {
2206
+ return await runTaskScheduleCliAsync([operation ?? "", ...args], root);
2207
+ }
2208
+ catch (error) {
2209
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
2210
+ return 1;
2211
+ }
2212
+ }
2213
+ return runTaskCli(argv, root);
2214
+ }
1026
2215
  //# sourceMappingURL=task.js.map