@telora/daemon 0.22.104 → 0.22.132

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 (482) hide show
  1. package/build-info.json +4 -3
  2. package/dist/completion/commit-verdict-release.d.ts +49 -0
  3. package/dist/completion/commit-verdict-release.d.ts.map +1 -0
  4. package/dist/completion/commit-verdict-release.js +240 -0
  5. package/dist/completion/commit-verdict-release.js.map +1 -0
  6. package/dist/completion/completion-phase-registry.d.ts +10 -4
  7. package/dist/completion/completion-phase-registry.d.ts.map +1 -1
  8. package/dist/completion/completion-phase-registry.js +19 -7
  9. package/dist/completion/completion-phase-registry.js.map +1 -1
  10. package/dist/completion/detector.d.ts.map +1 -1
  11. package/dist/completion/detector.js +1 -0
  12. package/dist/completion/detector.js.map +1 -1
  13. package/dist/completion/event-entry-phases.d.ts +6 -3
  14. package/dist/completion/event-entry-phases.d.ts.map +1 -1
  15. package/dist/completion/event-entry-phases.js +135 -76
  16. package/dist/completion/event-entry-phases.js.map +1 -1
  17. package/dist/completion/event-phases.d.ts +24 -3
  18. package/dist/completion/event-phases.d.ts.map +1 -1
  19. package/dist/completion/event-phases.js +9 -9
  20. package/dist/completion/event-phases.js.map +1 -1
  21. package/dist/completion/event.d.ts +8 -0
  22. package/dist/completion/event.d.ts.map +1 -1
  23. package/dist/completion/event.js +47 -21
  24. package/dist/completion/event.js.map +1 -1
  25. package/dist/completion/exit-classification.d.ts.map +1 -1
  26. package/dist/completion/exit-classification.js +1 -0
  27. package/dist/completion/exit-classification.js.map +1 -1
  28. package/dist/completion/merge-phase.d.ts +21 -9
  29. package/dist/completion/merge-phase.d.ts.map +1 -1
  30. package/dist/completion/merge-phase.js +35 -10
  31. package/dist/completion/merge-phase.js.map +1 -1
  32. package/dist/completion/review-auto-approval-record.d.ts +19 -0
  33. package/dist/completion/review-auto-approval-record.d.ts.map +1 -0
  34. package/dist/completion/review-auto-approval-record.js +102 -0
  35. package/dist/completion/review-auto-approval-record.js.map +1 -0
  36. package/dist/completion/review-cycle-cap.d.ts +62 -0
  37. package/dist/completion/review-cycle-cap.d.ts.map +1 -0
  38. package/dist/completion/review-cycle-cap.js +180 -0
  39. package/dist/completion/review-cycle-cap.js.map +1 -0
  40. package/dist/completion/review-exit-deps.d.ts +17 -2
  41. package/dist/completion/review-exit-deps.d.ts.map +1 -1
  42. package/dist/completion/review-exit-deps.js +19 -2
  43. package/dist/completion/review-exit-deps.js.map +1 -1
  44. package/dist/completion/review-exit-escalations.d.ts +45 -23
  45. package/dist/completion/review-exit-escalations.d.ts.map +1 -1
  46. package/dist/completion/review-exit-escalations.js +15 -74
  47. package/dist/completion/review-exit-escalations.js.map +1 -1
  48. package/dist/completion/review-exit-evidence.d.ts +9 -0
  49. package/dist/completion/review-exit-evidence.d.ts.map +1 -1
  50. package/dist/completion/review-exit-evidence.js +4 -1
  51. package/dist/completion/review-exit-evidence.js.map +1 -1
  52. package/dist/completion/review-exit-foreign-findings.d.ts +151 -0
  53. package/dist/completion/review-exit-foreign-findings.d.ts.map +1 -0
  54. package/dist/completion/review-exit-foreign-findings.js +474 -0
  55. package/dist/completion/review-exit-foreign-findings.js.map +1 -0
  56. package/dist/completion/review-exit-phase.d.ts.map +1 -1
  57. package/dist/completion/review-exit-phase.js +71 -64
  58. package/dist/completion/review-exit-phase.js.map +1 -1
  59. package/dist/completion/review-exit-progress.d.ts +20 -0
  60. package/dist/completion/review-exit-progress.d.ts.map +1 -1
  61. package/dist/completion/review-exit-progress.js +28 -19
  62. package/dist/completion/review-exit-progress.js.map +1 -1
  63. package/dist/completion/review-exit-rehoming.d.ts +5 -0
  64. package/dist/completion/review-exit-rehoming.d.ts.map +1 -1
  65. package/dist/completion/review-exit-rehoming.js.map +1 -1
  66. package/dist/completion/review-exit-verdict-gate.d.ts +202 -0
  67. package/dist/completion/review-exit-verdict-gate.d.ts.map +1 -0
  68. package/dist/completion/review-exit-verdict-gate.js +228 -0
  69. package/dist/completion/review-exit-verdict-gate.js.map +1 -0
  70. package/dist/completion/review-next-step.d.ts +62 -0
  71. package/dist/completion/review-next-step.d.ts.map +1 -0
  72. package/dist/completion/review-next-step.js +63 -0
  73. package/dist/completion/review-next-step.js.map +1 -0
  74. package/dist/completion/session-hold-sweep-deps.d.ts +17 -0
  75. package/dist/completion/session-hold-sweep-deps.d.ts.map +1 -0
  76. package/dist/completion/session-hold-sweep-deps.js +89 -0
  77. package/dist/completion/session-hold-sweep-deps.js.map +1 -0
  78. package/dist/completion/session-hold.d.ts +180 -0
  79. package/dist/completion/session-hold.d.ts.map +1 -0
  80. package/dist/completion/session-hold.js +238 -0
  81. package/dist/completion/session-hold.js.map +1 -0
  82. package/dist/completion/state-cascade.d.ts +19 -0
  83. package/dist/completion/state-cascade.d.ts.map +1 -1
  84. package/dist/completion/state-cascade.js +85 -31
  85. package/dist/completion/state-cascade.js.map +1 -1
  86. package/dist/completion/team-lifecycle.d.ts +35 -2
  87. package/dist/completion/team-lifecycle.d.ts.map +1 -1
  88. package/dist/completion/team-lifecycle.js +165 -94
  89. package/dist/completion/team-lifecycle.js.map +1 -1
  90. package/dist/completion/team-phase.d.ts +27 -15
  91. package/dist/completion/team-phase.d.ts.map +1 -1
  92. package/dist/completion/team-phase.js +34 -15
  93. package/dist/completion/team-phase.js.map +1 -1
  94. package/dist/delivery/commit-verdict-hold.d.ts +55 -0
  95. package/dist/delivery/commit-verdict-hold.d.ts.map +1 -0
  96. package/dist/delivery/commit-verdict-hold.js +118 -0
  97. package/dist/delivery/commit-verdict-hold.js.map +1 -0
  98. package/dist/directive/directive-dispatch.d.ts.map +1 -1
  99. package/dist/directive/directive-dispatch.js +10 -3
  100. package/dist/directive/directive-dispatch.js.map +1 -1
  101. package/dist/directive/directive-executor.d.ts.map +1 -1
  102. package/dist/directive/directive-executor.js +1 -0
  103. package/dist/directive/directive-executor.js.map +1 -1
  104. package/dist/directive/directive-queue.d.ts.map +1 -1
  105. package/dist/directive/directive-queue.js +6 -1
  106. package/dist/directive/directive-queue.js.map +1 -1
  107. package/dist/directive/phase-sync.d.ts +29 -2
  108. package/dist/directive/phase-sync.d.ts.map +1 -1
  109. package/dist/directive/phase-sync.js +30 -6
  110. package/dist/directive/phase-sync.js.map +1 -1
  111. package/dist/drift/artifact-ref-shape.d.ts +34 -0
  112. package/dist/drift/artifact-ref-shape.d.ts.map +1 -0
  113. package/dist/drift/artifact-ref-shape.js +94 -0
  114. package/dist/drift/artifact-ref-shape.js.map +1 -0
  115. package/dist/drift/drift-eval-loop.d.ts +7 -0
  116. package/dist/drift/drift-eval-loop.d.ts.map +1 -1
  117. package/dist/drift/drift-eval-loop.js +34 -5
  118. package/dist/drift/drift-eval-loop.js.map +1 -1
  119. package/dist/drift/drift-evaluator.d.ts.map +1 -1
  120. package/dist/drift/drift-evaluator.js +8 -3
  121. package/dist/drift/drift-evaluator.js.map +1 -1
  122. package/dist/focus/awaiting-slot.d.ts +34 -0
  123. package/dist/focus/awaiting-slot.d.ts.map +1 -0
  124. package/dist/focus/awaiting-slot.js +26 -0
  125. package/dist/focus/awaiting-slot.js.map +1 -0
  126. package/dist/focus/focus-lifecycle.js +2 -2
  127. package/dist/focus/focus-lifecycle.js.map +1 -1
  128. package/dist/focus/focus-phase.d.ts.map +1 -1
  129. package/dist/focus/focus-phase.js +3 -1
  130. package/dist/focus/focus-phase.js.map +1 -1
  131. package/dist/focus/focus-spawn-decision.d.ts +62 -0
  132. package/dist/focus/focus-spawn-decision.d.ts.map +1 -0
  133. package/dist/focus/focus-spawn-decision.js +41 -0
  134. package/dist/focus/focus-spawn-decision.js.map +1 -0
  135. package/dist/focus/focus-team-state.d.ts.map +1 -1
  136. package/dist/focus/focus-team-state.js +1 -13
  137. package/dist/focus/focus-team-state.js.map +1 -1
  138. package/dist/focus/listener-spawn.d.ts +16 -55
  139. package/dist/focus/listener-spawn.d.ts.map +1 -1
  140. package/dist/focus/listener-spawn.js +102 -64
  141. package/dist/focus/listener-spawn.js.map +1 -1
  142. package/dist/focus/listener-state.d.ts.map +1 -1
  143. package/dist/focus/listener-state.js +4 -1
  144. package/dist/focus/listener-state.js.map +1 -1
  145. package/dist/focus/listener.d.ts +41 -2
  146. package/dist/focus/listener.d.ts.map +1 -1
  147. package/dist/focus/listener.js +135 -83
  148. package/dist/focus/listener.js.map +1 -1
  149. package/dist/focus/pending-spawn-pass-deps.d.ts +69 -0
  150. package/dist/focus/pending-spawn-pass-deps.d.ts.map +1 -0
  151. package/dist/focus/pending-spawn-pass-deps.js +34 -0
  152. package/dist/focus/pending-spawn-pass-deps.js.map +1 -0
  153. package/dist/focus/pending-spawn-review-next-step.d.ts +83 -0
  154. package/dist/focus/pending-spawn-review-next-step.d.ts.map +1 -0
  155. package/dist/focus/pending-spawn-review-next-step.js +325 -0
  156. package/dist/focus/pending-spawn-review-next-step.js.map +1 -0
  157. package/dist/focus/review-cycle-cap-hold.d.ts +132 -0
  158. package/dist/focus/review-cycle-cap-hold.d.ts.map +1 -0
  159. package/dist/focus/review-cycle-cap-hold.js +178 -0
  160. package/dist/focus/review-cycle-cap-hold.js.map +1 -0
  161. package/dist/focus/team-actionable-work.js +2 -2
  162. package/dist/focus/verify-open-issues.d.ts +22 -0
  163. package/dist/focus/verify-open-issues.d.ts.map +1 -1
  164. package/dist/focus/verify-open-issues.js +118 -57
  165. package/dist/focus/verify-open-issues.js.map +1 -1
  166. package/dist/focus/verify-routing-passes.d.ts +32 -0
  167. package/dist/focus/verify-routing-passes.d.ts.map +1 -0
  168. package/dist/focus/verify-routing-passes.js +18 -0
  169. package/dist/focus/verify-routing-passes.js.map +1 -0
  170. package/dist/git/index.d.ts.map +1 -1
  171. package/dist/git/index.js +9 -5
  172. package/dist/git/index.js.map +1 -1
  173. package/dist/merge/focus-merge.d.ts +16 -2
  174. package/dist/merge/focus-merge.d.ts.map +1 -1
  175. package/dist/merge/focus-merge.js +53 -30
  176. package/dist/merge/focus-merge.js.map +1 -1
  177. package/dist/merge/merge-back-loop.d.ts +5 -0
  178. package/dist/merge/merge-back-loop.d.ts.map +1 -1
  179. package/dist/merge/merge-back-loop.js +17 -8
  180. package/dist/merge/merge-back-loop.js.map +1 -1
  181. package/dist/merge/merge-gate-coverage.d.ts +94 -0
  182. package/dist/merge/merge-gate-coverage.d.ts.map +1 -0
  183. package/dist/merge/merge-gate-coverage.js +217 -0
  184. package/dist/merge/merge-gate-coverage.js.map +1 -0
  185. package/dist/prompt/focus-prompt-builder.d.ts.map +1 -1
  186. package/dist/prompt/focus-prompt-builder.js +6 -0
  187. package/dist/prompt/focus-prompt-builder.js.map +1 -1
  188. package/dist/prompt/prompt-listing.d.ts.map +1 -1
  189. package/dist/prompt/prompt-listing.js +8 -0
  190. package/dist/prompt/prompt-listing.js.map +1 -1
  191. package/dist/prompt/team-prompt-base.d.ts.map +1 -1
  192. package/dist/prompt/team-prompt-base.js +5 -1
  193. package/dist/prompt/team-prompt-base.js.map +1 -1
  194. package/dist/prompt-sections/execution-sections.d.ts.map +1 -1
  195. package/dist/prompt-sections/execution-sections.js +14 -39
  196. package/dist/prompt-sections/execution-sections.js.map +1 -1
  197. package/dist/prompt-sections/gate-ownership.d.ts +36 -0
  198. package/dist/prompt-sections/gate-ownership.d.ts.map +1 -0
  199. package/dist/prompt-sections/gate-ownership.js +68 -0
  200. package/dist/prompt-sections/gate-ownership.js.map +1 -0
  201. package/dist/prompt-sections/gate-verdict-section.d.ts +58 -0
  202. package/dist/prompt-sections/gate-verdict-section.d.ts.map +1 -0
  203. package/dist/prompt-sections/gate-verdict-section.js +88 -0
  204. package/dist/prompt-sections/gate-verdict-section.js.map +1 -0
  205. package/dist/prompt-sections/persona-sections.d.ts +10 -0
  206. package/dist/prompt-sections/persona-sections.d.ts.map +1 -1
  207. package/dist/prompt-sections/persona-sections.js +35 -11
  208. package/dist/prompt-sections/persona-sections.js.map +1 -1
  209. package/dist/prompt-sections/shared.js +1 -1
  210. package/dist/prompt-sections/shared.js.map +1 -1
  211. package/dist/queries/agent-resolvable-promotion.d.ts +6 -3
  212. package/dist/queries/agent-resolvable-promotion.d.ts.map +1 -1
  213. package/dist/queries/agent-resolvable-promotion.js +20 -9
  214. package/dist/queries/agent-resolvable-promotion.js.map +1 -1
  215. package/dist/queries/deliveries.d.ts +46 -4
  216. package/dist/queries/deliveries.d.ts.map +1 -1
  217. package/dist/queries/deliveries.js +69 -16
  218. package/dist/queries/deliveries.js.map +1 -1
  219. package/dist/queries/delivery-gate-state.d.ts +151 -1
  220. package/dist/queries/delivery-gate-state.d.ts.map +1 -1
  221. package/dist/queries/delivery-gate-state.js +95 -14
  222. package/dist/queries/delivery-gate-state.js.map +1 -1
  223. package/dist/queries/delivery-write-discipline.d.ts +65 -0
  224. package/dist/queries/delivery-write-discipline.d.ts.map +1 -0
  225. package/dist/queries/delivery-write-discipline.js +101 -0
  226. package/dist/queries/delivery-write-discipline.js.map +1 -0
  227. package/dist/queries/escalation-consumption.d.ts +11 -0
  228. package/dist/queries/escalation-consumption.d.ts.map +1 -1
  229. package/dist/queries/escalation-consumption.js +22 -0
  230. package/dist/queries/escalation-consumption.js.map +1 -1
  231. package/dist/queries/escalation-spool.d.ts +75 -0
  232. package/dist/queries/escalation-spool.d.ts.map +1 -0
  233. package/dist/queries/escalation-spool.js +232 -0
  234. package/dist/queries/escalation-spool.js.map +1 -0
  235. package/dist/queries/escalation-suppression.d.ts.map +1 -1
  236. package/dist/queries/escalation-suppression.js +2 -0
  237. package/dist/queries/escalation-suppression.js.map +1 -1
  238. package/dist/queries/escalations.js +1 -1
  239. package/dist/queries/filing-observation.d.ts.map +1 -1
  240. package/dist/queries/filing-observation.js +2 -0
  241. package/dist/queries/filing-observation.js.map +1 -1
  242. package/dist/queries/focus-discovery.d.ts +4 -4
  243. package/dist/queries/focus-discovery.d.ts.map +1 -1
  244. package/dist/queries/focus-discovery.js +1 -0
  245. package/dist/queries/focus-discovery.js.map +1 -1
  246. package/dist/queries/focus-review-approval.d.ts +84 -0
  247. package/dist/queries/focus-review-approval.d.ts.map +1 -0
  248. package/dist/queries/focus-review-approval.js +158 -0
  249. package/dist/queries/focus-review-approval.js.map +1 -0
  250. package/dist/queries/focuses.d.ts +6 -5
  251. package/dist/queries/focuses.d.ts.map +1 -1
  252. package/dist/queries/focuses.js +9 -5
  253. package/dist/queries/focuses.js.map +1 -1
  254. package/dist/queries/incident-correlation.d.ts +5 -4
  255. package/dist/queries/incident-correlation.d.ts.map +1 -1
  256. package/dist/queries/incident-correlation.js +11 -5
  257. package/dist/queries/incident-correlation.js.map +1 -1
  258. package/dist/queries/issues.d.ts.map +1 -1
  259. package/dist/queries/issues.js +2 -1
  260. package/dist/queries/issues.js.map +1 -1
  261. package/dist/queries/loop-refusal-observation.d.ts +64 -0
  262. package/dist/queries/loop-refusal-observation.d.ts.map +1 -0
  263. package/dist/queries/loop-refusal-observation.js +137 -0
  264. package/dist/queries/loop-refusal-observation.js.map +1 -0
  265. package/dist/queries/schemas.d.ts +9 -0
  266. package/dist/queries/schemas.d.ts.map +1 -1
  267. package/dist/queries/schemas.js +11 -3
  268. package/dist/queries/schemas.js.map +1 -1
  269. package/dist/queries/shared.js +1 -1
  270. package/dist/queries/verification.d.ts.map +1 -1
  271. package/dist/queries/verification.js +1 -15
  272. package/dist/queries/verification.js.map +1 -1
  273. package/dist/queries/wire-contract.generated.d.ts +3 -0
  274. package/dist/queries/wire-contract.generated.d.ts.map +1 -1
  275. package/dist/queries/wire-contract.generated.js +3 -0
  276. package/dist/queries/wire-contract.generated.js.map +1 -1
  277. package/dist/resolvers/assembly-engine.d.ts.map +1 -1
  278. package/dist/resolvers/assembly-engine.js +3 -1
  279. package/dist/resolvers/assembly-engine.js.map +1 -1
  280. package/dist/resolvers/git-diff-against-base.d.ts +5 -2
  281. package/dist/resolvers/git-diff-against-base.d.ts.map +1 -1
  282. package/dist/resolvers/git-diff-against-base.js +121 -39
  283. package/dist/resolvers/git-diff-against-base.js.map +1 -1
  284. package/dist/resolvers/shared/git-diff.d.ts +2 -0
  285. package/dist/resolvers/shared/git-diff.d.ts.map +1 -1
  286. package/dist/resolvers/shared/git-diff.js +5 -1
  287. package/dist/resolvers/shared/git-diff.js.map +1 -1
  288. package/dist/resolvers/shared/review-window-commits.d.ts +96 -0
  289. package/dist/resolvers/shared/review-window-commits.d.ts.map +1 -0
  290. package/dist/resolvers/shared/review-window-commits.js +262 -0
  291. package/dist/resolvers/shared/review-window-commits.js.map +1 -0
  292. package/dist/session/session-lineage.d.ts.map +1 -1
  293. package/dist/session/session-lineage.js +4 -1
  294. package/dist/session/session-lineage.js.map +1 -1
  295. package/dist/shell/fail-stop.d.ts +18 -0
  296. package/dist/shell/fail-stop.d.ts.map +1 -0
  297. package/dist/shell/fail-stop.js +53 -0
  298. package/dist/shell/fail-stop.js.map +1 -0
  299. package/dist/shell/graceful-shutdown.d.ts +48 -0
  300. package/dist/shell/graceful-shutdown.d.ts.map +1 -0
  301. package/dist/shell/graceful-shutdown.js +152 -0
  302. package/dist/shell/graceful-shutdown.js.map +1 -0
  303. package/dist/shell/heartbeat.d.ts.map +1 -1
  304. package/dist/shell/heartbeat.js +5 -4
  305. package/dist/shell/heartbeat.js.map +1 -1
  306. package/dist/shell/log.d.ts.map +1 -1
  307. package/dist/shell/log.js +4 -1
  308. package/dist/shell/log.js.map +1 -1
  309. package/dist/shell/stop-request.d.ts.map +1 -1
  310. package/dist/shell/stop-request.js +2 -1
  311. package/dist/shell/stop-request.js.map +1 -1
  312. package/dist/shell/unified-shell.d.ts.map +1 -1
  313. package/dist/shell/unified-shell.js +41 -114
  314. package/dist/shell/unified-shell.js.map +1 -1
  315. package/dist/spawn/lifecycle.d.ts +12 -0
  316. package/dist/spawn/lifecycle.d.ts.map +1 -1
  317. package/dist/spawn/lifecycle.js +25 -21
  318. package/dist/spawn/lifecycle.js.map +1 -1
  319. package/dist/spawn/prompt-assembly.d.ts +19 -1
  320. package/dist/spawn/prompt-assembly.d.ts.map +1 -1
  321. package/dist/spawn/prompt-assembly.js +70 -21
  322. package/dist/spawn/prompt-assembly.js.map +1 -1
  323. package/dist/spawn/review-hold-park.d.ts.map +1 -1
  324. package/dist/spawn/review-hold-park.js +18 -8
  325. package/dist/spawn/review-hold-park.js.map +1 -1
  326. package/dist/spawn/spawn-cooldown.d.ts.map +1 -1
  327. package/dist/spawn/spawn-cooldown.js +4 -0
  328. package/dist/spawn/spawn-cooldown.js.map +1 -1
  329. package/dist/spawn/spawn-decision.d.ts.map +1 -1
  330. package/dist/spawn/spawn-decision.js +2 -1
  331. package/dist/spawn/spawn-decision.js.map +1 -1
  332. package/dist/spawn/worktree-session.d.ts +6 -0
  333. package/dist/spawn/worktree-session.d.ts.map +1 -1
  334. package/dist/spawn/worktree-session.js +15 -2
  335. package/dist/spawn/worktree-session.js.map +1 -1
  336. package/dist/testing/fixtures/index.d.ts +10 -1
  337. package/dist/testing/fixtures/index.d.ts.map +1 -1
  338. package/dist/testing/fixtures/index.js +59 -1
  339. package/dist/testing/fixtures/index.js.map +1 -1
  340. package/dist/testing/fixtures/pending-spawn-world.d.ts +34 -0
  341. package/dist/testing/fixtures/pending-spawn-world.d.ts.map +1 -0
  342. package/dist/testing/fixtures/pending-spawn-world.js +92 -0
  343. package/dist/testing/fixtures/pending-spawn-world.js.map +1 -0
  344. package/dist/types/index.js +1 -1
  345. package/dist/verify/commit-gate-configured.d.ts +86 -0
  346. package/dist/verify/commit-gate-configured.d.ts.map +1 -0
  347. package/dist/verify/commit-gate-configured.js +234 -0
  348. package/dist/verify/commit-gate-configured.js.map +1 -0
  349. package/dist/verify/commit-verdict-record.d.ts +98 -0
  350. package/dist/verify/commit-verdict-record.d.ts.map +1 -0
  351. package/dist/verify/commit-verdict-record.js +297 -0
  352. package/dist/verify/commit-verdict-record.js.map +1 -0
  353. package/dist/verify/explicit-gate-outcome.d.ts +161 -0
  354. package/dist/verify/explicit-gate-outcome.d.ts.map +1 -0
  355. package/dist/verify/explicit-gate-outcome.js +215 -0
  356. package/dist/verify/explicit-gate-outcome.js.map +1 -0
  357. package/dist/verify/explicit-rearm.d.ts +27 -0
  358. package/dist/verify/explicit-rearm.d.ts.map +1 -0
  359. package/dist/verify/explicit-rearm.js +161 -0
  360. package/dist/verify/explicit-rearm.js.map +1 -0
  361. package/dist/verify/explicit-run-ledger.d.ts +26 -0
  362. package/dist/verify/explicit-run-ledger.d.ts.map +1 -0
  363. package/dist/verify/explicit-run-ledger.js +93 -0
  364. package/dist/verify/explicit-run-ledger.js.map +1 -0
  365. package/dist/verify/failure-signature.d.ts.map +1 -1
  366. package/dist/verify/failure-signature.js +5 -1
  367. package/dist/verify/failure-signature.js.map +1 -1
  368. package/dist/verify/gate-run-registry.d.ts +105 -0
  369. package/dist/verify/gate-run-registry.d.ts.map +1 -0
  370. package/dist/verify/gate-run-registry.js +111 -0
  371. package/dist/verify/gate-run-registry.js.map +1 -0
  372. package/dist/verify/gate-verdict-source.d.ts +68 -0
  373. package/dist/verify/gate-verdict-source.d.ts.map +1 -0
  374. package/dist/verify/gate-verdict-source.js +143 -0
  375. package/dist/verify/gate-verdict-source.js.map +1 -0
  376. package/dist/verify/judged-commit-gate.d.ts +11 -0
  377. package/dist/verify/judged-commit-gate.d.ts.map +1 -0
  378. package/dist/verify/judged-commit-gate.js +48 -0
  379. package/dist/verify/judged-commit-gate.js.map +1 -0
  380. package/dist/verify/rework-judgment.d.ts +58 -0
  381. package/dist/verify/rework-judgment.d.ts.map +1 -0
  382. package/dist/verify/rework-judgment.js +54 -0
  383. package/dist/verify/rework-judgment.js.map +1 -0
  384. package/dist/verify/verification-attribution.d.ts +105 -0
  385. package/dist/verify/verification-attribution.d.ts.map +1 -0
  386. package/dist/verify/verification-attribution.js +322 -0
  387. package/dist/verify/verification-attribution.js.map +1 -0
  388. package/dist/verify/verification-baseline-run.d.ts +123 -0
  389. package/dist/verify/verification-baseline-run.d.ts.map +1 -0
  390. package/dist/verify/verification-baseline-run.js +386 -0
  391. package/dist/verify/verification-baseline-run.js.map +1 -0
  392. package/dist/verify/verification-baseline.d.ts +79 -33
  393. package/dist/verify/verification-baseline.d.ts.map +1 -1
  394. package/dist/verify/verification-baseline.js +99 -106
  395. package/dist/verify/verification-baseline.js.map +1 -1
  396. package/dist/verify/verification-checkout.d.ts +13 -0
  397. package/dist/verify/verification-checkout.d.ts.map +1 -1
  398. package/dist/verify/verification-checkout.js +39 -2
  399. package/dist/verify/verification-checkout.js.map +1 -1
  400. package/dist/verify/verification-commit-sharing.d.ts +84 -0
  401. package/dist/verify/verification-commit-sharing.d.ts.map +1 -0
  402. package/dist/verify/verification-commit-sharing.js +416 -0
  403. package/dist/verify/verification-commit-sharing.js.map +1 -0
  404. package/dist/verify/verification-config.d.ts.map +1 -1
  405. package/dist/verify/verification-config.js +12 -2
  406. package/dist/verify/verification-config.js.map +1 -1
  407. package/dist/verify/verification-default-on.d.ts +27 -11
  408. package/dist/verify/verification-default-on.d.ts.map +1 -1
  409. package/dist/verify/verification-default-on.js +159 -29
  410. package/dist/verify/verification-default-on.js.map +1 -1
  411. package/dist/verify/verification-deps-default.d.ts.map +1 -1
  412. package/dist/verify/verification-deps-default.js +49 -42
  413. package/dist/verify/verification-deps-default.js.map +1 -1
  414. package/dist/verify/verification-deps.d.ts +69 -4
  415. package/dist/verify/verification-deps.d.ts.map +1 -1
  416. package/dist/verify/verification-deterministic.d.ts +15 -2
  417. package/dist/verify/verification-deterministic.d.ts.map +1 -1
  418. package/dist/verify/verification-deterministic.js +12 -3
  419. package/dist/verify/verification-deterministic.js.map +1 -1
  420. package/dist/verify/verification-diagnostics.d.ts +16 -0
  421. package/dist/verify/verification-diagnostics.d.ts.map +1 -0
  422. package/dist/verify/verification-diagnostics.js +219 -0
  423. package/dist/verify/verification-diagnostics.js.map +1 -0
  424. package/dist/verify/verification-engine.d.ts +12 -8
  425. package/dist/verify/verification-engine.d.ts.map +1 -1
  426. package/dist/verify/verification-engine.js +110 -92
  427. package/dist/verify/verification-engine.js.map +1 -1
  428. package/dist/verify/verification-evidence-unavailable-feedback.d.ts +2 -1
  429. package/dist/verify/verification-evidence-unavailable-feedback.d.ts.map +1 -1
  430. package/dist/verify/verification-evidence-unavailable-feedback.js +14 -4
  431. package/dist/verify/verification-evidence-unavailable-feedback.js.map +1 -1
  432. package/dist/verify/verification-failure-parser.d.ts +37 -3
  433. package/dist/verify/verification-failure-parser.d.ts.map +1 -1
  434. package/dist/verify/verification-failure-parser.js +66 -3
  435. package/dist/verify/verification-failure-parser.js.map +1 -1
  436. package/dist/verify/verification-feedback.d.ts +21 -34
  437. package/dist/verify/verification-feedback.d.ts.map +1 -1
  438. package/dist/verify/verification-feedback.js +37 -88
  439. package/dist/verify/verification-feedback.js.map +1 -1
  440. package/dist/verify/verification-gate-stages.d.ts +110 -0
  441. package/dist/verify/verification-gate-stages.d.ts.map +1 -0
  442. package/dist/verify/verification-gate-stages.js +179 -0
  443. package/dist/verify/verification-gate-stages.js.map +1 -0
  444. package/dist/verify/verification-history-reset.d.ts +61 -0
  445. package/dist/verify/verification-history-reset.d.ts.map +1 -0
  446. package/dist/verify/verification-history-reset.js +90 -0
  447. package/dist/verify/verification-history-reset.js.map +1 -0
  448. package/dist/verify/verification-manifest.d.ts.map +1 -1
  449. package/dist/verify/verification-manifest.js +2 -1
  450. package/dist/verify/verification-manifest.js.map +1 -1
  451. package/dist/verify/verification-rework-messages.d.ts +19 -0
  452. package/dist/verify/verification-rework-messages.d.ts.map +1 -0
  453. package/dist/verify/verification-rework-messages.js +52 -0
  454. package/dist/verify/verification-rework-messages.js.map +1 -0
  455. package/dist/worktree/install-inputs.d.ts +89 -0
  456. package/dist/worktree/install-inputs.d.ts.map +1 -0
  457. package/dist/worktree/install-inputs.js +625 -0
  458. package/dist/worktree/install-inputs.js.map +1 -0
  459. package/dist/worktree/install-script-effects.d.ts +30 -0
  460. package/dist/worktree/install-script-effects.d.ts.map +1 -0
  461. package/dist/worktree/install-script-effects.js +524 -0
  462. package/dist/worktree/install-script-effects.js.map +1 -0
  463. package/dist/worktree/install-script-tokens.d.ts +57 -0
  464. package/dist/worktree/install-script-tokens.d.ts.map +1 -0
  465. package/dist/worktree/install-script-tokens.js +299 -0
  466. package/dist/worktree/install-script-tokens.js.map +1 -0
  467. package/dist/worktree/provision.d.ts +27 -4
  468. package/dist/worktree/provision.d.ts.map +1 -1
  469. package/dist/worktree/provision.js +46 -7
  470. package/dist/worktree/provision.js.map +1 -1
  471. package/dist/worktree/safety.d.ts +11 -0
  472. package/dist/worktree/safety.d.ts.map +1 -1
  473. package/dist/worktree/safety.js +20 -3
  474. package/dist/worktree/safety.js.map +1 -1
  475. package/dist/worktree/verify-interlock.d.ts.map +1 -1
  476. package/dist/worktree/verify-interlock.js +3 -1
  477. package/dist/worktree/verify-interlock.js.map +1 -1
  478. package/dist/worktree/worktree-package-provisioning.d.ts +75 -0
  479. package/dist/worktree/worktree-package-provisioning.d.ts.map +1 -0
  480. package/dist/worktree/worktree-package-provisioning.js +362 -0
  481. package/dist/worktree/worktree-package-provisioning.js.map +1 -0
  482. package/package.json +1 -1
