@caupulican/pi-adaptative 0.81.39 → 0.81.40

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 (667) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +2 -0
  3. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts +2 -0
  4. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +1 -1
  5. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +2 -0
  6. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +1 -1
  7. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +3 -0
  8. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts +9 -0
  9. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
  10. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +290 -107
  11. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
  12. package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +357 -122
  13. package/dist/bundled-resources/skills/tool-call-repair/references/repair-catalogue.md +2 -2
  14. package/dist/cli/args.d.ts +2 -0
  15. package/dist/cli/args.d.ts.map +1 -1
  16. package/dist/cli/args.js +9 -0
  17. package/dist/cli/args.js.map +1 -1
  18. package/dist/core/agent-directory-layout.d.ts +15 -0
  19. package/dist/core/agent-directory-layout.d.ts.map +1 -0
  20. package/dist/core/agent-directory-layout.js +72 -0
  21. package/dist/core/agent-directory-layout.js.map +1 -0
  22. package/dist/core/agent-paths.d.ts +19 -2
  23. package/dist/core/agent-paths.d.ts.map +1 -1
  24. package/dist/core/agent-paths.js +67 -4
  25. package/dist/core/agent-paths.js.map +1 -1
  26. package/dist/core/agent-session-runtime.d.ts +52 -8
  27. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  28. package/dist/core/agent-session-runtime.js +397 -79
  29. package/dist/core/agent-session-runtime.js.map +1 -1
  30. package/dist/core/agent-session-services.d.ts +1 -0
  31. package/dist/core/agent-session-services.d.ts.map +1 -1
  32. package/dist/core/agent-session-services.js +1 -0
  33. package/dist/core/agent-session-services.js.map +1 -1
  34. package/dist/core/agent-session.d.ts +71 -136
  35. package/dist/core/agent-session.d.ts.map +1 -1
  36. package/dist/core/agent-session.js +477 -1318
  37. package/dist/core/agent-session.js.map +1 -1
  38. package/dist/core/autonomy/approval-gate.d.ts +3 -2
  39. package/dist/core/autonomy/approval-gate.d.ts.map +1 -1
  40. package/dist/core/autonomy/approval-gate.js +6 -28
  41. package/dist/core/autonomy/approval-gate.js.map +1 -1
  42. package/dist/core/autonomy/bounded-completion.d.ts +1 -1
  43. package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
  44. package/dist/core/autonomy/bounded-completion.js +1 -1
  45. package/dist/core/autonomy/bounded-completion.js.map +1 -1
  46. package/dist/core/autonomy/contracts.d.ts +20 -12
  47. package/dist/core/autonomy/contracts.d.ts.map +1 -1
  48. package/dist/core/autonomy/contracts.js.map +1 -1
  49. package/dist/core/autonomy/foreground-envelope.d.ts +8 -2
  50. package/dist/core/autonomy/foreground-envelope.d.ts.map +1 -1
  51. package/dist/core/autonomy/foreground-envelope.js +8 -25
  52. package/dist/core/autonomy/foreground-envelope.js.map +1 -1
  53. package/dist/core/autonomy/gates.d.ts.map +1 -1
  54. package/dist/core/autonomy/gates.js +8 -10
  55. package/dist/core/autonomy/gates.js.map +1 -1
  56. package/dist/core/autonomy/lane-private-paths.d.ts +2 -0
  57. package/dist/core/autonomy/lane-private-paths.d.ts.map +1 -0
  58. package/dist/core/autonomy/lane-private-paths.js +16 -0
  59. package/dist/core/autonomy/lane-private-paths.js.map +1 -0
  60. package/dist/core/autonomy/lane-tool-surface.d.ts +10 -0
  61. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  62. package/dist/core/autonomy/lane-tool-surface.js +46 -8
  63. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  64. package/dist/core/autonomy/lane-tracker.d.ts +14 -0
  65. package/dist/core/autonomy/lane-tracker.d.ts.map +1 -1
  66. package/dist/core/autonomy/lane-tracker.js +38 -0
  67. package/dist/core/autonomy/lane-tracker.js.map +1 -1
  68. package/dist/core/autonomy/risk-assessment.d.ts +1 -2
  69. package/dist/core/autonomy/risk-assessment.d.ts.map +1 -1
  70. package/dist/core/autonomy/risk-assessment.js +1 -123
  71. package/dist/core/autonomy/risk-assessment.js.map +1 -1
  72. package/dist/core/autonomy/session-lane-record.d.ts +4 -4
  73. package/dist/core/autonomy/session-lane-record.d.ts.map +1 -1
  74. package/dist/core/autonomy/session-lane-record.js +16 -29
  75. package/dist/core/autonomy/session-lane-record.js.map +1 -1
  76. package/dist/core/autonomy/telemetry-events.d.ts +1 -1
  77. package/dist/core/autonomy/telemetry-events.d.ts.map +1 -1
  78. package/dist/core/autonomy/telemetry-events.js +1 -1
  79. package/dist/core/autonomy/telemetry-events.js.map +1 -1
  80. package/dist/core/autonomy-telemetry.d.ts +7 -7
  81. package/dist/core/autonomy-telemetry.d.ts.map +1 -1
  82. package/dist/core/autonomy-telemetry.js +9 -9
  83. package/dist/core/autonomy-telemetry.js.map +1 -1
  84. package/dist/core/background-lane-controller.d.ts +54 -236
  85. package/dist/core/background-lane-controller.d.ts.map +1 -1
  86. package/dist/core/background-lane-controller.js +140 -1273
  87. package/dist/core/background-lane-controller.js.map +1 -1
  88. package/dist/core/capability-contract.d.ts +4 -0
  89. package/dist/core/capability-contract.d.ts.map +1 -0
  90. package/dist/core/capability-contract.js +28 -0
  91. package/dist/core/capability-contract.js.map +1 -0
  92. package/dist/core/compaction-controller.d.ts +90 -0
  93. package/dist/core/compaction-controller.d.ts.map +1 -0
  94. package/dist/core/compaction-controller.js +452 -0
  95. package/dist/core/compaction-controller.js.map +1 -0
  96. package/dist/core/compaction-support.d.ts +12 -11
  97. package/dist/core/compaction-support.d.ts.map +1 -1
  98. package/dist/core/compaction-support.js.map +1 -1
  99. package/dist/core/context/context-artifacts.d.ts +6 -2
  100. package/dist/core/context/context-artifacts.d.ts.map +1 -1
  101. package/dist/core/context/context-artifacts.js +34 -2
  102. package/dist/core/context/context-artifacts.js.map +1 -1
  103. package/dist/core/context/context-store-retention.d.ts +8 -2
  104. package/dist/core/context/context-store-retention.d.ts.map +1 -1
  105. package/dist/core/context/context-store-retention.js +158 -35
  106. package/dist/core/context/context-store-retention.js.map +1 -1
  107. package/dist/core/context/okf-memory.d.ts.map +1 -1
  108. package/dist/core/context/okf-memory.js +9 -11
  109. package/dist/core/context/okf-memory.js.map +1 -1
  110. package/dist/core/context/sqlite-runtime-index.d.ts.map +1 -1
  111. package/dist/core/context/sqlite-runtime-index.js +6 -8
  112. package/dist/core/context/sqlite-runtime-index.js.map +1 -1
  113. package/dist/core/context-gc.d.ts +3 -0
  114. package/dist/core/context-gc.d.ts.map +1 -1
  115. package/dist/core/context-gc.js +10 -5
  116. package/dist/core/context-gc.js.map +1 -1
  117. package/dist/core/context-pipeline.d.ts.map +1 -1
  118. package/dist/core/context-pipeline.js +9 -4
  119. package/dist/core/context-pipeline.js.map +1 -1
  120. package/dist/core/default-tool-surface.d.ts.map +1 -1
  121. package/dist/core/default-tool-surface.js +1 -0
  122. package/dist/core/default-tool-surface.js.map +1 -1
  123. package/dist/core/delegation/managed-lane-controller.d.ts +34 -0
  124. package/dist/core/delegation/managed-lane-controller.d.ts.map +1 -0
  125. package/dist/core/delegation/managed-lane-controller.js +217 -0
  126. package/dist/core/delegation/managed-lane-controller.js.map +1 -0
  127. package/dist/core/delegation/session-worker-claim.d.ts +44 -0
  128. package/dist/core/delegation/session-worker-claim.d.ts.map +1 -0
  129. package/dist/core/delegation/session-worker-claim.js +98 -0
  130. package/dist/core/delegation/session-worker-claim.js.map +1 -0
  131. package/dist/core/delegation/worker-actions.d.ts +7 -5
  132. package/dist/core/delegation/worker-actions.d.ts.map +1 -1
  133. package/dist/core/delegation/worker-actions.js +20 -4
  134. package/dist/core/delegation/worker-actions.js.map +1 -1
  135. package/dist/core/delegation/{worker-result.d.ts → worker-claim.d.ts} +13 -13
  136. package/dist/core/delegation/worker-claim.d.ts.map +1 -0
  137. package/dist/core/delegation/{worker-result.js → worker-claim.js} +61 -51
  138. package/dist/core/delegation/worker-claim.js.map +1 -0
  139. package/dist/core/delegation/worker-delegation-controller.d.ts +110 -0
  140. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -0
  141. package/dist/core/delegation/worker-delegation-controller.js +861 -0
  142. package/dist/core/delegation/worker-delegation-controller.js.map +1 -0
  143. package/dist/core/delegation/worker-delegation-request.d.ts +11 -0
  144. package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -0
  145. package/dist/core/delegation/worker-delegation-request.js +2 -0
  146. package/dist/core/delegation/worker-delegation-request.js.map +1 -0
  147. package/dist/core/delegation/worker-dispatch-scheduler.d.ts +40 -0
  148. package/dist/core/delegation/worker-dispatch-scheduler.d.ts.map +1 -0
  149. package/dist/core/delegation/worker-dispatch-scheduler.js +93 -0
  150. package/dist/core/delegation/worker-dispatch-scheduler.js.map +1 -0
  151. package/dist/core/delegation/worker-execution-policy.d.ts +62 -0
  152. package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -0
  153. package/dist/core/delegation/worker-execution-policy.js +160 -0
  154. package/dist/core/delegation/worker-execution-policy.js.map +1 -0
  155. package/dist/core/delegation/worker-lane-projection.d.ts +14 -0
  156. package/dist/core/delegation/worker-lane-projection.d.ts.map +1 -0
  157. package/dist/core/delegation/worker-lane-projection.js +100 -0
  158. package/dist/core/delegation/worker-lane-projection.js.map +1 -0
  159. package/dist/core/delegation/worker-lifecycle.d.ts +97 -0
  160. package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -0
  161. package/dist/core/delegation/worker-lifecycle.js +339 -0
  162. package/dist/core/delegation/worker-lifecycle.js.map +1 -0
  163. package/dist/core/delegation/worker-notification-coordinator.d.ts +36 -0
  164. package/dist/core/delegation/worker-notification-coordinator.d.ts.map +1 -0
  165. package/dist/core/delegation/worker-notification-coordinator.js +90 -0
  166. package/dist/core/delegation/worker-notification-coordinator.js.map +1 -0
  167. package/dist/core/delegation/worker-profile-resolver.d.ts +55 -0
  168. package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -0
  169. package/dist/core/delegation/worker-profile-resolver.js +113 -0
  170. package/dist/core/delegation/worker-profile-resolver.js.map +1 -0
  171. package/dist/core/delegation/worker-runner.d.ts +25 -14
  172. package/dist/core/delegation/worker-runner.d.ts.map +1 -1
  173. package/dist/core/delegation/worker-runner.js +122 -53
  174. package/dist/core/delegation/worker-runner.js.map +1 -1
  175. package/dist/core/delegation/worker-task-label.d.ts +3 -0
  176. package/dist/core/delegation/worker-task-label.d.ts.map +1 -0
  177. package/dist/core/delegation/worker-task-label.js +11 -0
  178. package/dist/core/delegation/worker-task-label.js.map +1 -0
  179. package/dist/core/doctor.d.ts +8 -0
  180. package/dist/core/doctor.d.ts.map +1 -1
  181. package/dist/core/doctor.js +32 -1
  182. package/dist/core/doctor.js.map +1 -1
  183. package/dist/core/extensions/index.d.ts +1 -1
  184. package/dist/core/extensions/index.d.ts.map +1 -1
  185. package/dist/core/extensions/index.js.map +1 -1
  186. package/dist/core/extensions/loader.d.ts +5 -1
  187. package/dist/core/extensions/loader.d.ts.map +1 -1
  188. package/dist/core/extensions/loader.js +50 -15
  189. package/dist/core/extensions/loader.js.map +1 -1
  190. package/dist/core/extensions/runner.d.ts.map +1 -1
  191. package/dist/core/extensions/runner.js +6 -0
  192. package/dist/core/extensions/runner.js.map +1 -1
  193. package/dist/core/extensions/storage.d.ts +8 -0
  194. package/dist/core/extensions/storage.d.ts.map +1 -0
  195. package/dist/core/extensions/storage.js +28 -0
  196. package/dist/core/extensions/storage.js.map +1 -0
  197. package/dist/core/extensions/types.d.ts +70 -21
  198. package/dist/core/extensions/types.d.ts.map +1 -1
  199. package/dist/core/extensions/types.js.map +1 -1
  200. package/dist/core/failure-corpus.d.ts +1 -15
  201. package/dist/core/failure-corpus.d.ts.map +1 -1
  202. package/dist/core/failure-corpus.js +9 -37
  203. package/dist/core/failure-corpus.js.map +1 -1
  204. package/dist/core/foreground-recovery-controller.d.ts +52 -0
  205. package/dist/core/foreground-recovery-controller.d.ts.map +1 -0
  206. package/dist/core/foreground-recovery-controller.js +111 -0
  207. package/dist/core/foreground-recovery-controller.js.map +1 -0
  208. package/dist/core/gateways/channel-provider.d.ts +3 -0
  209. package/dist/core/gateways/channel-provider.d.ts.map +1 -1
  210. package/dist/core/gateways/channel-provider.js +31 -6
  211. package/dist/core/gateways/channel-provider.js.map +1 -1
  212. package/dist/core/goals/goal-acceptance.d.ts +11 -0
  213. package/dist/core/goals/goal-acceptance.d.ts.map +1 -0
  214. package/dist/core/goals/goal-acceptance.js +25 -0
  215. package/dist/core/goals/goal-acceptance.js.map +1 -0
  216. package/dist/core/goals/goal-auto-continue-controller.d.ts +27 -0
  217. package/dist/core/goals/goal-auto-continue-controller.d.ts.map +1 -0
  218. package/dist/core/goals/goal-auto-continue-controller.js +93 -0
  219. package/dist/core/goals/goal-auto-continue-controller.js.map +1 -0
  220. package/dist/core/goals/goal-continuation-controller.d.ts +1 -1
  221. package/dist/core/goals/goal-continuation-controller.d.ts.map +1 -1
  222. package/dist/core/goals/goal-continuation-controller.js +10 -0
  223. package/dist/core/goals/goal-continuation-controller.js.map +1 -1
  224. package/dist/core/goals/goal-continuation-prompt.d.ts +1 -1
  225. package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
  226. package/dist/core/goals/goal-continuation-prompt.js +6 -6
  227. package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
  228. package/dist/core/goals/goal-lifecycle.d.ts +20 -0
  229. package/dist/core/goals/goal-lifecycle.d.ts.map +1 -0
  230. package/dist/core/goals/goal-lifecycle.js +17 -0
  231. package/dist/core/goals/goal-lifecycle.js.map +1 -0
  232. package/dist/core/goals/goal-runtime-snapshot.d.ts +11 -9
  233. package/dist/core/goals/goal-runtime-snapshot.d.ts.map +1 -1
  234. package/dist/core/goals/goal-runtime-snapshot.js +10 -8
  235. package/dist/core/goals/goal-runtime-snapshot.js.map +1 -1
  236. package/dist/core/goals/goal-state.d.ts +1 -0
  237. package/dist/core/goals/goal-state.d.ts.map +1 -1
  238. package/dist/core/goals/goal-state.js +7 -10
  239. package/dist/core/goals/goal-state.js.map +1 -1
  240. package/dist/core/goals/goal-tool-core.d.ts +8 -6
  241. package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
  242. package/dist/core/goals/goal-tool-core.js +11 -41
  243. package/dist/core/goals/goal-tool-core.js.map +1 -1
  244. package/dist/core/goals/session-goal-state.d.ts +2 -4
  245. package/dist/core/goals/session-goal-state.d.ts.map +1 -1
  246. package/dist/core/goals/session-goal-state.js +10 -33
  247. package/dist/core/goals/session-goal-state.js.map +1 -1
  248. package/dist/core/human-input.d.ts +100 -0
  249. package/dist/core/human-input.d.ts.map +1 -0
  250. package/dist/core/human-input.js +362 -0
  251. package/dist/core/human-input.js.map +1 -0
  252. package/dist/core/index.d.ts +9 -1
  253. package/dist/core/index.d.ts.map +1 -1
  254. package/dist/core/index.js +9 -1
  255. package/dist/core/index.js.map +1 -1
  256. package/dist/core/{telemetry.d.ts → install-telemetry.d.ts} +1 -1
  257. package/dist/core/install-telemetry.d.ts.map +1 -0
  258. package/dist/core/{telemetry.js → install-telemetry.js} +1 -1
  259. package/dist/core/install-telemetry.js.map +1 -0
  260. package/dist/core/keybindings.d.ts +17 -1
  261. package/dist/core/keybindings.d.ts.map +1 -1
  262. package/dist/core/keybindings.js +24 -6
  263. package/dist/core/keybindings.js.map +1 -1
  264. package/dist/core/learning/learning-audit.d.ts +2 -4
  265. package/dist/core/learning/learning-audit.d.ts.map +1 -1
  266. package/dist/core/learning/learning-audit.js +9 -29
  267. package/dist/core/learning/learning-audit.js.map +1 -1
  268. package/dist/core/learning/learning-gate.d.ts.map +1 -1
  269. package/dist/core/learning/learning-gate.js +1 -6
  270. package/dist/core/learning/learning-gate.js.map +1 -1
  271. package/dist/core/learning/session-learning-decision.d.ts +2 -4
  272. package/dist/core/learning/session-learning-decision.d.ts.map +1 -1
  273. package/dist/core/learning/session-learning-decision.js +9 -29
  274. package/dist/core/learning/session-learning-decision.js.map +1 -1
  275. package/dist/core/memory-controller.d.ts.map +1 -1
  276. package/dist/core/memory-controller.js +4 -4
  277. package/dist/core/memory-controller.js.map +1 -1
  278. package/dist/core/model-capability.d.ts.map +1 -1
  279. package/dist/core/model-capability.js +1 -0
  280. package/dist/core/model-capability.js.map +1 -1
  281. package/dist/core/model-resolver.d.ts +1 -1
  282. package/dist/core/model-resolver.d.ts.map +1 -1
  283. package/dist/core/model-resolver.js +6 -9
  284. package/dist/core/model-resolver.js.map +1 -1
  285. package/dist/core/model-router/intent-classifier.d.ts +1 -4
  286. package/dist/core/model-router/intent-classifier.d.ts.map +1 -1
  287. package/dist/core/model-router/intent-classifier.js +1 -156
  288. package/dist/core/model-router/intent-classifier.js.map +1 -1
  289. package/dist/core/model-router-controller.d.ts.map +1 -1
  290. package/dist/core/model-router-controller.js +2 -2
  291. package/dist/core/model-router-controller.js.map +1 -1
  292. package/dist/core/model-selection-controller.d.ts +4 -4
  293. package/dist/core/model-selection-controller.d.ts.map +1 -1
  294. package/dist/core/model-selection-controller.js.map +1 -1
  295. package/dist/core/model-tool-protocol.d.ts +23 -0
  296. package/dist/core/model-tool-protocol.d.ts.map +1 -0
  297. package/dist/core/model-tool-protocol.js +43 -0
  298. package/dist/core/model-tool-protocol.js.map +1 -0
  299. package/dist/core/models/adaptation-store.d.ts +4 -6
  300. package/dist/core/models/adaptation-store.d.ts.map +1 -1
  301. package/dist/core/models/adaptation-store.js +95 -83
  302. package/dist/core/models/adaptation-store.js.map +1 -1
  303. package/dist/core/models/fitness-store.d.ts +2 -12
  304. package/dist/core/models/fitness-store.d.ts.map +1 -1
  305. package/dist/core/models/fitness-store.js +84 -57
  306. package/dist/core/models/fitness-store.js.map +1 -1
  307. package/dist/core/models/host-state-store.d.ts +34 -0
  308. package/dist/core/models/host-state-store.d.ts.map +1 -0
  309. package/dist/core/models/host-state-store.js +86 -0
  310. package/dist/core/models/host-state-store.js.map +1 -0
  311. package/dist/core/orchestration/agent-resume.d.ts +24 -0
  312. package/dist/core/orchestration/agent-resume.d.ts.map +1 -0
  313. package/dist/core/orchestration/agent-resume.js +90 -0
  314. package/dist/core/orchestration/agent-resume.js.map +1 -0
  315. package/dist/core/orchestration/capability-gateway.d.ts +61 -0
  316. package/dist/core/orchestration/capability-gateway.d.ts.map +1 -0
  317. package/dist/core/orchestration/capability-gateway.js +152 -0
  318. package/dist/core/orchestration/capability-gateway.js.map +1 -0
  319. package/dist/core/orchestration/contracts.d.ts +343 -0
  320. package/dist/core/orchestration/contracts.d.ts.map +1 -0
  321. package/dist/core/orchestration/contracts.js +135 -0
  322. package/dist/core/orchestration/contracts.js.map +1 -0
  323. package/dist/core/orchestration/delegation-ledger.d.ts +56 -0
  324. package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -0
  325. package/dist/core/orchestration/delegation-ledger.js +197 -0
  326. package/dist/core/orchestration/delegation-ledger.js.map +1 -0
  327. package/dist/core/orchestration/event-store.d.ts +83 -0
  328. package/dist/core/orchestration/event-store.d.ts.map +1 -0
  329. package/dist/core/orchestration/event-store.js +560 -0
  330. package/dist/core/orchestration/event-store.js.map +1 -0
  331. package/dist/core/orchestration/lane-tool-manifests.d.ts +9 -0
  332. package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -0
  333. package/dist/core/orchestration/lane-tool-manifests.js +37 -0
  334. package/dist/core/orchestration/lane-tool-manifests.js.map +1 -0
  335. package/dist/core/orchestration/model-binding.d.ts +15 -0
  336. package/dist/core/orchestration/model-binding.d.ts.map +1 -0
  337. package/dist/core/orchestration/model-binding.js +29 -0
  338. package/dist/core/orchestration/model-binding.js.map +1 -0
  339. package/dist/core/orchestration/policy-compiler.d.ts +49 -0
  340. package/dist/core/orchestration/policy-compiler.d.ts.map +1 -0
  341. package/dist/core/orchestration/policy-compiler.js +191 -0
  342. package/dist/core/orchestration/policy-compiler.js.map +1 -0
  343. package/dist/core/orchestration/policy-gate.d.ts +18 -0
  344. package/dist/core/orchestration/policy-gate.d.ts.map +1 -0
  345. package/dist/core/orchestration/policy-gate.js +24 -0
  346. package/dist/core/orchestration/policy-gate.js.map +1 -0
  347. package/dist/core/orchestration/profile-registry.d.ts +51 -0
  348. package/dist/core/orchestration/profile-registry.d.ts.map +1 -0
  349. package/dist/core/orchestration/profile-registry.js +393 -0
  350. package/dist/core/orchestration/profile-registry.js.map +1 -0
  351. package/dist/core/orchestration/profile-store.d.ts +31 -0
  352. package/dist/core/orchestration/profile-store.d.ts.map +1 -0
  353. package/dist/core/orchestration/profile-store.js +136 -0
  354. package/dist/core/orchestration/profile-store.js.map +1 -0
  355. package/dist/core/orchestration/risk-budget.d.ts +9 -0
  356. package/dist/core/orchestration/risk-budget.d.ts.map +1 -0
  357. package/dist/core/orchestration/risk-budget.js +48 -0
  358. package/dist/core/orchestration/risk-budget.js.map +1 -0
  359. package/dist/core/orchestration/task-runtime.d.ts +168 -0
  360. package/dist/core/orchestration/task-runtime.d.ts.map +1 -0
  361. package/dist/core/orchestration/task-runtime.js +1600 -0
  362. package/dist/core/orchestration/task-runtime.js.map +1 -0
  363. package/dist/core/orchestration/work-state-projection.d.ts +32 -0
  364. package/dist/core/orchestration/work-state-projection.d.ts.map +1 -0
  365. package/dist/core/orchestration/work-state-projection.js +116 -0
  366. package/dist/core/orchestration/work-state-projection.js.map +1 -0
  367. package/dist/core/orchestration/worker-execution-contract.d.ts +21 -0
  368. package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -0
  369. package/dist/core/orchestration/worker-execution-contract.js +179 -0
  370. package/dist/core/orchestration/worker-execution-contract.js.map +1 -0
  371. package/dist/core/orchestration/worker-result-adapter.d.ts +21 -0
  372. package/dist/core/orchestration/worker-result-adapter.d.ts.map +1 -0
  373. package/dist/core/orchestration/worker-result-adapter.js +109 -0
  374. package/dist/core/orchestration/worker-result-adapter.js.map +1 -0
  375. package/dist/core/process-identity.d.ts +11 -0
  376. package/dist/core/process-identity.d.ts.map +1 -0
  377. package/dist/core/process-identity.js +26 -0
  378. package/dist/core/process-identity.js.map +1 -0
  379. package/dist/core/process-matrix/codes.d.ts +14 -3
  380. package/dist/core/process-matrix/codes.d.ts.map +1 -1
  381. package/dist/core/process-matrix/codes.js.map +1 -1
  382. package/dist/core/process-matrix/resume-launcher.d.ts +26 -0
  383. package/dist/core/process-matrix/resume-launcher.d.ts.map +1 -0
  384. package/dist/core/process-matrix/resume-launcher.js +62 -0
  385. package/dist/core/process-matrix/resume-launcher.js.map +1 -0
  386. package/dist/core/process-matrix/runtime.d.ts +37 -22
  387. package/dist/core/process-matrix/runtime.d.ts.map +1 -1
  388. package/dist/core/process-matrix/runtime.js +399 -76
  389. package/dist/core/process-matrix/runtime.js.map +1 -1
  390. package/dist/core/process-matrix/store.d.ts +5 -2
  391. package/dist/core/process-matrix/store.d.ts.map +1 -1
  392. package/dist/core/process-matrix/store.js +123 -14
  393. package/dist/core/process-matrix/store.js.map +1 -1
  394. package/dist/core/process-matrix/supervisor.d.ts +10 -7
  395. package/dist/core/process-matrix/supervisor.d.ts.map +1 -1
  396. package/dist/core/process-matrix/supervisor.js +45 -14
  397. package/dist/core/process-matrix/supervisor.js.map +1 -1
  398. package/dist/core/profile-registry.d.ts.map +1 -1
  399. package/dist/core/profile-registry.js +6 -8
  400. package/dist/core/profile-registry.js.map +1 -1
  401. package/dist/core/reflection-controller.d.ts +4 -4
  402. package/dist/core/reflection-controller.d.ts.map +1 -1
  403. package/dist/core/reflection-controller.js +2 -1
  404. package/dist/core/reflection-controller.js.map +1 -1
  405. package/dist/core/reload-blockers.d.ts.map +1 -1
  406. package/dist/core/reload-blockers.js +6 -8
  407. package/dist/core/reload-blockers.js.map +1 -1
  408. package/dist/core/research/evidence-bundle.d.ts.map +1 -1
  409. package/dist/core/research/evidence-bundle.js +1 -6
  410. package/dist/core/research/evidence-bundle.js.map +1 -1
  411. package/dist/core/research/lane-model-resolver.d.ts +33 -0
  412. package/dist/core/research/lane-model-resolver.d.ts.map +1 -0
  413. package/dist/core/research/lane-model-resolver.js +65 -0
  414. package/dist/core/research/lane-model-resolver.js.map +1 -0
  415. package/dist/core/research/model-fitness-controller.d.ts +38 -0
  416. package/dist/core/research/model-fitness-controller.d.ts.map +1 -0
  417. package/dist/core/research/model-fitness-controller.js +106 -0
  418. package/dist/core/research/model-fitness-controller.js.map +1 -0
  419. package/dist/core/research/model-fitness.d.ts +1 -1
  420. package/dist/core/research/model-fitness.d.ts.map +1 -1
  421. package/dist/core/research/model-fitness.js +4 -4
  422. package/dist/core/research/model-fitness.js.map +1 -1
  423. package/dist/core/research/research-gate.d.ts.map +1 -1
  424. package/dist/core/research/research-gate.js +7 -7
  425. package/dist/core/research/research-gate.js.map +1 -1
  426. package/dist/core/research/research-lane-controller.d.ts +62 -0
  427. package/dist/core/research/research-lane-controller.d.ts.map +1 -0
  428. package/dist/core/research/research-lane-controller.js +292 -0
  429. package/dist/core/research/research-lane-controller.js.map +1 -0
  430. package/dist/core/research/session-evidence-bundle.d.ts +2 -4
  431. package/dist/core/research/session-evidence-bundle.d.ts.map +1 -1
  432. package/dist/core/research/session-evidence-bundle.js +10 -46
  433. package/dist/core/research/session-evidence-bundle.js.map +1 -1
  434. package/dist/core/resource-loader.d.ts.map +1 -1
  435. package/dist/core/resource-loader.js +7 -2
  436. package/dist/core/resource-loader.js.map +1 -1
  437. package/dist/core/risk-classifier.d.ts +6 -0
  438. package/dist/core/risk-classifier.d.ts.map +1 -0
  439. package/dist/core/risk-classifier.js +225 -0
  440. package/dist/core/risk-classifier.js.map +1 -0
  441. package/dist/core/runtime-builder.d.ts +26 -20
  442. package/dist/core/runtime-builder.d.ts.map +1 -1
  443. package/dist/core/runtime-builder.js +237 -178
  444. package/dist/core/runtime-builder.js.map +1 -1
  445. package/dist/core/sdk.d.ts +6 -3
  446. package/dist/core/sdk.d.ts.map +1 -1
  447. package/dist/core/sdk.js +61 -24
  448. package/dist/core/sdk.js.map +1 -1
  449. package/dist/core/session-analytics.d.ts.map +1 -1
  450. package/dist/core/session-analytics.js +28 -1
  451. package/dist/core/session-analytics.js.map +1 -1
  452. package/dist/core/session-image-store.d.ts +33 -0
  453. package/dist/core/session-image-store.d.ts.map +1 -0
  454. package/dist/core/session-image-store.js +283 -0
  455. package/dist/core/session-image-store.js.map +1 -0
  456. package/dist/core/session-role.d.ts +6 -4
  457. package/dist/core/session-role.d.ts.map +1 -1
  458. package/dist/core/session-role.js +10 -4
  459. package/dist/core/session-role.js.map +1 -1
  460. package/dist/core/session-snapshot.d.ts +34 -0
  461. package/dist/core/session-snapshot.d.ts.map +1 -0
  462. package/dist/core/session-snapshot.js +68 -0
  463. package/dist/core/session-snapshot.js.map +1 -0
  464. package/dist/core/session-supervision-runtime.d.ts +31 -0
  465. package/dist/core/session-supervision-runtime.d.ts.map +1 -0
  466. package/dist/core/session-supervision-runtime.js +97 -0
  467. package/dist/core/session-supervision-runtime.js.map +1 -0
  468. package/dist/core/settings-manager.d.ts +9 -4
  469. package/dist/core/settings-manager.d.ts.map +1 -1
  470. package/dist/core/settings-manager.js +80 -28
  471. package/dist/core/settings-manager.js.map +1 -1
  472. package/dist/core/tasks/session-task-state.d.ts +2 -4
  473. package/dist/core/tasks/session-task-state.d.ts.map +1 -1
  474. package/dist/core/tasks/session-task-state.js +10 -28
  475. package/dist/core/tasks/session-task-state.js.map +1 -1
  476. package/dist/core/tasks/task-projection.d.ts +20 -0
  477. package/dist/core/tasks/task-projection.d.ts.map +1 -0
  478. package/dist/core/tasks/task-projection.js +47 -0
  479. package/dist/core/tasks/task-projection.js.map +1 -0
  480. package/dist/core/tasks/task-state.d.ts +4 -0
  481. package/dist/core/tasks/task-state.d.ts.map +1 -1
  482. package/dist/core/tasks/task-state.js +28 -11
  483. package/dist/core/tasks/task-state.js.map +1 -1
  484. package/dist/core/tool-capability-policy.d.ts +13 -0
  485. package/dist/core/tool-capability-policy.d.ts.map +1 -0
  486. package/dist/core/tool-capability-policy.js +85 -0
  487. package/dist/core/tool-capability-policy.js.map +1 -0
  488. package/dist/core/tool-protocol-controller.d.ts +91 -0
  489. package/dist/core/tool-protocol-controller.d.ts.map +1 -0
  490. package/dist/core/tool-protocol-controller.js +512 -0
  491. package/dist/core/tool-protocol-controller.js.map +1 -0
  492. package/dist/core/tool-recovery-log-records.d.ts +2 -3
  493. package/dist/core/tool-recovery-log-records.d.ts.map +1 -1
  494. package/dist/core/tool-recovery-log-records.js +9 -35
  495. package/dist/core/tool-recovery-log-records.js.map +1 -1
  496. package/dist/core/tool-selection/tool-performance-store.d.ts +3 -7
  497. package/dist/core/tool-selection/tool-performance-store.d.ts.map +1 -1
  498. package/dist/core/tool-selection/tool-performance-store.js +97 -138
  499. package/dist/core/tool-selection/tool-performance-store.js.map +1 -1
  500. package/dist/core/tools/ask-question.d.ts +124 -0
  501. package/dist/core/tools/ask-question.d.ts.map +1 -0
  502. package/dist/core/tools/ask-question.js +693 -0
  503. package/dist/core/tools/ask-question.js.map +1 -0
  504. package/dist/core/tools/delegate-status.d.ts +31 -3
  505. package/dist/core/tools/delegate-status.d.ts.map +1 -1
  506. package/dist/core/tools/delegate-status.js +149 -29
  507. package/dist/core/tools/delegate-status.js.map +1 -1
  508. package/dist/core/tools/delegate.d.ts +15 -13
  509. package/dist/core/tools/delegate.d.ts.map +1 -1
  510. package/dist/core/tools/delegate.js +108 -23
  511. package/dist/core/tools/delegate.js.map +1 -1
  512. package/dist/core/tools/extensionify.d.ts.map +1 -1
  513. package/dist/core/tools/extensionify.js +1 -0
  514. package/dist/core/tools/extensionify.js.map +1 -1
  515. package/dist/core/tools/goal.d.ts +5 -5
  516. package/dist/core/tools/goal.d.ts.map +1 -1
  517. package/dist/core/tools/goal.js +10 -10
  518. package/dist/core/tools/goal.js.map +1 -1
  519. package/dist/core/tools/model-fitness.d.ts.map +1 -1
  520. package/dist/core/tools/model-fitness.js +2 -2
  521. package/dist/core/tools/model-fitness.js.map +1 -1
  522. package/dist/core/tools/orchestration-panel.d.ts +43 -0
  523. package/dist/core/tools/orchestration-panel.d.ts.map +1 -0
  524. package/dist/core/tools/orchestration-panel.js +168 -0
  525. package/dist/core/tools/orchestration-panel.js.map +1 -0
  526. package/dist/core/tools/run-process.d.ts +26 -0
  527. package/dist/core/tools/run-process.d.ts.map +1 -0
  528. package/dist/core/tools/run-process.js +138 -0
  529. package/dist/core/tools/run-process.js.map +1 -0
  530. package/dist/core/tools/task-steps.d.ts +2 -0
  531. package/dist/core/tools/task-steps.d.ts.map +1 -1
  532. package/dist/core/tools/task-steps.js +102 -0
  533. package/dist/core/tools/task-steps.js.map +1 -1
  534. package/dist/core/tools/tmux-dispatch.d.ts +3 -5
  535. package/dist/core/tools/tmux-dispatch.d.ts.map +1 -1
  536. package/dist/core/tools/tmux-dispatch.js +4 -4
  537. package/dist/core/tools/tmux-dispatch.js.map +1 -1
  538. package/dist/core/tools/windows-shell-engine.d.ts.map +1 -1
  539. package/dist/core/tools/windows-shell-engine.js +4 -6
  540. package/dist/core/tools/windows-shell-engine.js.map +1 -1
  541. package/dist/core/util/bounded-jsonl.d.ts +10 -0
  542. package/dist/core/util/bounded-jsonl.d.ts.map +1 -0
  543. package/dist/core/util/bounded-jsonl.js +75 -0
  544. package/dist/core/util/bounded-jsonl.js.map +1 -0
  545. package/dist/core/util/value-guards.d.ts +5 -0
  546. package/dist/core/util/value-guards.d.ts.map +1 -0
  547. package/dist/core/util/value-guards.js +12 -0
  548. package/dist/core/util/value-guards.js.map +1 -0
  549. package/dist/core/worktree-sync/store.d.ts +3 -3
  550. package/dist/core/worktree-sync/store.d.ts.map +1 -1
  551. package/dist/core/worktree-sync/store.js +10 -5
  552. package/dist/core/worktree-sync/store.js.map +1 -1
  553. package/dist/index.d.ts +13 -3
  554. package/dist/index.d.ts.map +1 -1
  555. package/dist/index.js +12 -2
  556. package/dist/index.js.map +1 -1
  557. package/dist/main.d.ts.map +1 -1
  558. package/dist/main.js +128 -44
  559. package/dist/main.js.map +1 -1
  560. package/dist/migrations.d.ts +4 -6
  561. package/dist/migrations.d.ts.map +1 -1
  562. package/dist/migrations.js +186 -28
  563. package/dist/migrations.js.map +1 -1
  564. package/dist/modes/interactive/clipboard-input.d.ts +7 -1
  565. package/dist/modes/interactive/clipboard-input.d.ts.map +1 -1
  566. package/dist/modes/interactive/clipboard-input.js +44 -6
  567. package/dist/modes/interactive/clipboard-input.js.map +1 -1
  568. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  569. package/dist/modes/interactive/components/settings-selector.js +2 -2
  570. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  571. package/dist/modes/interactive/config-backup.d.ts.map +1 -1
  572. package/dist/modes/interactive/config-backup.js +5 -4
  573. package/dist/modes/interactive/config-backup.js.map +1 -1
  574. package/dist/modes/interactive/extension-ui-host.d.ts +14 -0
  575. package/dist/modes/interactive/extension-ui-host.d.ts.map +1 -1
  576. package/dist/modes/interactive/extension-ui-host.js +76 -15
  577. package/dist/modes/interactive/extension-ui-host.js.map +1 -1
  578. package/dist/modes/interactive/interactive-mode.d.ts +3 -0
  579. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  580. package/dist/modes/interactive/interactive-mode.js +63 -1
  581. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  582. package/dist/modes/interactive/key-handlers.d.ts.map +1 -1
  583. package/dist/modes/interactive/key-handlers.js +1 -1
  584. package/dist/modes/interactive/key-handlers.js.map +1 -1
  585. package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -1
  586. package/dist/modes/interactive/profile-menu-controller.js +7 -7
  587. package/dist/modes/interactive/profile-menu-controller.js.map +1 -1
  588. package/dist/modes/interactive/report-commands.d.ts.map +1 -1
  589. package/dist/modes/interactive/report-commands.js +21 -0
  590. package/dist/modes/interactive/report-commands.js.map +1 -1
  591. package/dist/modes/interactive/session-flow-commands.d.ts +17 -2
  592. package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -1
  593. package/dist/modes/interactive/session-flow-commands.js +50 -17
  594. package/dist/modes/interactive/session-flow-commands.js.map +1 -1
  595. package/dist/modes/interactive/session-io-commands.d.ts.map +1 -1
  596. package/dist/modes/interactive/session-io-commands.js +16 -6
  597. package/dist/modes/interactive/session-io-commands.js.map +1 -1
  598. package/dist/modes/interactive/session-replacement-errors.d.ts +7 -0
  599. package/dist/modes/interactive/session-replacement-errors.d.ts.map +1 -0
  600. package/dist/modes/interactive/session-replacement-errors.js +15 -0
  601. package/dist/modes/interactive/session-replacement-errors.js.map +1 -0
  602. package/dist/modes/interactive/startup-checks.d.ts.map +1 -1
  603. package/dist/modes/interactive/startup-checks.js +1 -1
  604. package/dist/modes/interactive/startup-checks.js.map +1 -1
  605. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  606. package/dist/modes/rpc/rpc-mode.js +82 -23
  607. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  608. package/dist/modes/rpc/rpc-types.d.ts +15 -0
  609. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  610. package/dist/modes/rpc/rpc-types.js +138 -1
  611. package/dist/modes/rpc/rpc-types.js.map +1 -1
  612. package/dist/utils/clipboard-image.d.ts.map +1 -1
  613. package/dist/utils/clipboard-image.js +2 -13
  614. package/dist/utils/clipboard-image.js.map +1 -1
  615. package/dist/utils/clipboard-native.d.ts +1 -0
  616. package/dist/utils/clipboard-native.d.ts.map +1 -1
  617. package/dist/utils/clipboard-native.js.map +1 -1
  618. package/dist/utils/clipboard.d.ts +1 -0
  619. package/dist/utils/clipboard.d.ts.map +1 -1
  620. package/dist/utils/clipboard.js +52 -1
  621. package/dist/utils/clipboard.js.map +1 -1
  622. package/dist/utils/platform.d.ts +3 -0
  623. package/dist/utils/platform.d.ts.map +1 -0
  624. package/dist/utils/platform.js +8 -0
  625. package/dist/utils/platform.js.map +1 -0
  626. package/dist/utils/work-directory.d.ts +11 -0
  627. package/dist/utils/work-directory.d.ts.map +1 -1
  628. package/dist/utils/work-directory.js +30 -9
  629. package/dist/utils/work-directory.js.map +1 -1
  630. package/docs/UI_POLISH_ORCHESTRATION.md +44 -0
  631. package/docs/UI_QUALITY_ORCHESTRATION.md +30 -0
  632. package/docs/docs.json +4 -0
  633. package/docs/extensions.md +62 -2
  634. package/docs/harness-architecture.md +156 -0
  635. package/docs/keybindings.md +11 -1
  636. package/docs/process-matrix.md +59 -26
  637. package/docs/rpc.md +45 -2
  638. package/docs/sessions.md +15 -0
  639. package/docs/settings.md +125 -11
  640. package/docs/task-steps.md +8 -0
  641. package/docs/telemetry.md +19 -0
  642. package/docs/tmux-agent-manager.md +10 -3
  643. package/docs/ui-reference/README.md +9 -0
  644. package/docs/ui-reference/orchestration-after.txt +7 -0
  645. package/docs/ui-reference/orchestration-before.txt +7 -0
  646. package/docs/ui-reference/orchestration-reference.txt +6 -0
  647. package/docs/usage.md +14 -2
  648. package/docs/work-directory.md +19 -8
  649. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  650. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  651. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  652. package/examples/extensions/question.ts +34 -245
  653. package/examples/extensions/questionnaire.ts +41 -407
  654. package/examples/extensions/sandbox/package-lock.json +2 -2
  655. package/examples/extensions/sandbox/package.json +1 -1
  656. package/examples/extensions/with-deps/package-lock.json +2 -2
  657. package/examples/extensions/with-deps/package.json +1 -1
  658. package/npm-shrinkwrap.json +12 -12
  659. package/package.json +4 -4
  660. package/dist/core/delegation/session-worker-result.d.ts +0 -46
  661. package/dist/core/delegation/session-worker-result.d.ts.map +0 -1
  662. package/dist/core/delegation/session-worker-result.js +0 -113
  663. package/dist/core/delegation/session-worker-result.js.map +0 -1
  664. package/dist/core/delegation/worker-result.d.ts.map +0 -1
  665. package/dist/core/delegation/worker-result.js.map +0 -1
  666. package/dist/core/telemetry.d.ts.map +0 -1
  667. package/dist/core/telemetry.js.map +0 -1
