@shivaedev/work-fleet 0.5.0 → 0.7.0

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 (492) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +7 -5
  3. package/dist/DecisionCode.d.ts +1 -1
  4. package/dist/DecisionCode.d.ts.map +1 -1
  5. package/dist/DecisionCode.js +1 -0
  6. package/dist/DecisionCode.js.map +1 -1
  7. package/dist/admit.d.ts +2 -4
  8. package/dist/admit.d.ts.map +1 -1
  9. package/dist/board/acknowledgeDecision.d.ts.map +1 -1
  10. package/dist/board/acknowledgeDecision.js +11 -5
  11. package/dist/board/acknowledgeDecision.js.map +1 -1
  12. package/dist/board/briefRevision.d.ts +1 -1
  13. package/dist/board/briefRevision.d.ts.map +1 -1
  14. package/dist/board/briefRevision.js +1 -1
  15. package/dist/board/briefRevision.js.map +1 -1
  16. package/dist/board/closePublishedDecision.d.ts +22 -0
  17. package/dist/board/closePublishedDecision.d.ts.map +1 -0
  18. package/dist/board/closePublishedDecision.js +41 -0
  19. package/dist/board/closePublishedDecision.js.map +1 -0
  20. package/dist/board/decisionAnswer.d.ts +2 -2
  21. package/dist/board/decisionAnswer.d.ts.map +1 -1
  22. package/dist/board/decisionAnswer.js +8 -8
  23. package/dist/board/decisionAnswer.js.map +1 -1
  24. package/dist/board/decisionReading.js +2 -2
  25. package/dist/board/decisionReading.js.map +1 -1
  26. package/dist/board/documents.d.ts +1 -2
  27. package/dist/board/documents.d.ts.map +1 -1
  28. package/dist/board/documents.js +4 -4
  29. package/dist/board/documents.js.map +1 -1
  30. package/dist/board/fleetField.d.ts +1 -1
  31. package/dist/board/fleetField.d.ts.map +1 -1
  32. package/dist/board/markdown.d.ts.map +1 -1
  33. package/dist/board/markdown.js +6 -5
  34. package/dist/board/markdown.js.map +1 -1
  35. package/dist/board/publish.d.ts +1 -1
  36. package/dist/board/publish.d.ts.map +1 -1
  37. package/dist/board/publish.js +10 -8
  38. package/dist/board/publish.js.map +1 -1
  39. package/dist/board/publishReport.js +2 -2
  40. package/dist/board/publishReport.js.map +1 -1
  41. package/dist/board/readDocument.js +1 -1
  42. package/dist/board/readDocument.js.map +1 -1
  43. package/dist/board/readPass.d.ts +1 -1
  44. package/dist/board/readPass.d.ts.map +1 -1
  45. package/dist/board/readPass.js +1 -1
  46. package/dist/board/readPass.js.map +1 -1
  47. package/dist/board/reportIdentity.js +1 -1
  48. package/dist/board/reportIdentity.js.map +1 -1
  49. package/dist/board/reportLinks.js +1 -1
  50. package/dist/board/reportLinks.js.map +1 -1
  51. package/dist/board/schema.d.ts +13 -13
  52. package/dist/board/schema.js +2 -2
  53. package/dist/board/schema.js.map +1 -1
  54. package/dist/board/upgradeDecisionClosure.d.ts +5 -0
  55. package/dist/board/upgradeDecisionClosure.d.ts.map +1 -0
  56. package/dist/board/upgradeDecisionClosure.js +46 -0
  57. package/dist/board/upgradeDecisionClosure.js.map +1 -0
  58. package/dist/board/workRevision.js +2 -2
  59. package/dist/board/workRevision.js.map +1 -1
  60. package/dist/board/writeHealth.d.ts +1 -1
  61. package/dist/board/writeHealth.d.ts.map +1 -1
  62. package/dist/board/writeHealth.js +1 -1
  63. package/dist/board/writeHealth.js.map +1 -1
  64. package/dist/board/writePublished.d.ts +1 -1
  65. package/dist/board/writePublished.d.ts.map +1 -1
  66. package/dist/board/writePublished.js +5 -1
  67. package/dist/board/writePublished.js.map +1 -1
  68. package/dist/cli.js +11 -5
  69. package/dist/cli.js.map +1 -1
  70. package/dist/engine/abandonStalled.d.ts +530 -569
  71. package/dist/engine/abandonStalled.d.ts.map +1 -1
  72. package/dist/engine/admissionOrder.d.ts +4 -8
  73. package/dist/engine/admissionOrder.d.ts.map +1 -1
  74. package/dist/engine/applyResolution.d.ts +4 -8
  75. package/dist/engine/applyResolution.d.ts.map +1 -1
  76. package/dist/engine/approveBrief.d.ts +6 -12
  77. package/dist/engine/approveBrief.d.ts.map +1 -1
  78. package/dist/engine/authorizeResolution.d.ts +528 -565
  79. package/dist/engine/authorizeResolution.d.ts.map +1 -1
  80. package/dist/engine/authorizeResolution.js +1 -1
  81. package/dist/engine/authorizeResolution.js.map +1 -1
  82. package/dist/engine/boardBrief.d.ts +7 -12
  83. package/dist/engine/boardBrief.d.ts.map +1 -1
  84. package/dist/engine/boardBrief.js +3 -10
  85. package/dist/engine/boardBrief.js.map +1 -1
  86. package/dist/engine/capacityRetry.d.ts +1715 -1828
  87. package/dist/engine/capacityRetry.d.ts.map +1 -1
  88. package/dist/engine/closeDecisions.d.ts +4 -8
  89. package/dist/engine/closeDecisions.d.ts.map +1 -1
  90. package/dist/engine/completeBoardWork.d.ts +4 -8
  91. package/dist/engine/completeBoardWork.d.ts.map +1 -1
  92. package/dist/engine/completeReport.d.ts +277 -284
  93. package/dist/engine/completeReport.d.ts.map +1 -1
  94. package/dist/engine/continueCommand.d.ts +2 -4
  95. package/dist/engine/continueCommand.d.ts.map +1 -1
  96. package/dist/engine/continueWorker.d.ts +4 -8
  97. package/dist/engine/continueWorker.d.ts.map +1 -1
  98. package/dist/engine/decisionCopy.d.ts +15 -0
  99. package/dist/engine/decisionCopy.d.ts.map +1 -0
  100. package/dist/engine/decisionCopy.js +44 -0
  101. package/dist/engine/decisionCopy.js.map +1 -0
  102. package/dist/engine/deliverPendingAnswers.d.ts +534 -577
  103. package/dist/engine/deliverPendingAnswers.d.ts.map +1 -1
  104. package/dist/engine/dispatchCommand.d.ts +3 -6
  105. package/dist/engine/dispatchCommand.d.ts.map +1 -1
  106. package/dist/engine/dispatchCommand.js +4 -29
  107. package/dist/engine/dispatchCommand.js.map +1 -1
  108. package/dist/engine/dispatchFailure.d.ts +9391 -0
  109. package/dist/engine/dispatchFailure.d.ts.map +1 -0
  110. package/dist/engine/dispatchFailure.js +24 -0
  111. package/dist/engine/dispatchFailure.js.map +1 -0
  112. package/dist/engine/ensureDecisionOwner.d.ts +4 -8
  113. package/dist/engine/ensureDecisionOwner.d.ts.map +1 -1
  114. package/dist/engine/ensurePublication.d.ts +4 -8
  115. package/dist/engine/ensurePublication.d.ts.map +1 -1
  116. package/dist/engine/failureCode.js +1 -1
  117. package/dist/engine/failureCode.js.map +1 -1
  118. package/dist/engine/health.d.ts +1 -1
  119. package/dist/engine/health.d.ts.map +1 -1
  120. package/dist/engine/inspectRenewal.d.ts +4 -8
  121. package/dist/engine/inspectRenewal.d.ts.map +1 -1
  122. package/dist/engine/launchInput.d.ts +2 -4
  123. package/dist/engine/launchInput.d.ts.map +1 -1
  124. package/dist/engine/launchReceipt.d.ts +2 -4
  125. package/dist/engine/launchReceipt.d.ts.map +1 -1
  126. package/dist/engine/makeAdopt.d.ts +4 -8
  127. package/dist/engine/makeAdopt.d.ts.map +1 -1
  128. package/dist/engine/makeAdvance.d.ts +2 -4
  129. package/dist/engine/makeAdvance.d.ts.map +1 -1
  130. package/dist/engine/makeDeliver.d.ts +4 -8
  131. package/dist/engine/makeDeliver.d.ts.map +1 -1
  132. package/dist/engine/makeDeliver.js +5 -1
  133. package/dist/engine/makeDeliver.js.map +1 -1
  134. package/dist/engine/makeHuman.d.ts +4 -8
  135. package/dist/engine/makeHuman.d.ts.map +1 -1
  136. package/dist/engine/makeLaunch.d.ts +4 -8
  137. package/dist/engine/makeLaunch.d.ts.map +1 -1
  138. package/dist/engine/makeObserve.d.ts +4 -8
  139. package/dist/engine/makeObserve.d.ts.map +1 -1
  140. package/dist/engine/makeReview.d.ts +4 -8
  141. package/dist/engine/makeReview.d.ts.map +1 -1
  142. package/dist/engine/makeState.d.ts +534 -568
  143. package/dist/engine/makeState.d.ts.map +1 -1
  144. package/dist/engine/makeState.js +18 -3
  145. package/dist/engine/makeState.js.map +1 -1
  146. package/dist/engine/makeValidate.d.ts +4 -8
  147. package/dist/engine/makeValidate.d.ts.map +1 -1
  148. package/dist/engine/mergeReadiness.d.ts +536 -581
  149. package/dist/engine/mergeReadiness.d.ts.map +1 -1
  150. package/dist/engine/mergeReadiness.js +1 -1
  151. package/dist/engine/mergeReadiness.js.map +1 -1
  152. package/dist/engine/missingBoardWork.d.ts +9936 -0
  153. package/dist/engine/missingBoardWork.d.ts.map +1 -0
  154. package/dist/engine/missingBoardWork.js +17 -0
  155. package/dist/engine/missingBoardWork.js.map +1 -0
  156. package/dist/engine/observeDeliveryFailure.d.ts +530 -569
  157. package/dist/engine/observeDeliveryFailure.d.ts.map +1 -1
  158. package/dist/engine/observeRenewal.d.ts +6 -12
  159. package/dist/engine/observeRenewal.d.ts.map +1 -1
  160. package/dist/engine/obtainReview.d.ts +2 -4
  161. package/dist/engine/obtainReview.d.ts.map +1 -1
  162. package/dist/engine/obtainReview.js +1 -1
  163. package/dist/engine/obtainReview.js.map +1 -1
  164. package/dist/engine/operationRecord.d.ts +26 -52
  165. package/dist/engine/operationRecord.d.ts.map +1 -1
  166. package/dist/engine/pendingAcknowledgements.d.ts.map +1 -1
  167. package/dist/engine/pendingAcknowledgements.js +3 -1
  168. package/dist/engine/pendingAcknowledgements.js.map +1 -1
  169. package/dist/engine/persistTerminalReceipts.d.ts +4 -8
  170. package/dist/engine/persistTerminalReceipts.d.ts.map +1 -1
  171. package/dist/engine/prepareCommand.d.ts +2 -4
  172. package/dist/engine/prepareCommand.d.ts.map +1 -1
  173. package/dist/engine/queueAnswerCommand.d.ts +2 -4
  174. package/dist/engine/queueAnswerCommand.d.ts.map +1 -1
  175. package/dist/engine/readOrContinueReview.d.ts +2 -4
  176. package/dist/engine/readOrContinueReview.d.ts.map +1 -1
  177. package/dist/engine/readOrContinueReview.js +1 -1
  178. package/dist/engine/readOrContinueReview.js.map +1 -1
  179. package/dist/engine/readResolution.d.ts +1 -1
  180. package/dist/engine/readResolution.js +1 -1
  181. package/dist/engine/readResolution.js.map +1 -1
  182. package/dist/engine/readRetry.d.ts +1177 -1255
  183. package/dist/engine/readRetry.d.ts.map +1 -1
  184. package/dist/engine/reassignCommand.d.ts +2 -4
  185. package/dist/engine/reassignCommand.d.ts.map +1 -1
  186. package/dist/engine/reconcileAttempt.d.ts +2 -4
  187. package/dist/engine/reconcileAttempt.d.ts.map +1 -1
  188. package/dist/engine/reconcileCommand.d.ts +2 -4
  189. package/dist/engine/reconcileCommand.d.ts.map +1 -1
  190. package/dist/engine/reconcileCommand.js +2 -1
  191. package/dist/engine/reconcileCommand.js.map +1 -1
  192. package/dist/engine/recordResponseCommand.d.ts +2 -4
  193. package/dist/engine/recordResponseCommand.d.ts.map +1 -1
  194. package/dist/engine/recoverStall.d.ts +530 -569
  195. package/dist/engine/recoverStall.d.ts.map +1 -1
  196. package/dist/engine/recoverUnobservable.d.ts +530 -569
  197. package/dist/engine/recoverUnobservable.d.ts.map +1 -1
  198. package/dist/engine/refreshBrief.d.ts +1177 -1255
  199. package/dist/engine/refreshBrief.d.ts.map +1 -1
  200. package/dist/engine/refreshReviewResult.d.ts +4 -8
  201. package/dist/engine/refreshReviewResult.d.ts.map +1 -1
  202. package/dist/engine/releaseClosedPreparation.d.ts +530 -569
  203. package/dist/engine/releaseClosedPreparation.d.ts.map +1 -1
  204. package/dist/engine/releaseExecution.d.ts +530 -569
  205. package/dist/engine/releaseExecution.d.ts.map +1 -1
  206. package/dist/engine/releaseFinishedWork.d.ts +2 -4
  207. package/dist/engine/releaseFinishedWork.d.ts.map +1 -1
  208. package/dist/engine/releaseFinishedWork.js +0 -1
  209. package/dist/engine/releaseFinishedWork.js.map +1 -1
  210. package/dist/engine/repository.d.ts +24 -48
  211. package/dist/engine/repository.d.ts.map +1 -1
  212. package/dist/engine/repository.js +1 -1
  213. package/dist/engine/repository.js.map +1 -1
  214. package/dist/engine/requestConflictRepair.d.ts +530 -569
  215. package/dist/engine/requestConflictRepair.d.ts.map +1 -1
  216. package/dist/engine/requestRework.d.ts +4 -8
  217. package/dist/engine/requestRework.d.ts.map +1 -1
  218. package/dist/engine/resolveCommand.d.ts +2 -4
  219. package/dist/engine/resolveCommand.d.ts.map +1 -1
  220. package/dist/engine/resolveExecution.d.ts +530 -569
  221. package/dist/engine/resolveExecution.d.ts.map +1 -1
  222. package/dist/engine/resumeAttempt.d.ts +530 -569
  223. package/dist/engine/resumeAttempt.d.ts.map +1 -1
  224. package/dist/engine/retireUnacknowledged.d.ts +4 -8
  225. package/dist/engine/retireUnacknowledged.d.ts.map +1 -1
  226. package/dist/engine/retryTerminal.d.ts +528 -565
  227. package/dist/engine/retryTerminal.d.ts.map +1 -1
  228. package/dist/engine/saveLaunch.d.ts +533 -574
  229. package/dist/engine/saveLaunch.d.ts.map +1 -1
  230. package/dist/engine/saveLaunch.js +16 -2
  231. package/dist/engine/saveLaunch.js.map +1 -1
  232. package/dist/engine/scheduler.d.ts +4 -8
  233. package/dist/engine/scheduler.d.ts.map +1 -1
  234. package/dist/engine/scheduler.js +4 -1
  235. package/dist/engine/scheduler.js.map +1 -1
  236. package/dist/engine/sessionCleanup.d.ts +4 -8
  237. package/dist/engine/sessionCleanup.d.ts.map +1 -1
  238. package/dist/engine/settleMergedDelivery.d.ts +530 -569
  239. package/dist/engine/settleMergedDelivery.d.ts.map +1 -1
  240. package/dist/engine/situations/choices.d.ts +20 -0
  241. package/dist/engine/situations/choices.d.ts.map +1 -0
  242. package/dist/engine/situations/choices.js +21 -0
  243. package/dist/engine/situations/choices.js.map +1 -0
  244. package/dist/engine/situations/service.d.ts +60 -0
  245. package/dist/engine/situations/service.d.ts.map +1 -0
  246. package/dist/engine/situations/service.js +51 -0
  247. package/dist/engine/situations/service.js.map +1 -0
  248. package/dist/engine/situations/stop.d.ts +25 -0
  249. package/dist/engine/situations/stop.d.ts.map +1 -0
  250. package/dist/engine/situations/stop.js +25 -0
  251. package/dist/engine/situations/stop.js.map +1 -0
  252. package/dist/engine/situations/work.d.ts +114 -0
  253. package/dist/engine/situations/work.d.ts.map +1 -0
  254. package/dist/engine/situations/work.js +91 -0
  255. package/dist/engine/situations/work.js.map +1 -0
  256. package/dist/engine/steerBrief.d.ts +532 -573
  257. package/dist/engine/steerBrief.d.ts.map +1 -1
  258. package/dist/engine/submissionFailure.d.ts +526 -561
  259. package/dist/engine/submissionFailure.d.ts.map +1 -1
  260. package/dist/engine/submitLaunch.d.ts +528 -565
  261. package/dist/engine/submitLaunch.d.ts.map +1 -1
  262. package/dist/engine/threadNames.js +1 -1
  263. package/dist/engine/threadNames.js.map +1 -1
  264. package/dist/engine/workerReport.d.ts +7 -13
  265. package/dist/engine/workerReport.d.ts.map +1 -1
  266. package/dist/exposeFailure.js +1 -1
  267. package/dist/exposeFailure.js.map +1 -1
  268. package/dist/fleet.d.ts +26 -52
  269. package/dist/fleet.d.ts.map +1 -1
  270. package/dist/fleet.js +1 -1
  271. package/dist/fleet.js.map +1 -1
  272. package/dist/host/actionCommands.d.ts +10 -10
  273. package/dist/host/actionCommands.d.ts.map +1 -1
  274. package/dist/host/actionCommands.js +6 -6
  275. package/dist/host/actionCommands.js.map +1 -1
  276. package/dist/host/admission.d.ts +4 -8
  277. package/dist/host/admission.d.ts.map +1 -1
  278. package/dist/host/answerWork.d.ts +4 -5
  279. package/dist/host/answerWork.d.ts.map +1 -1
  280. package/dist/host/cliOptions.d.ts +5 -1
  281. package/dist/host/cliOptions.d.ts.map +1 -1
  282. package/dist/host/cliOptions.js +6 -4
  283. package/dist/host/cliOptions.js.map +1 -1
  284. package/dist/host/commands.d.ts +1 -1
  285. package/dist/host/commands.d.ts.map +1 -1
  286. package/dist/host/configSettings.d.ts +5 -5
  287. package/dist/host/daemon.d.ts +133 -150
  288. package/dist/host/daemon.d.ts.map +1 -1
  289. package/dist/host/daemon.js +7 -3
  290. package/dist/host/daemon.js.map +1 -1
  291. package/dist/host/daemonClient.d.ts +1054 -1072
  292. package/dist/host/daemonClient.d.ts.map +1 -1
  293. package/dist/host/daemonClient.js +1 -1
  294. package/dist/host/daemonClient.js.map +1 -1
  295. package/dist/host/daemonContract.d.ts +146 -172
  296. package/dist/host/daemonContract.d.ts.map +1 -1
  297. package/dist/host/daemonContract.js +1 -1
  298. package/dist/host/daemonContract.js.map +1 -1
  299. package/dist/host/daemonDiagnostics.js +1 -1
  300. package/dist/host/daemonDiagnostics.js.map +1 -1
  301. package/dist/host/daemonHandlers.d.ts +1 -1
  302. package/dist/host/daemonHandlers.d.ts.map +1 -1
  303. package/dist/host/daemonPort.d.ts +6 -0
  304. package/dist/host/daemonPort.d.ts.map +1 -0
  305. package/dist/host/daemonPort.js +40 -0
  306. package/dist/host/daemonPort.js.map +1 -0
  307. package/dist/host/daemonSnapshots.d.ts +1 -1
  308. package/dist/host/daemonSnapshots.d.ts.map +1 -1
  309. package/dist/host/daemonSnapshots.js +1 -1
  310. package/dist/host/daemonSnapshots.js.map +1 -1
  311. package/dist/host/fleetStatus.d.ts +5 -5
  312. package/dist/host/follow.d.ts +1 -0
  313. package/dist/host/follow.d.ts.map +1 -1
  314. package/dist/host/follow.js +10 -4
  315. package/dist/host/follow.js.map +1 -1
  316. package/dist/host/followCommands.d.ts +2 -2
  317. package/dist/host/followCommands.d.ts.map +1 -1
  318. package/dist/host/followCommands.js +4 -2
  319. package/dist/host/followCommands.js.map +1 -1
  320. package/dist/host/githubApi.js +1 -1
  321. package/dist/host/githubApi.js.map +1 -1
  322. package/dist/host/githubDelivery.js +3 -1
  323. package/dist/host/githubDelivery.js.map +1 -1
  324. package/dist/host/healthLayer.js +1 -1
  325. package/dist/host/healthLayer.js.map +1 -1
  326. package/dist/host/integrations.js +1 -1
  327. package/dist/host/integrations.js.map +1 -1
  328. package/dist/host/mainSource.js +1 -1
  329. package/dist/host/mainSource.js.map +1 -1
  330. package/dist/host/providerHealth.js +1 -1
  331. package/dist/host/providerHealth.js.map +1 -1
  332. package/dist/host/quota.js +1 -1
  333. package/dist/host/quota.js.map +1 -1
  334. package/dist/host/recordDecisionResponse.d.ts +3 -2
  335. package/dist/host/recordDecisionResponse.d.ts.map +1 -1
  336. package/dist/host/recordDecisionResponse.js +1 -1
  337. package/dist/host/recordDecisionResponse.js.map +1 -1
  338. package/dist/host/releaseWork.d.ts +6 -9
  339. package/dist/host/releaseWork.d.ts.map +1 -1
  340. package/dist/host/releaseWork.js +2 -2
  341. package/dist/host/releaseWork.js.map +1 -1
  342. package/dist/host/renderStatus.d.ts +4 -1
  343. package/dist/host/renderStatus.d.ts.map +1 -1
  344. package/dist/host/renderStatus.js +6 -6
  345. package/dist/host/renderStatus.js.map +1 -1
  346. package/dist/host/reportBoard.js +1 -1
  347. package/dist/host/reportBoard.js.map +1 -1
  348. package/dist/host/runtime.d.ts +2 -2
  349. package/dist/host/runtime.d.ts.map +1 -1
  350. package/dist/host/runtime.js +1 -1
  351. package/dist/host/runtime.js.map +1 -1
  352. package/dist/host/statusLayer.js +2 -2
  353. package/dist/host/statusLayer.js.map +1 -1
  354. package/dist/host/watch.d.ts.map +1 -1
  355. package/dist/host/watch.js +1 -1
  356. package/dist/host/watch.js.map +1 -1
  357. package/dist/model.d.ts +9 -12
  358. package/dist/model.d.ts.map +1 -1
  359. package/dist/model.js +1 -2
  360. package/dist/model.js.map +1 -1
  361. package/dist/operations.d.ts +57 -99
  362. package/dist/operations.d.ts.map +1 -1
  363. package/dist/packageInfo.d.ts +1 -1
  364. package/dist/packageInfo.js +1 -1
  365. package/dist/policy.d.ts +3 -2
  366. package/dist/policy.d.ts.map +1 -1
  367. package/dist/policy.js +2 -1
  368. package/dist/policy.js.map +1 -1
  369. package/dist/prompt/briefEdit.js +1 -1
  370. package/dist/prompt/briefEdit.js.map +1 -1
  371. package/dist/providers/codexCloud.js +1 -1
  372. package/dist/providers/codexCloud.js.map +1 -1
  373. package/dist/providers/codexLocal.js +1 -1
  374. package/dist/providers/codexLocal.js.map +1 -1
  375. package/dist/qualifyDependencies.d.ts +2 -4
  376. package/dist/qualifyDependencies.d.ts.map +1 -1
  377. package/dist/reportFileDirectory.js +1 -1
  378. package/dist/reportFileDirectory.js.map +1 -1
  379. package/dist/scheduling/admission.d.ts +6 -12
  380. package/dist/scheduling/admission.d.ts.map +1 -1
  381. package/dist/scheduling/areas.d.ts +7 -12
  382. package/dist/scheduling/areas.d.ts.map +1 -1
  383. package/dist/scheduling/areas.js +2 -2
  384. package/dist/scheduling/areas.js.map +1 -1
  385. package/dist/scheduling/backPressure.d.ts +6 -12
  386. package/dist/scheduling/backPressure.d.ts.map +1 -1
  387. package/dist/session/schema.d.ts +1 -1
  388. package/dist/session/service.js +1 -1
  389. package/dist/session/service.js.map +1 -1
  390. package/dist/storage/fleetMigrations.d.ts.map +1 -1
  391. package/dist/storage/fleetMigrations.js +10 -0
  392. package/dist/storage/fleetMigrations.js.map +1 -1
  393. package/dist/storage/makeFleetTransaction.d.ts +1 -1
  394. package/dist/storage/makeFleetTransaction.d.ts.map +1 -1
  395. package/dist/storage/makeFleetTransaction.js +1 -1
  396. package/dist/storage/makeFleetTransaction.js.map +1 -1
  397. package/dist/storage/makeForeignReservations.d.ts.map +1 -1
  398. package/dist/storage/makeForeignReservations.js +16 -4
  399. package/dist/storage/makeForeignReservations.js.map +1 -1
  400. package/dist/storage/model.d.ts +1 -0
  401. package/dist/storage/model.d.ts.map +1 -1
  402. package/package.json +8 -8
  403. package/src/DecisionCode.ts +1 -0
  404. package/src/board/acknowledgeDecision.ts +11 -5
  405. package/src/board/briefRevision.ts +2 -2
  406. package/src/board/closePublishedDecision.ts +51 -0
  407. package/src/board/decisionAnswer.ts +11 -9
  408. package/src/board/decisionReading.ts +3 -3
  409. package/src/board/documents.ts +5 -6
  410. package/src/board/fleetField.ts +1 -1
  411. package/src/board/markdown.ts +6 -5
  412. package/src/board/publish.ts +10 -8
  413. package/src/board/publishReport.ts +2 -2
  414. package/src/board/readDocument.ts +1 -1
  415. package/src/board/readPass.ts +2 -2
  416. package/src/board/reportIdentity.ts +1 -1
  417. package/src/board/reportLinks.ts +1 -1
  418. package/src/board/schema.ts +2 -2
  419. package/src/board/upgradeDecisionClosure.ts +61 -0
  420. package/src/board/workRevision.ts +2 -2
  421. package/src/board/writeHealth.ts +2 -2
  422. package/src/board/writePublished.ts +13 -4
  423. package/src/cli.ts +13 -5
  424. package/src/engine/authorizeResolution.ts +1 -1
  425. package/src/engine/boardBrief.ts +11 -19
  426. package/src/engine/decisionCopy.ts +63 -0
  427. package/src/engine/dispatchCommand.ts +4 -36
  428. package/src/engine/dispatchFailure.ts +25 -0
  429. package/src/engine/failureCode.ts +1 -1
  430. package/src/engine/health.ts +1 -1
  431. package/src/engine/makeDeliver.ts +5 -1
  432. package/src/engine/makeState.ts +24 -5
  433. package/src/engine/mergeReadiness.ts +0 -2
  434. package/src/engine/missingBoardWork.ts +24 -0
  435. package/src/engine/obtainReview.ts +1 -1
  436. package/src/engine/pendingAcknowledgements.ts +9 -1
  437. package/src/engine/readOrContinueReview.ts +1 -1
  438. package/src/engine/readResolution.ts +2 -2
  439. package/src/engine/reconcileCommand.ts +7 -1
  440. package/src/engine/releaseFinishedWork.ts +0 -1
  441. package/src/engine/repository.ts +1 -1
  442. package/src/engine/saveLaunch.ts +27 -2
  443. package/src/engine/scheduler.ts +4 -1
  444. package/src/engine/situations/choices.ts +36 -0
  445. package/src/engine/situations/service.ts +82 -0
  446. package/src/engine/situations/stop.ts +60 -0
  447. package/src/engine/situations/work.ts +94 -0
  448. package/src/engine/threadNames.ts +1 -1
  449. package/src/exposeFailure.ts +1 -1
  450. package/src/fleet.ts +1 -1
  451. package/src/host/actionCommands.ts +6 -6
  452. package/src/host/cliOptions.ts +10 -5
  453. package/src/host/daemon.ts +7 -3
  454. package/src/host/daemonClient.ts +1 -1
  455. package/src/host/daemonContract.ts +1 -1
  456. package/src/host/daemonDiagnostics.ts +1 -1
  457. package/src/host/daemonPort.ts +50 -0
  458. package/src/host/daemonSnapshots.ts +1 -1
  459. package/src/host/follow.ts +16 -5
  460. package/src/host/followCommands.ts +4 -2
  461. package/src/host/githubApi.ts +1 -1
  462. package/src/host/githubDelivery.ts +3 -1
  463. package/src/host/healthLayer.ts +1 -1
  464. package/src/host/integrations.ts +1 -1
  465. package/src/host/mainSource.ts +1 -1
  466. package/src/host/providerHealth.ts +1 -1
  467. package/src/host/quota.ts +1 -1
  468. package/src/host/recordDecisionResponse.ts +1 -1
  469. package/src/host/releaseWork.ts +2 -2
  470. package/src/host/renderStatus.ts +6 -7
  471. package/src/host/reportBoard.ts +1 -1
  472. package/src/host/runtime.ts +1 -1
  473. package/src/host/statusLayer.ts +3 -3
  474. package/src/host/watch.ts +4 -1
  475. package/src/model.ts +1 -2
  476. package/src/packageInfo.ts +1 -1
  477. package/src/policy.ts +2 -1
  478. package/src/prompt/briefEdit.ts +1 -1
  479. package/src/providers/codexCloud.ts +1 -1
  480. package/src/providers/codexLocal.ts +1 -1
  481. package/src/reportFileDirectory.ts +1 -1
  482. package/src/scheduling/areas.ts +2 -2
  483. package/src/session/service.ts +1 -1
  484. package/src/storage/fleetMigrations.ts +10 -0
  485. package/src/storage/makeFleetTransaction.ts +2 -2
  486. package/src/storage/makeForeignReservations.ts +15 -4
  487. package/src/storage/model.ts +1 -1
  488. package/dist/engine/releaseOnly.d.ts +0 -3
  489. package/dist/engine/releaseOnly.d.ts.map +0 -1
  490. package/dist/engine/releaseOnly.js +0 -19
  491. package/dist/engine/releaseOnly.js.map +0 -1
  492. package/src/engine/releaseOnly.ts +0 -24