@@ -0,0 +1,89 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/completion/review-window-idle-coding-lead-regression.test.ts,
3
+ // packages/daemon/src/completion/session-hold.test.ts,
4
+ // packages/daemon/src/directive/review-during-hold-terminates-coding.test.ts
5
+ // PINNED-BY-END
6
+ /**
7
+ * Production wiring for the bounded session-hold sweep (session-hold.ts): the
8
+ * live active-team map, the real terminateTeam, the pending spawn-directive
9
+ * queue, and the escalation filer. Split from session-hold.ts so that module
10
+ * stays a leaf (the directive dispatcher and the completion iterator both import
11
+ * it) while this one carries the heavier collaborators; only the poll loop
12
+ * (focus/listener.ts) and tests import it.
13
+ */
14
+ import { ESCALATION_REASONS, ESCALATION_DISPOSITIONS } from '@telora/daemon-core';
15
+ import { getActiveTeams } from '../focus/focus-team-state.js';
16
+ import { getPendingSpawnDirective } from '../directive/directive-queue.js';
17
+ import { createEscalation as defaultCreateEscalation } from '../queries/escalations.js';
18
+ import { NO_HUMAN_ACT } from '../queries/filing-observation.js';
19
+ import { terminateTeam, forceReapTeam } from './team-lifecycle.js';
20
+ import { SESSION_HOLD_TEARDOWN_MAX_ATTEMPTS } from './session-hold.js';
21
+ /** metadata.cause stamped on a session-hold expiry escalation. */
22
+ export const SESSION_HOLD_EXPIRED_CAUSE = 'session_hold_expired';
23
+ function describeStillActive({ hold, team, elapsedMs, reason }) {
24
+ return {
25
+ description: `A ${hold.kind} session hold kept the team for focus "${team.focusName}" alive for ${Math.round(elapsedMs / 1000)}s, ` +
26
+ `past its ${Math.round(hold.maxMs / 1000)}s bound, and the team is still active (${reason}).\n\n` +
27
+ `**Focus ID:** ${hold.focusId}\n\n` +
28
+ `The hold has re-windowed once: if the team is still held when that window lapses, the daemon ` +
29
+ `tears it down.`,
30
+ whatWasTried: `Kept the team alive under a bounded ${hold.kind} hold; the bound lapsed while the team kept working.`,
31
+ helpNeeded: `Read the team's session log and decide whether the work it is doing belongs to this pass; ` +
32
+ `if not, stop the team so the queued pass can spawn.`,
33
+ };
34
+ }
35
+ function describeTeardownUnsignalable({ hold, team, reason }) {
36
+ return {
37
+ description: `A ${hold.kind} session hold on focus "${team.focusName}" expired (${reason}), but the daemon could not ` +
38
+ `signal the team lead to tear it down in ${SESSION_HOLD_TEARDOWN_MAX_ATTEMPTS} attempts ` +
39
+ `(lead pid: ${team.leadPid ?? 'none recorded'}). It force-reaped the team's registration -- released its ` +
40
+ `session slot and dropped it from the active-team map -- so the queued pass can spawn.\n\n` +
41
+ `**Focus ID:** ${hold.focusId}`,
42
+ whatWasTried: `Retried the ${hold.kind} teardown ${SESSION_HOLD_TEARDOWN_MAX_ATTEMPTS} times (terminateTeam found no ` +
43
+ `signalable lead each time), then force-reaped the registration.`,
44
+ helpNeeded: `Confirm no orphaned lead process for this focus is still running against its worktree` +
45
+ `${team.leadPid ? ` (pid ${team.leadPid})` : ''}; if one is, stop it before the next pass works the worktree.`,
46
+ };
47
+ }
48
+ /**
49
+ * File the ONE escalation a hold expiry owes: a still-active kept team, or a
50
+ * teardown that could not signal the lead and ended in a forced registration
51
+ * reap. Both are agent work (read the log / check for an orphan process) -- no
52
+ * human act -- so the filing chokepoint sends them to the machine lane as
53
+ * observations.
54
+ */
55
+ export async function fileSessionHoldExpiryEscalation(expired, deps = { createEscalation: defaultCreateEscalation }) {
56
+ const { hold, team, elapsedMs, cause } = expired;
57
+ const forced = cause === 'teardown_unsignalable';
58
+ await deps.createEscalation({
59
+ organizationId: team.organizationId,
60
+ sessionId: team.leadSessionId ?? '',
61
+ issueId: null,
62
+ reasonType: ESCALATION_REASONS.ERROR_ENCOUNTERED,
63
+ disposition: ESCALATION_DISPOSITIONS.NEEDS_OPERATOR,
64
+ humanAct: NO_HUMAN_ACT,
65
+ anchor: { focusId: hold.focusId },
66
+ metadata: {
67
+ cause: SESSION_HOLD_EXPIRED_CAUSE, hold_kind: hold.kind, expiry_cause: cause, elapsed_ms: elapsedMs, max_ms: hold.maxMs,
68
+ ...(forced ? { forced_cleanup: true, teardown_attempts: SESSION_HOLD_TEARDOWN_MAX_ATTEMPTS } : {}),
69
+ },
70
+ ...(forced ? describeTeardownUnsignalable(expired) : describeStillActive(expired)),
71
+ });
72
+ }
73
+ /** The production sweep deps; tests override individual collaborators. */
74
+ export function buildSessionHoldSweepDeps(overrides = {}) {
75
+ return {
76
+ getActiveTeam: (focusId) => getActiveTeams().get(focusId),
77
+ terminateTeam: (focusId, shutdownReason) => terminateTeam(focusId, shutdownReason),
78
+ forceReapTeam: async (focusId, shutdownReason) => {
79
+ // Deferred: the governor binding lives in the spawn graph (focus-executor).
80
+ // This path is rarely hit, so keep that graph out of the sweep's static imports.
81
+ const { getGovernor } = await import('../focus/focus-executor.js');
82
+ return forceReapTeam(focusId, shutdownReason, { governor: getGovernor() });
83
+ },
84
+ fileEscalation: (expired) => fileSessionHoldExpiryEscalation(expired),
85
+ isDirectiveStillQueued: (focusId, contentHash) => getPendingSpawnDirective(focusId)?.contentHash === contentHash,
86
+ ...overrides,
87
+ };
88
+ }
89
+ //# sourceMappingURL=session-hold-sweep-deps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-hold-sweep-deps.js","sourceRoot":"","sources":["../../src/completion/session-hold-sweep-deps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Bounded session holds: every daemon decision that KEEPS a team alive (or
3
+ * defers the queued directive that would replace it) records a hold here, and
4
+ * the poll loop sweeps the holds each tick. A hold carries its own bound and the
5
+ * outcome its expiry fires -- teardown or escalation -- so no keep is open-ended.
6
+ *
7
+ * Why (2026-09-15, daemon v0.22.104): an idle coding lead in a review window was
8
+ * kept by review-window routing ('leave_running', no expiry) while the queued
9
+ * review directive was deferred behind the same young team
10
+ * ('defer_young_divergence', "stays queued for the natural exit", no expiry). The
11
+ * lead waited on the review and the review waited on the lead's exit; the review
12
+ * spawned only after an operator killed the lead 800s+ later. Each hold was
13
+ * locally reasonable; the missing piece was a bound on either of them.
14
+ *
15
+ * A hold is keyed to the focus AND the team identity (team.startedAt) it was
16
+ * recorded against, so a hold never outlives its team: the sweep drops a hold
17
+ * whose team exited or was replaced. Re-recording a hold for the same team keeps
18
+ * the original clock -- a kept team emitting result after result cannot extend
19
+ * its own bound.
20
+ *
21
+ * Expiry policy per kind (resolveSessionHoldExpiry):
22
+ * - young_team_directive_deferral: teardown (shutdownReason 'handoff', the same
23
+ * outcome the past-window 'respawn' decision takes) iff the deferred directive
24
+ * is still queued; a consumed/replaced directive drops the hold silently.
25
+ * - merge_resolution: teardown iff resolvingMergeConflict is STILL set past
26
+ * requestTeamLeadResolution's own bounded wait; else drop.
27
+ * - review_window_keep_alive / first_result_teardown_demoted (keep-alives):
28
+ * no agent activity since the hold was recorded -> teardown. Still active ->
29
+ * ONE escalation, and the hold re-windows; its next expiry ends in teardown.
30
+ *
31
+ * A teardown that cannot signal the lead (terminateTeam returns false: no lead
32
+ * pid, or the signal threw) does NOT drop the hold -- a dropped hold would leave
33
+ * the stale active-team entry excluding the focus from the pending-spawn pass
34
+ * with nothing bounding it. The hold re-windows by SESSION_HOLD_TEARDOWN_RETRY_MS
35
+ * and retries; the SESSION_HOLD_TEARDOWN_MAX_ATTEMPTS-th failure clears the hold,
36
+ * force-reaps the registration (team-lifecycle forceReapTeam: the reapers' own
37
+ * reclamation), and files ONE escalation.
38
+ *
39
+ * Every fired expiry logs exactly:
40
+ * [session-hold] <kind> hold on focus <id8> expired after <N>s -- fired: teardown|escalation (<reason>)
41
+ * and a teardown that could not signal the lead follows it with:
42
+ * [session-hold] <kind> hold on focus <id8> teardown attempt <n>/<max> found no signalable lead -- fired: teardown_retry|forced_cleanup (...)
43
+ *
44
+ * Pure registry + sweep: collaborators arrive through SessionHoldSweepDeps (the
45
+ * production wiring lives in session-hold-sweep-deps.ts) so this module stays a
46
+ * leaf the directive dispatcher and the completion iterator can both import.
47
+ */
48
+ import type { FocusTeamState } from '../types/index.js';
49
+ /** The keep/defer decisions a hold bounds. */
50
+ export type SessionHoldKind = 'review_window_keep_alive' | 'young_team_directive_deferral' | 'first_result_teardown_demoted' | 'merge_resolution';
51
+ /** What an expired hold fires. */
52
+ export type SessionHoldExpiry = 'teardown' | 'escalation';
53
+ /**
54
+ * What a sweep actually did for an expired hold: its expiry outcome, or -- when
55
+ * the teardown could not signal the lead -- a bounded retry or the terminal
56
+ * forced cleanup (registration reaped + one escalation).
57
+ */
58
+ export type SessionHoldFired = SessionHoldExpiry | 'teardown_retry' | 'forced_cleanup';
59
+ /** Teardown attempts an expired hold makes before it force-reaps the team registration. */
60
+ export declare const SESSION_HOLD_TEARDOWN_MAX_ATTEMPTS = 3;
61
+ /** Re-window between teardown attempts whose lead could not be signalled. */
62
+ export declare const SESSION_HOLD_TEARDOWN_RETRY_MS = 60000;
63
+ /** A declared bound: how long a hold may stand and what its expiry fires. */
64
+ export interface SessionHoldBound {
65
+ kind: SessionHoldKind;
66
+ maxMs: number;
67
+ onExpire: SessionHoldExpiry;
68
+ }
69
+ /** Bound on keeping a coding pass alive inside a review window while it still has actionable work. */
70
+ export declare const REVIEW_WINDOW_KEEP_ALIVE_MAX_MS: number;
71
+ /** Bound on the demoted (observe-only) teardown-at-first-result keep. */
72
+ export declare const FIRST_RESULT_DEMOTED_KEEP_MAX_MS: number;
73
+ /**
74
+ * Bound on the merge-resolution completion hold. Set ABOVE
75
+ * requestTeamLeadResolution's 300s wait (merge/focus-merge.ts
76
+ * MERGE_CONFLICT_RESOLUTION_TIMEOUT_MS), whose finally clears the flag -- so the
77
+ * hold only fires when that self-limit failed to run. Pinned by session-hold.test.ts.
78
+ */
79
+ export declare const MERGE_RESOLUTION_HOLD_MAX_MS: number;
80
+ /** Grace past the spawn-guard window before a deferred directive tears the young team down. */
81
+ export declare const YOUNG_TEAM_DEFERRAL_GRACE_MS = 5000;
82
+ export declare const REVIEW_WINDOW_KEEP_ALIVE_BOUND: SessionHoldBound;
83
+ export declare const MERGE_RESOLUTION_HOLD_BOUND: SessionHoldBound;
84
+ export declare const FIRST_RESULT_DEMOTED_KEEP_BOUND: SessionHoldBound;
85
+ /** The shutdown reason each kind's teardown stamps (read by the exit classifier + cooldown). */
86
+ export declare const SESSION_HOLD_TEARDOWN_REASON: Readonly<Record<SessionHoldKind, FocusTeamState['shutdownReason']>>;
87
+ /** A recorded hold. */
88
+ export interface SessionHold extends SessionHoldBound {
89
+ focusId: string;
90
+ reason: string;
91
+ /** Team identity the hold was recorded against (team.startedAt epoch ms). */
92
+ teamStartedAtMs: number;
93
+ recordedAtMs: number;
94
+ /** young_team_directive_deferral only: the deferred directive's contentHash. */
95
+ directiveHash?: string;
96
+ /** Set once the hold's expiry filed its one escalation; the next expiry tears down. */
97
+ escalated?: boolean;
98
+ /**
99
+ * Teardown attempts that could not signal the lead so far. Each re-windows the
100
+ * hold by SESSION_HOLD_TEARDOWN_RETRY_MS; the attempt that reaches
101
+ * SESSION_HOLD_TEARDOWN_MAX_ATTEMPTS force-reaps instead.
102
+ */
103
+ teardownAttempts?: number;
104
+ }
105
+ export interface RecordSessionHoldInput extends SessionHoldBound {
106
+ focusId: string;
107
+ reason: string;
108
+ teamStartedAt: Date;
109
+ nowMs: number;
110
+ directiveHash?: string;
111
+ }
112
+ /**
113
+ * Record (or refresh) a hold. Re-recording for the SAME team identity keeps the
114
+ * original clock, bound, and escalation state -- a re-record can never extend a
115
+ * bound. A different team identity replaces the hold with a fresh one.
116
+ */
117
+ export declare function recordSessionHold(input: RecordSessionHoldInput): SessionHold;
118
+ /**
119
+ * Record the bounded young-team directive deferral: the directive waits for the
120
+ * young team only until the spawn-guard window (measured from team.startedAt)
121
+ * lapses, plus a small grace.
122
+ */
123
+ export declare function recordYoungTeamDeferralHold(args: {
124
+ focusId: string;
125
+ teamStartedAt: Date;
126
+ contentHash: string;
127
+ nowMs: number;
128
+ }): SessionHold;
129
+ /** Clear one kind of hold for a focus, or every hold on it when kind is omitted. */
130
+ export declare function clearSessionHold(focusId: string, kind?: SessionHoldKind): void;
131
+ /** Read the holds currently recorded for a focus (snapshot copies). */
132
+ export declare function getSessionHolds(focusId: string): SessionHold[];
133
+ /** Test-only: drop every recorded hold. */
134
+ export declare function __resetSessionHoldsForTesting(): void;
135
+ /** The team facts the expiry policy reads (structural slice of FocusTeamState). */
136
+ export type SessionHoldTeam = Pick<FocusTeamState, 'startedAt' | 'lastActivityAt' | 'resolvingMergeConflict' | 'organizationId' | 'focusName' | 'leadSessionId' | 'leadPid'>;
137
+ /**
138
+ * Why an expiry files an escalation: the kept team is still active past its
139
+ * bound, or its teardown could not signal the lead and the registration was
140
+ * force-reaped.
141
+ */
142
+ export type SessionHoldEscalationCause = 'still_active' | 'teardown_unsignalable';
143
+ /** What an expiry that files an escalation hands the filer. */
144
+ export interface ExpiredSessionHold {
145
+ hold: SessionHold;
146
+ team: SessionHoldTeam;
147
+ elapsedMs: number;
148
+ reason: string;
149
+ cause: SessionHoldEscalationCause;
150
+ }
151
+ export interface SessionHoldSweepDeps {
152
+ getActiveTeam: (focusId: string) => SessionHoldTeam | undefined;
153
+ terminateTeam: (focusId: string, shutdownReason: FocusTeamState['shutdownReason']) => boolean;
154
+ /** Force-reclaim a registration whose teardown could not signal the lead; true iff one was reaped. */
155
+ forceReapTeam: (focusId: string, shutdownReason: FocusTeamState['shutdownReason']) => Promise<boolean>;
156
+ fileEscalation: (expired: ExpiredSessionHold) => Promise<void>;
157
+ /** True while a pending spawn directive with this contentHash is still queued for the focus. */
158
+ isDirectiveStillQueued: (focusId: string, contentHash: string) => boolean;
159
+ }
160
+ export interface FiredSessionHold {
161
+ focusId: string;
162
+ kind: SessionHoldKind;
163
+ fired: SessionHoldFired;
164
+ elapsedMs: number;
165
+ reason: string;
166
+ }
167
+ /**
168
+ * Decide what an expired hold fires, re-checking the condition that justified
169
+ * it. Pure; exported for test.
170
+ */
171
+ export declare function resolveSessionHoldExpiry(hold: SessionHold, team: SessionHoldTeam, isDirectiveStillQueued: SessionHoldSweepDeps['isDirectiveStillQueued']): {
172
+ outcome: SessionHoldExpiry | 'drop';
173
+ detail: string;
174
+ };
175
+ /**
176
+ * Sweep every recorded hold once. A hold whose team exited or was replaced is
177
+ * dropped; an expired hold fires its (re-checked) outcome. Returns what fired.
178
+ */
179
+ export declare function sweepExpiredSessionHolds(nowMs: number, deps: SessionHoldSweepDeps): Promise<FiredSessionHold[]>;
180
+ //# sourceMappingURL=session-hold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-hold.d.ts","sourceRoot":"","sources":["../../src/completion/session-hold.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,238 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/completion/completion-event-phase-registry.test.ts,
3
+ // packages/daemon/src/completion/review-window-idle-coding-lead-regression.test.ts,
4
+ // packages/daemon/src/completion/review-window-no-premature-teardown.test.ts,
5
+ // packages/daemon/src/completion/session-hold.test.ts,
6
+ // packages/daemon/src/completion/teardown-demotion-gate.test.ts,
7
+ // packages/daemon/src/directive/review-during-hold-terminates-coding.test.ts
8
+ // PINNED-BY-END
9
+ import { SPAWN_GUARD_WINDOW_MS } from '../directive/directive-queue.js';
10
+ import { createLogger } from '../shell/log.js';
11
+ const log = createLogger({ module: 'session-hold' });
12
+ /** Teardown attempts an expired hold makes before it force-reaps the team registration. */
13
+ export const SESSION_HOLD_TEARDOWN_MAX_ATTEMPTS = 3;
14
+ /** Re-window between teardown attempts whose lead could not be signalled. */
15
+ export const SESSION_HOLD_TEARDOWN_RETRY_MS = 60_000;
16
+ /** Bound on keeping a coding pass alive inside a review window while it still has actionable work. */
17
+ export const REVIEW_WINDOW_KEEP_ALIVE_MAX_MS = 10 * 60_000;
18
+ /** Bound on the demoted (observe-only) teardown-at-first-result keep. */
19
+ export const FIRST_RESULT_DEMOTED_KEEP_MAX_MS = 10 * 60_000;
20
+ /**
21
+ * Bound on the merge-resolution completion hold. Set ABOVE
22
+ * requestTeamLeadResolution's 300s wait (merge/focus-merge.ts
23
+ * MERGE_CONFLICT_RESOLUTION_TIMEOUT_MS), whose finally clears the flag -- so the
24
+ * hold only fires when that self-limit failed to run. Pinned by session-hold.test.ts.
25
+ */
26
+ export const MERGE_RESOLUTION_HOLD_MAX_MS = 6 * 60_000;
27
+ /** Grace past the spawn-guard window before a deferred directive tears the young team down. */
28
+ export const YOUNG_TEAM_DEFERRAL_GRACE_MS = 5_000;
29
+ export const REVIEW_WINDOW_KEEP_ALIVE_BOUND = {
30
+ kind: 'review_window_keep_alive', maxMs: REVIEW_WINDOW_KEEP_ALIVE_MAX_MS, onExpire: 'teardown',
31
+ };
32
+ export const MERGE_RESOLUTION_HOLD_BOUND = {
33
+ kind: 'merge_resolution', maxMs: MERGE_RESOLUTION_HOLD_MAX_MS, onExpire: 'teardown',
34
+ };
35
+ export const FIRST_RESULT_DEMOTED_KEEP_BOUND = {
36
+ kind: 'first_result_teardown_demoted', maxMs: FIRST_RESULT_DEMOTED_KEEP_MAX_MS, onExpire: 'teardown',
37
+ };
38
+ /** The shutdown reason each kind's teardown stamps (read by the exit classifier + cooldown). */
39
+ export const SESSION_HOLD_TEARDOWN_REASON = {
40
+ young_team_directive_deferral: 'handoff',
41
+ merge_resolution: 'teardown',
42
+ review_window_keep_alive: 'teardown',
43
+ first_result_teardown_demoted: 'no_actionable_work',
44
+ };
45
+ const holds = new Map();
46
+ function teamIdentityMs(startedAt) {
47
+ return startedAt instanceof Date ? startedAt.getTime() : Number.NaN;
48
+ }
49
+ /**
50
+ * Record (or refresh) a hold. Re-recording for the SAME team identity keeps the
51
+ * original clock, bound, and escalation state -- a re-record can never extend a
52
+ * bound. A different team identity replaces the hold with a fresh one.
53
+ */
54
+ export function recordSessionHold(input) {
55
+ const byKind = holds.get(input.focusId) ?? new Map();
56
+ const teamStartedAtMs = teamIdentityMs(input.teamStartedAt);
57
+ const prior = byKind.get(input.kind);
58
+ const hold = prior !== undefined && prior.teamStartedAtMs === teamStartedAtMs
59
+ ? { ...prior, reason: input.reason, ...(input.directiveHash !== undefined ? { directiveHash: input.directiveHash } : {}) }
60
+ : {
61
+ focusId: input.focusId,
62
+ kind: input.kind,
63
+ reason: input.reason,
64
+ maxMs: input.maxMs,
65
+ onExpire: input.onExpire,
66
+ teamStartedAtMs,
67
+ recordedAtMs: input.nowMs,
68
+ ...(input.directiveHash !== undefined ? { directiveHash: input.directiveHash } : {}),
69
+ };
70
+ byKind.set(input.kind, hold);
71
+ holds.set(input.focusId, byKind);
72
+ return hold;
73
+ }
74
+ /**
75
+ * Record the bounded young-team directive deferral: the directive waits for the
76
+ * young team only until the spawn-guard window (measured from team.startedAt)
77
+ * lapses, plus a small grace.
78
+ */
79
+ export function recordYoungTeamDeferralHold(args) {
80
+ const deadlineMs = teamIdentityMs(args.teamStartedAt) + SPAWN_GUARD_WINDOW_MS + YOUNG_TEAM_DEFERRAL_GRACE_MS;
81
+ return recordSessionHold({
82
+ focusId: args.focusId,
83
+ kind: 'young_team_directive_deferral',
84
+ maxMs: Math.max(0, deadlineMs - args.nowMs),
85
+ onExpire: 'teardown',
86
+ reason: 'a divergent spawn directive was deferred behind a young team',
87
+ teamStartedAt: args.teamStartedAt,
88
+ nowMs: args.nowMs,
89
+ directiveHash: args.contentHash,
90
+ });
91
+ }
92
+ /** Clear one kind of hold for a focus, or every hold on it when kind is omitted. */
93
+ export function clearSessionHold(focusId, kind) {
94
+ if (kind === undefined) {
95
+ holds.delete(focusId);
96
+ return;
97
+ }
98
+ const byKind = holds.get(focusId);
99
+ if (!byKind)
100
+ return;
101
+ byKind.delete(kind);
102
+ if (byKind.size === 0)
103
+ holds.delete(focusId);
104
+ }
105
+ /** Read the holds currently recorded for a focus (snapshot copies). */
106
+ export function getSessionHolds(focusId) {
107
+ return [...(holds.get(focusId)?.values() ?? [])].map((h) => ({ ...h }));
108
+ }
109
+ /** Test-only: drop every recorded hold. */
110
+ export function __resetSessionHoldsForTesting() {
111
+ holds.clear();
112
+ }
113
+ /**
114
+ * Decide what an expired hold fires, re-checking the condition that justified
115
+ * it. Pure; exported for test.
116
+ */
117
+ export function resolveSessionHoldExpiry(hold, team, isDirectiveStillQueued) {
118
+ if (hold.kind === 'young_team_directive_deferral') {
119
+ return hold.directiveHash !== undefined && isDirectiveStillQueued(hold.focusId, hold.directiveHash)
120
+ ? { outcome: 'teardown', detail: 'the deferred spawn directive is still queued behind this team' }
121
+ : { outcome: 'drop', detail: 'the deferred spawn directive was consumed or replaced' };
122
+ }
123
+ if (hold.kind === 'merge_resolution') {
124
+ return team.resolvingMergeConflict
125
+ ? { outcome: hold.onExpire, detail: 'the merge-conflict resolution flag is still set past its bounded wait' }
126
+ : { outcome: 'drop', detail: 'the merge-conflict resolution already ended' };
127
+ }
128
+ // A keep-alive whose teardown already failed stays on the teardown path: the
129
+ // decision was made, and activity cannot re-open it into an escalation.
130
+ if ((hold.teardownAttempts ?? 0) > 0) {
131
+ return { outcome: 'teardown', detail: 'retrying a teardown whose lead could not be signalled' };
132
+ }
133
+ const activeSinceRecorded = (team.lastActivityAt ?? Number.NEGATIVE_INFINITY) > hold.recordedAtMs;
134
+ if (!activeSinceRecorded)
135
+ return { outcome: hold.onExpire, detail: 'no agent activity since the hold was recorded' };
136
+ if (hold.escalated)
137
+ return { outcome: 'teardown', detail: 'still active after the escalated bound' };
138
+ return { outcome: 'escalation', detail: 'the kept team is still active' };
139
+ }
140
+ function holdTag(hold) {
141
+ return `[session-hold] ${hold.kind} hold on focus ${hold.focusId.slice(0, 8)}`;
142
+ }
143
+ async function fireExpiredHold(hold, team, nowMs, deps) {
144
+ const elapsedMs = nowMs - hold.recordedAtMs;
145
+ const { outcome, detail } = resolveSessionHoldExpiry(hold, team, deps.isDirectiveStillQueued);
146
+ if (outcome === 'drop') {
147
+ clearSessionHold(hold.focusId, hold.kind);
148
+ log.debug(`${holdTag(hold)} dropped at expiry (${detail})`);
149
+ return null;
150
+ }
151
+ const reason = `${hold.reason}; ${detail}`;
152
+ log.warn(`${holdTag(hold)} expired after ${Math.round(elapsedMs / 1000)}s -- fired: ${outcome} (${reason})`);
153
+ const expired = { hold, team, elapsedMs, reason, cause: 'still_active' };
154
+ const fired = outcome === 'teardown'
155
+ ? await fireTeardown(expired, nowMs, deps)
156
+ : await fireEscalation(expired, nowMs, deps);
157
+ return { focusId: hold.focusId, kind: hold.kind, fired, elapsedMs, reason };
158
+ }
159
+ async function fileHoldEscalation(expired, deps) {
160
+ try {
161
+ await deps.fileEscalation(expired);
162
+ }
163
+ catch (err) {
164
+ log.warn(`${holdTag(expired.hold)} escalation filing failed: ${err.message}`);
165
+ }
166
+ }
167
+ /**
168
+ * One filing per expiry, never repeated for this hold: re-window it so the NEXT
169
+ * expiry ends in teardown rather than a second escalation.
170
+ */
171
+ async function fireEscalation(expired, nowMs, deps) {
172
+ const { hold } = expired;
173
+ holds.get(hold.focusId)?.set(hold.kind, { ...hold, escalated: true, recordedAtMs: nowMs });
174
+ await fileHoldEscalation(expired, deps);
175
+ return 'escalation';
176
+ }
177
+ /**
178
+ * Tear the held team down. A teardown that cannot signal the lead keeps the hold
179
+ * and re-windows it for a bounded retry; the last allowed attempt force-reaps.
180
+ */
181
+ async function fireTeardown(expired, nowMs, deps) {
182
+ const { hold } = expired;
183
+ if (deps.terminateTeam(hold.focusId, SESSION_HOLD_TEARDOWN_REASON[hold.kind])) {
184
+ clearSessionHold(hold.focusId, hold.kind);
185
+ return 'teardown';
186
+ }
187
+ const attempts = (hold.teardownAttempts ?? 0) + 1;
188
+ const attemptNote = `teardown attempt ${attempts}/${SESSION_HOLD_TEARDOWN_MAX_ATTEMPTS} found no signalable lead`;
189
+ if (attempts >= SESSION_HOLD_TEARDOWN_MAX_ATTEMPTS)
190
+ return forceCleanup(expired, attemptNote, deps);
191
+ holds.get(hold.focusId)?.set(hold.kind, {
192
+ ...hold, teardownAttempts: attempts, recordedAtMs: nowMs, maxMs: SESSION_HOLD_TEARDOWN_RETRY_MS,
193
+ });
194
+ log.warn(`${holdTag(hold)} ${attemptNote} -- fired: teardown_retry ` +
195
+ `(hold re-windowed for ${Math.round(SESSION_HOLD_TEARDOWN_RETRY_MS / 1000)}s)`);
196
+ return 'teardown_retry';
197
+ }
198
+ /**
199
+ * Terminal outcome of a teardown that never reached the lead: clear the hold,
200
+ * force-reap the stale registration (so the pending-spawn pass stops excluding
201
+ * the focus), and file ONE escalation naming the forced cleanup.
202
+ */
203
+ async function forceCleanup(expired, attemptNote, deps) {
204
+ const { hold } = expired;
205
+ clearSessionHold(hold.focusId, hold.kind);
206
+ let registration;
207
+ try {
208
+ registration = await deps.forceReapTeam(hold.focusId, SESSION_HOLD_TEARDOWN_REASON[hold.kind]) ? 'reaped' : 'already gone';
209
+ }
210
+ catch (err) {
211
+ registration = `reap failed: ${err.message}`;
212
+ }
213
+ log.warn(`${holdTag(hold)} ${attemptNote} -- fired: forced_cleanup (registration ${registration}; escalated; ${expired.reason})`);
214
+ await fileHoldEscalation({ ...expired, cause: 'teardown_unsignalable' }, deps);
215
+ return 'forced_cleanup';
216
+ }
217
+ /**
218
+ * Sweep every recorded hold once. A hold whose team exited or was replaced is
219
+ * dropped; an expired hold fires its (re-checked) outcome. Returns what fired.
220
+ */
221
+ export async function sweepExpiredSessionHolds(nowMs, deps) {
222
+ const fired = [];
223
+ const snapshot = [...holds.values()].flatMap((byKind) => [...byKind.values()]);
224
+ for (const hold of snapshot) {
225
+ const team = deps.getActiveTeam(hold.focusId);
226
+ if (!team || teamIdentityMs(team.startedAt) !== hold.teamStartedAtMs) {
227
+ clearSessionHold(hold.focusId, hold.kind);
228
+ continue;
229
+ }
230
+ if (nowMs - hold.recordedAtMs < hold.maxMs)
231
+ continue;
232
+ const result = await fireExpiredHold(hold, team, nowMs, deps);
233
+ if (result)
234
+ fired.push(result);
235
+ }
236
+ return fired;
237
+ }
238
+ //# sourceMappingURL=session-hold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-hold.js","sourceRoot":"","sources":["../../src/completion/session-hold.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import type { DaemonConfig, PipelineConfig } from '../types/index.js';
2
2
  import type { FocusDeliveryInfo } from '../types/index.js';