@@ -11,47 +11,42 @@
11
11
  * instead be adopted by a new parent). "No new turns" after that point is automatic: a dead
12
12
  * parent injects no further follow-ups, so the worker simply runs out of work to do.
13
13
  * - A MASTER is everything else (no known parent). On startup it scans the matrix for orphaned
14
- * workers (workers whose recorded parent is dead) and, when interactive, ASKS the owner before
15
- * touching anything -- adopt, cooperative cleanup, or leave untouched. Non-interactive: report
16
- * only, zero writes, zero kills.
14
+ * workers (workers whose recorded parent is dead). Workers owned by this exact resumed session
15
+ * are restored automatically; foreign workers remain owner-gated interactively and report-only
16
+ * headlessly.
17
17
  *
18
- * One sanctioned exception to "a worker's entry is written only by that worker": the master
19
- * orphan-scan writes an adoption or a cooperative-cleanup request directly into an ORPHANED
20
- * worker's own entry, but ONLY after explicit owner confirmation (`promptConfirm`) -- mirroring
21
- * the worktree-sync integration lock's dead-owner takeover (a new owner may claim a PROVABLY DEAD
22
- * owner's resource). The worker itself later confirms/applies that grant locally via
23
- * `pollWorkerDirective` and re-writes its own entry -- see `docs/process-matrix.md`. Outside this
24
- * one ask-gated handshake, a master NEVER writes another session's entry, and nothing here ever
25
- * kills a process directly: every termination is either owner-confirmed or the worker's own
26
- * cooperative self-exit.
18
+ * Sanctioned exceptions to "a worker's entry is written only by that worker": an exact resumed
19
+ * parent may restore its recorded ownership, and an owner may explicitly approve adoption or
20
+ * cooperative cleanup of a foreign orphan. The worker later confirms/applies the directive via
21
+ * `pollWorkerDirective` and re-writes its own entry -- see `docs/process-matrix.md`. Outside these
22
+ * identity/approval-fenced handshakes, a master NEVER writes another session's entry, and nothing
23
+ * here ever kills a process directly.
27
24
  */