@@ -1,7 +1,8 @@
1
1
  import { Effect } from "effect";
2
- import { attention } from "@shivaedev/work-board/integration/attention.ts";
3
- import { board as boardApi } from "@shivaedev/work-board/integration/board.ts";
4
- import { responses } from "@shivaedev/work-board/integration/responses.ts";
2
+ import { attention } from "@shivaedev/work-board/server/integration/attention.ts";
3
+ import { board as boardApi } from "@shivaedev/work-board/server/integration/board.ts";
4
+ import { responses } from "@shivaedev/work-board/server/integration/responses.ts";
5
+ import { closePublishedDecision } from "#board/closePublishedDecision.ts";
5
6
  import { type BoardSnapshot, recordBoardSource } from "#board/readPass.ts";
6
7
  import { BoardAcknowledgementStale, type BoardDecisionAcknowledgement } from "#board/schema.ts";
7
8
  import { BoardFailure } from "#policy.ts";
@@ -37,8 +38,10 @@ export function acknowledgeDecision(root: string, realRoot: string, snapshot: Ef
37
38
  const content = `---\n${JSON.stringify({ id, kind: "result", "request_receipt": requestReceipt })}\n---\n# Managed request acknowledgement\n\nThis immutable receipt acknowledges request handling; it grants no execution, acceptance or delivery authority.\n`;
38
39
  const file = `responses/${id}.md`;
39
40
  const receiptDocument = { file, parsed: boardApi.metadataParse(content) };
40
- const model = metadataModel([...all.filter((document) => document.file !== file), receiptDocument]);
41
- if (!request || managedRequestReceipt(source, request, model) === undefined) {
41
+ const others = all.filter((document) => document.file !== file);
42
+ const acknowledged = others.some((document) => document.parsed.fields.requestReceipt?.question === decision.questionId);
43
+ const model = metadataModel([...others, receiptDocument]);
44
+ if (!request || acknowledged || managedRequestReceipt(source, request, model) === undefined) {
42
45
  return yield* Effect.fail(
43
46
  new BoardAcknowledgementStale({ message: "The exact managed question and applicable response cannot be qualified for acknowledgement." }),
44
47
  );
@@ -47,5 +50,8 @@ export function acknowledgeDecision(root: string, realRoot: string, snapshot: Ef
47
50
  Effect.mapError(() => new BoardFailure({ message: "The managed request acknowledgement could not be recorded on Board." })),
48
51
  );
49
52
  yield* recordBoardSource(realRoot, file, content, receiptDocument.parsed);
53
+ if (input.disposition === "superseded") {
54
+ yield* closePublishedDecision(root, realRoot, source);
55
+ }
50
56
  });
51
57
  }
