@telora/daemon 0.21.98 → 0.21.134

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 (226) hide show
  1. package/build-info.json +6 -3
  2. package/dist/audit/audit-hooks.d.ts +106 -0
  3. package/dist/audit/audit-hooks.d.ts.map +1 -1
  4. package/dist/audit/audit-hooks.js +149 -17
  5. package/dist/audit/audit-hooks.js.map +1 -1
  6. package/dist/ci/ci-sensor-loop.d.ts +6 -0
  7. package/dist/ci/ci-sensor-loop.d.ts.map +1 -1
  8. package/dist/ci/ci-sensor-loop.js +50 -3
  9. package/dist/ci/ci-sensor-loop.js.map +1 -1
  10. package/dist/completion/coverage-drift-state.d.ts +29 -2
  11. package/dist/completion/coverage-drift-state.d.ts.map +1 -1
  12. package/dist/completion/coverage-drift-state.js +42 -2
  13. package/dist/completion/coverage-drift-state.js.map +1 -1
  14. package/dist/completion/coverage-stabilized.d.ts +58 -0
  15. package/dist/completion/coverage-stabilized.d.ts.map +1 -0
  16. package/dist/completion/coverage-stabilized.js +84 -0
  17. package/dist/completion/coverage-stabilized.js.map +1 -0
  18. package/dist/completion/delivery-advancement-guard.d.ts +21 -0
  19. package/dist/completion/delivery-advancement-guard.d.ts.map +1 -1
  20. package/dist/completion/delivery-advancement-guard.js +31 -3
  21. package/dist/completion/delivery-advancement-guard.js.map +1 -1
  22. package/dist/completion/event-escalations.d.ts +15 -0
  23. package/dist/completion/event-escalations.d.ts.map +1 -1
  24. package/dist/completion/event-escalations.js +42 -4
  25. package/dist/completion/event-escalations.js.map +1 -1
  26. package/dist/completion/event-phases.d.ts.map +1 -1
  27. package/dist/completion/event-phases.js +5 -2
  28. package/dist/completion/event-phases.js.map +1 -1
  29. package/dist/completion/machine-remediable-demotion.d.ts +74 -0
  30. package/dist/completion/machine-remediable-demotion.d.ts.map +1 -0
  31. package/dist/completion/machine-remediable-demotion.js +147 -0
  32. package/dist/completion/machine-remediable-demotion.js.map +1 -0
  33. package/dist/completion/review-exit-phase.d.ts.map +1 -1
  34. package/dist/completion/review-exit-phase.js +10 -6
  35. package/dist/completion/review-exit-phase.js.map +1 -1
  36. package/dist/completion/settle-injection-sweep.d.ts +55 -0
  37. package/dist/completion/settle-injection-sweep.d.ts.map +1 -0
  38. package/dist/completion/settle-injection-sweep.js +88 -0
  39. package/dist/completion/settle-injection-sweep.js.map +1 -0
  40. package/dist/completion/state-cascade.d.ts.map +1 -1
  41. package/dist/completion/state-cascade.js +41 -0
  42. package/dist/completion/state-cascade.js.map +1 -1
  43. package/dist/completion/status-advance-phase.d.ts.map +1 -1
  44. package/dist/completion/status-advance-phase.js +18 -1
  45. package/dist/completion/status-advance-phase.js.map +1 -1
  46. package/dist/completion/team-lifecycle.d.ts +42 -0
  47. package/dist/completion/team-lifecycle.d.ts.map +1 -1
  48. package/dist/completion/team-lifecycle.js +71 -0
  49. package/dist/completion/team-lifecycle.js.map +1 -1
  50. package/dist/delivery/delivery-lifecycle.d.ts +19 -33
  51. package/dist/delivery/delivery-lifecycle.d.ts.map +1 -1
  52. package/dist/delivery/delivery-lifecycle.js +19 -147
  53. package/dist/delivery/delivery-lifecycle.js.map +1 -1
  54. package/dist/delivery/delivery-merge-ops.d.ts +46 -0
  55. package/dist/delivery/delivery-merge-ops.d.ts.map +1 -0
  56. package/dist/delivery/delivery-merge-ops.js +154 -0
  57. package/dist/delivery/delivery-merge-ops.js.map +1 -0
  58. package/dist/delivery/delivery-reconciler-apply.d.ts +28 -0
  59. package/dist/delivery/delivery-reconciler-apply.d.ts.map +1 -1
  60. package/dist/delivery/delivery-reconciler-apply.js +30 -0
  61. package/dist/delivery/delivery-reconciler-apply.js.map +1 -1
  62. package/dist/delivery/delivery-reconciler.d.ts +7 -2
  63. package/dist/delivery/delivery-reconciler.d.ts.map +1 -1
  64. package/dist/delivery/delivery-reconciler.js +34 -5
  65. package/dist/delivery/delivery-reconciler.js.map +1 -1
  66. package/dist/delivery/external-hold-surface.d.ts +32 -0
  67. package/dist/delivery/external-hold-surface.d.ts.map +1 -0
  68. package/dist/delivery/external-hold-surface.js +67 -0
  69. package/dist/delivery/external-hold-surface.js.map +1 -0
  70. package/dist/delivery/external-hold.d.ts +21 -0
  71. package/dist/delivery/external-hold.d.ts.map +1 -1
  72. package/dist/delivery/external-hold.js +40 -5
  73. package/dist/delivery/external-hold.js.map +1 -1
  74. package/dist/delivery/paused-revival.d.ts +140 -0
  75. package/dist/delivery/paused-revival.d.ts.map +1 -0
  76. package/dist/delivery/paused-revival.js +229 -0
  77. package/dist/delivery/paused-revival.js.map +1 -0
  78. package/dist/delivery/wait-reachability.d.ts.map +1 -1
  79. package/dist/delivery/wait-reachability.js +11 -0
  80. package/dist/delivery/wait-reachability.js.map +1 -1
  81. package/dist/directive/close-loop-dispatcher.d.ts +16 -263
  82. package/dist/directive/close-loop-dispatcher.d.ts.map +1 -1
  83. package/dist/directive/close-loop-dispatcher.js +21 -259
  84. package/dist/directive/close-loop-dispatcher.js.map +1 -1
  85. package/dist/directive/directive-dispatch.d.ts +19 -0
  86. package/dist/directive/directive-dispatch.d.ts.map +1 -1
  87. package/dist/directive/directive-dispatch.js +18 -0
  88. package/dist/directive/directive-dispatch.js.map +1 -1
  89. package/dist/directive/directive-executor.d.ts +1 -3
  90. package/dist/directive/directive-executor.d.ts.map +1 -1
  91. package/dist/directive/directive-executor.js +23 -21
  92. package/dist/directive/directive-executor.js.map +1 -1
  93. package/dist/directive/phase-sync.d.ts +28 -15
  94. package/dist/directive/phase-sync.d.ts.map +1 -1
  95. package/dist/directive/phase-sync.js +28 -36
  96. package/dist/directive/phase-sync.js.map +1 -1
  97. package/dist/directive/resolver-dispatch.d.ts +19 -92
  98. package/dist/directive/resolver-dispatch.d.ts.map +1 -1
  99. package/dist/directive/resolver-dispatch.js +19 -65
  100. package/dist/directive/resolver-dispatch.js.map +1 -1
  101. package/dist/focus/focus-engine.d.ts.map +1 -1
  102. package/dist/focus/focus-engine.js +26 -0
  103. package/dist/focus/focus-engine.js.map +1 -1
  104. package/dist/focus/focus-executor.d.ts.map +1 -1
  105. package/dist/focus/focus-executor.js +290 -256
  106. package/dist/focus/focus-executor.js.map +1 -1
  107. package/dist/focus/focus-loop-registry.d.ts.map +1 -1
  108. package/dist/focus/focus-loop-registry.js +43 -1
  109. package/dist/focus/focus-loop-registry.js.map +1 -1
  110. package/dist/focus/focus-respawn-guard.d.ts.map +1 -1
  111. package/dist/focus/focus-respawn-guard.js +11 -2
  112. package/dist/focus/focus-respawn-guard.js.map +1 -1
  113. package/dist/focus/focus-team-state.d.ts +11 -0
  114. package/dist/focus/focus-team-state.d.ts.map +1 -1
  115. package/dist/focus/focus-team-state.js +17 -0
  116. package/dist/focus/focus-team-state.js.map +1 -1
  117. package/dist/focus/listener-auto-advance.d.ts +13 -1
  118. package/dist/focus/listener-auto-advance.d.ts.map +1 -1
  119. package/dist/focus/listener-auto-advance.js +103 -22
  120. package/dist/focus/listener-auto-advance.js.map +1 -1
  121. package/dist/focus/listener.d.ts.map +1 -1
  122. package/dist/focus/listener.js +125 -75
  123. package/dist/focus/listener.js.map +1 -1
  124. package/dist/focus/tick-deadline.d.ts +55 -0
  125. package/dist/focus/tick-deadline.d.ts.map +1 -0
  126. package/dist/focus/tick-deadline.js +91 -0
  127. package/dist/focus/tick-deadline.js.map +1 -0
  128. package/dist/focus-stage-lifecycle/index.d.ts +18 -25
  129. package/dist/focus-stage-lifecycle/index.d.ts.map +1 -1
  130. package/dist/focus-stage-lifecycle/index.js +26 -38
  131. package/dist/focus-stage-lifecycle/index.js.map +1 -1
  132. package/dist/focus-stage-lifecycle/wedge-cause-arbiter.d.ts +52 -0
  133. package/dist/focus-stage-lifecycle/wedge-cause-arbiter.d.ts.map +1 -0
  134. package/dist/focus-stage-lifecycle/wedge-cause-arbiter.js +94 -0
  135. package/dist/focus-stage-lifecycle/wedge-cause-arbiter.js.map +1 -0
  136. package/dist/focus-stage-lifecycle/wedge-watchdog.d.ts +18 -1
  137. package/dist/focus-stage-lifecycle/wedge-watchdog.d.ts.map +1 -1
  138. package/dist/focus-stage-lifecycle/wedge-watchdog.js +57 -7
  139. package/dist/focus-stage-lifecycle/wedge-watchdog.js.map +1 -1
  140. package/dist/guard/condition-evaluators.d.ts +9 -0
  141. package/dist/guard/condition-evaluators.d.ts.map +1 -1
  142. package/dist/guard/condition-evaluators.js +15 -0
  143. package/dist/guard/condition-evaluators.js.map +1 -1
  144. package/dist/guard/guard-evaluator.d.ts +17 -1
  145. package/dist/guard/guard-evaluator.d.ts.map +1 -1
  146. package/dist/guard/guard-evaluator.js +61 -2
  147. package/dist/guard/guard-evaluator.js.map +1 -1
  148. package/dist/guard/trigger-executor.d.ts +30 -18
  149. package/dist/guard/trigger-executor.d.ts.map +1 -1
  150. package/dist/guard/trigger-executor.js +55 -31
  151. package/dist/guard/trigger-executor.js.map +1 -1
  152. package/dist/prompt/team-prompt-base.d.ts +1 -1
  153. package/dist/prompt/team-prompt-base.d.ts.map +1 -1
  154. package/dist/prompt/team-prompt-base.js +1 -1
  155. package/dist/prompt/team-prompt-base.js.map +1 -1
  156. package/dist/prompt-sections/persona-sections.d.ts +0 -32
  157. package/dist/prompt-sections/persona-sections.d.ts.map +1 -1
  158. package/dist/prompt-sections/persona-sections.js +19 -88
  159. package/dist/prompt-sections/persona-sections.js.map +1 -1
  160. package/dist/queries/deliveries.d.ts +23 -0
  161. package/dist/queries/deliveries.d.ts.map +1 -1
  162. package/dist/queries/deliveries.js +6 -0
  163. package/dist/queries/deliveries.js.map +1 -1
  164. package/dist/queries/focuses.d.ts +36 -0
  165. package/dist/queries/focuses.d.ts.map +1 -1
  166. package/dist/queries/focuses.js +45 -0
  167. package/dist/queries/focuses.js.map +1 -1
  168. package/dist/queries/guards.d.ts +10 -0
  169. package/dist/queries/guards.d.ts.map +1 -1
  170. package/dist/queries/guards.js +14 -1
  171. package/dist/queries/guards.js.map +1 -1
  172. package/dist/queries/issues.d.ts +65 -1
  173. package/dist/queries/issues.d.ts.map +1 -1
  174. package/dist/queries/issues.js +135 -2
  175. package/dist/queries/issues.js.map +1 -1
  176. package/dist/queries/schemas.d.ts +51 -0
  177. package/dist/queries/schemas.d.ts.map +1 -1
  178. package/dist/queries/schemas.js +34 -0
  179. package/dist/queries/schemas.js.map +1 -1
  180. package/dist/queries/verification.d.ts +5 -6
  181. package/dist/queries/verification.d.ts.map +1 -1
  182. package/dist/queries/verification.js +5 -6
  183. package/dist/queries/verification.js.map +1 -1
  184. package/dist/resolvers/loop-persona.d.ts +1 -11
  185. package/dist/resolvers/loop-persona.d.ts.map +1 -1
  186. package/dist/resolvers/loop-persona.js +2 -16
  187. package/dist/resolvers/loop-persona.js.map +1 -1
  188. package/dist/shell/unified-shell-provisioning.d.ts +40 -0
  189. package/dist/shell/unified-shell-provisioning.d.ts.map +1 -1
  190. package/dist/shell/unified-shell-provisioning.js +72 -0
  191. package/dist/shell/unified-shell-provisioning.js.map +1 -1
  192. package/dist/shell/unified-shell.d.ts.map +1 -1
  193. package/dist/shell/unified-shell.js +18 -1
  194. package/dist/shell/unified-shell.js.map +1 -1
  195. package/dist/spawn/helpers.d.ts.map +1 -1
  196. package/dist/spawn/helpers.js +6 -1
  197. package/dist/spawn/helpers.js.map +1 -1
  198. package/dist/spawn/process-spawn.d.ts.map +1 -1
  199. package/dist/spawn/process-spawn.js +7 -0
  200. package/dist/spawn/process-spawn.js.map +1 -1
  201. package/dist/spawn/spawn-cooldown.d.ts +41 -7
  202. package/dist/spawn/spawn-cooldown.d.ts.map +1 -1
  203. package/dist/spawn/spawn-cooldown.js +47 -0
  204. package/dist/spawn/spawn-cooldown.js.map +1 -1
  205. package/dist/spawn/spawn-decision.d.ts.map +1 -1
  206. package/dist/spawn/spawn-decision.js +33 -1
  207. package/dist/spawn/spawn-decision.js.map +1 -1
  208. package/dist/verify/stall-detectors.d.ts +20 -8
  209. package/dist/verify/stall-detectors.d.ts.map +1 -1
  210. package/dist/verify/stall-detectors.js +27 -46
  211. package/dist/verify/stall-detectors.js.map +1 -1
  212. package/dist/workflow/gate-failure-policy.d.ts +48 -0
  213. package/dist/workflow/gate-failure-policy.d.ts.map +1 -0
  214. package/dist/workflow/gate-failure-policy.js +57 -0
  215. package/dist/workflow/gate-failure-policy.js.map +1 -0
  216. package/dist/workflow/pipeline-config.d.ts +2 -2
  217. package/dist/workflow/pipeline-config.js +2 -2
  218. package/package.json +1 -1
  219. package/dist/directive/close-loop-stage.d.ts +0 -50
  220. package/dist/directive/close-loop-stage.d.ts.map +0 -1
  221. package/dist/directive/close-loop-stage.js +0 -210
  222. package/dist/directive/close-loop-stage.js.map +0 -1
  223. package/dist/focus-stage-lifecycle/review-convergence.d.ts +0 -133
  224. package/dist/focus-stage-lifecycle/review-convergence.d.ts.map +0 -1
  225. package/dist/focus-stage-lifecycle/review-convergence.js +0 -237
  226. package/dist/focus-stage-lifecycle/review-convergence.js.map +0 -1
