@amsterdamdatalabs/enact-operator 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (377) hide show
  1. package/README.md +33 -0
  2. package/dist/index.d.ts +24 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +24 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/lanes/autopilot/index.d.ts +95 -0
  7. package/dist/lanes/autopilot/index.d.ts.map +1 -0
  8. package/dist/lanes/autopilot/index.js +499 -0
  9. package/dist/lanes/autopilot/index.js.map +1 -0
  10. package/dist/lanes/ralph/index.d.ts +118 -0
  11. package/dist/lanes/ralph/index.d.ts.map +1 -0
  12. package/dist/lanes/ralph/index.js +680 -0
  13. package/dist/lanes/ralph/index.js.map +1 -0
  14. package/dist/lanes/team/index.d.ts +110 -0
  15. package/dist/lanes/team/index.d.ts.map +1 -0
  16. package/dist/lanes/team/index.js +748 -0
  17. package/dist/lanes/team/index.js.map +1 -0
  18. package/dist/lanes/team/roles.d.ts +15 -0
  19. package/dist/lanes/team/roles.d.ts.map +1 -0
  20. package/dist/lanes/team/roles.js +89 -0
  21. package/dist/lanes/team/roles.js.map +1 -0
  22. package/dist/lanes/ultrawork/burst.d.ts +69 -0
  23. package/dist/lanes/ultrawork/burst.d.ts.map +1 -0
  24. package/dist/lanes/ultrawork/burst.js +254 -0
  25. package/dist/lanes/ultrawork/burst.js.map +1 -0
  26. package/dist/lanes/ultrawork/index.d.ts +159 -0
  27. package/dist/lanes/ultrawork/index.d.ts.map +1 -0
  28. package/dist/lanes/ultrawork/index.js +919 -0
  29. package/dist/lanes/ultrawork/index.js.map +1 -0
  30. package/dist/lanes/ultrawork/phases.d.ts +57 -0
  31. package/dist/lanes/ultrawork/phases.d.ts.map +1 -0
  32. package/dist/lanes/ultrawork/phases.js +116 -0
  33. package/dist/lanes/ultrawork/phases.js.map +1 -0
  34. package/dist/mcp/activation.d.ts +5 -0
  35. package/dist/mcp/activation.d.ts.map +1 -0
  36. package/dist/mcp/activation.js +234 -0
  37. package/dist/mcp/activation.js.map +1 -0
  38. package/dist/mcp/cli.d.ts +11 -0
  39. package/dist/mcp/cli.d.ts.map +1 -0
  40. package/dist/mcp/cli.js +140 -0
  41. package/dist/mcp/cli.js.map +1 -0
  42. package/dist/mcp/continuation.d.ts +5 -0
  43. package/dist/mcp/continuation.d.ts.map +1 -0
  44. package/dist/mcp/continuation.js +360 -0
  45. package/dist/mcp/continuation.js.map +1 -0
  46. package/dist/mcp/jobs.d.ts +5 -0
  47. package/dist/mcp/jobs.d.ts.map +1 -0
  48. package/dist/mcp/jobs.js +212 -0
  49. package/dist/mcp/jobs.js.map +1 -0
  50. package/dist/mcp/laneSupport.d.ts +19 -0
  51. package/dist/mcp/laneSupport.d.ts.map +1 -0
  52. package/dist/mcp/laneSupport.js +21 -0
  53. package/dist/mcp/laneSupport.js.map +1 -0
  54. package/dist/mcp/lanes/autopilot.d.ts +5 -0
  55. package/dist/mcp/lanes/autopilot.d.ts.map +1 -0
  56. package/dist/mcp/lanes/autopilot.js +227 -0
  57. package/dist/mcp/lanes/autopilot.js.map +1 -0
  58. package/dist/mcp/lanes/ralph.d.ts +5 -0
  59. package/dist/mcp/lanes/ralph.d.ts.map +1 -0
  60. package/dist/mcp/lanes/ralph.js +392 -0
  61. package/dist/mcp/lanes/ralph.js.map +1 -0
  62. package/dist/mcp/lanes/team.d.ts +5 -0
  63. package/dist/mcp/lanes/team.d.ts.map +1 -0
  64. package/dist/mcp/lanes/team.js +413 -0
  65. package/dist/mcp/lanes/team.js.map +1 -0
  66. package/dist/mcp/lanes/ultrawork.d.ts +5 -0
  67. package/dist/mcp/lanes/ultrawork.d.ts.map +1 -0
  68. package/dist/mcp/lanes/ultrawork.js +497 -0
  69. package/dist/mcp/lanes/ultrawork.js.map +1 -0
  70. package/dist/mcp/linkage.d.ts +5 -0
  71. package/dist/mcp/linkage.d.ts.map +1 -0
  72. package/dist/mcp/linkage.js +126 -0
  73. package/dist/mcp/linkage.js.map +1 -0
  74. package/dist/mcp/planning.d.ts +5 -0
  75. package/dist/mcp/planning.d.ts.map +1 -0
  76. package/dist/mcp/planning.js +584 -0
  77. package/dist/mcp/planning.js.map +1 -0
  78. package/dist/mcp/rpcTransport.d.ts +17 -0
  79. package/dist/mcp/rpcTransport.d.ts.map +1 -0
  80. package/dist/mcp/rpcTransport.js +90 -0
  81. package/dist/mcp/rpcTransport.js.map +1 -0
  82. package/dist/mcp/schemas/ralphVerify.d.ts +32 -0
  83. package/dist/mcp/schemas/ralphVerify.d.ts.map +1 -0
  84. package/dist/mcp/schemas/ralphVerify.js +20 -0
  85. package/dist/mcp/schemas/ralphVerify.js.map +1 -0
  86. package/dist/mcp/server.d.ts +5 -0
  87. package/dist/mcp/server.d.ts.map +1 -0
  88. package/dist/mcp/server.js +176 -0
  89. package/dist/mcp/server.js.map +1 -0
  90. package/dist/mcp/system.d.ts +5 -0
  91. package/dist/mcp/system.d.ts.map +1 -0
  92. package/dist/mcp/system.js +445 -0
  93. package/dist/mcp/system.js.map +1 -0
  94. package/dist/mcp/toolFilter.d.ts +2 -0
  95. package/dist/mcp/toolFilter.d.ts.map +1 -0
  96. package/dist/mcp/toolFilter.js +2 -0
  97. package/dist/mcp/toolFilter.js.map +1 -0
  98. package/dist/mcp/toolPartitions.d.ts +20 -0
  99. package/dist/mcp/toolPartitions.d.ts.map +1 -0
  100. package/dist/mcp/toolPartitions.js +280 -0
  101. package/dist/mcp/toolPartitions.js.map +1 -0
  102. package/dist/mcp/toolRuntime.d.ts +9 -0
  103. package/dist/mcp/toolRuntime.d.ts.map +1 -0
  104. package/dist/mcp/toolRuntime.js +179 -0
  105. package/dist/mcp/toolRuntime.js.map +1 -0
  106. package/dist/mcp/workflow.d.ts +12 -0
  107. package/dist/mcp/workflow.d.ts.map +1 -0
  108. package/dist/mcp/workflow.js +723 -0
  109. package/dist/mcp/workflow.js.map +1 -0
  110. package/dist/operator/hooks/hookDispatcher.d.ts +39 -0
  111. package/dist/operator/hooks/hookDispatcher.d.ts.map +1 -0
  112. package/dist/operator/hooks/hookDispatcher.js +58 -0
  113. package/dist/operator/hooks/hookDispatcher.js.map +1 -0
  114. package/dist/operator/hooks/hookGating.d.ts +28 -0
  115. package/dist/operator/hooks/hookGating.d.ts.map +1 -0
  116. package/dist/operator/hooks/hookGating.js +61 -0
  117. package/dist/operator/hooks/hookGating.js.map +1 -0
  118. package/dist/operator/hooks/hooks.d.ts +20 -0
  119. package/dist/operator/hooks/hooks.d.ts.map +1 -0
  120. package/dist/operator/hooks/hooks.js +124 -0
  121. package/dist/operator/hooks/hooks.js.map +1 -0
  122. package/dist/operator/hooks/toolGuardHooks.d.ts +86 -0
  123. package/dist/operator/hooks/toolGuardHooks.d.ts.map +1 -0
  124. package/dist/operator/hooks/toolGuardHooks.js +163 -0
  125. package/dist/operator/hooks/toolGuardHooks.js.map +1 -0
  126. package/dist/operator/hud.d.ts +115 -0
  127. package/dist/operator/hud.d.ts.map +1 -0
  128. package/dist/operator/hud.js +229 -0
  129. package/dist/operator/hud.js.map +1 -0
  130. package/dist/operator/missions.d.ts +125 -0
  131. package/dist/operator/missions.d.ts.map +1 -0
  132. package/dist/operator/missions.js +304 -0
  133. package/dist/operator/missions.js.map +1 -0
  134. package/dist/operator/operatorCore.d.ts +11 -0
  135. package/dist/operator/operatorCore.d.ts.map +1 -0
  136. package/dist/operator/operatorCore.js +9 -0
  137. package/dist/operator/operatorCore.js.map +1 -0
  138. package/dist/operator/operatorRuntimeCore.d.ts +17 -0
  139. package/dist/operator/operatorRuntimeCore.d.ts.map +1 -0
  140. package/dist/operator/operatorRuntimeCore.js +17 -0
  141. package/dist/operator/operatorRuntimeCore.js.map +1 -0
  142. package/dist/operator/runtime.d.ts +74 -0
  143. package/dist/operator/runtime.d.ts.map +1 -0
  144. package/dist/operator/runtime.js +357 -0
  145. package/dist/operator/runtime.js.map +1 -0
  146. package/dist/shared/core/bootstrap.d.ts +16 -0
  147. package/dist/shared/core/bootstrap.d.ts.map +1 -0
  148. package/dist/shared/core/bootstrap.js +77 -0
  149. package/dist/shared/core/bootstrap.js.map +1 -0
  150. package/dist/shared/core/contract.d.ts +71 -0
  151. package/dist/shared/core/contract.d.ts.map +1 -0
  152. package/dist/shared/core/contract.js +452 -0
  153. package/dist/shared/core/contract.js.map +1 -0
  154. package/dist/shared/core/events.d.ts +57 -0
  155. package/dist/shared/core/events.d.ts.map +1 -0
  156. package/dist/shared/core/events.js +36 -0
  157. package/dist/shared/core/events.js.map +1 -0
  158. package/dist/shared/core/jobs.d.ts +46 -0
  159. package/dist/shared/core/jobs.d.ts.map +1 -0
  160. package/dist/shared/core/jobs.js +137 -0
  161. package/dist/shared/core/jobs.js.map +1 -0
  162. package/dist/shared/core/json.d.ts +12 -0
  163. package/dist/shared/core/json.d.ts.map +1 -0
  164. package/dist/shared/core/json.js +52 -0
  165. package/dist/shared/core/json.js.map +1 -0
  166. package/dist/shared/core/layoutMigration.d.ts +11 -0
  167. package/dist/shared/core/layoutMigration.d.ts.map +1 -0
  168. package/dist/shared/core/layoutMigration.js +56 -0
  169. package/dist/shared/core/layoutMigration.js.map +1 -0
  170. package/dist/shared/core/lifecycle.d.ts +61 -0
  171. package/dist/shared/core/lifecycle.d.ts.map +1 -0
  172. package/dist/shared/core/lifecycle.js +123 -0
  173. package/dist/shared/core/lifecycle.js.map +1 -0
  174. package/dist/shared/core/packagePaths.d.ts +2 -0
  175. package/dist/shared/core/packagePaths.d.ts.map +1 -0
  176. package/dist/shared/core/packagePaths.js +9 -0
  177. package/dist/shared/core/packagePaths.js.map +1 -0
  178. package/dist/shared/core/terminology.d.ts +38 -0
  179. package/dist/shared/core/terminology.d.ts.map +1 -0
  180. package/dist/shared/core/terminology.js +54 -0
  181. package/dist/shared/core/terminology.js.map +1 -0
  182. package/dist/shared/core/types.d.ts +30 -0
  183. package/dist/shared/core/types.d.ts.map +1 -0
  184. package/dist/shared/core/types.js +2 -0
  185. package/dist/shared/core/types.js.map +1 -0
  186. package/dist/shared/diagnostics/doctor.d.ts +19 -0
  187. package/dist/shared/diagnostics/doctor.d.ts.map +1 -0
  188. package/dist/shared/diagnostics/doctor.js +82 -0
  189. package/dist/shared/diagnostics/doctor.js.map +1 -0
  190. package/dist/shared/diagnostics/hostRollout.d.ts +16 -0
  191. package/dist/shared/diagnostics/hostRollout.d.ts.map +1 -0
  192. package/dist/shared/diagnostics/hostRollout.js +78 -0
  193. package/dist/shared/diagnostics/hostRollout.js.map +1 -0
  194. package/dist/shared/observability/emit.d.ts +3 -0
  195. package/dist/shared/observability/emit.d.ts.map +1 -0
  196. package/dist/shared/observability/emit.js +17 -0
  197. package/dist/shared/observability/emit.js.map +1 -0
  198. package/dist/shared/observability/testWorkspace.d.ts +4 -0
  199. package/dist/shared/observability/testWorkspace.d.ts.map +1 -0
  200. package/dist/shared/observability/testWorkspace.js +35 -0
  201. package/dist/shared/observability/testWorkspace.js.map +1 -0
  202. package/dist/shared/state/installRegistry.d.ts +22 -0
  203. package/dist/shared/state/installRegistry.d.ts.map +1 -0
  204. package/dist/shared/state/installRegistry.js +51 -0
  205. package/dist/shared/state/installRegistry.js.map +1 -0
  206. package/dist/shared/state/session.d.ts +18 -0
  207. package/dist/shared/state/session.d.ts.map +1 -0
  208. package/dist/shared/state/session.js +127 -0
  209. package/dist/shared/state/session.js.map +1 -0
  210. package/dist/shared/state/state.d.ts +16 -0
  211. package/dist/shared/state/state.d.ts.map +1 -0
  212. package/dist/shared/state/state.js +91 -0
  213. package/dist/shared/state/state.js.map +1 -0
  214. package/dist/shared/state/tasks.d.ts +113 -0
  215. package/dist/shared/state/tasks.d.ts.map +1 -0
  216. package/dist/shared/state/tasks.js +274 -0
  217. package/dist/shared/state/tasks.js.map +1 -0
  218. package/dist/shared/workflow/activation/activeSkill.d.ts +46 -0
  219. package/dist/shared/workflow/activation/activeSkill.d.ts.map +1 -0
  220. package/dist/shared/workflow/activation/activeSkill.js +158 -0
  221. package/dist/shared/workflow/activation/activeSkill.js.map +1 -0
  222. package/dist/shared/workflow/activation/gateProfiles.d.ts +26 -0
  223. package/dist/shared/workflow/activation/gateProfiles.d.ts.map +1 -0
  224. package/dist/shared/workflow/activation/gateProfiles.js +102 -0
  225. package/dist/shared/workflow/activation/gateProfiles.js.map +1 -0
  226. package/dist/shared/workflow/activation/modeMatrix.d.ts +28 -0
  227. package/dist/shared/workflow/activation/modeMatrix.d.ts.map +1 -0
  228. package/dist/shared/workflow/activation/modeMatrix.js +91 -0
  229. package/dist/shared/workflow/activation/modeMatrix.js.map +1 -0
  230. package/dist/shared/workflow/activation/skillActivation.d.ts +74 -0
  231. package/dist/shared/workflow/activation/skillActivation.d.ts.map +1 -0
  232. package/dist/shared/workflow/activation/skillActivation.js +485 -0
  233. package/dist/shared/workflow/activation/skillActivation.js.map +1 -0
  234. package/dist/shared/workflow/activation/skillVariant.d.ts +18 -0
  235. package/dist/shared/workflow/activation/skillVariant.d.ts.map +1 -0
  236. package/dist/shared/workflow/activation/skillVariant.js +44 -0
  237. package/dist/shared/workflow/activation/skillVariant.js.map +1 -0
  238. package/dist/shared/workflow/authority/authority.d.ts +34 -0
  239. package/dist/shared/workflow/authority/authority.d.ts.map +1 -0
  240. package/dist/shared/workflow/authority/authority.js +64 -0
  241. package/dist/shared/workflow/authority/authority.js.map +1 -0
  242. package/dist/shared/workflow/closure/closureManifest.d.ts +39 -0
  243. package/dist/shared/workflow/closure/closureManifest.d.ts.map +1 -0
  244. package/dist/shared/workflow/closure/closureManifest.js +62 -0
  245. package/dist/shared/workflow/closure/closureManifest.js.map +1 -0
  246. package/dist/shared/workflow/closure/closureRequirements.d.ts +12 -0
  247. package/dist/shared/workflow/closure/closureRequirements.d.ts.map +1 -0
  248. package/dist/shared/workflow/closure/closureRequirements.js +30 -0
  249. package/dist/shared/workflow/closure/closureRequirements.js.map +1 -0
  250. package/dist/shared/workflow/closure/contractParity.d.ts +24 -0
  251. package/dist/shared/workflow/closure/contractParity.d.ts.map +1 -0
  252. package/dist/shared/workflow/closure/contractParity.js +238 -0
  253. package/dist/shared/workflow/closure/contractParity.js.map +1 -0
  254. package/dist/shared/workflow/closure/contractParityContext.d.ts +8 -0
  255. package/dist/shared/workflow/closure/contractParityContext.d.ts.map +1 -0
  256. package/dist/shared/workflow/closure/contractParityContext.js +50 -0
  257. package/dist/shared/workflow/closure/contractParityContext.js.map +1 -0
  258. package/dist/shared/workflow/closure/scopeGuard.d.ts +11 -0
  259. package/dist/shared/workflow/closure/scopeGuard.d.ts.map +1 -0
  260. package/dist/shared/workflow/closure/scopeGuard.js +69 -0
  261. package/dist/shared/workflow/closure/scopeGuard.js.map +1 -0
  262. package/dist/shared/workflow/closure/ultragoalArtifact.d.ts +13 -0
  263. package/dist/shared/workflow/closure/ultragoalArtifact.d.ts.map +1 -0
  264. package/dist/shared/workflow/closure/ultragoalArtifact.js +31 -0
  265. package/dist/shared/workflow/closure/ultragoalArtifact.js.map +1 -0
  266. package/dist/shared/workflow/closure/workflowReconcile.d.ts +70 -0
  267. package/dist/shared/workflow/closure/workflowReconcile.d.ts.map +1 -0
  268. package/dist/shared/workflow/closure/workflowReconcile.js +267 -0
  269. package/dist/shared/workflow/closure/workflowReconcile.js.map +1 -0
  270. package/dist/shared/workflow/continuation/continuation.d.ts +109 -0
  271. package/dist/shared/workflow/continuation/continuation.d.ts.map +1 -0
  272. package/dist/shared/workflow/continuation/continuation.js +550 -0
  273. package/dist/shared/workflow/continuation/continuation.js.map +1 -0
  274. package/dist/shared/workflow/continuation/continuationEventReservations.d.ts +17 -0
  275. package/dist/shared/workflow/continuation/continuationEventReservations.d.ts.map +1 -0
  276. package/dist/shared/workflow/continuation/continuationEventReservations.js +88 -0
  277. package/dist/shared/workflow/continuation/continuationEventReservations.js.map +1 -0
  278. package/dist/shared/workflow/continuation/continuationFollowUp.d.ts +114 -0
  279. package/dist/shared/workflow/continuation/continuationFollowUp.d.ts.map +1 -0
  280. package/dist/shared/workflow/continuation/continuationFollowUp.js +330 -0
  281. package/dist/shared/workflow/continuation/continuationFollowUp.js.map +1 -0
  282. package/dist/shared/workflow/continuation/continuationOrchestrator.d.ts +66 -0
  283. package/dist/shared/workflow/continuation/continuationOrchestrator.d.ts.map +1 -0
  284. package/dist/shared/workflow/continuation/continuationOrchestrator.js +144 -0
  285. package/dist/shared/workflow/continuation/continuationOrchestrator.js.map +1 -0
  286. package/dist/shared/workflow/continuation/hookContinuation.d.ts +44 -0
  287. package/dist/shared/workflow/continuation/hookContinuation.d.ts.map +1 -0
  288. package/dist/shared/workflow/continuation/hookContinuation.js +85 -0
  289. package/dist/shared/workflow/continuation/hookContinuation.js.map +1 -0
  290. package/dist/shared/workflow/continuation/stopPolicy.d.ts +38 -0
  291. package/dist/shared/workflow/continuation/stopPolicy.d.ts.map +1 -0
  292. package/dist/shared/workflow/continuation/stopPolicy.js +435 -0
  293. package/dist/shared/workflow/continuation/stopPolicy.js.map +1 -0
  294. package/dist/shared/workflow/continuation/stopVerdict.d.ts +31 -0
  295. package/dist/shared/workflow/continuation/stopVerdict.d.ts.map +1 -0
  296. package/dist/shared/workflow/continuation/stopVerdict.js +98 -0
  297. package/dist/shared/workflow/continuation/stopVerdict.js.map +1 -0
  298. package/dist/shared/workflow/delegation/delegatedSession.d.ts +118 -0
  299. package/dist/shared/workflow/delegation/delegatedSession.d.ts.map +1 -0
  300. package/dist/shared/workflow/delegation/delegatedSession.js +496 -0
  301. package/dist/shared/workflow/delegation/delegatedSession.js.map +1 -0
  302. package/dist/shared/workflow/delegation/delegationPrompt.d.ts +3 -0
  303. package/dist/shared/workflow/delegation/delegationPrompt.d.ts.map +1 -0
  304. package/dist/shared/workflow/delegation/delegationPrompt.js +15 -0
  305. package/dist/shared/workflow/delegation/delegationPrompt.js.map +1 -0
  306. package/dist/shared/workflow/delegation/sessionTasks.d.ts +40 -0
  307. package/dist/shared/workflow/delegation/sessionTasks.d.ts.map +1 -0
  308. package/dist/shared/workflow/delegation/sessionTasks.js +73 -0
  309. package/dist/shared/workflow/delegation/sessionTasks.js.map +1 -0
  310. package/dist/shared/workflow/delegation/subagentRuntime.d.ts +26 -0
  311. package/dist/shared/workflow/delegation/subagentRuntime.d.ts.map +1 -0
  312. package/dist/shared/workflow/delegation/subagentRuntime.js +231 -0
  313. package/dist/shared/workflow/delegation/subagentRuntime.js.map +1 -0
  314. package/dist/shared/workflow/delivery/adoAuxiliaryRuntime.d.ts +79 -0
  315. package/dist/shared/workflow/delivery/adoAuxiliaryRuntime.d.ts.map +1 -0
  316. package/dist/shared/workflow/delivery/adoAuxiliaryRuntime.js +166 -0
  317. package/dist/shared/workflow/delivery/adoAuxiliaryRuntime.js.map +1 -0
  318. package/dist/shared/workflow/delivery/finalWave.d.ts +57 -0
  319. package/dist/shared/workflow/delivery/finalWave.d.ts.map +1 -0
  320. package/dist/shared/workflow/delivery/finalWave.js +123 -0
  321. package/dist/shared/workflow/delivery/finalWave.js.map +1 -0
  322. package/dist/shared/workflow/delivery/lifecyclePushMap.d.ts +68 -0
  323. package/dist/shared/workflow/delivery/lifecyclePushMap.d.ts.map +1 -0
  324. package/dist/shared/workflow/delivery/lifecyclePushMap.js +82 -0
  325. package/dist/shared/workflow/delivery/lifecyclePushMap.js.map +1 -0
  326. package/dist/shared/workflow/delivery/prSidecar.d.ts +7 -0
  327. package/dist/shared/workflow/delivery/prSidecar.d.ts.map +1 -0
  328. package/dist/shared/workflow/delivery/prSidecar.js +4 -0
  329. package/dist/shared/workflow/delivery/prSidecar.js.map +1 -0
  330. package/dist/shared/workflow/delivery/reviewStaleness.d.ts +37 -0
  331. package/dist/shared/workflow/delivery/reviewStaleness.d.ts.map +1 -0
  332. package/dist/shared/workflow/delivery/reviewStaleness.js +94 -0
  333. package/dist/shared/workflow/delivery/reviewStaleness.js.map +1 -0
  334. package/dist/shared/workflow/planning/hyperplan.d.ts +40 -0
  335. package/dist/shared/workflow/planning/hyperplan.d.ts.map +1 -0
  336. package/dist/shared/workflow/planning/hyperplan.js +133 -0
  337. package/dist/shared/workflow/planning/hyperplan.js.map +1 -0
  338. package/dist/shared/workflow/planning/notepad.d.ts +17 -0
  339. package/dist/shared/workflow/planning/notepad.d.ts.map +1 -0
  340. package/dist/shared/workflow/planning/notepad.js +84 -0
  341. package/dist/shared/workflow/planning/notepad.js.map +1 -0
  342. package/dist/shared/workflow/planning/planFormat.d.ts +3 -0
  343. package/dist/shared/workflow/planning/planFormat.d.ts.map +1 -0
  344. package/dist/shared/workflow/planning/planFormat.js +14 -0
  345. package/dist/shared/workflow/planning/planFormat.js.map +1 -0
  346. package/package.json +155 -0
  347. package/runtime/hooks/_continuation.mjs +2 -0
  348. package/runtime/hooks/_lib.mjs +2 -0
  349. package/runtime/hooks/_toolGuards.mjs +2 -0
  350. package/runtime/hooks/lanes/resolveSkillActivation.mjs +241 -0
  351. package/runtime/hooks/lanes/user-prompt-submit.mjs +326 -0
  352. package/runtime/hooks/layout-dir.mjs +2 -0
  353. package/runtime/hooks/lifecycle/pre-compact.mjs +121 -0
  354. package/runtime/hooks/lifecycle/session-start.mjs +356 -0
  355. package/runtime/hooks/lifecycle/stop.mjs +223 -0
  356. package/runtime/hooks/observability.mjs +2 -0
  357. package/runtime/hooks/post-tool-use-failure.mjs +5 -0
  358. package/runtime/hooks/post-tool-use.mjs +4 -0
  359. package/runtime/hooks/pre-compact.mjs +4 -0
  360. package/runtime/hooks/pre-tool-use.mjs +4 -0
  361. package/runtime/hooks/resolveSkillActivation.mjs +4 -0
  362. package/runtime/hooks/root-dir.mjs +2 -0
  363. package/runtime/hooks/session-start.mjs +4 -0
  364. package/runtime/hooks/shared/_continuation.mjs +341 -0
  365. package/runtime/hooks/shared/_lib.mjs +60 -0
  366. package/runtime/hooks/shared/_toolGuards.mjs +237 -0
  367. package/runtime/hooks/shared/config.mjs +143 -0
  368. package/runtime/hooks/shared/layout-dir.mjs +12 -0
  369. package/runtime/hooks/shared/observability.mjs +257 -0
  370. package/runtime/hooks/shared/root-dir.mjs +9 -0
  371. package/runtime/hooks/stop.mjs +4 -0
  372. package/runtime/hooks/subagent-tracker.mjs +4 -0
  373. package/runtime/hooks/subagents/subagent-tracker.mjs +106 -0
  374. package/runtime/hooks/tools/post-tool-use-failure.mjs +251 -0
  375. package/runtime/hooks/tools/post-tool-use.mjs +205 -0
  376. package/runtime/hooks/tools/pre-tool-use.mjs +268 -0
  377. package/runtime/hooks/user-prompt-submit.mjs +4 -0