@@ -1,5 +1,5 @@
1
- import type { ParsedMetadata } from "@shivaedev/work-board/integration/board.ts";
2
- import { responses } from "@shivaedev/work-board/integration/responses.ts";
1
+ import type { ParsedMetadata } from "@shivaedev/work-board/server/integration/board.ts";
2
+ import { responses } from "@shivaedev/work-board/server/integration/responses.ts";
3
3
  import { fleetDeliverable } from "#board/fleetField.ts";
4
4
 
5
5
  const { revisionOf } = responses;
@@ -0,0 +1,51 @@
1
+ import { Effect } from "effect";
2
+ import { parseDocument } from "yaml";
3
+ import { board } from "@shivaedev/work-board/server/integration/board.ts";
4
+ import type { BoardDocument } from "#board/documents.ts";
5
+ import { recordBoardSource } from "#board/readPass.ts";
6
+ import { writeCompletion } from "#board/writeCompletion.ts";
7
+ import { BoardFailure } from "#policy.ts";
8
+
9
+ export function publishedDecision(document: BoardDocument) {
10
+ const { fields, body, diagnostics } = document.parsed;
11
+ const workId = fields.relationships?.find((relation) => relation.kind === "relates_to")?.target;
12
+ const request = fields.attention?.[0];
13
+ if (
14
+ diagnostics.length > 0
15
+ || fields.kind !== "decision"
16
+ || !fields.id?.startsWith("decision.")
17
+ || workId === undefined
18
+ || !body.startsWith(`# Fleet decision for ${workId}\n`)
19
+ || fields.attention?.length !== 1
20
+ || request?.managed !== true
21
+ || !request.id.startsWith(`${workId}.`)
22
+ ) {
23
+ return;
24
+ }
25
+ const sequence = Number(request.id.slice(workId.length + 1));
26
+ return Number.isSafeInteger(sequence) ? { request, sequence, workId } : undefined;
27
+ }
28
+
29
+ export const closePublishedDecision = Effect.fn("FleetBoard.closePublishedDecision")(function* (
30
+ root: string,
31
+ realRoot: string,
32
+ document: BoardDocument,
33
+ ) {
34
+ const decision = publishedDecision(document);
35
+ if (decision === undefined || decision.request.state !== "open") {
36
+ return;
37
+ }
38
+ const header = document.parsed.raw;
39
+ if (header === undefined) {
40
+ return;
41
+ }
42
+ const metadata = parseDocument(header.replace(/^---\r?\n/u, "").replace(/---\r?\n?$/u, ""));
43
+ metadata.setIn(["attention", 0, "state"], "closed");
44
+ const content = `---\n${metadata.toString()}---\n${document.parsed.body}`;
45
+ yield* writeCompletion(root, realRoot, document.file, document.source, content).pipe(
46
+ Effect.mapError((error) => new BoardFailure({ message: error.message })),
47
+ );
48
+ const parsed = board.metadataParse(content);
49
+ yield* recordBoardSource(realRoot, document.file, content, parsed);
50
+ return { file: document.file, parsed, source: content };
51
+ });
@@ -1,12 +1,14 @@
1
- import { releaseOnly } from "#engine/releaseOnly.ts";
2
- import type { Decision } from "#policy.ts";
1
+ import type { DecisionCopy } from "#engine/decisionCopy.ts";
2
+ import type { Choice } from "#engine/situations/choices.ts";
3
3
 