@@ -29,6 +29,18 @@
29
29
  * @module external-hold
30
30
  */
31
31
  import type { ExternalHoldState, updateDeliveryStatus } from '../queries/deliveries.js';
32
+ /**
33
+ * Pure decision: is this held, reference-less external hold now STALE (age-bounded)?
34
+ *
35
+ * True when the hold is reference-less -- its wait is UNREACHABLE (nothing the
36
+ * daemon can re-read will ever fire it: crossProductRequestWait over an empty
37
+ * reference set classifies as not-`canStillFire`) -- AND it has been declared
38
+ * longer ago than the bound. This is the live branch on the wait-reachability
39
+ * verdict (previously render-only): a reachable wait (a hold with a re-readable
40
+ * request reference) is NEVER stale-surfaced, because it self-clears when the
41
+ * request closes. Exported for direct unit testing (no clock, no daemon-core).
42
+ */
43
+ export declare function isReferenceLessHoldStale(hold: Pick<ExternalHoldState, 'declaredAt' | 'clearsWhenRequestsClosed'>, nowMs: number, boundMs?: number): boolean;
32
44
  /** The slice of deps this gate needs (structural, so no import cycle). */
33
45
  export interface ExternalHoldDeps {
34
46
  updateDeliveryStatus: typeof updateDeliveryStatus;
@@ -116,6 +128,15 @@ export interface ExternalHold {
116
128
  * not held, when cleared, or when the hold carries a reference.
117
129
  */
118
130
  referenceLess?: boolean;
131
+ /**
132
+ * True when the hold is reference-less AND has been held past the staleness
133
+ * age bound (isReferenceLessHoldStale): it can never self-clear and has now sat
134
+ * long enough to be SURFACED so a human re-declares it with a clearing reference
135
+ * or clears it. The caller emits the operator-visible signal (this module stays
136
+ * free of the @telora/daemon-core value import health surfacing needs). Absent/
137
+ * false when not held, reference-less but within the bound, or reference-bearing.
138
+ */
139
+ staleReferenceLess?: boolean;
119
140
  }
120
141
  /** Narrow a delivery's `gate_state` JSONB to its externalHold, if any. */
121
142
  export declare function readExternalHoldState(gateState: unknown): ExternalHoldState | null;
@@ -1 +1 @@
1
- {"version":3,"file":"external-hold.d.ts","sourceRoot":"","sources":["../../src/delivery/external-hold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAqB,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AA6B3G,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,oBAAoB,EAAE,OAAO,oBAAoB,CAAC;CACnD;AAED;;;;;GAKG;AACH,MAAM,MAAM,0BAA0B,GAAG,CACvC,IAAI,EAAE,iBAAiB,KACpB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,EAAE,0BAAwC,CAAC;AAElF;;;;;;;;GAQG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAChC,UAAU,EAAE,MAAM,EAAE,KACjB,OAAO,CAAC,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAAC;AAErD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,mBAAmB,GAChC,0BAA0B,CAe5B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mCAAmC,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,CAKjG;AAED,yDAAyD;AACzD,MAAM,WAAW,YAAY;IAC3B,mEAAmE;IACnE,IAAI,EAAE,OAAO,CAAC;IACd,4DAA4D;IAC5D,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC/B,0EAA0E;IAC1E,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,0EAA0E;AAC1E,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,iBAAiB,GAAG,IAAI,CAmBlF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,gBAAgB,EACtB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GACzG,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,gBAAgB,EACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,gBAAgB,EACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,OAAO,EAClB,iBAAiB,EAAE,0BAA0B,EAC7C,KAAK,GAAE,MAAM,MAAuC,GACnD,OAAO,CAAC,YAAY,CAAC,CAoCvB;AAED,+DAA+D;AAC/D,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAmB/D"}
1
+ {"version":3,"file":"external-hold.d.ts","sourceRoot":"","sources":["../../src/delivery/external-hold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAqB,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAyC3G;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,IAAI,CAAC,iBAAiB,EAAE,YAAY,GAAG,0BAA0B,CAAC,EACxE,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,MAAqC,GAC7C,OAAO,CAMT;AAED,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,oBAAoB,EAAE,OAAO,oBAAoB,CAAC;CACnD;AAED;;;;;GAKG;AACH,MAAM,MAAM,0BAA0B,GAAG,CACvC,IAAI,EAAE,iBAAiB,KACpB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,EAAE,0BAAwC,CAAC;AAElF;;;;;;;;GAQG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAChC,UAAU,EAAE,MAAM,EAAE,KACjB,OAAO,CAAC,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAAC;AAErD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,mBAAmB,GAChC,0BAA0B,CAe5B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mCAAmC,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,CAKjG;AAED,yDAAyD;AACzD,MAAM,WAAW,YAAY;IAC3B,mEAAmE;IACnE,IAAI,EAAE,OAAO,CAAC;IACd,4DAA4D;IAC5D,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC/B,0EAA0E;IAC1E,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,0EAA0E;AAC1E,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,iBAAiB,GAAG,IAAI,CAmBlF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,gBAAgB,EACtB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GACzG,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,gBAAgB,EACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,gBAAgB,EACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,OAAO,EAClB,iBAAiB,EAAE,0BAA0B,EAC7C,KAAK,GAAE,MAAM,MAAuC,GACnD,OAAO,CAAC,YAAY,CAAC,CA2CvB;AAED,+DAA+D;AAC/D,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAmB/D"}
@@ -29,7 +29,8 @@
29
29
  * @module external-hold
30
30
  */
31
31
  import { createLogger } from '../shell/log.js';
32
- import { classifyWaitReachability, describeWaitReachability, crossProductRequestWait, } from './wait-reachability.js';
32
+ import { classifyWaitReachability, describeWaitReachability, crossProductRequestWait, canStillFire, } from './wait-reachability.js';
33
+ import { safetyGateFailsClosed } from '../workflow/gate-failure-policy.js';
33
34
  const log = createLogger({ module: 'external-hold' });
34
35
  // The `verify` status re-asserted by a gate_state write. Daemon-local literal
35
36
  // for the same reason as operator-hold.ts's VERIFY_STATUS: this module is
@@ -48,6 +49,35 @@ const VERIFY_STATUS = 'verify';
48
49
  // is non-terminal-for-the-source and 'declined' is a terminal exit that is NOT
49
50
  // closure -- neither clears the hold, only 'closed' does.
50
51
  const REQUEST_STATUS_CLOSED = 'closed';
52
+ /**
53
+ * How long a REFERENCE-LESS external hold may sit before it is surfaced as stale.
54
+ * A reference-less hold has nothing for the daemon to re-read, so it can NEVER
55
+ * self-clear; left silent it withholds the delivery from done -- and the focus
56
+ * from winding_down -- forever. After this age it is surfaced (age-bounded) so a
57
+ * human can re-declare it with a clearing reference or clear it. Daemon-local
58
+ * (this module avoids a bare @telora/daemon-core VALUE import; see VERIFY_STATUS).
59
+ */
60
+ const REFERENCE_LESS_HOLD_STALE_MS = 24 * 3_600_000;
61
+ /**
62
+ * Pure decision: is this held, reference-less external hold now STALE (age-bounded)?
63
+ *
64
+ * True when the hold is reference-less -- its wait is UNREACHABLE (nothing the
65
+ * daemon can re-read will ever fire it: crossProductRequestWait over an empty
66
+ * reference set classifies as not-`canStillFire`) -- AND it has been declared
67
+ * longer ago than the bound. This is the live branch on the wait-reachability
68
+ * verdict (previously render-only): a reachable wait (a hold with a re-readable
69
+ * request reference) is NEVER stale-surfaced, because it self-clears when the
70
+ * request closes. Exported for direct unit testing (no clock, no daemon-core).
71
+ */
72
+ export function isReferenceLessHoldStale(hold, nowMs, boundMs = REFERENCE_LESS_HOLD_STALE_MS) {
73
+ const wait = crossProductRequestWait(hold.clearsWhenRequestsClosed ?? []);
74
+ if (canStillFire(wait))
75
+ return false; // has a re-readable reference -> self-clears
76
+ const declaredMs = Date.parse(hold.declaredAt);
77
+ if (Number.isNaN(declaredMs))
78
+ return false;
79
+ return nowMs - declaredMs >= boundMs;
80
+ }
51
81
  /**
52
82
  * The default production evaluator: an irreducibly-external dependency does not
53
83
  * auto-clear from its free-text condition -- there is no generic probe for
@@ -204,14 +234,19 @@ export async function resolveExternalHold(deps, deliveryId, gateState, evaluateC
204
234
  // for the daemon to re-read, so it cannot self-clear -- surface it rather than
205
235
  // let it read as a normal, self-clearing hold.
206
236
  const referenceLess = !hold.clearsWhenRequestsClosed || hold.clearsWhenRequestsClosed.length === 0;
237
+ // Age-bound the reference-less hold (branches on the wait-reachability verdict,
238
+ // previously render-only): once it has sat past REFERENCE_LESS_HOLD_STALE_MS it
239
+ // is surfaced by the caller so it is never a silent permanent hold.
240
+ const staleReferenceLess = isReferenceLessHoldStale(hold, Date.parse(clock()));
207
241
  let conditionMet = false;
208
242
  try {
209
243
  conditionMet = await evaluateCondition(hold);
210
244
  }
211
245
  catch (err) {
212
- log.warn(`[external-hold] condition re-evaluation failed for delivery ${deliveryId} -- ` +
213
- `holding verify->done (fail-closed): ${err.message}`);
214
- return { held: true, hold, cleared: false, referenceLess };
246
+ // SAFETY GATE (the external-hold verify->done gate) -> FAIL CLOSED per the
247
+ // stated per-class policy: hold. A missed external hold lets an
248
+ // externally-blocked delivery reach done -- the failure this focus fights.
249
+ return safetyGateFailsClosed(`external-hold verify->done delivery ${deliveryId}`, err, { held: true, hold, cleared: false, referenceLess, staleReferenceLess });
215
250
  }
216
251
  if (conditionMet) {
217
252
  try {
@@ -226,7 +261,7 @@ export async function resolveExternalHold(deps, deliveryId, gateState, evaluateC
226
261
  }
227
262
  return { held: false, hold, cleared: true };
228
263
  }
229
- return { held: true, hold, cleared: false, referenceLess };
264
+ return { held: true, hold, cleared: false, referenceLess, staleReferenceLess };
230
265
  }
231
266
  /** Human-readable hold reason for an exit/advance log line. */
232
267
  export function describeExternalHold(hold) {
@@ -1 +1 @@
1
- {"version":3,"file":"external-hold.js","sourceRoot":"","sources":["../../src/delivery/external-hold.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"external-hold.js","sourceRoot":"","sources":["../../src/delivery/external-hold.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Paused-delivery revival -- the daemon-traversable EXIT from `paused` (TEL-1:
3
+ * "Every path into `paused` has a daemon-traversable exit or a named human-act
4
+ * hold").
5
+ *
6
+ * A `paused` delivery is a guard BLOCK on a transition (coding->verify or
7
+ * verify->done), written with an open `transition_blocks` row carrying the
8
+ * blocked transition and its human decision_paths (retry / override). Before
9
+ * this consumer, that block row was written but "nothing read it back": a paused
10
+ * delivery was skipped by every actionable-status pass, never re-evaluated, and
11
+ * -- because paused BLOCKS lower-ranked deliveries -- it wedged the whole ranked
12
+ * queue until a human re-queued it. On an ARMED focus that human never comes
13
+ * (2026-07-28 ruling: an armed focus reaches its terminal without a human;
14
+ * decide-and-record, reversibility as tiebreaker).
15
+ *
16
+ * This module reads the block row back. Each sweep, for every paused delivery it
17
+ * re-evaluates the SAME blocked transition's guards and routes the fresh verdict
18
+ * through the single-writer reconciler (delivery-reconciler `paused` case):
19
+ * - guard CLEARED -> revive `paused` -> `queued` (the canonical revival edge);
20
+ * the normal walk re-drives and re-hits the gate. This is
21
+ * the daemon-traversable exit.
22
+ * - guard STILL blocks -> hold. The pause stays a NAMED human-act hold (its
23
+ * gate_state blocking conditions + the block's `override`
24
+ * decision path name the act only a human can perform), and
25
+ * the wedge watchdog surfaces it. The daemon never OVERRIDES
26
+ * an unclear gate -- that irreversible act is the human's.
27
+ *
28
+ * A paused delivery with NO open block row is NOT abandoned: the blocked FORWARD
29
+ * transition (coding->verify / verify->done) is recovered from the delivery's
30
+ * preserved source stage and re-evaluated the same way -- so a hard-guard pause
31
+ * that wrote no block_transition row still gets a daemon-traversable exit. Only a
32
+ * pause whose stage yields no recoverable forward transition (unknown/ambiguous)
33
+ * stays `no-block` for the watchdog.
34
+ *
35
+ * DI-first: `reconcilePausedDelivery` + `checkPausedDeliveriesForRevival` take a
36
+ * deps object so they unit-test with plain stubs (no `mock.module`, which would
37
+ * poison the daemon-core bare-import loader). `buildDefaultPausedRevivalDeps`
38
+ * wires the real query/guard functions for the listener.
39
+ */
40
+ /** The minimal paused-delivery shape this consumer reads. */
41
+ export interface PausedDeliveryInfo {
42
+ id: string;
43
+ name: string;
44
+ executionStatus: string | null;
45
+ /**
46
+ * The delivery's workflow stage id. A pause PRESERVES this at the SOURCE stage
47
+ * of the blocked advance (delivery-lifecycle sets deliveryStageId=currentStageId
48
+ * on a guard block), so it recovers the blocked FORWARD transition even when no
49
+ * transition_blocks row was written (a hard guard with no block_transition
50
+ * trigger). Absent => the derived-transition fallback is skipped.
51
+ */
52
+ currentWorkflowStageId?: string | null;
53
+ }
54
+ /** Per-delivery revival deps (the I/O seam). */
55
+ export interface PausedRevivalDeps {
56
+ /**
57
+ * The open (unresolved) transition block for a paused delivery, yielding the
58
+ * blocked transition id. null when the paused delivery has no block row
59
+ * (nothing to re-evaluate).
60
+ */
61
+ getActiveTransitionBlock(deliveryId: string): Promise<{
62
+ id: string;
63
+ transitionId: string;
64
+ } | null>;
65
+ /**
66
+ * Fallback transition recovery for a paused delivery with NO open block row:
67
+ * derive the blocked FORWARD transition (coding->verify / verify->done) from
68
+ * the delivery's preserved source stage. Returns the transition id, or null
69
+ * when the stage is unknown/ambiguous (then the delivery stays paused for the
70
+ * watchdog). Only consulted when getActiveTransitionBlock returns null.
71
+ */
72
+ resolveForwardTransitionId(deliveryId: string, currentStageId: string | null | undefined): Promise<string | null>;
73
+ /**
74
+ * Re-evaluate the blocked transition's guards. Returns whether they STILL
75
+ * block (true = still blocked, false = cleared). Pure measurement -- MUST NOT
76
+ * write the delivery's execution_status.
77
+ */
78
+ reEvaluateGuardBlocked(deliveryId: string, organizationId: string, transitionId: string): Promise<boolean>;
79
+ /** Resolve the workflow stage id for a status name on this delivery's effective workflow. */
80
+ resolveStageId(deliveryId: string, statusName: string): Promise<string | undefined>;
81
+ /**
82
+ * The single physical writer (queries/deliveries.updateDeliveryStatus). Param
83
+ * order mirrors the real writer: (id, status, stageId, gateState,
84
+ * completionArtifacts, transition). Revival passes null gateState +
85
+ * completionArtifacts (clearing the block's gate_state on the way out).
86
+ */
87
+ updateDeliveryStatus(deliveryId: string, status: string, stageId: string | null | undefined, gateState: unknown, completionArtifacts: unknown, transition: {
88
+ organizationId: string;
89
+ fromStatus: string;
90
+ }): Promise<void>;
91
+ /**
92
+ * Close out the transition block this revival acted on (stamps decided_at +
93
+ * decision_path, decided_by stays NULL). Called ONLY on a successful revival
94
+ * that read an open block row; a derived-forward revival (no block row) has
95
+ * nothing to close. Best-effort: a failure is logged, never blocks the
96
+ * already-decided revival.
97
+ */
98
+ resolveTransitionBlock(blockId: string, decisionPath: string): Promise<boolean>;
99
+ }
100
+ export type PausedRevivalOutcome = 'revived' | 'held' | 'no-block';
101
+ /**
102
+ * Re-evaluate one paused delivery's blocking guard and, if it has cleared,
103
+ * traverse it out of paused via the single-writer reconciler. Returns the
104
+ * outcome for sweep accounting. Never throws for an expected I/O failure -- a
105
+ * guard-reeval failure holds the delivery (safe: stays paused) rather than
106
+ * risking a wrong revival.
107
+ */
108
+ export declare function reconcilePausedDelivery(delivery: PausedDeliveryInfo, organizationId: string, deps: PausedRevivalDeps): Promise<PausedRevivalOutcome>;
109
+ /** Sweep deps: per-delivery deps plus the focus/delivery fetchers. */
110
+ export interface PausedRevivalSweepDeps extends PausedRevivalDeps {
111
+ getActiveFocuses(organizationId: string, productId: string): Promise<Array<{
112
+ focus_id: string;
113
+ }>>;
114
+ getFocusDeliveries(focusId: string): Promise<PausedDeliveryInfo[]>;
115
+ }
116
+ /**
117
+ * Sweep every active focus's paused deliveries and revive the ones whose
118
+ * blocking guard has cleared. Runs on TEAMLESS focuses too (a paused delivery
119
+ * wedges the queue so no team spawns) -- hence it iterates active focuses, not
120
+ * activeTeams. Best-effort per focus/delivery: one failure never aborts the
121
+ * sweep.
122
+ */
123
+ export declare function checkPausedDeliveriesForRevival(config: {
124
+ organizationId: string;
125
+ productId: string;
126
+ }, deps: PausedRevivalSweepDeps): Promise<{
127
+ revived: number;
128
+ held: number;
129
+ noBlock: number;
130
+ }>;
131
+ /**
132
+ * Wire the real query + guard functions into a sweep-deps object for the
133
+ * listener. Kept as thin adapters (not direct assignments) so the wide,
134
+ * strictly-typed writer/query signatures reduce to this consumer's narrow seam.
135
+ * `reEvaluateGuardBlocked` is PURE measurement: evaluateGuardsAtTransition
136
+ * fetches guards + builds context and returns a verdict; it does NOT write the
137
+ * delivery's execution_status (that stays the reconciler's job here).
138
+ */
139
+ export declare function buildDefaultPausedRevivalDeps(): PausedRevivalSweepDeps;
140
+ //# sourceMappingURL=paused-revival.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paused-revival.d.ts","sourceRoot":"","sources":["../../src/delivery/paused-revival.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAgBH,6DAA6D;AAC7D,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;AAwBD,gDAAgD;AAChD,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACnG;;;;;;OAMG;IACH,0BAA0B,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAClH;;;;OAIG;IACH,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3G,6FAA6F;IAC7F,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACpF;;;;;OAKG;IACH,oBAAoB,CAClB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAClC,SAAS,EAAE,OAAO,EAClB,mBAAmB,EAAE,OAAO,EAC5B,UAAU,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GACzD,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB;;;;;;OAMG;IACH,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACjF;AAED,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;AAEnE;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,kBAAkB,EAC5B,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,oBAAoB,CAAC,CAwE/B;AAED,sEAAsE;AACtE,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;IAC/D,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAClG,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;CACpE;AAED;;;;;;GAMG;AACH,wBAAsB,+BAA+B,CACnD,MAAM,EAAE;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EACrD,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAwC7D;AAED;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,IAAI,sBAAsB,CA4CtE"}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Paused-delivery revival -- the daemon-traversable EXIT from `paused` (TEL-1:
3
+ * "Every path into `paused` has a daemon-traversable exit or a named human-act
4
+ * hold").
5
+ *
6
+ * A `paused` delivery is a guard BLOCK on a transition (coding->verify or
7
+ * verify->done), written with an open `transition_blocks` row carrying the
8
+ * blocked transition and its human decision_paths (retry / override). Before
9
+ * this consumer, that block row was written but "nothing read it back": a paused
10
+ * delivery was skipped by every actionable-status pass, never re-evaluated, and
11
+ * -- because paused BLOCKS lower-ranked deliveries -- it wedged the whole ranked
12
+ * queue until a human re-queued it. On an ARMED focus that human never comes
13
+ * (2026-07-28 ruling: an armed focus reaches its terminal without a human;
14
+ * decide-and-record, reversibility as tiebreaker).
15
+ *
16
+ * This module reads the block row back. Each sweep, for every paused delivery it
17
+ * re-evaluates the SAME blocked transition's guards and routes the fresh verdict
18
+ * through the single-writer reconciler (delivery-reconciler `paused` case):
19
+ * - guard CLEARED -> revive `paused` -> `queued` (the canonical revival edge);
20
+ * the normal walk re-drives and re-hits the gate. This is
21
+ * the daemon-traversable exit.
22
+ * - guard STILL blocks -> hold. The pause stays a NAMED human-act hold (its
23
+ * gate_state blocking conditions + the block's `override`
24
+ * decision path name the act only a human can perform), and
25
+ * the wedge watchdog surfaces it. The daemon never OVERRIDES
26
+ * an unclear gate -- that irreversible act is the human's.
27
+ *
28
+ * A paused delivery with NO open block row is NOT abandoned: the blocked FORWARD
29
+ * transition (coding->verify / verify->done) is recovered from the delivery's
30
+ * preserved source stage and re-evaluated the same way -- so a hard-guard pause
31
+ * that wrote no block_transition row still gets a daemon-traversable exit. Only a
32
+ * pause whose stage yields no recoverable forward transition (unknown/ambiguous)
33
+ * stays `no-block` for the watchdog.
34
+ *
35
+ * DI-first: `reconcilePausedDelivery` + `checkPausedDeliveriesForRevival` take a
36
+ * deps object so they unit-test with plain stubs (no `mock.module`, which would
37
+ * poison the daemon-core bare-import loader). `buildDefaultPausedRevivalDeps`
38
+ * wires the real query/guard functions for the listener.
39
+ */
40
+ import { DELIVERY_STATUS } from '@telora/daemon-core';
41
+ import { resolveReconciledWrite } from './delivery-reconciler-apply.js';
42
+ import { getActiveTransitionBlock, resolveTransitionBlock } from '../queries/guards.js';
43
+ import { evaluateGuardsAtTransition } from '../guard/guard-evaluator.js';
44
+ import { fetchEffectiveWorkflow } from '../queries/workflows.js';
45
+ import { updateDeliveryStatus, getActiveFocuses } from '../queries/deliveries.js';
46
+ import { getFocusDeliveries } from '../queries/focuses.js';
47
+ import { createLogger } from '../shell/log.js';
48
+ const log = createLogger({ module: 'paused-revival' });
49
+ /**
50
+ * The canonical FORWARD delivery-stage a pause blocks. A `paused` delivery was
51
+ * blocked advancing coding->verify or verify->done (the only two guard-block
52
+ * pause producers, delivery-reconciler.ts:314/329); the blocked transition is the
53
+ * one FROM the source stage TO this forward stage. Used to recover the transition
54
+ * for re-evaluation when there is no transition_blocks row to read it from.
55
+ */
56
+ const FORWARD_DELIVERY_STAGE = {
57
+ [DELIVERY_STATUS.CODING]: DELIVERY_STATUS.VERIFY,
58
+ [DELIVERY_STATUS.VERIFY]: DELIVERY_STATUS.DONE,
59
+ };
60
+ /**
61
+ * The `decision_path` stamped on a block the daemon closes on auto-revival. The
62
+ * block leaves `decided_by` NULL (a machine action has no auth.users id), which
63
+ * is what keeps it OUT of the human-routing resolved-block query (that path
64
+ * requires decided_by IS NOT NULL). This value is the audit marker for "the
65
+ * daemon revived past this block because its guard cleared", never a human's
66
+ * retry/override choice.
67
+ */
68
+ const AUTO_REVIVAL_DECISION_PATH = 'daemon_auto_revival';
69
+ /**
70
+ * Re-evaluate one paused delivery's blocking guard and, if it has cleared,
71
+ * traverse it out of paused via the single-writer reconciler. Returns the
72
+ * outcome for sweep accounting. Never throws for an expected I/O failure -- a
73
+ * guard-reeval failure holds the delivery (safe: stays paused) rather than
74
+ * risking a wrong revival.
75
+ */
76
+ export async function reconcilePausedDelivery(delivery, organizationId, deps) {
77
+ // Recover the blocked transition: prefer the open block row (the block_transition
78
+ // producer), else derive the forward transition from the preserved source stage
79
+ // (a hard-guard pause with no block row). Either yields the transition whose
80
+ // guards we re-evaluate; neither => nothing recoverable, leave for the watchdog.
81
+ const block = await deps.getActiveTransitionBlock(delivery.id);
82
+ const transitionId = block?.transitionId ??
83
+ (await deps.resolveForwardTransitionId(delivery.id, delivery.currentWorkflowStageId));
84
+ if (!transitionId)
85
+ return 'no-block';
86
+ let stillBlocked;
87
+ try {
88
+ stillBlocked = await deps.reEvaluateGuardBlocked(delivery.id, organizationId, transitionId);
89
+ }
90
+ catch (err) {
91
+ log.warn(`[paused-revival] guard re-eval failed for "${delivery.name}" (${delivery.id.slice(0, 8)}): ` +
92
+ `${err.message} -- holding paused this tick`);
93
+ return 'held';
94
+ }
95
+ // Route the fresh verdict through the single reconciler computation. The
96
+ // paused case revives to `queued` only when the guard has cleared; otherwise
97
+ // it stays paused.
98
+ const decision = resolveReconciledWrite({
99
+ input: {
100
+ currentStatus: DELIVERY_STATUS.PAUSED,
101
+ issues: [],
102
+ gitState: { worktreeCommitted: true },
103
+ guardVerdict: { blocked: stillBlocked },
104
+ reviewState: null,
105
+ },
106
+ });
107
+ if (decision.target === DELIVERY_STATUS.PAUSED)
108
+ return 'held';
109
+ // Close out the block this revival acted on BEFORE the status write, so even a
110
+ // crash between the two leaves the block resolved (the next sweep then derives
111
+ // the forward transition from the preserved stage rather than re-reading a
112
+ // stale row). A derived-forward revival (block === null) has nothing to close.
113
+ // Best-effort: a close failure never blocks the already-decided revival.
114
+ if (block) {
115
+ try {
116
+ await deps.resolveTransitionBlock(block.id, AUTO_REVIVAL_DECISION_PATH);
117
+ }
118
+ catch (err) {
119
+ log.warn(`[paused-revival] failed to close block ${block.id.slice(0, 8)} for ` +
120
+ `"${delivery.name}" (${delivery.id.slice(0, 8)}): ${err.message} -- ` +
121
+ `revival proceeds; a stale-open block may be re-read on a later pause episode`);
122
+ }
123
+ }
124
+ const stageId = await deps.resolveStageId(delivery.id, decision.target);
125
+ // Clear gate_state + completion_artifacts explicitly (null, not undefined): the
126
+ // block that held this delivery no longer applies once it leaves paused, so the
127
+ // row must carry no gate state describing the block it has left. queries/
128
+ // deliveries.ts only clears the column on null; undefined would leave it stale.
129
+ await deps.updateDeliveryStatus(delivery.id, decision.target, stageId, null, null, { organizationId, fromStatus: DELIVERY_STATUS.PAUSED });
130
+ log.info(`[paused-revival] revived "${delivery.name}" (${delivery.id.slice(0, 8)}) ` +
131
+ `paused -> ${decision.target}: blocking guard cleared on re-eval`);
132
+ return 'revived';
133
+ }
134
+ /**
135
+ * Sweep every active focus's paused deliveries and revive the ones whose
136
+ * blocking guard has cleared. Runs on TEAMLESS focuses too (a paused delivery
137
+ * wedges the queue so no team spawns) -- hence it iterates active focuses, not
138
+ * activeTeams. Best-effort per focus/delivery: one failure never aborts the
139
+ * sweep.
140
+ */
141
+ export async function checkPausedDeliveriesForRevival(config, deps) {
142
+ let revived = 0;
143
+ let held = 0;
144
+ let noBlock = 0;
145
+ let focuses;
146
+ try {
147
+ focuses = await deps.getActiveFocuses(config.organizationId, config.productId);
148
+ }
149
+ catch (err) {
150
+ log.warn(`[paused-revival] failed to fetch active focuses: ${err.message}`);
151
+ return { revived, held, noBlock };
152
+ }
153
+ for (const focus of focuses) {
154
+ let deliveries;
155
+ try {
156
+ deliveries = await deps.getFocusDeliveries(focus.focus_id);
157
+ }
158
+ catch (err) {
159
+ log.warn(`[paused-revival] failed to fetch deliveries for focus ${focus.focus_id.slice(0, 8)}: ${err.message}`);
160
+ continue;
161
+ }
162
+ for (const delivery of deliveries) {
163
+ if ((delivery.executionStatus ?? '') !== DELIVERY_STATUS.PAUSED)
164
+ continue;
165
+ try {
166
+ const outcome = await reconcilePausedDelivery(delivery, config.organizationId, deps);
167
+ if (outcome === 'revived')
168
+ revived++;
169
+ else if (outcome === 'held')
170
+ held++;
171
+ else
172
+ noBlock++;
173
+ }
174
+ catch (err) {
175
+ log.warn(`[paused-revival] revival check failed for "${delivery.name}" (${delivery.id.slice(0, 8)}): ${err.message}`);
176
+ }
177
+ }
178
+ }
179
+ return { revived, held, noBlock };
180
+ }
181
+ /**
182
+ * Wire the real query + guard functions into a sweep-deps object for the
183
+ * listener. Kept as thin adapters (not direct assignments) so the wide,
184
+ * strictly-typed writer/query signatures reduce to this consumer's narrow seam.
185
+ * `reEvaluateGuardBlocked` is PURE measurement: evaluateGuardsAtTransition
186
+ * fetches guards + builds context and returns a verdict; it does NOT write the
187
+ * delivery's execution_status (that stays the reconciler's job here).
188
+ */
189
+ export function buildDefaultPausedRevivalDeps() {
190
+ return {
191
+ getActiveTransitionBlock: async (deliveryId) => {
192
+ const block = await getActiveTransitionBlock(deliveryId);
193
+ return block ? { id: block.id, transitionId: block.transition_id } : null;
194
+ },
195
+ resolveForwardTransitionId: async (deliveryId, currentStageId) => {
196
+ if (!currentStageId)
197
+ return null;
198
+ const workflow = await fetchEffectiveWorkflow(deliveryId);
199
+ const sourceStage = workflow.stages.find((s) => s.id === currentStageId);
200
+ if (!sourceStage)
201
+ return null;
202
+ const forwardName = FORWARD_DELIVERY_STAGE[sourceStage.name];
203
+ if (!forwardName)
204
+ return null;
205
+ const forwardStage = workflow.stages.find((s) => s.name === forwardName);
206
+ if (!forwardStage)
207
+ return null;
208
+ const transition = (workflow.transitions ?? []).find((t) => t.from_stage_id === currentStageId && t.to_stage_id === forwardStage.id);
209
+ return transition?.id ?? null;
210
+ },
211
+ reEvaluateGuardBlocked: async (deliveryId, organizationId, transitionId) => {
212
+ const result = await evaluateGuardsAtTransition(deliveryId, organizationId, transitionId, 0);
213
+ return !result.should_proceed;
214
+ },
215
+ resolveStageId: async (deliveryId, statusName) => {
216
+ const workflow = await fetchEffectiveWorkflow(deliveryId);
217
+ return workflow.stages.find((s) => s.name === statusName)?.id;
218
+ },
219
+ updateDeliveryStatus: (deliveryId, status, stageId, gateState, completionArtifacts, transition) =>
220
+ // Pass the caller's gate_state + completion_artifacts THROUGH (reconcile-
221
+ // PausedDelivery clears them with null on the way out of paused) instead of
222
+ // hardcoding, so the clear is driven by -- and testable at -- the caller.
223
+ updateDeliveryStatus(deliveryId, status, stageId, gateState, completionArtifacts, transition),
224
+ resolveTransitionBlock: (blockId, decisionPath) => resolveTransitionBlock(blockId, decisionPath),
225
+ getActiveFocuses: (organizationId, productId) => getActiveFocuses(organizationId, productId),
226
+ getFocusDeliveries: (focusId) => getFocusDeliveries(focusId),
227
+ };
228
+ }
229
+ //# sourceMappingURL=paused-revival.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paused-revival.js","sourceRoot":"","sources":["../../src/delivery/paused-revival.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"wait-reachability.d.ts","sourceRoot":"","sources":["../../src/delivery/wait-reachability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH;;;;;;;;;GASG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,MAAM,GAAG,aAAa,CAAC;AAEjE,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,SAAS,EAAE,WAAW,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE9C,yDAAyD;AACzD,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,SAAS,EAAE,OAAO,CAAC;IACnB,0EAA0E;IAC1E,SAAS,EAAE,WAAW,CAAC;IACvB,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,CAqB9E;AAED,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAEzD;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,gBAAgB,GAAG,MAAM,CASpE;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAEvD;AAOD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CAKvF;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAKpF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAK9D;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAK1E;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,gBAAgB,EAAE,MAAM,GAAG,gBAAgB,CAK3E;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,gBAAgB,CAUpG"}
1
+ {"version":3,"file":"wait-reachability.d.ts","sourceRoot":"","sources":["../../src/delivery/wait-reachability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH;;;;;;;;;GASG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,MAAM,GAAG,aAAa,CAAC;AAEjE,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,SAAS,EAAE,WAAW,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE9C,yDAAyD;AACzD,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,SAAS,EAAE,OAAO,CAAC;IACnB,0EAA0E;IAC1E,SAAS,EAAE,WAAW,CAAC;IACvB,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,CAqB9E;AAED,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAEzD;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,gBAAgB,GAAG,MAAM,CASpE;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAEvD;AAOD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CAgBvF;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAKpF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAK9D;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAK1E;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,gBAAgB,EAAE,MAAM,GAAG,gBAAgB,CAK3E;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,gBAAgB,CAUpG"}
@@ -103,6 +103,17 @@ export function renderWait(wait) {
103
103
  * external-hold.ts `clearsWhenRequestsClosed`.
104
104
  */
105
105
  export function crossProductRequestWait(requestIds) {
106
+ if (requestIds.length === 0) {
107
+ // No request reference: nothing names an actor that could ever close this, so
108
+ // it cannot arrive -- the REFERENCE-LESS external hold. Classifying it as a
109
+ // recorded fact (UNREACHABLE) rather than other_actor is what lets a caller
110
+ // branch on the reachability verdict (e.g. isReferenceLessHoldStale) instead
111
+ // of mistaking a hold with nothing to re-read for one a peer will close.
112
+ return {
113
+ condition: 'cross-product hold with NO request reference to close (nothing to re-read)',
114
+ blockedOn: 'static_fact',
115
+ };
116
+ }
106
117
  return {
107
118
  condition: `cross-product request(s) to close: ${requestIds.join(', ')}`,
108
119
  blockedOn: 'other_actor',
@@ -1 +1 @@
1
- {"version":3,"file":"wait-reachability.js","sourceRoot":"","sources":["../../src/delivery/wait-reachability.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wait-reachability.js","sourceRoot":"","sources":["../../src/delivery/wait-reachability.ts"],"names":[],"mappings":"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"}