@@ -0,0 +1,223 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Phase 7 — Stop-hook closure gate.
4
+ * Wraps the original continuation capture with stop-policy evaluation.
5
+ * On deny: writes durable stop-verdict artifact and returns a blocking
6
+ * Stop-hook payload with a human-readable reason so the live loop continues
7
+ * in-session until the goal is actually met.
8
+ * On allow: returns a minimal allow payload.
9
+ *
10
+ * Continuation state is ALWAYS captured (even on deny so the state is
11
+ * preserved for the next session).
12
+ *
13
+ * Policy evaluation is delegated to the compiled stop-policy and authority
14
+ * modules — no inline duplication. I3 (review-pending
15
+ * check) is included automatically via the shared evaluateStopPolicy.
16
+ */
17
+ import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
18
+ import { dirname, join } from "node:path";
19
+ import { execSync } from "node:child_process";
20
+ import { fileURLToPath } from "node:url";
21
+ import { rootDirFrom } from "../shared/root-dir.mjs";
22
+ import { layoutDir, layoutPath } from "../shared/layout-dir.mjs";
23
+ import { emitHookFired, emitStopVerdict, registerHookFailureTrap } from "../shared/observability.mjs";
24
+ import { readHooksVerbose, verboseLog } from "../shared/_lib.mjs";
25
+
26
+ const __filename = fileURLToPath(import.meta.url);
27
+ const __dirname = dirname(__filename);
28
+ const repoRoot = join(__dirname, "..", "..", "..");
29
+
30
+ // Import compiled TS modules (ESM, emitted by tsc into dist/)
31
+ const { evaluateStopPolicy } = await import("@amsterdamdatalabs/enact-operator/stopPolicy");
32
+ const { readOperatorAuthority } = await import("@amsterdamdatalabs/enact-operator/authority");
33
+ const { writeStopVerdict } = await import("@amsterdamdatalabs/enact-operator/stopVerdict");
34
+ const { markContinuationBlocked, resetContinuationState } = await import("@amsterdamdatalabs/enact-operator/continuation");
35
+ const {
36
+ enqueueContinuationFollowUp,
37
+ buildStopDenyDedupeKey,
38
+ fingerprintBlockers,
39
+ } = await import("@amsterdamdatalabs/enact-operator/continuationFollowUp");
40
+ const { captureActiveWorkflows } = await import("@amsterdamdatalabs/enact-operator/hookContinuation");
41
+
42
+ function readStdin() {
43
+ try {
44
+ return JSON.parse(readFileSync(0, "utf8") || "{}");
45
+ } catch {
46
+ return {};
47
+ }
48
+ }
49
+
50
+ function readJson(path, fallback) {
51
+ try {
52
+ return JSON.parse(readFileSync(path, "utf8"));
53
+ } catch {
54
+ return fallback;
55
+ }
56
+ }
57
+
58
+ function writeJson(path, value) {
59
+ mkdirSync(dirname(path), { recursive: true });
60
+ writeFileSync(path, JSON.stringify(value, null, 2), "utf8");
61
+ }
62
+
63
+ // ── Main ──────────────────────────────────────────────────────────────────────
64
+
65
+ const payload = readStdin();
66
+ // Prefer payload.cwd (the actual workspace codex is running in) and resolve the
67
+ // nearest workspace root from there rather than trusting the hook process cwd.
68
+ const root = rootDirFrom(payload?.cwd ?? process.cwd());
69
+ const startedAt = Date.now();
70
+ const completeHook = registerHookFailureTrap({
71
+ payload,
72
+ hookEvent: "Stop",
73
+ startedAt,
74
+ });
75
+ const operatorLayout = layoutDir(root);
76
+ mkdirSync(layoutPath(root, "logs"), { recursive: true });
77
+ mkdirSync(layoutPath(root, "state"), { recursive: true });
78
+ appendFileSync(layoutPath(root, "logs", "hooks.log"), `${new Date().toISOString()} Stop ${JSON.stringify(payload)}\n`, "utf8");
79
+
80
+ // Always capture continuation state (even on deny — preserves active state for next session)
81
+ const activeWorkflows = captureActiveWorkflows(root);
82
+ const capturedAt = activeWorkflows.capturedAt;
83
+
84
+ const runtimePath = join(operatorLayout, "state", "operator-hook-runtime.json");
85
+ const runtime = readJson(runtimePath, {});
86
+ writeJson(runtimePath, { ...runtime, lastStopAt: capturedAt, activeWorkflows });
87
+
88
+ // Evaluate stop policy via the compiled shared evaluator (includes §I3 review-pending check)
89
+ let outcome = "allow";
90
+ let reasons = [];
91
+ try {
92
+ const authority = readOperatorAuthority(root);
93
+ const verdict = evaluateStopPolicy({ authority, root });
94
+ outcome = verdict.outcome;
95
+ reasons = verdict.reasons;
96
+ } catch (err) {
97
+ // If authority read fails, allow stop with a warning rather than hard-blocking
98
+ appendFileSync(join(operatorLayout, "logs", "hooks.log"), `${new Date().toISOString()} Stop policy eval error: ${err?.message ?? String(err)}\n`, "utf8");
99
+ }
100
+
101
+ const commitHash = (() => {
102
+ try { return execSync("git rev-parse HEAD", { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim(); } catch { return "unknown"; }
103
+ })();
104
+
105
+ const verdict = {
106
+ outcome,
107
+ reasons,
108
+ capturedAt,
109
+ evidenceHorizon: {
110
+ commitHash,
111
+ verificationRunId: `vrun_${Math.random().toString(36).slice(2, 14)}`,
112
+ verificationRunTimestamp: capturedAt,
113
+ sessionSequence: 0,
114
+ },
115
+ // transportCanBlock: true — verified in interactive Codex TUI on 2026-05-16.
116
+ // Stop can deny live with the minimal payload shape:
117
+ // { decision:"block", reason:"..." }.
118
+ transportCanBlock: true,
119
+ };
120
+
121
+ const verdictPath = join(operatorLayout, "state", "stop-verdict.json");
122
+ let authority;
123
+ try {
124
+ authority = readOperatorAuthority(root);
125
+ } catch (err) {
126
+ appendFileSync(join(operatorLayout, "logs", "hooks.log"), `${new Date().toISOString()} Stop authority read error (post-verdict): ${err?.message ?? String(err)}\n`, "utf8");
127
+ authority = null;
128
+ }
129
+ writeStopVerdict(root, verdict);
130
+
131
+ // TUI gate — operator stop policy only enforces continuation for explicit autonomous lanes.
132
+ // Interactive TUI sessions must behave like vanilla codex: no auto-stop-policy interference.
133
+ // evaluateExecutor/Reviewer/Ultragoal/PipelineLike can emit deny without an active lane;
134
+ // short-circuit those to allow so the user is never forced to type "continue" in TUI mode.
135
+ const autonomousLaneActive =
136
+ authority?.ralph?.active === true ||
137
+ authority?.ultrawork?.active === true ||
138
+ authority?.autopilot?.active === true ||
139
+ authority?.team?.active === true;
140
+
141
+ if (outcome === "deny" && !autonomousLaneActive) {
142
+ appendFileSync(
143
+ join(operatorLayout, "logs", "hooks.log"),
144
+ `${new Date().toISOString()} Stop policy deny suppressed (TUI mode — no autonomous lane active): ${reasons.map((r) => r.blocker).join("; ")}\n`,
145
+ "utf8",
146
+ );
147
+ resetContinuationState(root, 'tui-gate-bypass', 'stop-hook');
148
+ if (readHooksVerbose(root)) verboseLog("stop", "allow (TUI mode — no autonomous lane active, deny suppressed)");
149
+ completeHook();
150
+ process.stdout.write(JSON.stringify({ continue: true }));
151
+ process.exit(0);
152
+ }
153
+
154
+ if (outcome === "deny") {
155
+ await emitStopVerdict({
156
+ payload,
157
+ verdict: "deny",
158
+ blockers: reasons.map((r) => r.blocker),
159
+ stopHookActive: true,
160
+ latencyMs: Date.now() - startedAt,
161
+ });
162
+ await emitHookFired({
163
+ payload,
164
+ hookEvent: "Stop",
165
+ outcome: "denied",
166
+ latencyMs: Date.now() - startedAt,
167
+ });
168
+ const blockerSummary = reasons.slice(0, 3).map((r) => r.blocker).join("; ");
169
+ const moreCount = reasons.length > 3 ? ` (and ${reasons.length - 3} more)` : "";
170
+ appendFileSync(
171
+ join(operatorLayout, "logs", "hooks.log"),
172
+ `${new Date().toISOString()} Stop policy deny persisted: ${blockerSummary}${moreCount}; verdict=${verdictPath}\n`,
173
+ "utf8",
174
+ );
175
+ const continuation = markContinuationBlocked(root, authority, verdict, {
176
+ sessionId: typeof payload.session_id === 'string' ? payload.session_id : null,
177
+ transcriptPath: typeof payload.transcript_path === 'string' ? payload.transcript_path : null,
178
+ });
179
+ const sid = typeof payload.session_id === "string" ? payload.session_id : null;
180
+ const blockerFp = fingerprintBlockers(reasons.map((r) => r.blocker));
181
+ enqueueContinuationFollowUp(root, {
182
+ sessionId: sid,
183
+ dedupeKey: buildStopDenyDedupeKey({
184
+ sessionId: sid,
185
+ lane: continuation.lane,
186
+ laneId: continuation.laneId,
187
+ blockerFingerprint: blockerFp,
188
+ }),
189
+ trigger: "stop-deny",
190
+ lane: continuation.lane,
191
+ laneId: continuation.laneId,
192
+ prompt: `Operator stop policy denied exit. Resolve blockers, then continue. ${continuation.resumeHint ?? ""}`.trim(),
193
+ });
194
+ // Codex Stop hooks continue the turn when they receive the minimal block
195
+ // contract: decision="block" plus a human-readable reason. Do not emit extra
196
+ // fields here; rely on the durable verdict artifacts for richer evidence.
197
+ if (readHooksVerbose(root)) verboseLog("stop", `deny — ${reasons.length} blocker(s): ${blockerSummary}${moreCount}`);
198
+ process.stdout.write(JSON.stringify({
199
+ decision: "block",
200
+ reason: `Operator stop policy DENY: ${blockerSummary}${moreCount}. Continue working until blockers are resolved. If you need details, inspect the persisted stop verdict and use operator_stop_evaluate for a dry-run recheck. ${continuation.resumeHint ?? ''}`.trim(),
201
+ }));
202
+ completeHook();
203
+ } else {
204
+ await emitStopVerdict({
205
+ payload,
206
+ verdict: "allow",
207
+ blockers: [],
208
+ stopHookActive: true,
209
+ latencyMs: Date.now() - startedAt,
210
+ });
211
+ await emitHookFired({
212
+ payload,
213
+ hookEvent: "Stop",
214
+ outcome: "allowed",
215
+ latencyMs: Date.now() - startedAt,
216
+ });
217
+ resetContinuationState(root, 'stop-allowed', 'stop-hook');
218
+ if (readHooksVerbose(root)) verboseLog("stop", "allow — no blockers, stop policy passed");
219
+ completeHook();
220
+ process.stdout.write(JSON.stringify({
221
+ continue: true,
222
+ }));
223
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./shared/observability.mjs";
2
+
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { runHookScript } from "./tools/post-tool-use-failure.mjs";
4
+
5
+ await runHookScript();
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+
3
+ import "./tools/post-tool-use.mjs";
4
+
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+
3
+ import "./lifecycle/pre-compact.mjs";
4
+
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+
3
+ import "./tools/pre-tool-use.mjs";
4
+
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+
3
+ import "./lanes/resolveSkillActivation.mjs";
4
+
@@ -0,0 +1,2 @@
1
+ export * from "./shared/root-dir.mjs";
2
+
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+
3
+ import "./lifecycle/session-start.mjs";
4
+
@@ -0,0 +1,341 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * _continuation.mjs — Self-contained runtime continuation orchestrator (no build step).
4
+ *
5
+ * TWIN note: src/continuationOrchestrator.ts is the typed twin of this file.
6
+ * If logic changes here it MUST be reflected in the TS twin, and vice-versa.
7
+ * The TS twin imports canonical predicates from src/terminology.ts and
8
+ * src/hookGating.ts; this .mjs file replicates their exact logic inline
9
+ * (those files are TypeScript-only and cannot be imported at runtime).
10
+ *
11
+ * This is the SINGLE SOURCE OF TRUTH for continuation orchestration at runtime.
12
+ * session-start.mjs imports buildContinuationContext from here rather than
13
+ * from dist/ so the SessionStart hook works even when dist/ is absent.
14
+ *
15
+ * Five predecessor surfaces wired here (mirroring the atlas plan):
16
+ * Surface 1 (compaction-context read): restore pending task IDs written by
17
+ * pre-compact.mjs into compaction-context.json.
18
+ * Surface 2 (delegated-session ledger): read delegated-sessions.json written
19
+ * by subagent-tracker to find active/stale delegated sessions.
20
+ * Surface 3 (protected-state guard): all state reads go through layoutPath
21
+ * (operator broker pattern) — never raw filesystem paths exposed externally.
22
+ * Surface 4 (member-turn injection): read continuation-state.json to surface
23
+ * pending task IDs and active lane so the agent resumes with full context.
24
+ * Surface 5 (manual-close filter): filter out tasks closed via
25
+ * task_manual_close or workitem_manual_close ledger kinds from the pending
26
+ * task list, so closed tasks don't block continuation.
27
+ *
28
+ * Run: node -e "import('./runtime/hooks/_continuation.mjs').then(m=>console.log('OK', typeof m.buildContinuationContext))"
29
+ */
30
+
31
+ import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
32
+ import { join, dirname } from 'node:path';
33
+
34
+ // ── Canonical predicates (replicated from src/terminology.ts) ─────────────────
35
+ // Twin note: keep in sync with isManualTaskCloseLedgerKind in src/terminology.ts.
36
+ // The TS version imports from @/terminology.js; we replicate the exact logic here.
37
+ const CANONICAL_LEDGER_KINDS_TASK_MANUAL_CLOSE = 'task_manual_close';
38
+ const CANONICAL_LEDGER_KINDS_WORKITEM_MANUAL_CLOSE = 'workitem_manual_close';
39
+
40
+ /**
41
+ * Returns true if the ledger entry kind represents a manual task close.
42
+ * Mirrors isManualTaskCloseLedgerKind from src/terminology.ts exactly.
43
+ *
44
+ * @param {string} kind
45
+ * @returns {boolean}
46
+ */
47
+ export function isManualTaskCloseLedgerKind(kind) {
48
+ return (
49
+ kind === CANONICAL_LEDGER_KINDS_TASK_MANUAL_CLOSE ||
50
+ kind === CANONICAL_LEDGER_KINDS_WORKITEM_MANUAL_CLOSE
51
+ );
52
+ }
53
+
54
+ // ── Protected-state path predicate (replicated from src/hookGating.ts) ────────
55
+ // Twin note: keep in sync with isProtectedOperatorPath in src/hookGating.ts.
56
+ // Used to guard against exposing raw .enact/operator/state paths externally.
57
+ const PROTECTED_PATH_PATTERNS = [
58
+ /(?:^|[/\\])\.enact[/\\]operator[/\\]state(?:[/\\]|$)/,
59
+ /(?:^|[/\\])\.enact[/\\]operator[/\\]sessions[/\\]current\.json$/,
60
+ /(?:^|[/\\])\.enact[/\\]operator[/\\]team[/\\]team\.json$/,
61
+ ];
62
+
63
+ /**
64
+ * Returns true if a path targets protected Operator control-plane state.
65
+ * Mirrors isProtectedOperatorPath from src/hookGating.ts exactly.
66
+ *
67
+ * @param {string} p
68
+ * @returns {boolean}
69
+ */
70
+ export function isProtectedOperatorStatePath(p) {
71
+ if (!p || typeof p !== 'string') return false;
72
+ const segments = p.replace(/\\/g, '/').split('/');
73
+ const resolved = [];
74
+ for (const seg of segments) {
75
+ if (seg === '' || seg === '.') continue;
76
+ if (seg === '..') { resolved.pop(); continue; }
77
+ resolved.push(seg);
78
+ }
79
+ const norm = resolved.join('/');
80
+ return PROTECTED_PATH_PATTERNS.some((re) => re.test(norm));
81
+ }
82
+
83
+ // ── JSON helpers ──────────────────────────────────────────────────────────────
84
+
85
+ /**
86
+ * Read and parse a JSON file. Returns fallback on any error.
87
+ *
88
+ * @param {string} filePath
89
+ * @param {*} fallback
90
+ * @returns {*}
91
+ */
92
+ function readJson(filePath, fallback) {
93
+ try {
94
+ if (!existsSync(filePath)) return fallback;
95
+ return JSON.parse(readFileSync(filePath, 'utf8'));
96
+ } catch {
97
+ return fallback;
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Write a value as JSON to a file, creating parent directories as needed.
103
+ *
104
+ * @param {string} filePath
105
+ * @param {*} value
106
+ */
107
+ function writeJson(filePath, value) {
108
+ mkdirSync(dirname(filePath), { recursive: true });
109
+ writeFileSync(filePath, JSON.stringify(value, null, 2), 'utf8');
110
+ }
111
+
112
+ const DEFAULT_DELEGATED_STALE_AFTER_MS = 2 * 60 * 60 * 1000;
113
+ const DEFAULT_DELEGATED_STALE_PRUNE_AFTER_MS = 48 * 60 * 60 * 1000;
114
+ const DEFAULT_DELEGATED_TERMINAL_PRUNE_AFTER_MS = 7 * 24 * 60 * 60 * 1000;
115
+
116
+ function parseTimestampMs(...candidates) {
117
+ for (const candidate of candidates) {
118
+ if (typeof candidate !== 'string' || candidate.trim() === '') continue;
119
+ const parsed = Date.parse(candidate);
120
+ if (Number.isFinite(parsed)) return parsed;
121
+ }
122
+ return null;
123
+ }
124
+
125
+ function delegatedSessionRetentionBaseMs(session) {
126
+ if (session.status === 'stale') {
127
+ const staleDetectedAt =
128
+ session.metadata && typeof session.metadata.staleDetectedAt === 'string'
129
+ ? session.metadata.staleDetectedAt
130
+ : undefined;
131
+ return parseTimestampMs(staleDetectedAt, session.lastSeenAt, session.startedAt);
132
+ }
133
+ if (session.status === 'completed' || session.status === 'failed' || session.status === 'orphaned') {
134
+ return parseTimestampMs(session.stoppedAt, session.lastSeenAt, session.startedAt);
135
+ }
136
+ return null;
137
+ }
138
+
139
+ function reconcileDelegatedSessions(operatorLayout, opts = {}) {
140
+ const path = join(operatorLayout, 'state', 'delegated-sessions.json');
141
+ const nowMs = opts.nowMs ?? Date.now();
142
+ const staleAfterMs = opts.staleAfterMs ?? DEFAULT_DELEGATED_STALE_AFTER_MS;
143
+ const stalePruneAfterMs = opts.stalePruneAfterMs ?? DEFAULT_DELEGATED_STALE_PRUNE_AFTER_MS;
144
+ const terminalPruneAfterMs = opts.terminalPruneAfterMs ?? DEFAULT_DELEGATED_TERMINAL_PRUNE_AFTER_MS;
145
+ const raw = readJson(path, { schemaVersion: 1, updatedAt: new Date(nowMs).toISOString(), sessions: [] });
146
+ const sessions = Array.isArray(raw.sessions) ? raw.sessions : [];
147
+ let changed = false;
148
+
149
+ const promoted = sessions.map((session) => {
150
+ if (session.status !== 'active') return session;
151
+ const lastSeenMs = parseTimestampMs(session.lastSeenAt, session.startedAt);
152
+ if (lastSeenMs === null || nowMs - lastSeenMs <= staleAfterMs) return session;
153
+ changed = true;
154
+ return {
155
+ ...session,
156
+ status: 'stale',
157
+ metadata: {
158
+ ...(session.metadata && typeof session.metadata === 'object' ? session.metadata : {}),
159
+ staleDetectedAt: new Date(nowMs).toISOString(),
160
+ },
161
+ };
162
+ });
163
+
164
+ const kept = promoted.filter((session) => {
165
+ if (session.status === 'active') return true;
166
+ const baseMs = delegatedSessionRetentionBaseMs(session);
167
+ if (baseMs === null) return true;
168
+ const pruneAfterMs = session.status === 'stale' ? stalePruneAfterMs : terminalPruneAfterMs;
169
+ const keep = nowMs - baseMs <= pruneAfterMs;
170
+ if (!keep) changed = true;
171
+ return keep;
172
+ });
173
+
174
+ if (changed) {
175
+ writeJson(path, {
176
+ schemaVersion: 1,
177
+ updatedAt: new Date(nowMs).toISOString(),
178
+ sessions: kept,
179
+ });
180
+ }
181
+ return kept;
182
+ }
183
+
184
+ // ── Surface 1: Compaction-context read ───────────────────────────────────────
185
+
186
+ /**
187
+ * Read the compaction-context.json written by pre-compact.mjs.
188
+ * Returns null if absent or empty.
189
+ *
190
+ * @param {string} operatorLayout Absolute path to the operator state directory.
191
+ * @returns {{ pendingLocalTaskIds: string[], pendingLocalTaskTitles: string[], resumeHint: string | null } | null}
192
+ */
193
+ export function readCompactionContext(operatorLayout) {
194
+ const path = join(operatorLayout, 'state', 'compaction-context.json');
195
+ const ctx = readJson(path, null);
196
+ if (!ctx) return null;
197
+ const ids = Array.isArray(ctx.pendingLocalTaskIds) ? ctx.pendingLocalTaskIds : [];
198
+ if (ids.length === 0) return null;
199
+ return {
200
+ pendingLocalTaskIds: ids,
201
+ pendingLocalTaskTitles: Array.isArray(ctx.pendingLocalTaskTitles) ? ctx.pendingLocalTaskTitles : [],
202
+ resumeHint: typeof ctx.resumeHint === 'string' ? ctx.resumeHint : null,
203
+ };
204
+ }
205
+
206
+ // ── Surface 2: Delegated-session ledger ──────────────────────────────────────
207
+
208
+ /**
209
+ * Read delegated-sessions.json written by subagent-tracker.
210
+ * Returns the sessions array (active and stale sessions).
211
+ *
212
+ * @param {string} operatorLayout
213
+ * @returns {Array<{ continuationId: string, kind: string, status: string, startedAt: string }>}
214
+ */
215
+ export function readDelegatedSessions(operatorLayout) {
216
+ const sessions = reconcileDelegatedSessions(operatorLayout);
217
+ return sessions.filter(
218
+ (s) => s.status === 'active' || s.status === 'stale',
219
+ );
220
+ }
221
+
222
+ // ── Surface 4: Member-turn injection (continuation-state.json) ────────────────
223
+
224
+ /**
225
+ * Read continuation-state.json to get current lane, pending task IDs, and resume hint.
226
+ * Returns a safe default if absent.
227
+ *
228
+ * @param {string} operatorLayout
229
+ * @returns {{ lane: string, laneId: string | null, pendingTaskIds: string[], pendingLocalTaskIds: string[], resumeHint: string | null, activeSubagentIds: string[] }}
230
+ */
231
+ export function readContinuationStateLocal(operatorLayout) {
232
+ const path = join(operatorLayout, 'state', 'continuation-state.json');
233
+ const raw = readJson(path, null);
234
+ return {
235
+ status: raw?.status ?? 'idle',
236
+ lane: raw?.lane ?? 'none',
237
+ laneId: raw?.laneId ?? null,
238
+ pendingTaskIds: Array.isArray(raw?.pendingTaskIds) ? raw.pendingTaskIds : [],
239
+ pendingLocalTaskIds: Array.isArray(raw?.pendingLocalTaskIds) ? raw.pendingLocalTaskIds : [],
240
+ pendingLocalTaskTitles: Array.isArray(raw?.pendingLocalTaskTitles) ? raw.pendingLocalTaskTitles : [],
241
+ resumeHint: raw?.resumeHint ?? null,
242
+ activeSubagentIds: Array.isArray(raw?.activeSubagentIds) ? raw.activeSubagentIds : [],
243
+ };
244
+ }
245
+
246
+ // ── Surface 5: Manual-close filter ───────────────────────────────────────────
247
+
248
+ /**
249
+ * Read ledger.json and return the set of task IDs that have been manually closed.
250
+ * Uses isManualTaskCloseLedgerKind to identify manual-close ledger entries.
251
+ *
252
+ * @param {string} operatorLayout
253
+ * @returns {Set<string>}
254
+ */
255
+ export function readManuallyClosedTaskIds(operatorLayout) {
256
+ const path = join(operatorLayout, 'logs', 'ledger.json');
257
+ const closed = new Set();
258
+ if (!existsSync(path)) return closed;
259
+ try {
260
+ const lines = readFileSync(path, 'utf8').split('\n').filter(Boolean);
261
+ for (const line of lines) {
262
+ try {
263
+ const entry = JSON.parse(line);
264
+ if (isManualTaskCloseLedgerKind(entry.kind ?? '')) {
265
+ // Coalese taskId from standard fields
266
+ const taskId = entry.taskId ?? entry.task_id ?? entry.metadata?.taskId ?? null;
267
+ if (typeof taskId === 'string' && taskId) {
268
+ closed.add(taskId);
269
+ }
270
+ }
271
+ } catch {
272
+ // skip malformed lines
273
+ }
274
+ }
275
+ } catch {
276
+ // ledger absent or unreadable — safe to return empty set
277
+ }
278
+ return closed;
279
+ }
280
+
281
+ // ── Main: buildContinuationContext ────────────────────────────────────────────
282
+
283
+ /**
284
+ * Build the continuation context object from all five predecessor surfaces.
285
+ *
286
+ * This is the integration sink imported by session-start.mjs so that the
287
+ * SessionStart hook can inject a rich continuation context without depending
288
+ * on the compiled dist/ output.
289
+ *
290
+ * @param {string} operatorLayout Absolute path to the operator layout root
291
+ * (the value returned by layoutDir(root) from layout-dir.mjs).
292
+ * @returns {{
293
+ * compactionContext: { pendingLocalTaskIds: string[], pendingLocalTaskTitles: string[], resumeHint: string | null } | null,
294
+ * delegatedSessions: Array<{ continuationId: string, kind: string, status: string }>,
295
+ * continuationState: { lane: string, laneId: string | null, pendingTaskIds: string[], pendingLocalTaskIds: string[], resumeHint: string | null, activeSubagentIds: string[] },
296
+ * manuallyClosedTaskIds: string[],
297
+ * effectivePendingTaskIds: string[],
298
+ * hasDelegatedSessions: boolean,
299
+ * hasCompactionSurvivors: boolean,
300
+ * }}
301
+ */
302
+ export function buildContinuationContext(operatorLayout) {
303
+ // Surface 3 (protected-state guard): assert we're reading from operator layout,
304
+ // not from a raw user-exposed path. Guard is enforced by always routing reads
305
+ // through operatorLayout (layoutPath result), never from arbitrary strings.
306
+ // (isProtectedOperatorStatePath is exposed for callers to validate paths.)
307
+
308
+ // Surface 1: compaction-context read
309
+ const compactionContext = readCompactionContext(operatorLayout);
310
+
311
+ // Surface 2: delegated-session ledger
312
+ const delegatedSessions = readDelegatedSessions(operatorLayout);
313
+
314
+ // Surface 4: member-turn injection — continuation-state.json
315
+ const continuationState = readContinuationStateLocal(operatorLayout);
316
+
317
+ // Surface 5: manual-close filter — remove closed tasks from pending list
318
+ const manuallyClosedTaskIds = readManuallyClosedTaskIds(operatorLayout);
319
+
320
+ // Merge pending task IDs from continuation-state and compaction-context,
321
+ // then filter out any that have been manually closed.
322
+ const allPendingIds = new Set([
323
+ ...continuationState.pendingTaskIds,
324
+ ...continuationState.pendingLocalTaskIds,
325
+ ...(compactionContext?.pendingLocalTaskIds ?? []),
326
+ ]);
327
+ for (const closedId of manuallyClosedTaskIds) {
328
+ allPendingIds.delete(closedId);
329
+ }
330
+ const effectivePendingTaskIds = Array.from(allPendingIds);
331
+
332
+ return {
333
+ compactionContext,
334
+ delegatedSessions,
335
+ continuationState,
336
+ manuallyClosedTaskIds: Array.from(manuallyClosedTaskIds),
337
+ effectivePendingTaskIds,
338
+ hasDelegatedSessions: delegatedSessions.length > 0,
339
+ hasCompactionSurvivors: (compactionContext?.pendingLocalTaskIds.length ?? 0) > 0,
340
+ };
341
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Shared verbose-hook helper.
3
+ *
4
+ * Usage (in any hook):
5
+ * import { verboseLog, readHooksVerbose } from "./_lib.mjs";
6
+ * if (readHooksVerbose()) verboseLog("stop", "allow", "no autonomous lane active");
7
+ *
8
+ * The verbose flag is read from merged operator config.
9
+ * No env vars — non-secret config goes in config.toml per INV-024/ADR-0012.
10
+ */
11
+ import { readMergedOperatorConfig } from "./config.mjs";
12
+
13
+ export function readWorkspaceConfig(startDir = process.cwd()) {
14
+ return readMergedOperatorConfig(startDir);
15
+ }
16
+
17
+ /**
18
+ * Returns true when [hooks].verbose = true in config.toml.
19
+ * Defaults to false when the section or key is absent.
20
+ */
21
+ export function readHooksVerbose(startDir = process.cwd()) {
22
+ const config = readWorkspaceConfig(startDir);
23
+ const value = config?.hooks?.verbose;
24
+ return value === true;
25
+ }
26
+
27
+ function operatorHookSection(startDir = process.cwd()) {
28
+ const config = readWorkspaceConfig(startDir);
29
+ return config?.operator?.hooks && typeof config.operator.hooks === "object"
30
+ ? config.operator.hooks
31
+ : null;
32
+ }
33
+
34
+ export function isOperatorHookPresetEnabled(presetId, startDir = process.cwd()) {
35
+ const hooks = operatorHookSection(startDir);
36
+ if (!hooks) return true;
37
+
38
+ const presets = Array.isArray(hooks.presets)
39
+ ? hooks.presets.filter((value) => typeof value === "string")
40
+ : null;
41
+ if (presets && presets.length > 0) {
42
+ return presets.includes(presetId);
43
+ }
44
+
45
+ const disabledPresets = Array.isArray(hooks.disabled_presets)
46
+ ? hooks.disabled_presets.filter((value) => typeof value === "string")
47
+ : [];
48
+ return !disabledPresets.includes(presetId);
49
+ }
50
+
51
+ /**
52
+ * Emit a single structured verbose line to stderr.
53
+ * Format: "[enact-operator] <hookName> ran — <result>"
54
+ *
55
+ * @param {string} hookName e.g. "stop", "session-start", "pre-tool-use"
56
+ * @param {string} result e.g. "allow (no autonomous lane active)", "denied (doom-loop)"
57
+ */
58
+ export function verboseLog(hookName, result) {
59
+ process.stderr.write(`[enact-operator] ${hookName} ran — ${result}\n`);
60
+ }