4
- export function decisionAnswer(input: Decision) {
5
- if (input.worker !== undefined) {
6
- return "Record your answer on this item’s answer card to continue the worker in its existing thread. Use a guided release answer or the release command to free terminal ownership instead.";
4
+ export function decisionAnswer({ question }: DecisionCopy) {
5
+ if (question === undefined) {
6
+ return undefined;
7
7
  }
8
- const explanation = releaseOnly(input.code);
9
- const retryText = "### Request changes\nFleet keeps the branch and PR and works on your answer";
10
- const retry = explanation === undefined ? `:::option{id="retry"}\n${retryText}\n:::\n\n` : "";
11
- return `${explanation === undefined ? "" : `${explanation}\n\n`}::::question{id="fleet-action" select="one"}\n### How should Fleet proceed?\n\n${retry}:::option{id="release"}\n### Release\nFleet stops and hands the work back\n:::\n::::`;
8
+ const retry = question.retry === undefined ? "" : `${option("retry", question.retry)}\n`;
9
+ return `::::question{id="fleet-action" select="one"}\n### ${question.title}\n\n${retry}${option("release", question.release)}::::`;
10
+ }
11
+
12
+ function option(id: string, choice: Choice) {
13
+ return `:::option{id="${id}"}\n### ${choice.label}\n${choice.outcome}\n:::\n`;
12
14
  }
@@ -1,7 +1,7 @@
1
1
  import { Effect } from "effect";
2
- import { board } from "@shivaedev/work-board/integration/board.ts";
3
- import type { Reading } from "@shivaedev/work-board/integration/responses.ts";
4
- import { responses } from "@shivaedev/work-board/integration/responses.ts";
2
+ import { board } from "@shivaedev/work-board/server/integration/board.ts";
3
+ import type { Reading } from "@shivaedev/work-board/server/integration/responses.ts";
4
+ import { responses } from "@shivaedev/work-board/server/integration/responses.ts";
5
5
  import type { BoardDocument } from "#board/documents.ts";
6
6
  import type { BoardDecision, BoardDecisionReading } from "#board/schema.ts";
7
7
  import { BoardFailure } from "#policy.ts";
@@ -1,6 +1,6 @@
1
1
  import { Effect, FileSystem, Path } from "effect";
2
- import type { MetadataDocument } from "@shivaedev/work-board/integration/board.ts";
3
- import { board as boardApi } from "@shivaedev/work-board/integration/board.ts";
2
+ import type { MetadataDocument } from "@shivaedev/work-board/server/integration/board.ts";
3
+ import { board as boardApi } from "@shivaedev/work-board/server/integration/board.ts";
4
4
  import { readDocument } from "#board/readDocument.ts";
5
5
  import { BoardSnapshot, readSnapshot } from "#board/readPass.ts";
6
6
  import { BoardFailure } from "#policy.ts";
@@ -13,6 +13,9 @@ export const snapshotDocument = Effect.fn("FleetBoard.snapshotDocument")(functio
13
13
  const matches = snapshot.model.ids.get(workId);
14
14
  const found = matches?.length === 1 ? snapshot.files.get(matches[0]?.file ?? "") : undefined;
15
15
  if (found === undefined) {
16
+ if (matches === undefined && snapshot.problems.size === 0) {
17
+ return yield* Effect.fail(new BoardFailure({ code: "board-item-missing", message: `Board item no longer exists: ${workId}`, workId }));
18
+ }
16
19
  const message = [
17
20
  `Board identity is missing or ambiguous: ${workId}`,
18
21
  ...Array.from(snapshot.problems.values(), (failure) => failure.message),
@@ -83,7 +86,3 @@ export function boardDocuments(root: string, realRoot: string) {
83
86
  export function boundSnapshot(root: string, realRoot: string, fs: FileSystem.FileSystem, path: Path.Path) {
84
87
  return boardSnapshot(root, realRoot).pipe(Effect.provideService(FileSystem.FileSystem, fs), Effect.provideService(Path.Path, path));
85
88
  }
86
-
87
- export function boundDocuments(root: string, realRoot: string, fs: FileSystem.FileSystem, path: Path.Path) {
88
- return boardDocuments(root, realRoot).pipe(Effect.provideService(FileSystem.FileSystem, fs), Effect.provideService(Path.Path, path));
89
- }
@@ -1,5 +1,5 @@
1
1
  import { parse } from "yaml";
2
- import type { ParsedMetadata } from "@shivaedev/work-board/integration/board.ts";
2
+ import type { ParsedMetadata } from "@shivaedev/work-board/server/integration/board.ts";
3
3
 
4
4
  const APPROVAL = "fleet";
5
5
  const LAUNCH = "fleet-launch";
@@ -1,15 +1,16 @@
1
1
  import { Context, Effect, FileSystem, Layer, Path, Schema } from "effect";
2
- import { defineService } from "@shivaedev/effect-service/define-service.ts";
3
- import { board as boardApi } from "@shivaedev/work-board/integration/board.ts";
2
+ import { defineService } from "@shivaedev/effect-service/defineService.ts";
3
+ import { board as boardApi } from "@shivaedev/work-board/server/integration/board.ts";
4
4
  import { acknowledgeDecision } from "#board/acknowledgeDecision.ts";
5
5
  import { briefRevision } from "#board/briefRevision.ts";
6
6
  import { completionMarkdown } from "#board/completionMarkdown.ts";
7
7
  import { decisionReading } from "#board/decisionReading.ts";
8
- import { boundDocuments, boundSnapshot, refreshSnapshotDocument, snapshotDocument } from "#board/documents.ts";
8
+ import { boundSnapshot, refreshSnapshotDocument, snapshotDocument } from "#board/documents.ts";
9
9
  import { fleetApproved, fleetDeliverable, fleetPriority } from "#board/fleetField.ts";
10
10
  import { publishBoard } from "#board/publish.ts";
11
11
  import { publishReport } from "#board/publishReport.ts";
12
12
  import { workMetadata } from "#board/readPass.ts";
13
+ import { upgradeDecisionClosure } from "#board/upgradeDecisionClosure.ts";
13
14
  import { workRevision } from "#board/workRevision.ts";
14
15
  import { writeCompletion } from "#board/writeCompletion.ts";
15
16
  import { BoardFailure, BoardGateway, Priority } from "#policy.ts";
@@ -24,8 +25,8 @@ const MarkdownBoard = defineService({
24
25
  const fs = yield* FileSystem.FileSystem;
25
26
  const path = yield* Path.Path;
26
27
  const realRoot = yield* fs.realPath(root);
27
- const documents = boundDocuments(root, realRoot, fs, path);
28
- const snapshot = boundSnapshot(root, realRoot, fs, path);
28
+ const snapshot = boundSnapshot(root, realRoot, fs, path).pipe(Effect.tap((current) => upgradeDecisionClosure(root, realRoot, current, fs)));
29
+ const documents = snapshot.pipe(Effect.map((current) => current.documents.filter((document) => !current.problems.has(document.file))));
29
30
  const get = Effect.fn("FleetBoard.get")(function* (workId: string, options?: { readonly fresh?: boolean }) {
30
31
  const current = yield* snapshot;
31
32
  const found = yield* options?.fresh
@@ -1,11 +1,12 @@
1
1
  import { relative } from "node:path";
2
2
  import { Clock, Effect } from "effect";
3
- import { board as boardApi } from "@shivaedev/work-board/integration/board.ts";
4
- import { responses } from "@shivaedev/work-board/integration/responses.ts";
3
+ import { board as boardApi } from "@shivaedev/work-board/server/integration/board.ts";
4
+ import { responses } from "@shivaedev/work-board/server/integration/responses.ts";
5
5
  import { decisionAnswer } from "#board/decisionAnswer.ts";
6
6
  import type { BoardDocument } from "#board/documents.ts";
7
7
  import { recordBoardSource } from "#board/readPass.ts";
8
8
  import type { BoardDecision } from "#board/schema.ts";
9
+ import { type DecisionCopy, decisionCopy } from "#engine/decisionCopy.ts";
9
10
  import { BoardFailure, type BoardWork, type Decision } from "#policy.ts";
10
11
 
11
12
  const { publish, questionFrom, questionId, questionMarkdown, revisionOf } = responses;
@@ -23,14 +24,14 @@ function linked(text: string): string {
23
24
  return url.protocol === "https:" || url.protocol === "http:" ? `<${url.href.replaceAll("<", "%3C").replaceAll(">", "%3E")}>` : quoted(text);
24
25
  }
25
26
 
26
- function decisionSource(itemId: string, work: BoardWork, input: Decision): string {
27
+ function decisionSource(itemId: string, work: BoardWork, input: Decision, copy: DecisionCopy): string {
27
28
  const metadata = {
28
29
  attention: [
29
30
  {
30
31
  id: input.id,
31
32
  kind: "decision",
32
33
  managed: true,
33
- reason: input.reason,
34
+ reason: copy.reason,
34
35
  "response_from": [input.attentionOwner ?? "orchestrator"],
35
36
  state: "open",
36
37
  unblocks: [work.workId],
@@ -40,8 +41,8 @@ function decisionSource(itemId: string, work: BoardWork, input: Decision): strin
40
41
  kind: "decision",
41
42
  relationships: [{ kind: "relates_to", target: work.workId }],
42
43
  };
43
- const answer = decisionAnswer(input);
44
- return `---\n${JSON.stringify(metadata)}\n---\n# Fleet decision for ${work.workId}\n\n## Decision\n\n${quoted(input.reason)}\n\n## Recommendation\n\n${quoted(input.recommendation)}\n\n## Relevant links\n\n${input.links.map(linked).join("\n\n")}\n\n${answer}\n\n## Reviewed Board work\n\n${quoted(work.context)}\n`;
44
+ const answer = decisionAnswer(copy);
45
+ return `---\n${JSON.stringify(metadata)}\n---\n# Fleet decision for ${work.workId}\n\n## Decision\n\n${quoted(copy.reason)}\n\n## Recommendation\n\n${quoted(copy.recommendation)}\n\n## Relevant links\n\n${input.links.map(linked).join("\n\n")}\n\n${answer === undefined ? "" : `${answer}\n\n`}## Reviewed Board work\n\n${quoted(work.context)}\n`;
45
46
  }
46
47
 
47
48
  export function publishBoard(root: string, realRoot: string, documents: Effect.Effect<readonly BoardDocument[], BoardFailure>) {
@@ -49,7 +50,8 @@ export function publishBoard(root: string, realRoot: string, documents: Effect.E
49
50
  const workSourcePath = relative(realRoot, work.sourcePath);
50
51
  const itemId = `decision.${revisionOf(JSON.stringify([work.workId, work.revision, workSourcePath, input.id, input.reason, input.recommendation, input.links, ...(input.worker === undefined ? [] : [input.worker])]))}`;
51
52
  const existing = input.published === undefined ? undefined : (yield* documents).find((document) => document.file === input.published?.sourcePath);
52
- const context = existing?.parsed.fields.id === itemId ? existing.source : decisionSource(itemId, work, input);
53
+ const copy = decisionCopy(input);
54
+ const context = existing?.parsed.fields.id === itemId ? existing.source : decisionSource(itemId, work, input, copy);
53
55
  const parsed = boardApi.metadataParse(context);
54
56
  if (new TextEncoder().encode(context).length > 256 * 1024 || parsed.diagnostics.length > 0) {
55
57
  return yield* Effect.fail(new BoardFailure({ message: "Fleet decision context exceeds Board limits or contains invalid attention metadata." }));
@@ -82,7 +84,7 @@ export function publishBoard(root: string, realRoot: string, documents: Effect.E
82
84
  question: {
83
85
  deadline: registeredAt + 48 * 60 * 60 * 1000,
84
86
  item: itemId,
85
- reason: input.reason,
87
+ reason: copy.reason,
86
88
  registeredAt,
87
89
  request: input.id,
88
90
  reviewedRevision: revision,
@@ -1,7 +1,7 @@
1
1
  import { relative } from "node:path";
2
2
  import { Effect } from "effect";
3
- import { board } from "@shivaedev/work-board/integration/board.ts";
4
- import { responses } from "@shivaedev/work-board/integration/responses.ts";
3
+ import { board } from "@shivaedev/work-board/server/integration/board.ts";
4
+ import { responses } from "@shivaedev/work-board/server/integration/responses.ts";
5
5
  import { briefRevision } from "#board/briefRevision.ts";
6
6
  import type { BoardDocument } from "#board/documents.ts";
7
7
  import { recordBoardSource, workMetadata } from "#board/readPass.ts";
@@ -1,5 +1,5 @@
1
1
  import { Effect, FileSystem } from "effect";
2
- import { board as boardApi } from "@shivaedev/work-board/integration/board.ts";
2
+ import { board as boardApi } from "@shivaedev/work-board/server/integration/board.ts";
3
3
  import { STATUS_MARKER } from "#board/statusMarkdown.ts";
4
4
  import { BoardFailure } from "#policy.ts";
5
5
 
@@ -1,7 +1,7 @@
1
1
  import { join } from "node:path";
2
2
  import { Context, Effect, type FileSystem, type Path } from "effect";
3
- import type { MetadataModel, ParsedMetadata } from "@shivaedev/work-board/integration/board.ts";
4
- import { board as boardApi } from "@shivaedev/work-board/integration/board.ts";
3
+ import type { MetadataModel, ParsedMetadata } from "@shivaedev/work-board/server/integration/board.ts";
4
+ import { board as boardApi } from "@shivaedev/work-board/server/integration/board.ts";
5
5
  import type { BoardDocument } from "#board/documents.ts";
6
6
  import type { BoardFailure, BoardWork } from "#policy.ts";
7
7
 
@@ -1,4 +1,4 @@
1
- import { responses } from "@shivaedev/work-board/integration/responses.ts";
1
+ import { responses } from "@shivaedev/work-board/server/integration/responses.ts";
2
2
  import type { BoardWork } from "#policy.ts";
3
3
  import type { SessionReceipt } from "#session/schema.ts";
4
4
 
@@ -1,5 +1,5 @@
1
1
  import { basename } from "node:path";
2
- import { responses } from "@shivaedev/work-board/integration/responses.ts";
2
+ import { responses } from "@shivaedev/work-board/server/integration/responses.ts";
3
3
  import type { ReportFile, UnavailableAttachment } from "#reportAttachments.ts";
4
4
 
5
5
  const { revisionOf } = responses;
@@ -1,6 +1,6 @@
1
1
  import { Schema } from "effect";
2
- import { attention } from "@shivaedev/work-board/integration/attention.ts";
3
- import { responses } from "@shivaedev/work-board/integration/responses.ts";
2
+ import { attention } from "@shivaedev/work-board/server/integration/attention.ts";
3
+ import { responses } from "@shivaedev/work-board/server/integration/responses.ts";
4
4
  import { SessionReceipt } from "#session/schema.ts";
5
5
 
6
6
  const { RequestReceipt } = attention;
@@ -0,0 +1,61 @@
1
+ import { Effect, type FileSystem } from "effect";
2
+ import { responses } from "@shivaedev/work-board/server/integration/responses.ts";
3
+ import { closePublishedDecision, publishedDecision } from "#board/closePublishedDecision.ts";
4
+ import type { BoardDocument } from "#board/documents.ts";
5
+ import type { BoardSnapshot } from "#board/readPass.ts";
6
+ import { writePublished } from "#board/writePublished.ts";
7
+ import { BoardFailure } from "#policy.ts";
8
+
9
+ const MARKER = ".fleet-decision-closure-v1.json";
10
+
11
+ export const upgradeDecisionClosure = Effect.fn("FleetBoard.upgradeDecisionClosure")(function* (
12
+ root: string,
13
+ realRoot: string,
14
+ snapshot: BoardSnapshot,
15
+ fs: FileSystem.FileSystem,
16
+ ) {
17
+ if (yield* fs.exists(`${realRoot}/${MARKER}`).pipe(Effect.mapError((error) => new BoardFailure({ message: error.message })))) {
18
+ return;
19
+ }
20
+ if (snapshot.problems.size > 0) {
21
+ yield* Effect.logWarning("Fleet decision closure upgrade deferred because the Board has problems", { problems: snapshot.problems.size });
22
+ return;
23
+ }
24
+ const documents = snapshot.documents;
25
+ const latest = latestSequences(documents);
26
+ const superseded = new Set(
27
+ documents.flatMap((document) => {
28
+ const receipt = document.parsed.fields.requestReceipt;
29
+ return receipt?.disposition === "superseded" ? [receipt.question] : [];
30
+ }),
31
+ );
32
+ const questions = new Map(
33
+ documents.flatMap((document) => {
34
+ const question = responses.questionFrom(document);
35
+ return question === undefined ? [] : [[question.question.source, question.id] as const];
36
+ }),
37
+ );
38
+ for (const document of documents) {
39
+ const decision = publishedDecision(document);
40
+ if (decision !== undefined && (decision.sequence < (latest.get(decision.workId) ?? -1) || superseded.has(questions.get(document.file) ?? ""))) {
41
+ const closed = yield* closePublishedDecision(root, realRoot, document);
42
+ if (closed !== undefined) {
43
+ snapshot.record(closed);
44
+ }
45
+ }
46
+ }
47
+ yield* writePublished(root, realRoot, MARKER, '{"version":1}\n', (source) => source === '{"version":1}\n').pipe(
48
+ Effect.mapError((error) => new BoardFailure({ message: error.message })),
49
+ );
50
+ });
51
+
52
+ function latestSequences(documents: readonly BoardDocument[]) {
53
+ const latest = new Map<string, number>();
54
+ for (const document of documents) {
55
+ const decision = publishedDecision(document);
56
+ if (decision !== undefined) {
57
+ latest.set(decision.workId, Math.max(latest.get(decision.workId) ?? -1, decision.sequence));
58
+ }
59
+ }
60
+ return latest;
61
+ }
@@ -1,5 +1,5 @@
1
- import { board as boardApi } from "@shivaedev/work-board/integration/board.ts";
2
- import { responses } from "@shivaedev/work-board/integration/responses.ts";
1
+ import { board as boardApi } from "@shivaedev/work-board/server/integration/board.ts";
2
+ import { responses } from "@shivaedev/work-board/server/integration/responses.ts";
3
3
  import { briefRevision } from "#board/briefRevision.ts";
4
4
 
5
5
  const { revisionOf } = responses;
@@ -1,6 +1,6 @@
1
1
  import { Effect, Schema } from "effect";
2
- import type { FleetHealth as BoardFleetHealth } from "@shivaedev/work-board/integration/diagnostics.ts";
3
- import { diagnostics as diagnosticsApi } from "@shivaedev/work-board/integration/diagnostics.ts";
2
+ import type { FleetHealth as BoardFleetHealth } from "@shivaedev/work-board/server/integration/diagnostics.ts";
3
+ import { diagnostics as diagnosticsApi } from "@shivaedev/work-board/server/integration/diagnostics.ts";
4
4
  import { writePublished } from "#board/writePublished.ts";
5
5
  import { BoardFailure } from "#policy.ts";
6
6
 
@@ -4,7 +4,12 @@ import { Effect } from "effect";
4
4
  import { type ReportDirectory, validateReportDirectory, withReportDirectory } from "#reportFileDirectory.ts";
5
5
  import { hasFileCode, ReportFileFailure, reportFileIo, withReportFile } from "#reportFileFailure.ts";
6
6
 
7
- function unchanged(folder: string, name: "status.md" | "health.json", content: string, owns: (source: string) => boolean) {
7
+ function unchanged(
8
+ folder: string,
9
+ name: "status.md" | "health.json" | ".fleet-decision-closure-v1.json",
10
+ content: string,
11
+ owns: (source: string) => boolean,
12
+ ) {
8
13
  const label = `fleet/${name}`;
9
14
  return withReportFile(
10
15
  label,
@@ -27,7 +32,7 @@ function unchanged(folder: string, name: "status.md" | "health.json", content: s
27
32
  const publish = Effect.fnUntraced(function* (
28
33
  directory: ReportDirectory,
29
34
  target: ReportDirectory,
30
- name: "status.md" | "health.json",
35
+ name: "status.md" | "health.json" | ".fleet-decision-closure-v1.json",
31
36
  content: string,
32
37
  owns: (source: string) => boolean,
33
38
  ) {
@@ -54,13 +59,17 @@ const publish = Effect.fnUntraced(function* (
54
59
  export const writePublished = Effect.fn("Fleet.writePublished")(function* (
55
60
  root: string,
56
61
  realRoot: string,
57
- name: "status.md" | "health.json",
62
+ name: "status.md" | "health.json" | ".fleet-decision-closure-v1.json",
58
63
  content: string,
59
64
  owns: (source: string) => boolean,
60
65
  ) {
61
- const label = `fleet/${name}`;
66
+ const upgrade = name === ".fleet-decision-closure-v1.json";
67
+ const label = upgrade ? name : `fleet/${name}`;
62
68
  return yield* withReportDirectory(label, root, realRoot, (directory) =>
63
69
  Effect.gen(function* () {
70
+ if (upgrade) {
71
+ return yield* publish(directory, directory, name, content, owns);
72
+ }
64
73
  yield* reportFileIo(label, () => mkdir(`${directory.folder}/fleet`)).pipe(
65
74
  Effect.catchTag("ReportFileFailure", (error) => (hasFileCode(error.cause, "EEXIST") ? Effect.void : Effect.fail(error))),
66
75
  );
package/src/cli.ts CHANGED
@@ -11,7 +11,7 @@ import * as Flag from "effect/cli/Flag";
11
11
  import * as Effect from "effect/Effect";
12
12
  import * as Option from "effect/Option";
13
13
  import { answerCommand, continueCommand, nameThreadsCommand, reassignCommand, releaseCommand } from "#host/actionCommands.ts";
14
- import { board, config, host, port } from "#host/cliOptions.ts";
14
+ import { board, clientPort, config, host, port } from "#host/cliOptions.ts";
15
15
  import { waitCommand, watchCommand } from "#host/followCommands.ts";
16
16
  import { VERSION } from "#packageInfo.ts";
17
17
 
@@ -20,7 +20,7 @@ const serveCommand = Command.make(
20
20
  { board: Argument.Directory("board-dir"), config, port },
21
21
  Effect.fn("WorkFleetCli.serve")(function* (input) {
22
22
  const { serveFleet } = yield* Effect.promise(() => import("#host/daemon.ts"));
23
- yield* serveFleet(yield* host(input.board, input.config), undefined, input.port);
23
+ yield* serveFleet(yield* host(input.board, input.config), undefined, Option.getOrUndefined(input.port));
24
24
  }),
25
25
  ).pipe(Command.withDescription("Serve the local Fleet HTTP RPC daemon and schedule approved Board work"));
26
26
 
@@ -40,7 +40,7 @@ const dispatchCommand = Command.make(
40
40
  Effect.fn("WorkFleetCli.dispatch")(function* (input) {
41
41
  const { daemonRequest } = yield* Effect.promise(() => import("#host/daemonClient.ts"));
42
42
  const value = yield* daemonRequest(
43
- input.port,
43
+ yield* clientPort(input),
44
44
  (client) => client("daemon.dispatch", { ignoreAreas: input.ignoreAreas, now: input.now, workId: input.workId }),
45
45
  `dispatch ${input.workId}`,
46
46
  );
@@ -62,12 +62,20 @@ const statusCommand = Command.make(
62
62
  Promise.all([import("#host/daemonClient.ts"), import("#host/renderStatus.ts")]),
63
63
  );
64
64
  const workId = Option.getOrUndefined(input.workId);
65
+ const daemonPort = yield* clientPort(input);
65
66
  const current = yield* daemonRequest(
66
- input.port,
67
+ daemonPort,
67
68
  (client) => client("daemon.status", workId === undefined ? {} : { workId }),
68
69
  workId === undefined ? "status" : `status ${workId}`,
69
70
  );
70
- yield* Console.log(input.json ? JSON.stringify(current) : renderStatus(current, input.port));
71
+ yield* Console.log(
72
+ input.json
73
+ ? JSON.stringify(current)
74
+ : renderStatus(current, {
75
+ board: input.board,
76
+ ...Option.match(input.port, { onNone: () => ({}), onSome: (value) => ({ port: value }) }),
77
+ }),
78
+ );
71
79
  }),
72
80
  ).pipe(Command.withDescription("Show active and completed Fleet work, and waiting work grouped by owner"));
73
81
 
@@ -17,7 +17,7 @@ export const authorizeResolution = Effect.fn("Fleet.authorizeResolution")(functi
17
17
  if (executing(record)) {
18
18
  return yield* Effect.fail(new Forbidden({ message: "Confirm terminal execution before releasing ownership" }));
19
19
  }
20
- if (record.result?.kind === "change") {
20
+ if (record.result?.kind === "change" && record.decision?.code !== "pr-closed") {
21
21
  yield* state.store.reserveForeign(record.result.pr, { backlog: true, executing: false });
22
22
  }
23
23
  });
@@ -1,14 +1,13 @@
1
1
  import { Effect } from "effect";
2
2
  import { Conflict, Forbidden } from "@shivaedev/platform/errors/taxonomy.ts";
3
3
  import { workRevision } from "#board/workRevision.ts";
4
- import { closeDecisions } from "#engine/closeDecisions.ts";
5
4
  import { withFailureContext } from "#engine/failureContext.ts";
6
5
  import type { EngineState } from "#engine/makeState.ts";
7
6
  import type { FleetRecord } from "#model.ts";
8
7
  import type { BoardWork } from "#policy.ts";
9
8
  import type { Versioned } from "#storage/model.ts";
10
9
 
11
- const CHANGED_BRIEF_REASON = "Board context changed";
10
+ export const CHANGED_BRIEF_REASON = "Board context changed";
12
11
 
13
12
  export function briefChanged(record: Pick<FleetRecord, "boardRevision" | "boardContext">, work: BoardWork): boolean {
14
13
  return workRevision(record.boardRevision, record.boardContext) !== workRevision(work.revision, work.context);
@@ -33,7 +32,7 @@ export const authorizeBriefContext = Effect.fn("Fleet.authorizeBriefContext")(fu
33
32
  ) {
34
33
  yield* authorizeBrief(work);
35
34
  if (briefChanged(record, work)) {
36
- return yield* withFailureContext(new Conflict({ message: CHANGED_BRIEF_REASON }), { attentionOwner: "maintainer", code: "fleet-stale" });
35
+ return yield* withFailureContext(new Conflict({ message: CHANGED_BRIEF_REASON }), { code: "fleet-stale" });
37
36
  }
38
37
  });
39
38
 
@@ -53,29 +52,22 @@ export function stopChangedBrief(state: EngineState) {
53
52
  ) {
54
53
  return stored;
55
54
  }
56
- const published = stored.value.decision?.published;
57
55
  const stopped = yield* state.save(stored, {
58
56
  ...stored.value,
59
57
  checks: undefined,
60
58
  mergeReadyAt: undefined,
61
59
  mergeReadyHead: undefined,
62
60
  review: undefined,
63
- supersededDecisions:
64
- published === undefined
65
- ? stored.value.supersededDecisions
66
- : [...(stored.value.supersededDecisions ?? []), { published, supersededAt: state.policy.now() }],
67
61
  });
68
- return yield* state
69
- .decision(
70
- stopped,
71
- "fleet-stale",
72
- CHANGED_BRIEF_REASON,
73
- "Dispatch to approve the current brief in place, retry this decision, or safely release this work",
74
- undefined,
75
- "maintainer",
76
- work,
77
- )
78
- .pipe(Effect.flatMap(closeDecisions(state)));
62
+ return yield* state.decision(
63
+ stopped,
64
+ "fleet-stale",
65
+ CHANGED_BRIEF_REASON,
66
+ "Dispatch to approve the current brief in place, retry this decision, or safely release this work",
67
+ undefined,
68
+ undefined,
69
+ work,
70
+ );
79
71
  });
80
72
  }
81
73
 
@@ -0,0 +1,63 @@
1
+ import type { DecisionCode } from "#DecisionCode.ts";
2
+ import { CHANGED_BRIEF_REASON } from "#engine/boardBrief.ts";
3
+ import { blocked, type Choice, RELEASE, type Situation } from "#engine/situations/choices.ts";
4
+ import { serviceSituations } from "#engine/situations/service.ts";
5
+ import { stopSituations } from "#engine/situations/stop.ts";
6
+ import { workSituations } from "#engine/situations/work.ts";
7
+ import type { Decision } from "#policy.ts";
8
+
9
+ export interface DecisionCopy {
10
+ readonly question?: {
11
+ readonly title: string;
12
+ readonly retry?: Choice;
13
+ readonly release: Choice;
14
+ };
15
+ readonly reason: string;
16
+ readonly recommendation: string;
17
+ }
18
+
19
+ const situations: Readonly<Record<DecisionCode, Situation>> = { ...serviceSituations, ...stopSituations, ...workSituations };
20
+
21
+ const changedBrief: Situation = {
22
+ happened: "The task was edited on the Board while this work was waiting.",
23
+ question: "Continue with the edited task?",
24
+ recommendation: "Fleet needs to know whether the edited task still fits the work done so far. If it does, continue. Otherwise stop here.",
25
+ retry: {
26
+ label: "Continue on the updated task",
27
+ outcome: "Fleet accepts the edited task and continues the same work with it, on the same branch and PR.",
28
+ },
29
+ };
30
+
31
+ const uncoded = blocked("Fleet stopped and needs your decision.", "Check the details, then let Fleet try again, or stop here.");
32
+
33
+ const WORKER =
34
+ "The worker needs your answer to keep going. Write it on this card. Fleet passes it to the same worker, which continues where it stopped.";
35
+
36
+ export function decisionCopy(decision: Pick<Decision, "code" | "publicationWork" | "reason" | "worker">): DecisionCopy {
37
+ if (decision.worker !== undefined) {
38
+ return { reason: decision.reason, recommendation: WORKER };
39
+ }
40
+ const situation = situationOf(decision);
41
+ const detailed = situation.details === true && decision.reason.trim() !== "" && decision.reason !== decision.code;
42
+ return {
43
+ question: {
44
+ release: situation.release ?? RELEASE,
45
+ title: situation.question ?? "What should Fleet do next?",
46
+ ...(situation.retry === undefined ? {} : { retry: situation.retry }),
47
+ },
48
+ reason: detailed ? `${situation.happened}\n\nDetails: ${decision.reason}` : situation.happened,
49
+ recommendation: situation.recommendation,
50
+ };
51
+ }
52
+
53
+ export function releaseOnly(code: DecisionCode | undefined) {
54
+ const situation = code === undefined ? undefined : situations[code];
55
+ return situation?.retry === undefined ? situation?.recommendation : undefined;
56
+ }
57
+
58
+ function situationOf(decision: Pick<Decision, "code" | "publicationWork" | "reason">) {
59
+ if (decision.code === "fleet-stale" && decision.reason === CHANGED_BRIEF_REASON && decision.publicationWork !== undefined) {
60
+ return changedBrief;
61
+ }
62
+ return decision.code === undefined ? uncoded : situations[decision.code];
63
+ }