28
25
  import { hostname as osHostname } from "node:os";
26
+ import { isAgentIdentity } from "../orchestration/agent-resume.js";
27
+ import { getParentPid, getParentSessionId, getProcessTaskRef } from "../process-identity.js";
29
28
  import { getBoundWorktreeLaneKey } from "../worktree-sync/runtime.js";
30
- import { buildEntryId, listEntries, readEntry, writeEntry, writeEntrySync } from "./store.js";
31
- import { applyAdoption, applyHeartbeat, beginWindDown, buildMasterEntry, buildWorkerEntry, detectOrphanedWorkers, markClosed, markResumable, pollWorkerDirective, } from "./supervisor.js";
32
- export const PI_PARENT_PID_ENV = "PI_PARENT_PID";
33
- export const PI_PARENT_SESSION_ENV = "PI_PARENT_SESSION";
34
- /** This process's declared parent pid, from the cross-process env contract. A malformed or
35
- * non-positive value is ignored (never a crash on bad env). */
36
- export function getParentPid(env = process.env) {
37
- const raw = env[PI_PARENT_PID_ENV];
38
- if (raw === undefined)
39
- return undefined;
40
- const value = Number.parseInt(raw, 10);
41
- return Number.isFinite(value) && value > 0 ? value : undefined;
42
- }
43
- /** This process's declared parent sessionId, from the cross-process env contract. */
44
- export function getParentSessionId(env = process.env) {
45
- const value = env[PI_PARENT_SESSION_ENV]?.trim();
46
- return value && value.length > 0 ? value : undefined;
47
- }
29
+ import { buildEntryId, listEntries, readEntry, removeEntryIfUnchanged, writeEntry, writeEntryIfUnchanged, writeEntryIfUnchangedSync, } from "./store.js";
30
+ import { applyAdoption, applyHeartbeat, beginWindDown, buildMasterEntry, buildWorkerEntry, detectOrphanedWorkers, markClosed, markResumable, markTerminal, markTerminalNotificationDelivered, pollWorkerDirective, reconcileMatrix, } from "./supervisor.js";
31
+ export { getOrchestrationAgentId, getParentPid, getParentSessionId, getProcessTaskRef, PI_ORCHESTRATION_AGENT_ID_ENV, PI_PARENT_PID_ENV, PI_PARENT_SESSION_ENV, PI_TASK_REF_ENV, } from "../process-identity.js";
48
32
  const NOOP_HANDLE = { stop: () => { } };
