@shivaedev/work-fleet 0.2.1 → 0.4.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 (515) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +61 -19
  3. package/dist/DispatchRequest.d.ts +13 -0
  4. package/dist/DispatchRequest.d.ts.map +1 -0
  5. package/dist/DispatchRequest.js +12 -0
  6. package/dist/DispatchRequest.js.map +1 -0
  7. package/dist/admit.d.ts +11 -0
  8. package/dist/admit.d.ts.map +1 -1
  9. package/dist/attention.d.ts +1 -0
  10. package/dist/attention.d.ts.map +1 -1
  11. package/dist/attention.js +4 -0
  12. package/dist/attention.js.map +1 -1
  13. package/dist/board/fleetField.d.ts +1 -0
  14. package/dist/board/fleetField.d.ts.map +1 -1
  15. package/dist/board/fleetField.js +4 -0
  16. package/dist/board/fleetField.js.map +1 -1
  17. package/dist/board/markdown.d.ts.map +1 -1
  18. package/dist/board/markdown.js +7 -2
  19. package/dist/board/markdown.js.map +1 -1
  20. package/dist/board/publish.d.ts +2 -0
  21. package/dist/board/publish.d.ts.map +1 -1
  22. package/dist/board/publishReport.d.ts +1 -0
  23. package/dist/board/publishReport.d.ts.map +1 -1
  24. package/dist/board/readPass.d.ts +1 -0
  25. package/dist/board/readPass.d.ts.map +1 -1
  26. package/dist/cli.js +13 -6
  27. package/dist/cli.js.map +1 -1
  28. package/dist/engine/abandonStalled.d.ts +1171 -1004
  29. package/dist/engine/abandonStalled.d.ts.map +1 -1
  30. package/dist/engine/admissionOrder.d.ts +1091 -0
  31. package/dist/engine/admissionOrder.d.ts.map +1 -0
  32. package/dist/engine/admissionOrder.js +15 -0
  33. package/dist/engine/admissionOrder.js.map +1 -0
  34. package/dist/engine/applyResolution.d.ts +20 -0
  35. package/dist/engine/applyResolution.d.ts.map +1 -1
  36. package/dist/engine/approveBrief.d.ts +31 -0
  37. package/dist/engine/approveBrief.d.ts.map +1 -1
  38. package/dist/engine/authorizeResolution.d.ts +1160 -1003
  39. package/dist/engine/authorizeResolution.d.ts.map +1 -1
  40. package/dist/engine/boardBrief.d.ts +32 -0
  41. package/dist/engine/boardBrief.d.ts.map +1 -1
  42. package/dist/engine/capacityRetry.d.ts +3488 -3007
  43. package/dist/engine/capacityRetry.d.ts.map +1 -1
  44. package/dist/engine/closeDecisions.d.ts +20 -0
  45. package/dist/engine/closeDecisions.d.ts.map +1 -1
  46. package/dist/engine/completeBoardWork.d.ts +20 -0
  47. package/dist/engine/completeBoardWork.d.ts.map +1 -1
  48. package/dist/engine/completeReport.d.ts +21 -0
  49. package/dist/engine/completeReport.d.ts.map +1 -1
  50. package/dist/engine/continueCommand.d.ts +10 -0
  51. package/dist/engine/continueCommand.d.ts.map +1 -1
  52. package/dist/engine/continueWorker.d.ts +20 -0
  53. package/dist/engine/continueWorker.d.ts.map +1 -1
  54. package/dist/engine/deliverPendingAnswers.d.ts +1085 -898
  55. package/dist/engine/deliverPendingAnswers.d.ts.map +1 -1
  56. package/dist/engine/dispatchCommand.d.ts +14 -1
  57. package/dist/engine/dispatchCommand.d.ts.map +1 -1
  58. package/dist/engine/dispatchCommand.js +25 -5
  59. package/dist/engine/dispatchCommand.js.map +1 -1
  60. package/dist/engine/ensureDecisionOwner.d.ts +20 -0
  61. package/dist/engine/ensureDecisionOwner.d.ts.map +1 -1
  62. package/dist/engine/ensurePublication.d.ts +20 -0
  63. package/dist/engine/ensurePublication.d.ts.map +1 -1
  64. package/dist/engine/failureContext.d.ts +1 -0
  65. package/dist/engine/failureContext.d.ts.map +1 -1
  66. package/dist/engine/failureContext.js.map +1 -1
  67. package/dist/engine/failureMessage.js +11 -1
  68. package/dist/engine/failureMessage.js.map +1 -1
  69. package/dist/engine/health.d.ts +10 -0
  70. package/dist/engine/health.d.ts.map +1 -1
  71. package/dist/engine/inspectRenewal.d.ts +21 -0
  72. package/dist/engine/inspectRenewal.d.ts.map +1 -1
  73. package/dist/engine/launchInput.d.ts +10 -0
  74. package/dist/engine/launchInput.d.ts.map +1 -1
  75. package/dist/engine/launchReceipt.d.ts +10 -0
  76. package/dist/engine/launchReceipt.d.ts.map +1 -1
  77. package/dist/engine/localOnlyCriteria.d.ts +1 -0
  78. package/dist/engine/localOnlyCriteria.d.ts.map +1 -1
  79. package/dist/engine/localOnlyCriteria.js +5 -1
  80. package/dist/engine/localOnlyCriteria.js.map +1 -1
  81. package/dist/engine/makeAdopt.d.ts +21 -0
  82. package/dist/engine/makeAdopt.d.ts.map +1 -1
  83. package/dist/engine/makeAdvance.d.ts +10 -0
  84. package/dist/engine/makeAdvance.d.ts.map +1 -1
  85. package/dist/engine/makeDeliver.d.ts +20 -0
  86. package/dist/engine/makeDeliver.d.ts.map +1 -1
  87. package/dist/engine/makeHuman.d.ts +20 -0
  88. package/dist/engine/makeHuman.d.ts.map +1 -1
  89. package/dist/engine/makeLaunch.d.ts +20 -0
  90. package/dist/engine/makeLaunch.d.ts.map +1 -1
  91. package/dist/engine/makeLaunch.js +4 -13
  92. package/dist/engine/makeLaunch.js.map +1 -1
  93. package/dist/engine/makeObserve.d.ts +20 -0
  94. package/dist/engine/makeObserve.d.ts.map +1 -1
  95. package/dist/engine/makeReview.d.ts +21 -0
  96. package/dist/engine/makeReview.d.ts.map +1 -1
  97. package/dist/engine/makeState.d.ts +1164 -1010
  98. package/dist/engine/makeState.d.ts.map +1 -1
  99. package/dist/engine/makeState.js +19 -11
  100. package/dist/engine/makeState.js.map +1 -1
  101. package/dist/engine/makeValidate.d.ts +21 -0
  102. package/dist/engine/makeValidate.d.ts.map +1 -1
  103. package/dist/engine/mergeReadiness.d.ts +1425 -1764
  104. package/dist/engine/mergeReadiness.d.ts.map +1 -1
  105. package/dist/engine/mergeReadiness.js +3 -4
  106. package/dist/engine/mergeReadiness.js.map +1 -1
  107. package/dist/engine/observeDeliveryFailure.d.ts +1170 -1003
  108. package/dist/engine/observeDeliveryFailure.d.ts.map +1 -1
  109. package/dist/engine/observeRenewal.d.ts +33 -0
  110. package/dist/engine/observeRenewal.d.ts.map +1 -1
  111. package/dist/engine/obtainReview.d.ts +11 -0
  112. package/dist/engine/obtainReview.d.ts.map +1 -1
  113. package/dist/engine/obtainReview.js +2 -1
  114. package/dist/engine/obtainReview.js.map +1 -1
  115. package/dist/engine/operationRecord.d.ts +1898 -1779
  116. package/dist/engine/operationRecord.d.ts.map +1 -1
  117. package/dist/engine/persistTerminalReceipts.d.ts +20 -0
  118. package/dist/engine/persistTerminalReceipts.d.ts.map +1 -1
  119. package/dist/engine/prepareCommand.d.ts +10 -0
  120. package/dist/engine/prepareCommand.d.ts.map +1 -1
  121. package/dist/engine/prepareCommand.js +1 -1
  122. package/dist/engine/prepareCommand.js.map +1 -1
  123. package/dist/engine/queueAnswerCommand.d.ts +10 -0
  124. package/dist/engine/queueAnswerCommand.d.ts.map +1 -1
  125. package/dist/engine/readOrContinueReview.d.ts +11 -0
  126. package/dist/engine/readOrContinueReview.d.ts.map +1 -1
  127. package/dist/engine/readOrContinueReview.js +2 -1
  128. package/dist/engine/readOrContinueReview.js.map +1 -1
  129. package/dist/engine/readResolution.d.ts +1 -0
  130. package/dist/engine/readResolution.d.ts.map +1 -1
  131. package/dist/engine/readRetry.d.ts +2345 -2010
  132. package/dist/engine/readRetry.d.ts.map +1 -1
  133. package/dist/engine/readRetry.js +22 -2
  134. package/dist/engine/readRetry.js.map +1 -1
  135. package/dist/engine/reassignCommand.d.ts +10 -0
  136. package/dist/engine/reassignCommand.d.ts.map +1 -1
  137. package/dist/engine/reconcileAttempt.d.ts +12 -1
  138. package/dist/engine/reconcileAttempt.d.ts.map +1 -1
  139. package/dist/engine/reconcileAttempt.js +2 -1
  140. package/dist/engine/reconcileAttempt.js.map +1 -1
  141. package/dist/engine/reconcileCommand.d.ts +10 -0
  142. package/dist/engine/reconcileCommand.d.ts.map +1 -1
  143. package/dist/engine/recordResponseCommand.d.ts +551 -0
  144. package/dist/engine/recordResponseCommand.d.ts.map +1 -0
  145. package/dist/engine/recordResponseCommand.js +30 -0
  146. package/dist/engine/recordResponseCommand.js.map +1 -0
  147. package/dist/engine/recoverStall.d.ts +1172 -1004
  148. package/dist/engine/recoverStall.d.ts.map +1 -1
  149. package/dist/engine/recoverStall.js +1 -1
  150. package/dist/engine/recoverStall.js.map +1 -1
  151. package/dist/engine/recoverUnobservable.d.ts +1172 -1004
  152. package/dist/engine/recoverUnobservable.d.ts.map +1 -1
  153. package/dist/engine/refreshBrief.d.ts +2344 -2009
  154. package/dist/engine/refreshBrief.d.ts.map +1 -1
  155. package/dist/engine/refreshReviewResult.d.ts +21 -0
  156. package/dist/engine/refreshReviewResult.d.ts.map +1 -1
  157. package/dist/engine/releaseClosedPreparation.d.ts +1171 -1003
  158. package/dist/engine/releaseClosedPreparation.d.ts.map +1 -1
  159. package/dist/engine/releaseExecution.d.ts +1170 -1003
  160. package/dist/engine/releaseExecution.d.ts.map +1 -1
  161. package/dist/engine/releaseFinishedWork.d.ts +10 -0
  162. package/dist/engine/releaseFinishedWork.d.ts.map +1 -1
  163. package/dist/engine/repository.d.ts +1115 -1003
  164. package/dist/engine/repository.d.ts.map +1 -1
  165. package/dist/engine/repository.js +12 -12
  166. package/dist/engine/repository.js.map +1 -1
  167. package/dist/engine/requestConflictRepair.d.ts +1170 -1003
  168. package/dist/engine/requestConflictRepair.d.ts.map +1 -1
  169. package/dist/engine/requestRework.d.ts +20 -0
  170. package/dist/engine/requestRework.d.ts.map +1 -1
  171. package/dist/engine/resolveCommand.d.ts +10 -0
  172. package/dist/engine/resolveCommand.d.ts.map +1 -1
  173. package/dist/engine/resolveExecution.d.ts +1170 -1003
  174. package/dist/engine/resolveExecution.d.ts.map +1 -1
  175. package/dist/engine/resumeAttempt.d.ts +1171 -1003
  176. package/dist/engine/resumeAttempt.d.ts.map +1 -1
  177. package/dist/engine/retireUnacknowledged.d.ts +20 -0
  178. package/dist/engine/retireUnacknowledged.d.ts.map +1 -1
  179. package/dist/engine/retryTerminal.d.ts +1160 -1003
  180. package/dist/engine/retryTerminal.d.ts.map +1 -1
  181. package/dist/engine/saveLaunch.d.ts +10598 -0
  182. package/dist/engine/saveLaunch.d.ts.map +1 -0
  183. package/dist/engine/saveLaunch.js +30 -0
  184. package/dist/engine/saveLaunch.js.map +1 -0
  185. package/dist/engine/scheduler.d.ts +21 -1
  186. package/dist/engine/scheduler.d.ts.map +1 -1
  187. package/dist/engine/scheduler.js +3 -5
  188. package/dist/engine/scheduler.js.map +1 -1
  189. package/dist/engine/sessionCleanup.d.ts +20 -0
  190. package/dist/engine/sessionCleanup.d.ts.map +1 -1
  191. package/dist/engine/settleMergedDelivery.d.ts +1170 -1003
  192. package/dist/engine/settleMergedDelivery.d.ts.map +1 -1
  193. package/dist/engine/steerBrief.d.ts +1075 -898
  194. package/dist/engine/steerBrief.d.ts.map +1 -1
  195. package/dist/engine/submissionFailure.d.ts +1150 -1003
  196. package/dist/engine/submissionFailure.d.ts.map +1 -1
  197. package/dist/engine/submitLaunch.d.ts +1160 -1003
  198. package/dist/engine/submitLaunch.d.ts.map +1 -1
  199. package/dist/engine/views.d.ts.map +1 -1
  200. package/dist/engine/views.js +4 -0
  201. package/dist/engine/views.js.map +1 -1
  202. package/dist/engine/workerReport.d.ts +30 -0
  203. package/dist/engine/workerReport.d.ts.map +1 -1
  204. package/dist/fleet.d.ts +2716 -983
  205. package/dist/fleet.d.ts.map +1 -1
  206. package/dist/fleet.js +4 -0
  207. package/dist/fleet.js.map +1 -1
  208. package/dist/host/actionCommands.d.ts.map +1 -1
  209. package/dist/host/actionCommands.js +7 -6
  210. package/dist/host/actionCommands.js.map +1 -1
  211. package/dist/host/admission.d.ts +24 -1
  212. package/dist/host/admission.d.ts.map +1 -1
  213. package/dist/host/admission.js +2 -2
  214. package/dist/host/admission.js.map +1 -1
  215. package/dist/host/answerWork.d.ts +12 -2
  216. package/dist/host/answerWork.d.ts.map +1 -1
  217. package/dist/host/answerWork.js +19 -23
  218. package/dist/host/answerWork.js.map +1 -1
  219. package/dist/host/cliOptions.d.ts +1 -1
  220. package/dist/host/cliOptions.d.ts.map +1 -1
  221. package/dist/host/cliOptions.js +1 -1
  222. package/dist/host/cliOptions.js.map +1 -1
  223. package/dist/host/commands.d.ts +28 -4
  224. package/dist/host/commands.d.ts.map +1 -1
  225. package/dist/host/commands.js +19 -5
  226. package/dist/host/commands.js.map +1 -1
  227. package/dist/host/config.d.ts +20 -5
  228. package/dist/host/config.d.ts.map +1 -1
  229. package/dist/host/config.js +17 -19
  230. package/dist/host/config.js.map +1 -1
  231. package/dist/host/configFile.d.ts +66 -0
  232. package/dist/host/configFile.d.ts.map +1 -0
  233. package/dist/host/configFile.js +37 -0
  234. package/dist/host/configFile.js.map +1 -0
  235. package/dist/host/configSettings.d.ts +488 -0
  236. package/dist/host/configSettings.d.ts.map +1 -0
  237. package/dist/host/configSettings.js +115 -0
  238. package/dist/host/configSettings.js.map +1 -0
  239. package/dist/host/daemon.d.ts +881 -1185
  240. package/dist/host/daemon.d.ts.map +1 -1
  241. package/dist/host/daemon.js +2 -1
  242. package/dist/host/daemon.js.map +1 -1
  243. package/dist/host/daemonClient.d.ts +301 -605
  244. package/dist/host/daemonClient.d.ts.map +1 -1
  245. package/dist/host/daemonClient.js +28 -7
  246. package/dist/host/daemonClient.js.map +1 -1
  247. package/dist/host/daemonContract.d.ts +1973 -3075
  248. package/dist/host/daemonContract.d.ts.map +1 -1
  249. package/dist/host/daemonContract.js +12 -4
  250. package/dist/host/daemonContract.js.map +1 -1
  251. package/dist/host/daemonDiagnostics.d.ts.map +1 -1
  252. package/dist/host/daemonDiagnostics.js +9 -3
  253. package/dist/host/daemonDiagnostics.js.map +1 -1
  254. package/dist/host/daemonHandlers.d.ts +2 -1
  255. package/dist/host/daemonHandlers.d.ts.map +1 -1
  256. package/dist/host/daemonHandlers.js +20 -7
  257. package/dist/host/daemonHandlers.js.map +1 -1
  258. package/dist/host/daemonSnapshots.d.ts.map +1 -1
  259. package/dist/host/daemonSnapshots.js +21 -1
  260. package/dist/host/daemonSnapshots.js.map +1 -1
  261. package/dist/host/dispatchRequests.d.ts +30 -0
  262. package/dist/host/dispatchRequests.d.ts.map +1 -0
  263. package/dist/host/dispatchRequests.js +40 -0
  264. package/dist/host/dispatchRequests.js.map +1 -0
  265. package/dist/host/follow.js +1 -1
  266. package/dist/host/follow.js.map +1 -1
  267. package/dist/host/followState.d.ts.map +1 -1
  268. package/dist/host/followState.js +5 -4
  269. package/dist/host/followState.js.map +1 -1
  270. package/dist/host/github.d.ts +5 -6
  271. package/dist/host/github.d.ts.map +1 -1
  272. package/dist/host/github.js +3 -4
  273. package/dist/host/github.js.map +1 -1
  274. package/dist/host/githubApi.d.ts +15 -0
  275. package/dist/host/githubApi.d.ts.map +1 -0
  276. package/dist/host/githubApi.js +117 -0
  277. package/dist/host/githubApi.js.map +1 -0
  278. package/dist/host/githubChecks.d.ts +13 -3
  279. package/dist/host/githubChecks.d.ts.map +1 -1
  280. package/dist/host/githubChecks.js +5 -5
  281. package/dist/host/githubChecks.js.map +1 -1
  282. package/dist/host/githubDelivery.d.ts +13 -1
  283. package/dist/host/githubDelivery.d.ts.map +1 -1
  284. package/dist/host/githubDelivery.js +39 -6
  285. package/dist/host/githubDelivery.js.map +1 -1
  286. package/dist/host/githubRateLimit.d.ts +23 -0
  287. package/dist/host/githubRateLimit.d.ts.map +1 -0
  288. package/dist/host/githubRateLimit.js +70 -0
  289. package/dist/host/githubRateLimit.js.map +1 -0
  290. package/dist/host/githubRequiredChecks.d.ts +1 -2
  291. package/dist/host/githubRequiredChecks.d.ts.map +1 -1
  292. package/dist/host/githubRequiredChecks.js +2 -2
  293. package/dist/host/githubRequiredChecks.js.map +1 -1
  294. package/dist/host/githubResponse.d.ts +10 -0
  295. package/dist/host/githubResponse.d.ts.map +1 -0
  296. package/dist/host/githubResponse.js +29 -0
  297. package/dist/host/githubResponse.js.map +1 -0
  298. package/dist/host/githubResult.d.ts +3 -2
  299. package/dist/host/githubResult.d.ts.map +1 -1
  300. package/dist/host/githubResult.js +9 -12
  301. package/dist/host/githubResult.js.map +1 -1
  302. package/dist/host/githubTransport.d.ts +13 -0
  303. package/dist/host/githubTransport.d.ts.map +1 -0
  304. package/dist/host/{githubRead.js → githubTransport.js} +9 -10
  305. package/dist/host/githubTransport.js.map +1 -0
  306. package/dist/host/integrations.d.ts +6 -0
  307. package/dist/host/integrations.d.ts.map +1 -0
  308. package/dist/host/integrations.js +34 -0
  309. package/dist/host/integrations.js.map +1 -0
  310. package/dist/host/liveConfig.d.ts +21 -0
  311. package/dist/host/liveConfig.d.ts.map +1 -0
  312. package/dist/host/liveConfig.js +75 -0
  313. package/dist/host/liveConfig.js.map +1 -0
  314. package/dist/host/providers.d.ts.map +1 -1
  315. package/dist/host/providers.js +2 -2
  316. package/dist/host/providers.js.map +1 -1
  317. package/dist/host/readWaitStates.d.ts.map +1 -1
  318. package/dist/host/readWaitStates.js +8 -18
  319. package/dist/host/readWaitStates.js.map +1 -1
  320. package/dist/host/reassignWork.d.ts +10 -0
  321. package/dist/host/reassignWork.d.ts.map +1 -1
  322. package/dist/host/recordDecisionResponse.d.ts +1 -0
  323. package/dist/host/recordDecisionResponse.d.ts.map +1 -1
  324. package/dist/host/releaseWork.d.ts +24 -3
  325. package/dist/host/releaseWork.d.ts.map +1 -1
  326. package/dist/host/releaseWork.js +11 -7
  327. package/dist/host/releaseWork.js.map +1 -1
  328. package/dist/host/renderStatus.d.ts +2 -2
  329. package/dist/host/renderStatus.d.ts.map +1 -1
  330. package/dist/host/renderStatus.js +8 -2
  331. package/dist/host/renderStatus.js.map +1 -1
  332. package/dist/host/reportBoard.d.ts +1 -1
  333. package/dist/host/reportBoard.d.ts.map +1 -1
  334. package/dist/host/reportBoard.js +6 -3
  335. package/dist/host/reportBoard.js.map +1 -1
  336. package/dist/host/reportPublication.d.ts +2 -1
  337. package/dist/host/reportPublication.d.ts.map +1 -1
  338. package/dist/host/reportPublication.js +5 -2
  339. package/dist/host/reportPublication.js.map +1 -1
  340. package/dist/host/runtime.d.ts +8 -6
  341. package/dist/host/runtime.d.ts.map +1 -1
  342. package/dist/host/runtime.js +38 -46
  343. package/dist/host/runtime.js.map +1 -1
  344. package/dist/host/snapshotStream.d.ts.map +1 -1
  345. package/dist/host/snapshotStream.js +4 -1
  346. package/dist/host/snapshotStream.js.map +1 -1
  347. package/dist/host/status.d.ts +22 -2
  348. package/dist/host/status.d.ts.map +1 -1
  349. package/dist/host/status.js +19 -5
  350. package/dist/host/status.js.map +1 -1
  351. package/dist/host/statusLayer.d.ts +3 -3
  352. package/dist/host/statusLayer.d.ts.map +1 -1
  353. package/dist/host/statusLayer.js +13 -3
  354. package/dist/host/statusLayer.js.map +1 -1
  355. package/dist/host/waitOutcome.d.ts.map +1 -1
  356. package/dist/host/waitOutcome.js +5 -2
  357. package/dist/host/waitOutcome.js.map +1 -1
  358. package/dist/model.d.ts +39 -0
  359. package/dist/model.d.ts.map +1 -1
  360. package/dist/model.js +5 -0
  361. package/dist/model.js.map +1 -1
  362. package/dist/operations.d.ts +270 -0
  363. package/dist/operations.d.ts.map +1 -1
  364. package/dist/packageInfo.d.ts +1 -1
  365. package/dist/packageInfo.js +1 -1
  366. package/dist/policy.d.ts +8 -0
  367. package/dist/policy.d.ts.map +1 -1
  368. package/dist/policy.js +2 -0
  369. package/dist/policy.js.map +1 -1
  370. package/dist/providers/codexCloud.d.ts +2 -0
  371. package/dist/providers/codexCloud.d.ts.map +1 -1
  372. package/dist/providers/codexCloud.js +2 -1
  373. package/dist/providers/codexCloud.js.map +1 -1
  374. package/dist/qualifyDependencies.d.ts +10 -0
  375. package/dist/qualifyDependencies.d.ts.map +1 -1
  376. package/dist/scheduling/admission.d.ts +1635 -0
  377. package/dist/scheduling/admission.d.ts.map +1 -0
  378. package/dist/scheduling/admission.js +11 -0
  379. package/dist/scheduling/admission.js.map +1 -0
  380. package/dist/scheduling/areas.d.ts +30 -0
  381. package/dist/scheduling/areas.d.ts.map +1 -1
  382. package/dist/scheduling/areas.js +1 -0
  383. package/dist/scheduling/areas.js.map +1 -1
  384. package/dist/scheduling/backPressure.d.ts +1637 -0
  385. package/dist/scheduling/backPressure.d.ts.map +1 -0
  386. package/dist/scheduling/backPressure.js +44 -0
  387. package/dist/scheduling/backPressure.js.map +1 -0
  388. package/dist/storage/FleetStoreOptions.d.ts +2 -2
  389. package/dist/storage/FleetStoreOptions.d.ts.map +1 -1
  390. package/dist/storage/addShapeColumns.d.ts +5 -0
  391. package/dist/storage/addShapeColumns.d.ts.map +1 -0
  392. package/dist/storage/addShapeColumns.js +24 -0
  393. package/dist/storage/addShapeColumns.js.map +1 -0
  394. package/dist/storage/dispatchStore.d.ts +47 -0
  395. package/dist/storage/dispatchStore.d.ts.map +1 -0
  396. package/dist/storage/dispatchStore.js +89 -0
  397. package/dist/storage/dispatchStore.js.map +1 -0
  398. package/dist/storage/errors.d.ts +2 -1
  399. package/dist/storage/errors.d.ts.map +1 -1
  400. package/dist/storage/errors.js +2 -1
  401. package/dist/storage/errors.js.map +1 -1
  402. package/dist/storage/fleetMigrations.d.ts +1 -1
  403. package/dist/storage/fleetMigrations.d.ts.map +1 -1
  404. package/dist/storage/fleetMigrations.js +24 -17
  405. package/dist/storage/fleetMigrations.js.map +1 -1
  406. package/dist/storage/listedRecords.d.ts +9 -0
  407. package/dist/storage/listedRecords.d.ts.map +1 -0
  408. package/dist/storage/listedRecords.js +40 -0
  409. package/dist/storage/listedRecords.js.map +1 -0
  410. package/dist/storage/makePostgresFleetStore.d.ts +2 -6
  411. package/dist/storage/makePostgresFleetStore.d.ts.map +1 -1
  412. package/dist/storage/makePostgresFleetStore.js +4 -10
  413. package/dist/storage/makePostgresFleetStore.js.map +1 -1
  414. package/dist/storage/model.d.ts +9 -0
  415. package/dist/storage/model.d.ts.map +1 -1
  416. package/dist/storage/model.js.map +1 -1
  417. package/dist/storage/shapeV14.d.ts +808 -0
  418. package/dist/storage/shapeV14.d.ts.map +1 -0
  419. package/dist/storage/shapeV14.js +18 -0
  420. package/dist/storage/shapeV14.js.map +1 -0
  421. package/package.json +6 -6
  422. package/src/DispatchRequest.ts +13 -0
  423. package/src/attention.ts +5 -0
  424. package/src/board/fleetField.ts +5 -0
  425. package/src/board/markdown.ts +7 -2
  426. package/src/cli.ts +24 -10
  427. package/src/engine/admissionOrder.ts +25 -0
  428. package/src/engine/dispatchCommand.ts +29 -5
  429. package/src/engine/failureContext.ts +1 -0
  430. package/src/engine/failureMessage.ts +12 -1
  431. package/src/engine/localOnlyCriteria.ts +6 -1
  432. package/src/engine/makeLaunch.ts +4 -17
  433. package/src/engine/makeState.ts +30 -26
  434. package/src/engine/mergeReadiness.ts +6 -5
  435. package/src/engine/obtainReview.ts +2 -1
  436. package/src/engine/prepareCommand.ts +1 -1
  437. package/src/engine/readOrContinueReview.ts +2 -1
  438. package/src/engine/readRetry.ts +26 -2
  439. package/src/engine/reconcileAttempt.ts +2 -1
  440. package/src/engine/recordResponseCommand.ts +38 -0
  441. package/src/engine/recoverStall.ts +1 -1
  442. package/src/engine/repository.ts +17 -16
  443. package/src/engine/saveLaunch.ts +45 -0
  444. package/src/engine/scheduler.ts +4 -6
  445. package/src/engine/views.ts +5 -0
  446. package/src/fleet.ts +4 -0
  447. package/src/host/actionCommands.ts +22 -7
  448. package/src/host/admission.ts +3 -3
  449. package/src/host/answerWork.ts +28 -27
  450. package/src/host/cliOptions.ts +1 -1
  451. package/src/host/commands.ts +29 -8
  452. package/src/host/config.ts +26 -22
  453. package/src/host/configFile.ts +40 -0
  454. package/src/host/configSettings.ts +126 -0
  455. package/src/host/daemon.ts +2 -1
  456. package/src/host/daemonClient.ts +42 -7
  457. package/src/host/daemonContract.ts +12 -4
  458. package/src/host/daemonDiagnostics.ts +11 -3
  459. package/src/host/daemonHandlers.ts +24 -7
  460. package/src/host/daemonSnapshots.ts +24 -1
  461. package/src/host/dispatchRequests.ts +53 -0
  462. package/src/host/follow.ts +1 -1
  463. package/src/host/followState.ts +6 -6
  464. package/src/host/github.ts +8 -6
  465. package/src/host/githubApi.ts +142 -0
  466. package/src/host/githubChecks.ts +6 -5
  467. package/src/host/githubDelivery.ts +47 -10
  468. package/src/host/githubRateLimit.ts +91 -0
  469. package/src/host/githubRequiredChecks.ts +2 -2
  470. package/src/host/githubResponse.ts +37 -0
  471. package/src/host/githubResult.ts +15 -17
  472. package/src/host/githubTransport.ts +31 -0
  473. package/src/host/integrations.ts +40 -0
  474. package/src/host/liveConfig.ts +135 -0
  475. package/src/host/providers.ts +4 -2
  476. package/src/host/readWaitStates.ts +8 -20
  477. package/src/host/releaseWork.ts +12 -9
  478. package/src/host/renderStatus.ts +10 -3
  479. package/src/host/reportBoard.ts +6 -3
  480. package/src/host/reportPublication.ts +6 -4
  481. package/src/host/runtime.ts +49 -56
  482. package/src/host/snapshotStream.ts +6 -1
  483. package/src/host/status.ts +24 -7
  484. package/src/host/statusLayer.ts +21 -5
  485. package/src/host/waitOutcome.ts +5 -2
  486. package/src/model.ts +6 -0
  487. package/src/packageInfo.ts +1 -1
  488. package/src/policy.ts +8 -0
  489. package/src/providers/codexCloud.ts +2 -1
  490. package/src/scheduling/admission.ts +19 -0
  491. package/src/scheduling/areas.ts +1 -0
  492. package/src/scheduling/backPressure.ts +55 -0
  493. package/src/storage/FleetStoreOptions.ts +7 -2
  494. package/src/storage/addShapeColumns.ts +24 -0
  495. package/src/storage/dispatchStore.ts +104 -0
  496. package/src/storage/errors.ts +2 -1
  497. package/src/storage/fleetMigrations.ts +24 -17
  498. package/src/storage/listedRecords.ts +53 -0
  499. package/src/storage/makePostgresFleetStore.ts +4 -10
  500. package/src/storage/model.ts +7 -0
  501. package/src/storage/shapeV14.ts +19 -0
  502. package/dist/host/githubRead.d.ts +0 -5
  503. package/dist/host/githubRead.d.ts.map +0 -1
  504. package/dist/host/githubRead.js.map +0 -1
  505. package/dist/host/recordPayloads.d.ts +0 -4
  506. package/dist/host/recordPayloads.d.ts.map +0 -1
  507. package/dist/host/recordPayloads.js +0 -21
  508. package/dist/host/recordPayloads.js.map +0 -1
  509. package/dist/storage/migrateFleet.d.ts +0 -3
  510. package/dist/storage/migrateFleet.d.ts.map +0 -1
  511. package/dist/storage/migrateFleet.js +0 -11
  512. package/dist/storage/migrateFleet.js.map +0 -1
  513. package/src/host/githubRead.ts +0 -20
  514. package/src/host/recordPayloads.ts +0 -24
  515. package/src/storage/migrateFleet.ts +0 -11
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shapeV14.d.ts","sourceRoot":"","sources":["../../src/storage/shapeV14.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAJR,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wCAJ2C,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2CACsB,QAAQ;;;;;;qBAKpF,MAAM;yBAAI,WAAW,EAAE,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCAFnC,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCAEF,MAAM;qCAAI,WAAW,EAAE,SAAS;;;yCAKM,QAAQ;;;;;CAEpC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { attemptV12 } from "#storage/attemptV12.ts";
2
+ import { cycleV12 } from "#storage/cycleV12.ts";
3
+ import { decisionV12 } from "#storage/typedDecisionsV12.ts";
4
+ const attempt = { fields: { ...attemptV12.fields, overLimit: "boolean" } };
5
+ const publicationWork = { fields: { ...decisionV12.fields.publicationWork.fields, priority: "string" } };
6
+ const cycle = {
7
+ ...cycleV12.fields,
8
+ attempts: { array: attempt },
9
+ decision: { fields: { ...decisionV12.fields, publicationWork } },
10
+ dispatchNow: { fields: { ignoreAreas: "boolean" } },
11
+ };
12
+ export const shapeV14 = {
13
+ fields: {
14
+ ...cycle,
15
+ history: { array: { fields: { ...cycle, archivedAt: "number" } } },
16
+ },
17
+ };
18
+ //# sourceMappingURL=shapeV14.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shapeV14.js","sourceRoot":"","sources":["../../src/storage/shapeV14.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE5D,MAAM,OAAO,GAAG,EAAE,MAAM,EAAE,EAAE,GAAG,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,EAAW,CAAC;AACpF,MAAM,eAAe,GAAG,EAAE,MAAM,EAAE,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAW,CAAC;AAClH,MAAM,KAAK,GAAG;IACb,GAAG,QAAQ,CAAC,MAAM;IAClB,QAAQ,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;IAC5B,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,GAAG,WAAW,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE;IAChE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE;CAC1C,CAAC;AACX,MAAM,CAAC,MAAM,QAAQ,GAAG;IACvB,MAAM,EAAE;QACP,GAAG,KAAK;QACR,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE;KAClE;CACwB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shivaedev/work-fleet",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
4
  "description": "Optional Board-backed execution, review and authorized delivery",