3
3
  import { type SettleSweepOutcome } from './settle-injection-sweep.js';
4
4
  import { type FocusExecutionPhase } from '../focus/focus-phase.js';
5
+ import { type ReviewNextStepIssue } from './review-next-step.js';
5
6
  /** Injectable dependencies for cascade functions (testing). */
6
7
  export interface CascadeDeps {
7
8
  getFocusDeliveries: (focusId: string) => Promise<FocusDeliveryInfo[]>;
@@ -37,6 +38,24 @@ export interface CascadeDeps {
37
38
  * object omitting it behaves as before (no hold).
38
39
  */
39
40
  hasOpenBreakerHold?: (focusId: string) => Promise<boolean>;
41
+ /**
42
+ * Whether the review-cycle cap holds the focus (focus/review-cycle-cap-hold.ts):
43
+ * its review loop reached TELORA_REVIEW_CYCLE_CAP without converging. The same
44
+ * hold every spawn gate reads; checkAutoReview declines to open the window while
45
+ * held. Fails CLOSED (unlike hasOpenBreakerHold). Wired per focus by
46
+ * runFocusCascadePass, which holds the row's review_cycle_count; a partial test
47
+ * deps object omitting it behaves as before (no hold).
48
+ */
49
+ isReviewCycleCapHeld?: (focusId: string) => Promise<boolean>;
50
+ /**
51
+ * The focus's issues, read by checkAutoReview for the open-work half of the
52
+ * shared review-next-step decision (completion/review-next-step.ts) -- read
53
+ * only once the focus has converged on verify with review enabled. A read
54
+ * failure fails OPEN (the window opens on the delivery census, as before).
55
+ * Optional: present in the default deps so production always applies the
56
+ * open-work matrix; a partial test deps object omitting it reads no issues.
57
+ */
58
+ getFocusIssues?: (focusId: string) => Promise<readonly ReviewNextStepIssue[]>;
40
59
  }
41
60
  /**
42
61
  * Whether a settle sweep's outcome permits latching the focus as swept (quiet
@@ -1 +1 @@
1
- {"version":3,"file":"state-cascade.d.ts","sourceRoot":"","sources":["../../src/completion/state-cascade.ts"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAU3D,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAoB,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAoBrF,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACtE,oBAAoB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,sBAAsB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D;;;;;;;;;OASG;IACH,qBAAqB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE;;;;;;;;;;;OAWG;IACH,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5D;AAqCD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAExE;AAcD;;;GAGG;AACH,wBAAgB,iCAAiC,IAAI,IAAI,CAGxD;AA8BD,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,mBAAmB,EAC1B,cAAc,EAAE,cAAc,GAAG,IAAI,EACrC,iBAAiB,EAAE,MAAM,GAAG,IAAI,EAChC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,IAAI,GAAE,WAAyB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAyFf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,mBAAmB,EAC1B,iBAAiB,EAAE,MAAM,GAAG,IAAI,EAChC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,kBAAkB,EAAE,MAAM,GAAG,IAAI,EACjC,IAAI,GAAE,WAAyB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAsEf;AAiJD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB1E"}
1
+ {"version":3,"file":"state-cascade.d.ts","sourceRoot":"","sources":["../../src/completion/state-cascade.ts"],"names":[],"mappings":"AA6CA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAW3D,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAoB,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAA8C,KAAK,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAqB7G,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACtE,oBAAoB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,sBAAsB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D;;;;;;;;;OASG;IACH,qBAAqB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE;;;;;;;;;;;OAWG;IACH,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7D;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC,CAAC;CAC/E;AAsCD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAExE;AAcD;;;GAGG;AACH,wBAAgB,iCAAiC,IAAI,IAAI,CAGxD;AA2ED,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,mBAAmB,EAC1B,cAAc,EAAE,cAAc,GAAG,IAAI,EACrC,iBAAiB,EAAE,MAAM,GAAG,IAAI,EAChC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,IAAI,GAAE,WAAyB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAgFf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,mBAAmB,EAC1B,iBAAiB,EAAE,MAAM,GAAG,IAAI,EAChC,UAAU,EAAE,iBAAiB,EAAE,EAC/B,kBAAkB,EAAE,MAAM,GAAG,IAAI,EACjC,IAAI,GAAE,WAAyB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAsEf;AA4JD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB1E"}