33
+ export const PROCESS_MATRIX_RESUMABLE_RETENTION_MS = 30 * 24 * 60 * 60_000;
49
34
  function describeError(error) {
50
35
  return error instanceof Error ? error.message : String(error);
51
36
  }
52
37
  function nowIso(now) {
53
38
  return new Date(now()).toISOString();
54
39
  }
40
+ function emitRuntimeNotice(config, text) {
41
+ try {
42
+ void Promise.resolve(config.notify(text)).catch((error) => {
43
+ config.onDiagnostic?.(`process-matrix: failed to notify session: ${describeError(error)}`);
44
+ });
45
+ }
46
+ catch (error) {
47
+ config.onDiagnostic?.(`process-matrix: failed to notify session: ${describeError(error)}`);
48
+ }
49
+ }
55
50
  /**
56
51
  * Start the per-session process-matrix runtime. No-op when disabled (byte-identical to not
57
52
  * calling this at all). Never throws: a broken store must surface as a diagnostic, not a startup
@@ -63,6 +58,8 @@ export async function startProcessMatrixRuntime(config) {
63
58
  const now = config.now ?? Date.now;
64
59
  const parentPid = getParentPid();
65
60
  try {
61
+ if (!isAgentIdentity(config.agent))
62
+ throw new TypeError("Process-matrix agent identity is invalid.");
66
63
  if (parentPid !== undefined) {
67
64
  return await startWorkerBranch(config, parentPid, now);
68
65
  }
@@ -78,7 +75,7 @@ export async function startProcessMatrixRuntime(config) {
78
75
  // ---------------------------------------------------------------------------
79
76
  async function startMasterBranch(config, now) {
80
77
  let entry = buildMasterEntry({
81
- sessionId: config.sessionId,
78
+ agent: config.agent,
82
79
  pid: process.pid,
83
80
  hostname: osHostname(),
84
81
  now: nowIso(now),
@@ -90,92 +87,377 @@ async function startMasterBranch(config, now) {
90
87
  config.onDiagnostic?.(`process-matrix: failed to register master entry: ${describeError(error)}`);
91
88
  }
92
89
  let stopped = false;
90
+ let ownsEntry = true;
91
+ let heartbeatTask;
92
+ const lifetime = new AbortController();
93
93
  const heartbeatTimer = setInterval(() => {
94
- if (stopped)
94
+ if (stopped || !ownsEntry || heartbeatTask)
95
95
  return;
96
- entry = applyHeartbeat(entry, nowIso(now));
97
- void writeEntry(config.agentDir, entry).catch((error) => {
96
+ const expected = entry;
97
+ const next = applyHeartbeat(expected, nowIso(now));
98
+ heartbeatTask = writeEntryIfUnchanged(config.agentDir, expected.entryId, expected, next)
99
+ .then((written) => {
100
+ if (written) {
101
+ entry = next;
102
+ return;
103
+ }
104
+ ownsEntry = false;
105
+ lifetime.abort();
106
+ clearInterval(heartbeatTimer);
107
+ process.off("exit", closeOnExit);
108
+ config.onDiagnostic?.("process-matrix: master entry ownership moved to a newer process generation");
109
+ })
110
+ .catch((error) => {
98
111
  config.onDiagnostic?.(`process-matrix: failed to write master heartbeat: ${describeError(error)}`);
112
+ })
113
+ .finally(() => {
114
+ heartbeatTask = undefined;
99
115
  });
100
116
  }, config.settings.heartbeatMs);
101
117
  heartbeatTimer.unref?.();
102
118
  // Best-effort close on process exit. A SIGKILLed master leaving "running" is fine -- reconcile's
103
119
  // own dead-pid detection covers it; this only makes the common clean-exit case tidy.
104
- process.on("exit", () => {
120
+ const closeOnExit = () => {
121
+ if (!ownsEntry)
122
+ return;
105
123
  try {
106
- writeEntrySync(config.agentDir, markClosed(entry, nowIso(now)));
124
+ const closed = markClosed(entry, nowIso(now));
125
+ if (writeEntryIfUnchangedSync(config.agentDir, entry, closed))
126
+ entry = closed;
107
127
  }
108
128
  catch {
109
129
  // Best-effort only -- see module doc.
110
130
  }
131
+ };
132
+ process.once("exit", closeOnExit);
133
+ const maintenance = reconcileAndRunOrphanScan(config, now, lifetime.signal).catch((error) => {
134
+ config.onDiagnostic?.(`process-matrix: maintenance failed: ${describeError(error)}`);
111
135
  });
112
- void runOrphanScan(config, now);
113
136
  return {
114
- stop() {
137
+ async stop() {
138
+ if (stopped)
139
+ return;
115
140
  stopped = true;
141
+ lifetime.abort();
116
142
  clearInterval(heartbeatTimer);
143
+ process.off("exit", closeOnExit);
144
+ await heartbeatTask;
145
+ if (ownsEntry) {
146
+ const closed = markClosed(entry, nowIso(now));
147
+ if (await writeEntryIfUnchanged(config.agentDir, entry.entryId, entry, closed))
148
+ entry = closed;
149
+ }
150
+ await maintenance;
117
151
  },
118
152
  };
119
153
  }
120
- async function runOrphanScan(config, now) {
154
+ async function reconcileAndRunOrphanScan(config, now, signal) {
121
155
  let entries;
122
156
  try {
123
157
  entries = await listEntries(config.agentDir);
124
158
  }
125
159
  catch (error) {
126
- config.onDiagnostic?.(`process-matrix: orphan scan failed to list entries: ${describeError(error)}`);
160
+ config.onDiagnostic?.(`process-matrix: reconciliation failed to list entries: ${describeError(error)}`);
161
+ return;
162
+ }
163
+ if (signal.aborted)
164
+ return;
165
+ const reconciled = reconcileMatrix(entries, {
166
+ isPidAlive: (pid) => pid === process.pid || config.isProcessAlive(pid),
167
+ now: now(),
168
+ resumableTtlMs: PROCESS_MATRIX_RESUMABLE_RETENTION_MS,
169
+ });
170
+ const originalByEntryId = new Map(entries.map((entry) => [entry.entryId, entry]));
171
+ const recoveredEntryIdSet = new Set(reconciled.recoveredEntryIds);
172
+ const [prunedOutcomes, recoveredOutcomes] = await Promise.all([
173
+ Promise.all(reconciled.prunedEntryIds.map((entryId) => {
174
+ const original = originalByEntryId.get(entryId);
175
+ return original ? removeEntryIfUnchanged(config.agentDir, original) : false;
176
+ })),
177
+ Promise.all(reconciled.kept
178
+ .filter((entry) => recoveredEntryIdSet.has(entry.entryId))
179
+ .map((entry) => {
180
+ const original = originalByEntryId.get(entry.entryId);
181
+ return original ? writeEntryIfUnchanged(config.agentDir, entry.entryId, original, entry) : false;
182
+ })),
183
+ ]);
184
+ if (signal.aborted)
127
185
  return;
186
+ const recoveredCount = recoveredOutcomes.filter(Boolean).length;
187
+ const prunedCount = prunedOutcomes.filter(Boolean).length;
188
+ if (recoveredCount > 0) {
189
+ config.onDiagnostic?.(`process-matrix: recovered ${recoveredCount} interrupted Pi worker entr${recoveredCount === 1 ? "y" : "ies"}`);
190
+ }
191
+ if (prunedCount > 0) {
192
+ config.onDiagnostic?.(`process-matrix: pruned ${prunedCount} terminal or expired entr${prunedCount === 1 ? "y" : "ies"}`);
193
+ }
194
+ const currentEntries = await listEntries(config.agentDir);
195
+ await deliverTerminalNotifications(config, currentEntries, now, signal);
196
+ if (signal.aborted)
197
+ return;
198
+ await runOrphanScan(config, currentEntries, now, signal);
199
+ }
200
+ async function deliverTerminalNotifications(config, entries, now, signal) {
201
+ for (const entry of entries) {
202
+ if (signal.aborted ||
203
+ entry.status !== "closed" ||
204
+ !entry.terminal ||
205
+ entry.terminal.notificationDeliveredAt ||
206
+ entry.parentSessionId !== config.agent.resumeContext.sessionId)
207
+ continue;
208
+ try {
209
+ await config.notify(formatTerminalNotification(entry));
210
+ if (signal.aborted)
211
+ return;
212
+ }
213
+ catch (error) {
214
+ config.onDiagnostic?.(`process-matrix: failed to deliver terminal handoff for ${entry.entryId}: ${describeError(error)}`);
215
+ continue;
216
+ }
217
+ try {
218
+ const delivered = markTerminalNotificationDelivered(entry, nowIso(now));
219
+ if (!(await writeEntryIfUnchanged(config.agentDir, entry.entryId, entry, delivered))) {
220
+ config.onDiagnostic?.(`process-matrix: terminal handoff changed before acknowledgement for ${entry.entryId}`);
221
+ }
222
+ }
223
+ catch (error) {
224
+ config.onDiagnostic?.(`process-matrix: failed to acknowledge terminal handoff for ${entry.entryId}: ${describeError(error)}`);
225
+ }
128
226
  }
227
+ }
228
+ function formatTerminalNotification(entry) {
229
+ const terminal = entry.terminal;
230
+ return `process-matrix: resumed agent ${entry.agent.agentId} reached a terminal process state (code ${terminal?.code ?? "none"}, signal ${terminal?.signal ?? "none"}). Inspect its persisted result before continuing.`;
231
+ }
232
+ async function runOrphanScan(config, entries, now, signal) {
129
233
  const orphans = detectOrphanedWorkers(entries, {
130
234
  isPidAlive: config.isProcessAlive,
131
- ownSessionId: config.sessionId,
235
+ ownSessionId: config.agent.resumeContext.sessionId,
132
236
  });
133
237
  if (orphans.length === 0)
134
238
  return;
135
- if (!config.hasUI) {
136
- config.onDiagnostic?.(`process-matrix: found ${orphans.length} orphaned worker(s) with no reachable parent (report-only, non-interactive; nothing written, nothing killed): ${orphans
137
- .map((orphan) => orphan.entryId)
138
- .join(", ")}`);
139
- return;
140
- }
141
239
  for (const orphan of orphans) {
142
- const adopt = await config.promptConfirm(`adopt worker ${orphan.entryId} (lane ${orphan.laneKey ?? "none"})?`);
143
- if (adopt) {
144
- const adopted = applyAdoption(orphan, { parentPid: process.pid, parentSessionId: config.sessionId });
145
- try {
146
- await writeEntry(config.agentDir, adopted);
147
- }
148
- catch (error) {
149
- config.onDiagnostic?.(`process-matrix: failed to write adoption for ${orphan.entryId}: ${describeError(error)}`);
240
+ if (signal.aborted)
241
+ return;
242
+ const recoveryBoundary = getAutomaticRecoveryBoundary(config, orphan);
243
+ const exactResumedParent = recoveryBoundary === undefined;
244
+ if (!config.isProcessAlive(orphan.pid)) {
245
+ if (!exactResumedParent) {
246
+ if (!config.hasUI) {
247
+ reportOwnerGatedOrphan(config, orphan, recoveryBoundary);
248
+ continue;
249
+ }
250
+ const payload = orphan.resumable;
251
+ if (!payload) {
252
+ config.onDiagnostic?.(`process-matrix: dead worker ${orphan.entryId} is not resumable because its launch context is unavailable`);
253
+ continue;
254
+ }
255
+ const resume = await config.promptConfirm(`resume agent ${payload.agent.agentId} from its persisted session?`);
256
+ if (!resume || signal.aborted)
257
+ continue;
150
258
  }
259
+ await resumeDeadOrphan(config, orphan, signal);
260
+ continue;
261
+ }
262
+ if (exactResumedParent) {
263
+ await adoptLiveOrphan(config, orphan, signal);
264
+ continue;
265
+ }
266
+ if (!config.hasUI) {
267
+ reportOwnerGatedOrphan(config, orphan, recoveryBoundary);
268
+ continue;
269
+ }
270
+ const adopt = await config.promptConfirm(`adopt worker ${orphan.entryId} (lane ${orphan.agent.resumeContext.worktreeLaneKey ?? "none"})?`);
271
+ if (signal.aborted)
272
+ return;
273
+ if (adopt) {
274
+ await adoptLiveOrphan(config, orphan, signal);
151
275
  continue;
152
276
  }
153
277
  const cleanup = await config.promptConfirm(`clean up worker ${orphan.entryId} gracefully?`);
154
- if (!cleanup)
278
+ if (!cleanup || signal.aborted)
155
279
  continue;
156
280
  const windingDown = beginWindDown(orphan, "user_cleanup", nowIso(now));
157
281
  try {
158
- await writeEntry(config.agentDir, windingDown);
282
+ if (!(await writeEntryIfUnchanged(config.agentDir, orphan.entryId, orphan, windingDown))) {
283
+ config.onDiagnostic?.(`process-matrix: cleanup skipped because ${orphan.entryId} changed`);
284
+ }
159
285
  }
160
286
  catch (error) {
161
287
  config.onDiagnostic?.(`process-matrix: failed to write cleanup for ${orphan.entryId}: ${describeError(error)}`);
162
288
  }
163
289
  }
164
290
  }
291
+ function getAutomaticRecoveryBoundary(config, orphan) {
292
+ if (orphan.parentSessionId !== config.agent.resumeContext.sessionId)
293
+ return "foreign parent session";
294
+ const entryTaskRef = orphan.taskRef;
295
+ const payloadTaskRef = orphan.resumable?.taskRef;
296
+ if (entryTaskRef !== undefined && payloadTaskRef !== undefined && entryTaskRef !== payloadTaskRef) {
297
+ return "inconsistent persisted task identity";
298
+ }
299
+ if ((payloadTaskRef ?? entryTaskRef) !== config.taskRef)
300
+ return "task identity does not match the current goal";
301
+ if (config.allowAutomaticRecovery === false)
302
+ return "current goal state does not permit automatic recovery";
303
+ return undefined;
304
+ }
305
+ function reportOwnerGatedOrphan(config, orphan, reason) {
306
+ config.onDiagnostic?.(`process-matrix: found owner-gated orphan ${orphan.entryId} (${reason}; report-only, non-interactive; nothing written, nothing killed)`);
307
+ }
308
+ async function adoptLiveOrphan(config, orphan, signal) {
309
+ if (signal.aborted)
310
+ return;
311
+ const adopted = applyAdoption(orphan, {
312
+ parentPid: process.pid,
313
+ parentSessionId: config.agent.resumeContext.sessionId,
314
+ });
315
+ try {
316
+ if (!(await writeEntryIfUnchanged(config.agentDir, orphan.entryId, orphan, adopted)))
317
+ return;
318
+ if (signal.aborted)
319
+ await writeEntryIfUnchanged(config.agentDir, orphan.entryId, adopted, orphan);
320
+ }
321
+ catch (error) {
322
+ config.onDiagnostic?.(`process-matrix: failed to write adoption for ${orphan.entryId}: ${describeError(error)}`);
323
+ }
324
+ }
325
+ async function resumeDeadOrphan(config, orphan, signal) {
326
+ if (signal.aborted)
327
+ return;
328
+ const payload = orphan.resumable;
329
+ if (!payload || !config.resumeWorker) {
330
+ config.onDiagnostic?.(`process-matrix: dead worker ${orphan.entryId} is not resumable because its launch context or resume launcher is unavailable`);
331
+ return;
332
+ }
333
+ const claimed = applyAdoption(orphan, {
334
+ parentPid: process.pid,
335
+ parentSessionId: config.agent.resumeContext.sessionId,
336
+ });
337
+ let launched;
338
+ try {
339
+ if (!(await writeEntryIfUnchanged(config.agentDir, orphan.entryId, orphan, claimed)))
340
+ return;
341
+ if (signal.aborted) {
342
+ await writeEntryIfUnchanged(config.agentDir, orphan.entryId, claimed, orphan);
343
+ return;
344
+ }
345
+ const launchOutcome = await config.resumeWorker(payload);
346
+ if (!launchOutcome.started) {
347
+ await writeEntryIfUnchanged(config.agentDir, orphan.entryId, claimed, orphan);
348
+ config.onDiagnostic?.(`process-matrix: failed to resume ${orphan.entryId}: ${launchOutcome.reason}`);
349
+ return;
350
+ }
351
+ launched = launchOutcome;
352
+ }
353
+ catch (error) {
354
+ try {
355
+ await writeEntryIfUnchanged(config.agentDir, orphan.entryId, claimed, orphan);
356
+ }
357
+ catch {
358
+ // The original resumable record remains the intended recovery state.
359
+ }
360
+ config.onDiagnostic?.(`process-matrix: failed to resume ${orphan.entryId}: ${describeError(error)}`);
361
+ return;
362
+ }
363
+ const launchedEntry = { ...claimed, pid: launched.pid };
364
+ if (!signal.aborted) {
365
+ try {
366
+ // Bridge the interval before the replacement can self-register. Without its real PID here, a
367
+ // restarted master can mistake this live replacement for the original dead process and spawn
368
+ // a duplicate.
369
+ await writeEntryIfUnchanged(config.agentDir, claimed.entryId, claimed, launchedEntry);
370
+ }
371
+ catch (error) {
372
+ config.onDiagnostic?.(`process-matrix: failed to record resumed worker pid for ${orphan.entryId}: ${describeError(error)}`);
373
+ }
374
+ }
375
+ else {
376
+ config.onDiagnostic?.(`process-matrix: resumed worker ${orphan.entryId} launched after owner shutdown; preserving its terminal handoff only`);
377
+ }
378
+ void launched.completion.then((result) => persistResumedWorkerTerminal(config, launchedEntry, claimed, result, signal), (error) => {
379
+ config.onDiagnostic?.(`process-matrix: resumed agent ${payload.agent.agentId} terminal signal failed: ${describeError(error)}`);
380
+ });
381
+ }
382
+ async function persistResumedWorkerTerminal(config, claimed, preLaunchClaim, result, lifetime) {
383
+ try {
384
+ const observedAt = new Date().toISOString();
385
+ const terminal = markTerminal(claimed, result, observedAt);
386
+ if (await writeEntryIfUnchanged(config.agentDir, claimed.entryId, claimed, terminal)) {
387
+ if (lifetime.aborted)
388
+ return;
389
+ await notifyResumedWorkerTerminal(config, terminal, lifetime);
390
+ return;
391
+ }
392
+ const selfRegistered = await readEntry(config.agentDir, claimed.entryId);
393
+ if (selfRegistered?.pid === claimed.pid) {
394
+ const registeredTerminal = markTerminal(selfRegistered, result, observedAt);
395
+ if (await writeEntryIfUnchanged(config.agentDir, claimed.entryId, selfRegistered, registeredTerminal)) {
396
+ if (lifetime.aborted)
397
+ return;
398
+ await notifyResumedWorkerTerminal(config, registeredTerminal, lifetime);
399
+ return;
400
+ }
401
+ }
402
+ // If recording the spawned PID failed (or shutdown won the race immediately after spawn), the
403
+ // untouched pre-launch claim proves no newer process has taken this logical entry. Upgrade it
404
+ // to the actual exited process before persisting its terminal handoff.
405
+ const fallbackTerminal = markTerminal({ ...preLaunchClaim, pid: claimed.pid }, result, observedAt);
406
+ if (await writeEntryIfUnchanged(config.agentDir, claimed.entryId, preLaunchClaim, fallbackTerminal)) {
407
+ if (lifetime.aborted)
408
+ return;
409
+ await notifyResumedWorkerTerminal(config, fallbackTerminal, lifetime);
410
+ return;
411
+ }
412
+ if (await writeEntryIfUnchanged(config.agentDir, claimed.entryId, undefined, terminal)) {
413
+ if (lifetime.aborted)
414
+ return;
415
+ await notifyResumedWorkerTerminal(config, terminal, lifetime);
416
+ return;
417
+ }
418
+ config.onDiagnostic?.(`process-matrix: ignored stale terminal handoff for ${claimed.entryId}`);
419
+ }
420
+ catch (error) {
421
+ config.onDiagnostic?.(`process-matrix: failed to persist terminal handoff for ${claimed.entryId}: ${describeError(error)}`);
422
+ }
423
+ }
424
+ async function notifyResumedWorkerTerminal(config, terminal, lifetime) {
425
+ if (lifetime.aborted)
426
+ return;
427
+ try {
428
+ await config.notify(formatTerminalNotification(terminal));
429
+ if (lifetime.aborted)
430
+ return;
431
+ const delivered = markTerminalNotificationDelivered(terminal, new Date().toISOString());
432
+ if (!(await writeEntryIfUnchanged(config.agentDir, terminal.entryId, terminal, delivered))) {
433
+ config.onDiagnostic?.(`process-matrix: terminal handoff changed before acknowledgement for ${terminal.entryId}`);
434
+ }
435
+ }
436
+ catch (error) {
437
+ config.onDiagnostic?.(`process-matrix: failed to deliver terminal handoff for ${terminal.entryId}: ${describeError(error)}`);
438
+ }
439
+ }
165
440
  // ---------------------------------------------------------------------------
166
441
  // Worker branch
167
442
  // ---------------------------------------------------------------------------
168
443
  async function startWorkerBranch(config, initialParentPid, now) {
169
444
  const parentSessionId = getParentSessionId();
445
+ const taskRef = (getProcessTaskRef() ?? config.taskRef)?.trim().slice(0, 512) || undefined;
446
+ const taskSummary = config.taskSummary?.trim().slice(0, 2_000) || undefined;
170
447
  const laneKey = getBoundWorktreeLaneKey();
448
+ const contextLaneKey = config.agent.resumeContext.worktreeLaneKey;
449
+ if (laneKey !== contextLaneKey) {
450
+ throw new TypeError(`Process-matrix agent lane '${contextLaneKey ?? "none"}' does not match active lane '${laneKey ?? "none"}'.`);
451
+ }
171
452
  let entry = buildWorkerEntry({
172
- sessionId: config.sessionId,
453
+ agent: config.agent,
173
454
  pid: process.pid,
174
455
  hostname: osHostname(),
175
456
  now: nowIso(now),
176
457
  parentPid: initialParentPid,
177
458
  ...(parentSessionId !== undefined ? { parentSessionId } : {}),
178
- ...(laneKey !== undefined ? { laneKey } : {}),
459
+ ...(taskRef !== undefined ? { taskRef } : {}),
460
+ ...(taskSummary !== undefined ? { taskSummary } : {}),
179
461
  });
180
462
  try {
181
463
  await writeEntry(config.agentDir, entry);
@@ -188,20 +470,53 @@ async function startWorkerBranch(config, initialParentPid, now) {
188
470
  let stopped = false;
189
471
  let timer;
190
472
  let ticking = false;
473
+ let preserveResumableOnExit = false;
474
+ const closeOnExit = (code = null) => {
475
+ if (preserveResumableOnExit)
476
+ return;
477
+ try {
478
+ const terminal = markTerminal(entry, { code, signal: null }, nowIso(now));
479
+ if (writeEntryIfUnchangedSync(config.agentDir, entry, terminal))
480
+ entry = terminal;
481
+ }
482
+ catch {
483
+ // Best-effort. Dead-pid reconciliation remains authoritative.
484
+ }
485
+ };
486
+ process.once("exit", closeOnExit);
191
487
  const stop = () => {
488
+ if (stopped)
489
+ return;
192
490
  stopped = true;
193
491
  if (timer)
194
492
  clearInterval(timer);
195
493
  timer = undefined;
494
+ if (!preserveResumableOnExit)
495
+ closeOnExit();
496
+ process.off("exit", closeOnExit);
196
497
  };
197
- const persist = async (next, failureContext) => {
198
- entry = next;
498
+ const persist = async (expected, next, failureContext) => {
199
499
  try {
200
- await writeEntry(config.agentDir, entry);
500
+ if (await writeEntryIfUnchanged(config.agentDir, expected.entryId, expected, next)) {
501
+ entry = next;
502
+ return true;
503
+ }
504
+ const current = await readEntry(config.agentDir, expected.entryId);
505
+ if (current?.pid === process.pid)
506
+ entry = current;
507
+ else {
508
+ stopped = true;
509
+ if (timer)
510
+ clearInterval(timer);
511
+ timer = undefined;
512
+ process.off("exit", closeOnExit);
513
+ config.onDiagnostic?.("process-matrix: worker entry ownership moved to a newer process generation");
514
+ }
201
515
  }
202
516
  catch (error) {
203
517
  config.onDiagnostic?.(`process-matrix: ${failureContext}: ${describeError(error)}`);
204
518
  }
519
+ return false;
205
520
  };
206
521
  const startHealthyWatch = () => {
207
522
  timer = setInterval(() => {
@@ -221,7 +536,7 @@ async function startWorkerBranch(config, initialParentPid, now) {
221
536
  if (!currentParentSessionId || !config.isProcessAlive(currentParentPid))
222
537
  return false;
223
538
  const parent = await readEntry(config.agentDir, buildEntryId("master", currentParentSessionId));
224
- if (!parent || parent.role !== "master" || parent.sessionId !== currentParentSessionId)
539
+ if (!parent || parent.role !== "master" || parent.agent.resumeContext.sessionId !== currentParentSessionId)
225
540
  return false;
226
541
  if (parent.pid !== currentParentPid || parent.status !== "running")
227
542
  return false;
@@ -243,22 +558,28 @@ async function startWorkerBranch(config, initialParentPid, now) {
243
558
  const directive = pollWorkerDirective(fresh, currentParentPid, { isPidAlive: config.isProcessAlive });
244
559
  if (directive.code !== "user_cleanup")
245
560
  return;
246
- await persist(beginWindDown(fresh, "user_cleanup", nowIso(now)), "failed to write a master-requested worker wind-down");
247
- config.notify("process-matrix: the parent session requested a cooperative cleanup. Winding down.");
561
+ if (!(await persist(fresh, beginWindDown(fresh, "user_cleanup", nowIso(now)), "failed to write a master-requested worker wind-down")))
562
+ return;
563
+ emitRuntimeNotice(config, "process-matrix: the parent session requested a cooperative cleanup. Winding down.");
248
564
  stop();
249
565
  config.requestExit();
250
566
  };
251
567
  const enterWindDown = async () => {
252
- if (timer) {
253
- clearInterval(timer);
254
- timer = undefined;
255
- }
256
568
  const windDownAt = nowIso(now);
257
- const resumable = { lastCode: "resumable" };
258
- if (laneKey !== undefined)
259
- resumable.laneKey = laneKey;
260
- await persist(markResumable(beginWindDown(entry, "parent_lost", windDownAt), resumable, windDownAt), "failed to write worker wind-down");
261
- config.notify(`process-matrix: parent process (pid ${currentParentPid}) is gone. Winding down gracefully; this task is resumable.`);
569
+ const expected = entry;
570
+ const resumable = { lastCode: "resumable", agent: structuredClone(config.agent) };
571
+ if (expected.taskRef !== undefined)
572
+ resumable.taskRef = expected.taskRef;
573
+ if (expected.taskSummary !== undefined)
574
+ resumable.taskSummary = expected.taskSummary;
575
+ const woundDown = markResumable(beginWindDown(expected, "parent_lost", windDownAt), resumable, windDownAt);
576
+ if (!(await persist(expected, woundDown, "failed to write worker wind-down")))
577
+ return;
578
+ if (timer)
579
+ clearInterval(timer);
580
+ timer = undefined;
581
+ preserveResumableOnExit = true;
582
+ emitRuntimeNotice(config, `process-matrix: parent process (pid ${currentParentPid}) is gone. Winding down gracefully; this task is resumable.`);
262
583
  startGraceWatch();
263
584
  };
264
585
  const startGraceWatch = () => {
@@ -282,10 +603,12 @@ async function startWorkerBranch(config, initialParentPid, now) {
282
603
  if (directive.code === "adopt" && fresh.parentSessionId) {
283
604
  // The adopting master persists its session id with the pid. Require both on the next
284
605
  // healthy tick; accepting a pid-only adoption would reintroduce the PID-reuse bug.
285
- await persist(applyAdoption(fresh, { parentPid: directive.parentPid, parentSessionId: fresh.parentSessionId }), "failed to write worker adoption");
286
- config.notify(`process-matrix: adopted by a new parent (pid ${directive.parentPid}). Resuming.`);
606
+ if (!(await persist(fresh, applyAdoption(fresh, { parentPid: directive.parentPid, parentSessionId: fresh.parentSessionId }), "failed to write worker adoption")))
607
+ return;
608
+ emitRuntimeNotice(config, `process-matrix: adopted by a new parent (pid ${directive.parentPid}). Resuming.`);
287
609
  currentParentPid = directive.parentPid;
288
610
  currentParentSessionId = fresh.parentSessionId;
611
+ preserveResumableOnExit = false;
289
612
  if (timer) {
290
613
  clearInterval(timer);
291
614
  timer = undefined;