5
5
  "homepage": "https://github.com/ShivaeDev/platform/tree/main/packages/work-fleet#readme",
6
6
  "bugs": {
@@ -48,8 +48,8 @@
48
48
  "@shivaedev/effect-contract": "0.5.1",
49
49
  "@shivaedev/effect-service": "0.3.0",
50
50
  "@shivaedev/effect-sql": "0.5.0",
51
- "@shivaedev/platform": "0.14.1",
52
- "@shivaedev/work-board": "0.14.2",
51
+ "@shivaedev/platform": "0.14.3",
52
+ "@shivaedev/work-board": "0.16.0",
53
53
  "yaml": "2.9.1"
54
54
  },
55
55
  "devDependencies": {
@@ -57,9 +57,9 @@
57
57
  "@effect/platform-node-shared": "4.0.4",
58
58
  "@effect/vitest": "4.0.4",
59
59
  "@shivaedev/effect-test": "0.5.0",
60
- "@shivaedev/effect-test-sql": "0.4.0",
61
- "@shivaedev/quality": "0.22.0",
62
- "@types/node": "24.19.1",
60
+ "@shivaedev/effect-test-sql": "0.5.3",
61
+ "@shivaedev/quality": "0.23.0",
62
+ "@types/node": "24.19.2",
63
63
  "@typescript/native": "npm:typescript@7.0.2",
64
64
  "effect": "4.0.4",
65
65
  "typescript": "npm:@typescript/typescript6@6.0.2",
@@ -0,0 +1,13 @@
1
+ import { Schema } from "effect";
2
+
3
+ export const DispatchRequest = Schema.Struct({
4
+ acceptedAt: Schema.Number,
5
+ completedAt: Schema.optional(Schema.Number),
6
+ error: Schema.optional(Schema.String),
7
+ id: Schema.String,
8
+ ignoreAreas: Schema.optional(Schema.Boolean),
9
+ now: Schema.optional(Schema.Boolean),
10
+ status: Schema.Literals(["pending", "completed", "failed"]),
11
+ workId: Schema.String,
12
+ });
13
+ export type DispatchRequest = typeof DispatchRequest.Type;
package/src/attention.ts CHANGED
@@ -3,6 +3,8 @@ import { Schema } from "effect";
3
3
  export const AttentionOwner = Schema.Literals(["maintainer", "orchestrator", "automation"]);
4
4
  export type AttentionOwner = typeof AttentionOwner.Type;
5
5
 
6
+ export const ANSWER_RECORDED = "Answer recorded; applying in the background";
7
+
6
8
  export function waitingOwner(record: {
7
9
  readonly attentionOwner?: AttentionOwner | undefined;
8
10
  readonly blocker?: string | undefined;
@@ -11,6 +13,9 @@ export function waitingOwner(record: {
11
13
  readonly launchRetry?: { readonly retryAt: number } | undefined;
12
14
  readonly stage: string;
13
15
  }): AttentionOwner | undefined {
16
+ if (record.blocker === ANSWER_RECORDED) {
17
+ return "automation";
18
+ }
14
19
  if (record.launchRetry !== undefined || (record.stage === "prepared" && record.blocker?.startsWith("waiting for dependency "))) {
15
20
  return "automation";
16
21
  }
@@ -4,6 +4,7 @@ import type { ParsedMetadata } from "@shivaedev/work-board/integration/board.ts"
4
4
  const APPROVAL = "fleet";
5
5
  const LAUNCH = "fleet-launch";
6
6
  const DELIVERABLE = "fleet-deliverable";
7
+ const PRIORITY = "fleet-priority";
7
8
  const parsedFields = new WeakMap<ParsedMetadata, ReadonlyMap<string, unknown>>();
8
9
 
9
10
  function fleetField(parsed: ParsedMetadata, field: string): unknown {
@@ -33,3 +34,7 @@ export function fleetLaunch(parsed: ParsedMetadata): unknown {
33
34
  export function fleetDeliverable(parsed: ParsedMetadata): unknown {
34
35
  return fleetField(parsed, DELIVERABLE);
35
36
  }
37
+
38
+ export function fleetPriority(parsed: ParsedMetadata): unknown {
39
+ return fleetField(parsed, PRIORITY);
40
+ }
@@ -6,13 +6,13 @@ import { briefRevision } from "#board/briefRevision.ts";
6
6
  import { completionMarkdown } from "#board/completionMarkdown.ts";
7
7
  import { decisionReading } from "#board/decisionReading.ts";
8
8
  import { boundDocuments, boundSnapshot, refreshSnapshotDocument, snapshotDocument } from "#board/documents.ts";
9
- import { fleetApproved, fleetDeliverable } from "#board/fleetField.ts";
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
13
  import { workRevision } from "#board/workRevision.ts";
14
14
  import { writeCompletion } from "#board/writeCompletion.ts";
15
- import { BoardFailure, BoardGateway } from "#policy.ts";
15
+ import { BoardFailure, BoardGateway, Priority } from "#policy.ts";
16
16
  import { RepositoryPath } from "#preparation/schema.ts";
17
17
 
18
18
  class BoardRoot extends Context.Service<BoardRoot, string>()("Fleet/BoardRoot") {}
@@ -38,6 +38,10 @@ const MarkdownBoard = defineService({
38
38
  if (deliverable !== undefined && deliverable !== "report") {
39
39
  return yield* Effect.fail(new BoardFailure({ message: "Invalid fleet-deliverable; use report or omit the field for pull requests." }));
40
40
  }
41
+ const priority = fleetPriority(found.parsed);
42
+ if (priority !== undefined && !Schema.is(Priority)(priority)) {
43
+ return yield* Effect.fail(new BoardFailure({ message: "Invalid fleet-priority; use urgent, high or normal, or omit the field." }));
44
+ }
41
45
  return {
42
46
  approved: fleetApproved(found.parsed),
43
47
  areas: found.parsed.fields.areas,
@@ -45,6 +49,7 @@ const MarkdownBoard = defineService({
45
49
  ...(deliverable === "report" ? { deliverable: "report" as const } : {}),
46
50
  context: found.source,
47
51
  dependsOn: (found.parsed.fields.relationships ?? []).filter((relation) => relation.kind === "depends_on").map((relation) => relation.target),
52
+ ...(priority === undefined ? {} : { priority }),
48
53
  revision: briefRevision(found.parsed),
49
54
  sourcePath: path.join(realRoot, found.file),
50
55
  workId,
package/src/cli.ts CHANGED
@@ -26,13 +26,25 @@ const serveCommand = Command.make(
26
26
 
27
27
  const dispatchCommand = Command.make(
28
28
  "dispatch",
29
- { board, config, port, workId: Argument.String("id") },
29
+ {
30
+ board,
31
+ config,
32
+ ignoreAreas: Flag.Boolean("ignore-areas").pipe(Flag.withDefault(false), Flag.withDescription("With --now, also skip area claims")),
33
+ now: Flag.Boolean("now").pipe(
34
+ Flag.withDefault(false),
35
+ Flag.withDescription("Launch over concurrency, open-PR back pressure and backlog limits; areas and dependencies still apply"),
36
+ ),
37
+ port,
38
+ workId: Argument.String("id"),
39
+ },
30
40
  Effect.fn("WorkFleetCli.dispatch")(function* (input) {
31
- const { daemonClient, daemonError } = yield* Effect.promise(() => import("#host/daemonClient.ts"));
32
- const value = yield* Effect.scoped(
33
- daemonClient(input.port).pipe(Effect.flatMap((client) => client("daemon.dispatch", { workId: input.workId }))),
34
- ).pipe(Effect.mapError((error) => daemonError(error, input.port)));
35
- yield* Console.log(`${value.workId} ${value.stage}${value.blocker === undefined ? "" : `: ${value.blocker}`}`);
41
+ const { daemonRequest } = yield* Effect.promise(() => import("#host/daemonClient.ts"));
42
+ const value = yield* daemonRequest(
43
+ input.port,
44
+ (client) => client("daemon.dispatch", { ignoreAreas: input.ignoreAreas, now: input.now, workId: input.workId }),
45
+ `dispatch ${input.workId}`,
46
+ );
47
+ yield* Console.log(`${value.workId}: dispatch recorded${value.now ? " over the limits" : ""}; preparing and launching in the background`);
36
48
  }),
37
49
  ).pipe(Command.withDescription("Prepare the current approved revision of one Board item and launch it"));
38
50
 
@@ -46,13 +58,15 @@ const statusCommand = Command.make(
46
58
  workId: Argument.String("id").pipe(Argument.optional),
47
59
  },
48
60
  Effect.fn("WorkFleetCli.status")(function* (input) {
49
- const [{ daemonClient, daemonError }, { renderStatus }] = yield* Effect.promise(() =>
61
+ const [{ daemonRequest }, { renderStatus }] = yield* Effect.promise(() =>
50
62
  Promise.all([import("#host/daemonClient.ts"), import("#host/renderStatus.ts")]),
51
63
  );
52
64
  const workId = Option.getOrUndefined(input.workId);
53
- const current = yield* Effect.scoped(
54
- daemonClient(input.port).pipe(Effect.flatMap((client) => client("daemon.status", workId === undefined ? {} : { workId }))),
55
- ).pipe(Effect.mapError((error) => daemonError(error, input.port)));
65
+ const current = yield* daemonRequest(
66
+ input.port,
67
+ (client) => client("daemon.status", workId === undefined ? {} : { workId }),
68
+ workId === undefined ? "status" : `status ${workId}`,
69
+ );
56
70
  yield* Console.log(input.json ? JSON.stringify(current) : renderStatus(current, input.port));
57
71
  }),
58
72
  ).pipe(Command.withDescription("Show active and completed Fleet work, and waiting work grouped by owner"));
@@ -0,0 +1,25 @@
1
+ import { Effect } from "effect";
2
+ import type { EngineState } from "#engine/makeState.ts";
3
+ import { retryPending } from "#engine/readRetry.ts";
4
+ import type { FleetRecord } from "#model.ts";
5
+ import type { Priority } from "#policy.ts";
6
+ import type { Versioned } from "#storage/model.ts";
7
+
8
+ const ranks: Readonly<Record<Priority, number>> = { high: 1, normal: 2, urgent: 0 };
9
+
10
+ export function admissionOrder(state: EngineState) {
11
+ return Effect.fn("Fleet.admissionOrder")(function* (records: readonly Versioned<FleetRecord>[]) {
12
+ const prepared = records.filter(({ value }) => value.stage === "prepared");
13
+ const ranked = yield* Effect.forEach(prepared, (entry) =>
14
+ retryPending(state, entry.value)
15
+ ? Effect.succeed({ entry, rank: ranks.normal })
16
+ : state.board.get(entry.value.workId).pipe(
17
+ Effect.map((work) => ({ entry, rank: ranks[work.priority ?? "normal"] })),
18
+ Effect.orElseSucceed(() => ({ entry, rank: ranks.normal })),
19
+ ),
20
+ );
21
+ return ranked
22
+ .sort((left, right) => (right.entry.value.launchRetry?.retryAt ?? 0) - (left.entry.value.launchRetry?.retryAt ?? 0) || left.rank - right.rank)
23
+ .map(({ entry }) => entry);
24
+ });
25
+ }
@@ -1,5 +1,6 @@
1
1
  import { Effect, Result } from "effect";
2
2
  import { Forbidden } from "@shivaedev/platform/errors/taxonomy.ts";
3
+ import { waitingOwner } from "#attention.ts";
3
4
  import { approveDispatchedBrief } from "#engine/approveBrief.ts";
4
5
  import { authorizeBriefContext } from "#engine/boardBrief.ts";
5
6
  import { failureCode } from "#engine/failureCode.ts";
@@ -10,10 +11,16 @@ import type { EngineState } from "#engine/makeState.ts";
10
11
  import { clearIntegrationRetry, readRetry, retryPending } from "#engine/readRetry.ts";
11
12
  import { refreshBrief } from "#engine/refreshBrief.ts";
12
13
  import { releaseClosedPreparation } from "#engine/releaseClosedPreparation.ts";
14
+ import type { DispatchNow, FleetRecord } from "#model.ts";
13
15
  import { assessPreparation } from "#preparation/compatibility.ts";
16
+ import type { Versioned } from "#storage/model.ts";
14
17
  export function dispatchCommand(state: EngineState, launch: ReturnType<typeof makeLaunch>) {
15
18
  const { board, load, save, decision, integrations, policy } = state;
16
- const dispatchPrepared = Effect.fn("Fleet.dispatchPrepared")(function* (workId: string, prompt?: string) {
19
+ function rememberNow(stored: Versioned<FleetRecord>, now: DispatchNow | undefined) {
20
+ const requested = requestedNow(stored.value, now);
21
+ return requested === undefined ? Effect.succeed(stored) : save(stored, requested);
22
+ }
23
+ const dispatchPrepared = Effect.fn("Fleet.dispatchPrepared")(function* (workId: string, prompt?: string, now?: DispatchNow) {
17
24
  let stored = yield* load(workId);
18
25
  const work = yield* board.get(workId);
19
26
  stored = yield* refreshBrief(state, stored, work);
@@ -25,6 +32,7 @@ export function dispatchCommand(state: EngineState, launch: ReturnType<typeof ma
25
32
  if (released !== undefined) {
26
33
  return released;
27
34
  }
35
+ stored = yield* rememberNow(stored, now);
28
36
  const authorized = yield* authorizeBriefContext(stored.value, work).pipe(Effect.result);
29
37
  if (Result.isFailure(authorized)) {
30
38
  return yield* decision(
@@ -56,18 +64,21 @@ export function dispatchCommand(state: EngineState, launch: ReturnType<typeof ma
56
64
  if (current.value.stage !== "prepared") {
57
65
  return current;
58
66
  }
59
- yield* save(current, {
67
+ const waiting = {
60
68
  ...current.value,
61
69
  admissionReady: !(error instanceof Forbidden),
62
70
  attentionOwner: failureOwner(error),
63
71
  blocker: failureMessage(error),
64
- });
72
+ };
73
+ if (!sameWait(current.value, waiting)) {
74
+ yield* save(current, waiting);
75
+ }
65
76
  return yield* Effect.fail(error);
66
77
  }),
67
78
  ),
68
79
  );
69
80
  });
70
- return Effect.fn("Fleet.dispatch")(function* (workId: string, prompt?: string) {
81
+ return Effect.fn("Fleet.dispatch")(function* (workId: string, prompt?: string, now?: DispatchNow) {
71
82
  const current = yield* load(workId);
72
83
  if (retryPending(state, current.value)) {
73
84
  return current;
@@ -75,7 +86,7 @@ export function dispatchCommand(state: EngineState, launch: ReturnType<typeof ma
75
86
  if (current.value.integrationRetry !== undefined) {
76
87
  yield* save(current, { ...current.value, attentionOwner: undefined, blocker: undefined });
77
88
  }
78
- return yield* dispatchPrepared(workId, prompt).pipe(
89
+ return yield* dispatchPrepared(workId, prompt, now).pipe(
79
90
  Effect.flatMap((updated) => clearIntegrationRetry(state, updated)),
80
91
  Effect.catch((error) =>
81
92
  Effect.gen(function* () {
@@ -86,3 +97,16 @@ export function dispatchCommand(state: EngineState, launch: ReturnType<typeof ma
86
97
  );
87
98
  });
88
99
  }
100
+
101
+ function requestedNow(record: FleetRecord, now: DispatchNow | undefined): FleetRecord | undefined {
102
+ const current = record.dispatchNow;
103
+ if (now === undefined || (current !== undefined && (current.ignoreAreas || !now.ignoreAreas))) {
104
+ return undefined;
105
+ }
106
+ return { ...record, dispatchNow: now };
107
+ }
108
+
109
+ // Every scheduler pass retries waiting work, so rewriting an unchanged wait would make each pass write and notify once per waiter.
110
+ function sameWait(current: FleetRecord, waiting: FleetRecord) {
111
+ return current.blocker === waiting.blocker && current.admissionReady === waiting.admissionReady && current.attentionOwner === waitingOwner(waiting);
112
+ }
@@ -7,6 +7,7 @@ interface FailureContext {
7
7
  readonly code?: DecisionCode | undefined;
8
8
  readonly head?: string;
9
9
  readonly mainRevision?: string;
10
+ readonly retryAt?: number;
10
11
  readonly retryable?: boolean;
11
12
  }
12
13
 
@@ -10,10 +10,21 @@ export function failureMessage(error: unknown): string {
10
10
  return "Fresh available provider quota is required";
11
11
  }
12
12
  if (error instanceof StorageCapacity) {
13
- return `${error.kind} capacity is occupied (limit ${error.limit})`;
13
+ return capacityMessage(error);
14
14
  }
15
15
  if (error instanceof StorageConflict) {
16
16
  return "Work changed during this observation; load the current record";
17
17
  }
18
18
  return "The integration is unavailable; inspect runtime diagnostics";
19
19
  }
20
+
21
+ function capacityMessage(error: StorageCapacity) {
22
+ switch (error.kind) {
23
+ case "open-pull-requests":
24
+ return `waiting for open PRs to merge: ${error.occupied ?? error.limit} of ${error.limit}`;
25
+ case "merge-work":
26
+ return `waiting for ${error.occupied ?? 0} review or repair launches to go first (limit ${error.limit})`;
27
+ default:
28
+ return `${error.kind} capacity is occupied (limit ${error.limit})`;
29
+ }
30
+ }
@@ -2,11 +2,16 @@ import { Effect } from "effect";
2
2
  import { workMetadata } from "#board/readPass.ts";
3
3
  import type { BoardWork } from "#policy.ts";
4
4
 
5
+ function mentions(text: string, localPath: string) {
6
+ const escaped = localPath.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
7
+ return new RegExp(`(?<![\\w.-])${escaped}(?![\\w-])`, "u").test(text);
8
+ }
9
+
5
10
  export const localOnlyCriteria = Effect.fn("Fleet.localOnlyCriteria")(function* (work: BoardWork, localPath: string | undefined) {
6
11
  if (localPath === undefined) {
7
12
  return undefined;
8
13
  }
9
- const criteria = (yield* workMetadata(work)).fields.criteria?.filter(({ text }) => text.includes(localPath)) ?? [];
14
+ const criteria = (yield* workMetadata(work)).fields.criteria?.filter(({ text }) => mentions(text, localPath)) ?? [];
10
15
  if (criteria.length > 0) {
11
16
  return `Criteria ${criteria.map(({ id }) => `"${id}"`).join(", ")} reference ${localPath}: Cloud workers cannot read local-only Board data`;
12
17
  }
@@ -7,6 +7,7 @@ import { launchRecord } from "#engine/launchRecord.ts";
7
7
  import { localOnlyCriteria } from "#engine/localOnlyCriteria.ts";
8
8
  import type { EngineState } from "#engine/makeState.ts";
9
9
  import { releaseClosedPreparation } from "#engine/releaseClosedPreparation.ts";
10
+ import { saveLaunch } from "#engine/saveLaunch.ts";
10
11
  import { submitLaunch } from "#engine/submitLaunch.ts";
11
12
  import type { Attempt, FleetRecord } from "#model.ts";
12
13
  import type { DecisionResponse } from "#policy.ts";
@@ -14,7 +15,7 @@ import { policyGuidance } from "#policyGuidance.ts";
14
15
  import { reportPrompt, withWorkerGuidance } from "#prompt/worker.ts";
15
16
  import type { Versioned } from "#storage/model.ts";
16
17
  export function makeLaunch(state: EngineState) {
17
- const { store, board, policy, sessions, load, save } = state;
18
+ const { store, board, sessions, load } = state;
18
19
  return Effect.fn("Fleet.launch")(function* (
19
20
  input: Versioned<FleetRecord>,
20
21
  role: "worker" | "repair",
@@ -27,6 +28,7 @@ export function makeLaunch(state: EngineState) {
27
28
  },
28
29
  ) {
29
30
  const stored = input;
31
+ const policy = yield* state.current;
30
32
  const work = yield* board.get(stored.value.workId, { fresh: true });
31
33
  const released = yield* releaseClosedPreparation(state, stored, work);
32
34
  if (released !== undefined) {
@@ -75,22 +77,7 @@ export function makeLaunch(state: EngineState) {
75
77
  submittedAt: policy.now(),
76
78
  };
77
79
  const record = launchRecord(stored.value, launchRole, policy.now(), continuation?.responses);
78
- yield* save(
79
- stored,
80
- {
81
- ...record,
82
- admissionReady: true,
83
- attempts: [...record.attempts, attempt],
84
- blocker: undefined,
85
- launchRetry: undefined,
86
- mergeAreasReleased: undefined,
87
- mergeReadyAt: undefined,
88
- mergeReadyHead: undefined,
89
- pendingAnswers: undefined,
90
- stage: "executing",
91
- },
92
- { quota, role: launchRole },
93
- );
80
+ yield* saveLaunch(state, stored, record, attempt, { priority: work.priority, quota, role: launchRole });
94
81
  const submitted =
95
82
  sessionId === undefined
96
83
  ? sessions.start({ cwd: stored.value.cwd, operationId: attempt.operationId, prompt: workerPrompt, settings })
@@ -6,11 +6,18 @@ import { originalWork } from "#engine/originalWork.ts";
6
6
  import { ReportInspection } from "#engine/ReportInspection.ts";
7
7
  import { FleetRepository } from "#engine/repository.ts";
8
8
  import type { Attempt, FleetRecord } from "#model.ts";
9
- import { BoardGateway, type BoardWork, type Decision, FleetIntegrations, FleetPolicy } from "#policy.ts";
9
+ import { BoardGateway, type BoardWork, type Decision, type FleetConfiguration, FleetIntegrations, FleetPolicy } from "#policy.ts";
10
10
  import { DEFAULT_AREA_MERGE_WAIT_MS } from "#scheduling/areas.ts";
11
11
  import type { SessionReceipt } from "#session/schema.ts";
12
12
  import { SessionService } from "#session/service.ts";
13
- import type { Versioned } from "#storage/model.ts";
13
+ import type { AdmissionLimits, Versioned } from "#storage/model.ts";
14
+ export interface LaunchAdmission {
15
+ readonly ignoreAreas?: boolean;
16
+ readonly implementer?: boolean;
17
+ readonly overLimit?: boolean;
18
+ readonly quota: FleetConfiguration["quota"];
19
+ readonly role: Attempt["role"];
20
+ }
14
21
  export const makeState = Effect.gen(function* () {
15
22
  const store = yield* FleetRepository;
16
23
  const board = yield* BoardGateway;
@@ -29,29 +36,13 @@ export const makeState = Effect.gen(function* () {
29
36
  ),
30
37
  );
31
38
  }
32
- function save(
33
- stored: Versioned<FleetRecord>,
34
- value: FleetRecord,
35
- admission?: {
36
- readonly role: Attempt["role"];
37
- readonly quota: typeof policy.quota;
38
- },
39
- ) {
40
- return store.compareAndSet(
41
- value.workId,
42
- stored.version,
43
- { ...value, attentionOwner: waitingOwner(value) },
44
- admission === undefined
45
- ? undefined
46
- : {
47
- scheduling: { areaMergeWaitMs: policy.areaMergeWaitMs ?? DEFAULT_AREA_MERGE_WAIT_MS, now: policy.now() },
48
- ...(admission.quota.available === undefined
49
- ? {}
50
- : { quota: { available: admission.quota.available, observedAt: admission.quota.observedAt } }),
51
- ...(policy.executionConcurrency === undefined ? {} : { maxExecuting: policy.executionConcurrency }),
52
- ...(admission.role !== "worker" || policy.deliveryBacklog === undefined ? {} : { maxBacklog: policy.deliveryBacklog }),
53
- },
54
- );
39
+ const current = policy.current ?? Effect.succeed(policy);
40
+ function save(stored: Versioned<FleetRecord>, value: FleetRecord, admission?: LaunchAdmission) {
41
+ const record = { ...value, attentionOwner: waitingOwner(value) };
42
+ if (admission === undefined) {
43
+ return store.compareAndSet(value.workId, stored.version, record);
44
+ }
45
+ return Effect.flatMap(current, (applied) => store.compareAndSet(value.workId, stored.version, record, launchLimits(applied, admission)));
55
46
  }
56
47
  const decision = Effect.fn("Fleet.decision")(function* (
57
48
  stored: Versioned<FleetRecord>,
@@ -84,6 +75,19 @@ export const makeState = Effect.gen(function* () {
84
75
  const published = yield* board.decision(stored.value.workId, value, publicationWork ?? originalWork(stored.value));
85
76
  return yield* save(updated, { ...updated.value, decision: { ...value, published }, decisionPublished: true });
86
77
  });
87
- return { board, decision, integrations, launching, launchScope, load, policy, reportInspection, save, sessions, store };
78
+ return { board, current, decision, integrations, launching, launchScope, load, policy, reportInspection, save, sessions, store };
88
79
  });
89
80
  export type EngineState = Effect.Success<typeof makeState>;
81
+
82
+ function launchLimits(policy: FleetConfiguration, admission: LaunchAdmission): AdmissionLimits {
83
+ const concurrency = admission.overLimit ? undefined : policy.executionConcurrency;
84
+ return {
85
+ ...(admission.ignoreAreas ? {} : { scheduling: { areaMergeWaitMs: policy.areaMergeWaitMs ?? DEFAULT_AREA_MERGE_WAIT_MS, now: policy.now() } }),
86
+ ...(admission.quota.available === undefined ? {} : { quota: { available: admission.quota.available, observedAt: admission.quota.observedAt } }),
87
+ ...(concurrency === undefined ? {} : { maxExecuting: concurrency }),
88
+ ...(admission.role !== "worker" || admission.overLimit || policy.deliveryBacklog === undefined ? {} : { maxBacklog: policy.deliveryBacklog }),
89
+ ...(concurrency === undefined || !admission.implementer
90
+ ? {}
91
+ : { implementers: { concurrency, ...(policy.openPullRequests === undefined ? {} : { openPullRequests: policy.openPullRequests }) } }),
92
+ };
93
+ }
@@ -36,9 +36,10 @@ export const awaitHumanMerge = Effect.fn("Fleet.awaitHumanMerge")(function* (
36
36
  );
37
37
  });
38
38
 
39
- export function expireMergeAreas({ save, policy }: EngineState, stored: Versioned<FleetRecord>) {
40
- return stored.value.mergeAreasReleased !== true
41
- && mergeWaitExpired(stored.value, policy.now(), policy.areaMergeWaitMs ?? DEFAULT_AREA_MERGE_WAIT_MS)
42
- ? save(stored, { ...stored.value, mergeAreasReleased: true })
43
- : Effect.succeed(stored);
39
+ export function expireMergeAreas({ save, current }: EngineState, stored: Versioned<FleetRecord>) {
40
+ return Effect.flatMap(current, (policy) =>
41
+ stored.value.mergeAreasReleased !== true && mergeWaitExpired(stored.value, policy.now(), policy.areaMergeWaitMs ?? DEFAULT_AREA_MERGE_WAIT_MS)
42
+ ? save(stored, { ...stored.value, mergeAreasReleased: true })
43
+ : Effect.succeed(stored),
44
+ );
44
45
  }
@@ -13,7 +13,7 @@ import { readReviewerVerdict, reviewerPrompt } from "#prompt/reviewer.ts";
13
13
  import type { Versioned } from "#storage/model.ts";
14
14
 
15
15
  export function obtainReview(state: EngineState) {
16
- const { store, policy, sessions, save, board } = state;
16
+ const { store, sessions, save, board } = state;
17
17
  return Effect.fn("Fleet.obtainReview")(function* (
18
18
  stored: Versioned<FleetRecord>,
19
19
  work: BoardWork,
@@ -25,6 +25,7 @@ export function obtainReview(state: EngineState) {
25
25
  readonly observationRetries?: number;
26
26
  },
27
27
  ) {
28
+ const policy = yield* state.current;
28
29
  if (stored.value.review?.head === result.head) {
29
30
  return stored.value.review.receipt;
30
31
  }
@@ -41,7 +41,7 @@ export function prepareCommand(state: EngineState) {
41
41
  return yield* store.insert(current);
42
42
  }
43
43
  if (unusedPreparation(existing.value)) {
44
- return yield* save(existing, { ...current, history: existing.value.history });
44
+ return yield* save(existing, { ...current, dispatchNow: existing.value.dispatchNow, history: existing.value.history });
45
45
  }
46
46
  if (refreshablePreparation(existing.value, work, input)) {
47
47
  return yield* save(existing, {
@@ -35,7 +35,8 @@ export function readOrContinueReview(state: EngineState) {
35
35
 
36
36
  function continueReview(state: EngineState) {
37
37
  return Effect.fn("Fleet.continueReview")(function* (stored: Versioned<FleetRecord>, work: BoardWork, result: WorkResult, receipt: SessionReceipt) {
38
- const { policy, store, board, save, sessions } = state;
38
+ const { store, board, save, sessions } = state;
39
+ const policy = yield* state.current;
39
40
  const reviewerGuidance = yield* policyGuidance(policy, "reviewer");
40
41
  const prompt = [
41
42
  reviewerPrompt({
@@ -11,6 +11,8 @@ import { SessionFailure } from "#session/schema.ts";
11
11
  import { requestTimedOut, transientFailure } from "#session/transientFailure.ts";
12
12
  import type { Versioned } from "#storage/model.ts";
13
13
 
14
+ export const DEFAULT_READ_RETRY_MS = 30_000;
15
+
14
16
  function retryKind(error: unknown, record: FleetRecord) {
15
17
  if (error instanceof SessionFailure && retryProviderRead(error, record)) {
16
18
  return "provider";
@@ -39,6 +41,24 @@ function retryAttempts(record: FleetRecord, operationId: string | undefined, ret
39
41
  );
40
42
  }
41
43
 
44
+ function rateLimitedUntil(kind: "integration" | "provider", error: unknown) {
45
+ return kind === "integration" ? failureContext(error).retryAt : undefined;
46
+ }
47
+
48
+ function providerReadClosed(kind: "integration" | "provider", attempt: Attempt | undefined) {
49
+ return kind === "provider" && (attempt === undefined || !["submitting", "accepted", "running"].includes(attempt.status));
50
+ }
51
+
52
+ // An integration that names its retry time, such as a GitHub rate limit, is pacing Fleet rather than failing, so the wait does not count toward escalation.
53
+ function waitForRateLimit(state: EngineState, current: Versioned<FleetRecord>, message: string, retryAt: number) {
54
+ return state.save(current, {
55
+ ...current.value,
56
+ attentionOwner: "automation",
57
+ blocker: message,
58
+ integrationRetry: { error: message, failures: current.value.integrationRetry?.failures ?? 0, retryAt },
59
+ });
60
+ }
61
+
42
62
  export const readRetry = Effect.fn("Fleet.readRetry")(function* (
43
63
  state: EngineState,
44
64
  current: Versioned<FleetRecord>,
@@ -56,18 +76,22 @@ export const readRetry = Effect.fn("Fleet.readRetry")(function* (
56
76
  return current;
57
77
  }
58
78
  const attempt = current.value.attempts.at(-1);
59
- if (kind === "provider" && (attempt === undefined || !["submitting", "accepted", "running"].includes(attempt.status))) {
79
+ if (providerReadClosed(kind, attempt)) {
60
80
  return undefined;
61
81
  }
62
82
  const previous = kind === "provider" ? attempt?.readRetry : current.value.integrationRetry;
63
83
  if (retryPending(state, current.value)) {
64
84
  return current;
65
85
  }
86
+ const limitedUntil = rateLimitedUntil(kind, error);
87
+ if (limitedUntil !== undefined) {
88
+ return yield* waitForRateLimit(state, current, failureMessage(error), limitedUntil);
89
+ }
66
90
  const failures = (previous?.failures ?? 0) + 1;
67
91
  if (failures >= 5 && (yield* retryLostReview(state, current.value, error))) {
68
92
  return yield* state.load(current.value.workId);
69
93
  }
70
- const retryAt = state.policy.now() + 30_000 * 2 ** (failures - 1);
94
+ const retryAt = state.policy.now() + ((yield* state.current).readRetryMs ?? DEFAULT_READ_RETRY_MS) * 2 ** (failures - 1);
71
95
  const message = failureMessage(error);
72
96
  const subject = { integration: "integration evidence", provider: "provider state" }[kind];
73
97
  const retry = failures < 5 ? { error: message, failures, retryAt } : undefined;
@@ -5,9 +5,10 @@ import type { Attempt, FleetRecord } from "#model.ts";
5
5
  import { reportPrompt } from "#prompt/worker.ts";
6
6
  import type { Versioned } from "#storage/model.ts";
7
7
 
8
- export function reconcileAttempt({ sessions, policy, board }: EngineState) {
8
+ export function reconcileAttempt({ sessions, current, board }: EngineState) {
9
9
  return Effect.fn("Fleet.reconcileAttempt")(function* (stored: Versioned<FleetRecord>, attempt: Attempt) {
10
10
  const work = yield* board.get(stored.value.workId);
11
+ const policy = yield* current;
11
12
  const authorized = briefApproved(work) && !briefChanged(stored.value, work);
12
13
  const preparedPrompt = stored.value.deliverable === "report" ? reportPrompt(stored.value.prompt) : stored.value.prompt;
13
14
  const prompt = attempt.prompt ?? (attempt.role === "worker" ? preparedPrompt : undefined);