crewly 1.20.362 → 1.20.363

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 (262) hide show
  1. package/config/hooks/destructive-git-guard/guard.mjs +96 -0
  2. package/config/skills/agent/core/ask-owner/SKILL.md +31 -0
  3. package/config/skills/agent/core/ask-owner/execute.sh +14 -3
  4. package/config/skills/agent/core/ask-owner/execute.test.sh +8 -0
  5. package/config/skills/agent/core/gmail-read/SKILL.md +8 -0
  6. package/config/skills/agent/core/gmail-send/SKILL.md +10 -3
  7. package/config/skills/agent/core/gmail-send/execute.sh +2 -1
  8. package/config/skills/agent/core/gmail-watch-thread/SKILL.md +69 -0
  9. package/config/skills/agent/core/gmail-watch-thread/execute.sh +51 -0
  10. package/config/skills/agent/core/project-tickets/SKILL.md +12 -0
  11. package/config/skills/agent/core/project-tickets/execute.sh +13 -3
  12. package/config/skills/agent/core/project-tickets/execute.test.sh +4 -0
  13. package/config/skills/agent/core/watch-for-event/SKILL.md +22 -0
  14. package/config/skills/orchestrator/harness-login/SKILL.md +1 -1
  15. package/dist/backend/backend/src/constants.d.ts +63 -2
  16. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  17. package/dist/backend/backend/src/constants.js +64 -3
  18. package/dist/backend/backend/src/constants.js.map +1 -1
  19. package/dist/backend/backend/src/controllers/google/google.controller.d.ts +44 -0
  20. package/dist/backend/backend/src/controllers/google/google.controller.d.ts.map +1 -1
  21. package/dist/backend/backend/src/controllers/google/google.controller.js +121 -3
  22. package/dist/backend/backend/src/controllers/google/google.controller.js.map +1 -1
  23. package/dist/backend/backend/src/controllers/google/google.routes.d.ts.map +1 -1
  24. package/dist/backend/backend/src/controllers/google/google.routes.js +5 -1
  25. package/dist/backend/backend/src/controllers/google/google.routes.js.map +1 -1
  26. package/dist/backend/backend/src/controllers/harness/owner-login.controller.d.ts +1 -1
  27. package/dist/backend/backend/src/controllers/harness/owner-login.controller.js +1 -1
  28. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts +1 -1
  29. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts.map +1 -1
  30. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js +2 -1
  31. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js.map +1 -1
  32. package/dist/backend/backend/src/index.d.ts.map +1 -1
  33. package/dist/backend/backend/src/index.js +61 -0
  34. package/dist/backend/backend/src/index.js.map +1 -1
  35. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
  36. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +2 -1
  37. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
  38. package/dist/backend/backend/src/services/decisions/decision-card.d.ts +46 -13
  39. package/dist/backend/backend/src/services/decisions/decision-card.d.ts.map +1 -1
  40. package/dist/backend/backend/src/services/decisions/decision-card.js +100 -50
  41. package/dist/backend/backend/src/services/decisions/decision-card.js.map +1 -1
  42. package/dist/backend/backend/src/services/decisions/decision-contract.d.ts +23 -1
  43. package/dist/backend/backend/src/services/decisions/decision-contract.d.ts.map +1 -1
  44. package/dist/backend/backend/src/services/decisions/decision-contract.js +76 -4
  45. package/dist/backend/backend/src/services/decisions/decision-contract.js.map +1 -1
  46. package/dist/backend/backend/src/services/decisions/decision-wording.d.ts +167 -0
  47. package/dist/backend/backend/src/services/decisions/decision-wording.d.ts.map +1 -0
  48. package/dist/backend/backend/src/services/decisions/decision-wording.js +406 -0
  49. package/dist/backend/backend/src/services/decisions/decision-wording.js.map +1 -0
  50. package/dist/backend/backend/src/services/decisions/decision.service.d.ts +30 -1
  51. package/dist/backend/backend/src/services/decisions/decision.service.d.ts.map +1 -1
  52. package/dist/backend/backend/src/services/decisions/decision.service.js +44 -8
  53. package/dist/backend/backend/src/services/decisions/decision.service.js.map +1 -1
  54. package/dist/backend/backend/src/services/decisions/decision.wiring.d.ts.map +1 -1
  55. package/dist/backend/backend/src/services/decisions/decision.wiring.js +17 -0
  56. package/dist/backend/backend/src/services/decisions/decision.wiring.js.map +1 -1
  57. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
  58. package/dist/backend/backend/src/services/event-bus/event-bus.service.js +1 -0
  59. package/dist/backend/backend/src/services/event-bus/event-bus.service.js.map +1 -1
  60. package/dist/backend/backend/src/services/google/gmail-reply-watch.service.d.ts +142 -0
  61. package/dist/backend/backend/src/services/google/gmail-reply-watch.service.d.ts.map +1 -0
  62. package/dist/backend/backend/src/services/google/gmail-reply-watch.service.js +304 -0
  63. package/dist/backend/backend/src/services/google/gmail-reply-watch.service.js.map +1 -0
  64. package/dist/backend/backend/src/services/google/gmail-send-approval.service.d.ts +130 -0
  65. package/dist/backend/backend/src/services/google/gmail-send-approval.service.d.ts.map +1 -0
  66. package/dist/backend/backend/src/services/google/gmail-send-approval.service.js +216 -0
  67. package/dist/backend/backend/src/services/google/gmail-send-approval.service.js.map +1 -0
  68. package/dist/backend/backend/src/services/google/gmail-send-gate.d.ts +28 -13
  69. package/dist/backend/backend/src/services/google/gmail-send-gate.d.ts.map +1 -1
  70. package/dist/backend/backend/src/services/google/gmail-send-gate.js +82 -29
  71. package/dist/backend/backend/src/services/google/gmail-send-gate.js.map +1 -1
  72. package/dist/backend/backend/src/services/google/gmail.service.d.ts +90 -0
  73. package/dist/backend/backend/src/services/google/gmail.service.d.ts.map +1 -1
  74. package/dist/backend/backend/src/services/google/gmail.service.js +122 -0
  75. package/dist/backend/backend/src/services/google/gmail.service.js.map +1 -1
  76. package/dist/backend/backend/src/services/harness/claude-accounts.d.ts +24 -14
  77. package/dist/backend/backend/src/services/harness/claude-accounts.d.ts.map +1 -1
  78. package/dist/backend/backend/src/services/harness/claude-accounts.js +35 -21
  79. package/dist/backend/backend/src/services/harness/claude-accounts.js.map +1 -1
  80. package/dist/backend/backend/src/services/harness/claude-native-login.d.ts +106 -0
  81. package/dist/backend/backend/src/services/harness/claude-native-login.d.ts.map +1 -0
  82. package/dist/backend/backend/src/services/harness/claude-native-login.js +174 -0
  83. package/dist/backend/backend/src/services/harness/claude-native-login.js.map +1 -0
  84. package/dist/backend/backend/src/services/harness/claude-token-migration.service.d.ts +158 -0
  85. package/dist/backend/backend/src/services/harness/claude-token-migration.service.d.ts.map +1 -0
  86. package/dist/backend/backend/src/services/harness/claude-token-migration.service.js +283 -0
  87. package/dist/backend/backend/src/services/harness/claude-token-migration.service.js.map +1 -0
  88. package/dist/backend/backend/src/services/harness/harness-credentials.store.d.ts +44 -24
  89. package/dist/backend/backend/src/services/harness/harness-credentials.store.d.ts.map +1 -1
  90. package/dist/backend/backend/src/services/harness/harness-credentials.store.js +96 -39
  91. package/dist/backend/backend/src/services/harness/harness-credentials.store.js.map +1 -1
  92. package/dist/backend/backend/src/services/harness/harness-registry.js +1 -1
  93. package/dist/backend/backend/src/services/harness/harness-registry.js.map +1 -1
  94. package/dist/backend/backend/src/services/harness/harness-relogin.service.d.ts +2 -2
  95. package/dist/backend/backend/src/services/harness/harness-relogin.service.js +2 -2
  96. package/dist/backend/backend/src/services/harness/harness.service.d.ts.map +1 -1
  97. package/dist/backend/backend/src/services/harness/harness.service.js +10 -1
  98. package/dist/backend/backend/src/services/harness/harness.service.js.map +1 -1
  99. package/dist/backend/backend/src/services/harness/login-broker.service.d.ts +24 -21
  100. package/dist/backend/backend/src/services/harness/login-broker.service.d.ts.map +1 -1
  101. package/dist/backend/backend/src/services/harness/login-broker.service.js +50 -64
  102. package/dist/backend/backend/src/services/harness/login-broker.service.js.map +1 -1
  103. package/dist/backend/backend/src/services/harness/login-rules.d.ts +17 -11
  104. package/dist/backend/backend/src/services/harness/login-rules.d.ts.map +1 -1
  105. package/dist/backend/backend/src/services/harness/login-rules.js +22 -25
  106. package/dist/backend/backend/src/services/harness/login-rules.js.map +1 -1
  107. package/dist/backend/backend/src/services/open-items/open-item-extractor.d.ts +36 -0
  108. package/dist/backend/backend/src/services/open-items/open-item-extractor.d.ts.map +1 -1
  109. package/dist/backend/backend/src/services/open-items/open-item-extractor.js +70 -0
  110. package/dist/backend/backend/src/services/open-items/open-item-extractor.js.map +1 -1
  111. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts +25 -0
  112. package/dist/backend/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
  113. package/dist/backend/backend/src/services/open-items/open-items.service.js +65 -5
  114. package/dist/backend/backend/src/services/open-items/open-items.service.js.map +1 -1
  115. package/dist/backend/backend/src/services/project-tickets/project-ticket.service.d.ts +5 -0
  116. package/dist/backend/backend/src/services/project-tickets/project-ticket.service.d.ts.map +1 -1
  117. package/dist/backend/backend/src/services/project-tickets/project-ticket.service.js +30 -6
  118. package/dist/backend/backend/src/services/project-tickets/project-ticket.service.js.map +1 -1
  119. package/dist/backend/backend/src/services/project-tickets/ticket-file.d.ts.map +1 -1
  120. package/dist/backend/backend/src/services/project-tickets/ticket-file.js +6 -1
  121. package/dist/backend/backend/src/services/project-tickets/ticket-file.js.map +1 -1
  122. package/dist/backend/backend/src/services/project-tickets/ticket-hold-registry.d.ts +64 -0
  123. package/dist/backend/backend/src/services/project-tickets/ticket-hold-registry.d.ts.map +1 -0
  124. package/dist/backend/backend/src/services/project-tickets/ticket-hold-registry.js +93 -0
  125. package/dist/backend/backend/src/services/project-tickets/ticket-hold-registry.js.map +1 -0
  126. package/dist/backend/backend/src/services/project-tickets/ticket-hold.d.ts +176 -0
  127. package/dist/backend/backend/src/services/project-tickets/ticket-hold.d.ts.map +1 -0
  128. package/dist/backend/backend/src/services/project-tickets/ticket-hold.js +301 -0
  129. package/dist/backend/backend/src/services/project-tickets/ticket-hold.js.map +1 -0
  130. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts +33 -3
  131. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts.map +1 -1
  132. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js +50 -4
  133. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js.map +1 -1
  134. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts +8 -1
  135. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts.map +1 -1
  136. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js +26 -0
  137. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js.map +1 -1
  138. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts +6 -1
  139. package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
  140. package/dist/backend/backend/src/services/reconciler/reconciler.service.js +3 -2
  141. package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
  142. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.d.ts.map +1 -1
  143. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.js +4 -1
  144. package/dist/backend/backend/src/services/runtime-fallback/runtime-fallback.wiring.js.map +1 -1
  145. package/dist/backend/backend/src/services/stall/stall-watcher.service.d.ts +34 -0
  146. package/dist/backend/backend/src/services/stall/stall-watcher.service.d.ts.map +1 -1
  147. package/dist/backend/backend/src/services/stall/stall-watcher.service.js +70 -2
  148. package/dist/backend/backend/src/services/stall/stall-watcher.service.js.map +1 -1
  149. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.d.ts +3 -0
  150. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.d.ts.map +1 -1
  151. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.js +5 -2
  152. package/dist/backend/backend/src/services/worktree/worktree-janitor.service.js.map +1 -1
  153. package/dist/backend/backend/src/services/worktree/worktree-unmerged-notice.d.ts +7 -2
  154. package/dist/backend/backend/src/services/worktree/worktree-unmerged-notice.d.ts.map +1 -1
  155. package/dist/backend/backend/src/services/worktree/worktree-unmerged-notice.js +11 -2
  156. package/dist/backend/backend/src/services/worktree/worktree-unmerged-notice.js.map +1 -1
  157. package/dist/backend/backend/src/types/decision.types.d.ts +53 -1
  158. package/dist/backend/backend/src/types/decision.types.d.ts.map +1 -1
  159. package/dist/backend/backend/src/types/event-bus.types.d.ts +4 -2
  160. package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
  161. package/dist/backend/backend/src/types/event-bus.types.js +8 -0
  162. package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
  163. package/dist/backend/backend/src/types/project-ticket.types.d.ts +7 -0
  164. package/dist/backend/backend/src/types/project-ticket.types.d.ts.map +1 -1
  165. package/dist/backend/backend/src/types/project-ticket.types.js +1 -0
  166. package/dist/backend/backend/src/types/project-ticket.types.js.map +1 -1
  167. package/dist/backend/backend/src/types/v2/open-item.types.d.ts +8 -1
  168. package/dist/backend/backend/src/types/v2/open-item.types.d.ts.map +1 -1
  169. package/dist/backend/build-info.json +2 -2
  170. package/dist/cli/backend/src/constants.d.ts +63 -2
  171. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  172. package/dist/cli/backend/src/constants.js +64 -3
  173. package/dist/cli/backend/src/constants.js.map +1 -1
  174. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
  175. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js +2 -1
  176. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
  177. package/dist/cli/backend/src/services/decisions/decision-card.d.ts +46 -13
  178. package/dist/cli/backend/src/services/decisions/decision-card.d.ts.map +1 -1
  179. package/dist/cli/backend/src/services/decisions/decision-card.js +100 -50
  180. package/dist/cli/backend/src/services/decisions/decision-card.js.map +1 -1
  181. package/dist/cli/backend/src/services/decisions/decision-contract.d.ts +23 -1
  182. package/dist/cli/backend/src/services/decisions/decision-contract.d.ts.map +1 -1
  183. package/dist/cli/backend/src/services/decisions/decision-contract.js +76 -4
  184. package/dist/cli/backend/src/services/decisions/decision-contract.js.map +1 -1
  185. package/dist/cli/backend/src/services/decisions/decision-wording.d.ts +167 -0
  186. package/dist/cli/backend/src/services/decisions/decision-wording.d.ts.map +1 -0
  187. package/dist/cli/backend/src/services/decisions/decision-wording.js +406 -0
  188. package/dist/cli/backend/src/services/decisions/decision-wording.js.map +1 -0
  189. package/dist/cli/backend/src/services/decisions/decision.service.d.ts +30 -1
  190. package/dist/cli/backend/src/services/decisions/decision.service.d.ts.map +1 -1
  191. package/dist/cli/backend/src/services/decisions/decision.service.js +44 -8
  192. package/dist/cli/backend/src/services/decisions/decision.service.js.map +1 -1
  193. package/dist/cli/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
  194. package/dist/cli/backend/src/services/event-bus/event-bus.service.js +1 -0
  195. package/dist/cli/backend/src/services/event-bus/event-bus.service.js.map +1 -1
  196. package/dist/cli/backend/src/services/harness/claude-accounts.d.ts +24 -14
  197. package/dist/cli/backend/src/services/harness/claude-accounts.d.ts.map +1 -1
  198. package/dist/cli/backend/src/services/harness/claude-accounts.js +35 -21
  199. package/dist/cli/backend/src/services/harness/claude-accounts.js.map +1 -1
  200. package/dist/cli/backend/src/services/harness/claude-native-login.d.ts +106 -0
  201. package/dist/cli/backend/src/services/harness/claude-native-login.d.ts.map +1 -0
  202. package/dist/cli/backend/src/services/harness/claude-native-login.js +174 -0
  203. package/dist/cli/backend/src/services/harness/claude-native-login.js.map +1 -0
  204. package/dist/cli/backend/src/services/harness/claude-token-migration.service.d.ts +158 -0
  205. package/dist/cli/backend/src/services/harness/claude-token-migration.service.d.ts.map +1 -0
  206. package/dist/cli/backend/src/services/harness/claude-token-migration.service.js +283 -0
  207. package/dist/cli/backend/src/services/harness/claude-token-migration.service.js.map +1 -0
  208. package/dist/cli/backend/src/services/harness/harness-credentials.store.d.ts +44 -24
  209. package/dist/cli/backend/src/services/harness/harness-credentials.store.d.ts.map +1 -1
  210. package/dist/cli/backend/src/services/harness/harness-credentials.store.js +96 -39
  211. package/dist/cli/backend/src/services/harness/harness-credentials.store.js.map +1 -1
  212. package/dist/cli/backend/src/services/harness/harness-registry.js +1 -1
  213. package/dist/cli/backend/src/services/harness/harness-registry.js.map +1 -1
  214. package/dist/cli/backend/src/services/harness/harness-relogin.service.d.ts +2 -2
  215. package/dist/cli/backend/src/services/harness/harness-relogin.service.js +2 -2
  216. package/dist/cli/backend/src/services/harness/harness.service.d.ts.map +1 -1
  217. package/dist/cli/backend/src/services/harness/harness.service.js +10 -1
  218. package/dist/cli/backend/src/services/harness/harness.service.js.map +1 -1
  219. package/dist/cli/backend/src/services/harness/login-broker.service.d.ts +24 -21
  220. package/dist/cli/backend/src/services/harness/login-broker.service.d.ts.map +1 -1
  221. package/dist/cli/backend/src/services/harness/login-broker.service.js +50 -64
  222. package/dist/cli/backend/src/services/harness/login-broker.service.js.map +1 -1
  223. package/dist/cli/backend/src/services/harness/login-rules.d.ts +17 -11
  224. package/dist/cli/backend/src/services/harness/login-rules.d.ts.map +1 -1
  225. package/dist/cli/backend/src/services/harness/login-rules.js +22 -25
  226. package/dist/cli/backend/src/services/harness/login-rules.js.map +1 -1
  227. package/dist/cli/backend/src/services/open-items/open-item-extractor.d.ts +36 -0
  228. package/dist/cli/backend/src/services/open-items/open-item-extractor.d.ts.map +1 -1
  229. package/dist/cli/backend/src/services/open-items/open-item-extractor.js +70 -0
  230. package/dist/cli/backend/src/services/open-items/open-item-extractor.js.map +1 -1
  231. package/dist/cli/backend/src/services/open-items/open-items.service.d.ts +25 -0
  232. package/dist/cli/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
  233. package/dist/cli/backend/src/services/open-items/open-items.service.js +65 -5
  234. package/dist/cli/backend/src/services/open-items/open-items.service.js.map +1 -1
  235. package/dist/cli/backend/src/services/orc/owner-completion-report.text.d.ts +86 -0
  236. package/dist/cli/backend/src/services/orc/owner-completion-report.text.d.ts.map +1 -0
  237. package/dist/cli/backend/src/services/orc/owner-completion-report.text.js +170 -0
  238. package/dist/cli/backend/src/services/orc/owner-completion-report.text.js.map +1 -0
  239. package/dist/cli/backend/src/services/project-tickets/project-ticket.service.d.ts +5 -0
  240. package/dist/cli/backend/src/services/project-tickets/project-ticket.service.d.ts.map +1 -1
  241. package/dist/cli/backend/src/services/project-tickets/project-ticket.service.js +30 -6
  242. package/dist/cli/backend/src/services/project-tickets/project-ticket.service.js.map +1 -1
  243. package/dist/cli/backend/src/services/project-tickets/ticket-file.d.ts.map +1 -1
  244. package/dist/cli/backend/src/services/project-tickets/ticket-file.js +6 -1
  245. package/dist/cli/backend/src/services/project-tickets/ticket-file.js.map +1 -1
  246. package/dist/cli/backend/src/services/project-tickets/ticket-hold.d.ts +176 -0
  247. package/dist/cli/backend/src/services/project-tickets/ticket-hold.d.ts.map +1 -0
  248. package/dist/cli/backend/src/services/project-tickets/ticket-hold.js +301 -0
  249. package/dist/cli/backend/src/services/project-tickets/ticket-hold.js.map +1 -0
  250. package/dist/cli/backend/src/types/decision.types.d.ts +53 -1
  251. package/dist/cli/backend/src/types/decision.types.d.ts.map +1 -1
  252. package/dist/cli/backend/src/types/event-bus.types.d.ts +4 -2
  253. package/dist/cli/backend/src/types/event-bus.types.d.ts.map +1 -1
  254. package/dist/cli/backend/src/types/event-bus.types.js +8 -0
  255. package/dist/cli/backend/src/types/event-bus.types.js.map +1 -1
  256. package/dist/cli/backend/src/types/project-ticket.types.d.ts +7 -0
  257. package/dist/cli/backend/src/types/project-ticket.types.d.ts.map +1 -1
  258. package/dist/cli/backend/src/types/project-ticket.types.js +1 -0
  259. package/dist/cli/backend/src/types/project-ticket.types.js.map +1 -1
  260. package/dist/cli/backend/src/types/v2/open-item.types.d.ts +8 -1
  261. package/dist/cli/backend/src/types/v2/open-item.types.d.ts.map +1 -1
  262. package/package.json +1 -1
@@ -0,0 +1,301 @@
1
+ /**
2
+ * Ticket holds (crewly#1369 gap 1) — pure rules.
3
+ *
4
+ * A ticket is on hold when the owner said to stop: "do not merge PR #1138, do
5
+ * not ask Steve". Before this module the hold lived only as a Log line, and
6
+ * nothing read it: days later a janitor notice about the same worktree became
7
+ * a new ticket ("Decide the fate of OPEN PR #1138") and a "merge?" card to the
8
+ * owner, who tapped Yes without recognising it.
9
+ *
10
+ * A hold is read from (first match wins):
11
+ * - the `hold` frontmatter field (set through the ticket update path);
12
+ * - a hold label ({@link TICKET_HOLD_CONSTANTS.LABELS});
13
+ * - legacy Log lines: "HOLD: …", "on hold", "do not merge", "不要合并", "owner
14
+ * said no" — unless a later Log line lifts it ("hold lifted").
15
+ *
16
+ * Held work is matched by what it names: PR numbers, branches and worktrees
17
+ * (a worktree named `wt-crew257` also names ticket CREW-257). On held work the
18
+ * only allowed action is {@link TICKET_HOLD_CONSTANTS.ALLOWED_ACTIONS}.
19
+ *
20
+ * @module services/project-tickets/ticket-hold
21
+ */
22
+ import { TICKET_HOLD_CONSTANTS } from '../../constants.js';
23
+ /** Uppercase HOLD as a word (not "holder", not "household"), and not "HOLD lifted". */
24
+ const HOLD_WORD = /(?:^|[\s:([\-—·*_"'`])HOLD\b(?![\s:]*(?:lifted|released|cleared|removed|off)\b)/;
25
+ /** Other ways to say it in a Log line. */
26
+ const HOLD_PHRASES = /\bon[\s-]hold\b|\b(?:do not|don't|dont|must not|mustn't|never|not to) (?:merge|ship|land)\b|\bowner (?:said|says|answered) (?:no|"no"|'no')\b|(?:不要|别|不准|先不|暂不|暂时不)(?:要)?(?:合并|合入|合进|merge)|暂停|搁置/iu;
27
+ /** A Log line that lifts a hold. */
28
+ const LIFT_PHRASES = /\bhold (?:lifted|released|cleared|removed)\b|\bunhold\b|\boff hold\b|\blift(?:ed)? the hold\b|解除(?:暂停|搁置|hold)|取消暂停/iu;
29
+ /**
30
+ * The message part of a Log line (`<iso> · <actor> · <message>`).
31
+ *
32
+ * @param line - Log line (without `- `)
33
+ * @returns The message
34
+ */
35
+ function logMessage(line) {
36
+ const parts = line.split(' · ');
37
+ return parts.length >= 3 ? parts.slice(2).join(' · ') : line;
38
+ }
39
+ /**
40
+ * Clip a reason for quoting.
41
+ *
42
+ * @param s - Text
43
+ * @returns One line of at most {@link TICKET_HOLD_CONSTANTS.REASON_MAX_CHARS}
44
+ */
45
+ export function clipHoldReason(s) {
46
+ const flat = s.replace(/\s+/g, ' ').trim();
47
+ const max = TICKET_HOLD_CONSTANTS.REASON_MAX_CHARS;
48
+ return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;
49
+ }
50
+ /**
51
+ * Whether a Log message puts the ticket on hold.
52
+ *
53
+ * @param message - Log message
54
+ * @returns True for "HOLD: …", "on hold", "do not merge", "不要合并", …
55
+ */
56
+ export function isHoldLogMessage(message) {
57
+ if (LIFT_PHRASES.test(message))
58
+ return false;
59
+ return HOLD_WORD.test(message) || HOLD_PHRASES.test(message);
60
+ }
61
+ /**
62
+ * Whether a Log message lifts a hold.
63
+ *
64
+ * @param message - Log message
65
+ * @returns True for "hold lifted", "unhold", …
66
+ */
67
+ export function isLiftLogMessage(message) {
68
+ return LIFT_PHRASES.test(message);
69
+ }
70
+ /**
71
+ * The ticket id in a linked hold reason ("held by CREW-257: …").
72
+ *
73
+ * @param reason - Hold reason
74
+ * @returns The id, or undefined
75
+ */
76
+ function heldByOf(reason) {
77
+ const m = new RegExp(`^${TICKET_HOLD_CONSTANTS.LINKED_PREFIX}\\s+([A-Za-z0-9]+-\\d+)\\b`, 'i').exec(reason.trim());
78
+ return m ? m[1].toUpperCase() : undefined;
79
+ }
80
+ /**
81
+ * A ticket's hold, or null when it is not held.
82
+ *
83
+ * @param t - Ticket
84
+ * @returns The hold
85
+ *
86
+ * @example
87
+ * readTicketHold({ ...t, log: ['2026-10-06T10:00:00Z · crewly-orc · HOLD: PR #1138: do not merge'] })
88
+ * // → { reason: 'HOLD: PR #1138: do not merge', source: 'log' }
89
+ */
90
+ export function readTicketHold(t) {
91
+ const field = typeof t.hold === 'string' ? t.hold.trim() : '';
92
+ if (field) {
93
+ const heldBy = heldByOf(field);
94
+ return { reason: clipHoldReason(field), source: 'field', ...(heldBy ? { heldBy } : {}) };
95
+ }
96
+ // The latest hold / lift line in the Log decides.
97
+ let fromLog = null;
98
+ for (const line of t.log ?? []) {
99
+ const message = logMessage(line);
100
+ if (isLiftLogMessage(message))
101
+ fromLog = null;
102
+ else if (isHoldLogMessage(message))
103
+ fromLog = message;
104
+ }
105
+ const labels = (t.labels ?? []).map((l) => l.toLowerCase());
106
+ if (labels.some((l) => TICKET_HOLD_CONSTANTS.LABELS.includes(l))) {
107
+ return { reason: clipHoldReason(fromLog ?? `labelled ${labels.find((l) => TICKET_HOLD_CONSTANTS.LABELS.includes(l))}`), source: 'label' };
108
+ }
109
+ return fromLog ? { reason: clipHoldReason(fromLog), source: 'log' } : null;
110
+ }
111
+ /**
112
+ * Ticket id a worktree folder names: `wt-crew257` / `wt-crew-257` → `CREW-257`.
113
+ *
114
+ * @param name - Worktree folder name
115
+ * @returns The id, or null
116
+ */
117
+ export function ticketIdOfWorktree(name) {
118
+ const m = /^wt-([a-z][a-z0-9]{0,9}?)-?(\d{1,6})$/i.exec(name.trim());
119
+ return m ? `${m[1].toUpperCase()}-${Number(m[2])}` : null;
120
+ }
121
+ /** Branch prefixes that make a `<prefix>/<name>` word a branch. */
122
+ const BRANCH_PREFIX = '(?:feat|feature|fix|bugfix|hotfix|chore|docs|refactor|perf|test|tests|release|ci|build|style|crew|agent|wip)';
123
+ /**
124
+ * PR numbers, branches, worktrees and ticket ids named in a text.
125
+ *
126
+ * Conservative: a bare `#123` is not a PR (issues use it too); a PR is
127
+ * "PR #123", "PR 123", "pull request #123" or a `/pull/123` link. Ticket ids
128
+ * come only from worktree names (`wt-crew257`), not from free text — a ticket
129
+ * that merely mentions another one is not the same work.
130
+ *
131
+ * @param text - Any text
132
+ * @returns The refs (deduplicated)
133
+ */
134
+ export function extractWorkRefs(text) {
135
+ const prs = new Set();
136
+ const branches = new Set();
137
+ const worktrees = new Set();
138
+ const tickets = new Set();
139
+ const src = String(text ?? '');
140
+ for (const m of src.matchAll(/\b(?:PR|pull request|pull)\s*#?\s*(\d{1,7})\b/gi))
141
+ prs.add(Number(m[1]));
142
+ for (const m of src.matchAll(/\/pull\/(\d{1,7})\b/g))
143
+ prs.add(Number(m[1]));
144
+ const clean = (b) => b.replace(/[.,;:)\]}'"`>]+$/, '').toLowerCase();
145
+ for (const m of src.matchAll(/\b(?:branch|分支)\s*[`'"]?([A-Za-z0-9._-]+\/[A-Za-z0-9._/-]+)/giu))
146
+ branches.add(clean(m[1]));
147
+ for (const m of src.matchAll(new RegExp(`(?:^|[\\s\`'"(\\[])(${BRANCH_PREFIX}\\/[A-Za-z0-9._/-]+)`, 'gi')))
148
+ branches.add(clean(m[1]));
149
+ for (const m of src.matchAll(/(?:^|[\s/`'"(\[])(wt-[A-Za-z0-9._-]+)/g)) {
150
+ const name = clean(m[1]);
151
+ worktrees.add(name);
152
+ const id = ticketIdOfWorktree(name);
153
+ if (id)
154
+ tickets.add(id);
155
+ }
156
+ return { prs: [...prs], branches: [...branches].filter((b) => b.length > 0), worktrees: [...worktrees], tickets: [...tickets] };
157
+ }
158
+ /**
159
+ * Merge several refs.
160
+ *
161
+ * @param all - Refs
162
+ * @returns Union
163
+ */
164
+ export function mergeWorkRefs(...all) {
165
+ const uniq = (xs) => [...new Set(xs)];
166
+ return {
167
+ prs: uniq(all.flatMap((r) => r.prs)),
168
+ branches: uniq(all.flatMap((r) => r.branches)),
169
+ worktrees: uniq(all.flatMap((r) => r.worktrees)),
170
+ tickets: uniq(all.flatMap((r) => r.tickets)),
171
+ };
172
+ }
173
+ /**
174
+ * Refs of a branch and worktree path (the janitor's view of a worktree).
175
+ *
176
+ * @param branch - Branch, or null
177
+ * @param worktreePath - Worktree path
178
+ * @returns Refs
179
+ */
180
+ export function worktreeRefs(branch, worktreePath) {
181
+ const name = (worktreePath.replace(/[\\/]+$/, '').split(/[\\/]/).pop() ?? '').toLowerCase();
182
+ const id = ticketIdOfWorktree(name);
183
+ return { prs: [], branches: branch ? [branch.toLowerCase()] : [], worktrees: name ? [name] : [], tickets: id ? [id] : [] };
184
+ }
185
+ /**
186
+ * Everything a ticket names: title, description, Log and the frontmatter keys
187
+ * a human may add (`pr`, `branch`, `worktree`).
188
+ *
189
+ * @param t - Ticket
190
+ * @returns Refs
191
+ */
192
+ export function ticketWorkRefs(t) {
193
+ const extra = t.extra ?? {};
194
+ const prField = extra.pr !== undefined && extra.pr !== null && /^\d+$/.test(String(extra.pr)) ? `PR #${extra.pr}` : '';
195
+ const branch = typeof extra.branch === 'string' ? extra.branch.trim().toLowerCase() : '';
196
+ const worktreeField = typeof extra.worktree === 'string' && extra.worktree.trim() ? ` ${extra.worktree.trim()}` : '';
197
+ const fromText = extractWorkRefs([t.title, t.description, ...(t.log ?? []), prField, worktreeField].join('\n'));
198
+ return branch ? mergeWorkRefs(fromText, { prs: [], branches: [branch], worktrees: [], tickets: [] }) : fromText;
199
+ }
200
+ /**
201
+ * Which held tickets the given refs point at.
202
+ *
203
+ * @param refs - What the new work names
204
+ * @param tickets - Candidate tickets (any status)
205
+ * @param opts - `excludeId`: the ticket being checked itself
206
+ * @returns Matches, tickets held in their own right first
207
+ */
208
+ export function findHeldMatches(refs, tickets, opts = {}) {
209
+ const out = [];
210
+ for (const t of tickets) {
211
+ if (opts.excludeId && t.id.toLowerCase() === opts.excludeId.toLowerCase())
212
+ continue;
213
+ const hold = readTicketHold(t);
214
+ if (!hold)
215
+ continue;
216
+ const own = ticketWorkRefs(t);
217
+ const matchedOn = [];
218
+ for (const n of refs.prs)
219
+ if (own.prs.includes(n))
220
+ matchedOn.push(`PR #${n}`);
221
+ for (const b of refs.branches)
222
+ if (own.branches.includes(b))
223
+ matchedOn.push(`branch ${b}`);
224
+ for (const w of refs.worktrees)
225
+ if (own.worktrees.includes(w))
226
+ matchedOn.push(`worktree ${w}`);
227
+ if (refs.tickets.includes(t.id.toUpperCase()))
228
+ matchedOn.push(`ticket ${t.id}`);
229
+ if (matchedOn.length === 0)
230
+ continue;
231
+ out.push({ ticketId: t.id, title: t.title, ...(t.projectPath ? { projectPath: t.projectPath } : {}), hold, matchedOn });
232
+ }
233
+ return out.sort((a, b) => Number(!!a.hold.heldBy) - Number(!!b.hold.heldBy));
234
+ }
235
+ /**
236
+ * The hold reason written on a ticket held through another one.
237
+ *
238
+ * @param match - The held ticket it references
239
+ * @returns `held by CREW-257: <reason>`
240
+ */
241
+ export function linkedHoldReason(match) {
242
+ const root = match.hold.heldBy ?? match.ticketId;
243
+ const reason = match.hold.reason.replace(new RegExp(`^${TICKET_HOLD_CONSTANTS.LINKED_PREFIX}\\s+[A-Za-z0-9]+-\\d+:\\s*`, 'i'), '');
244
+ return clipHoldReason(`${TICKET_HOLD_CONSTANTS.LINKED_PREFIX} ${root}: ${reason}`);
245
+ }
246
+ /**
247
+ * The note put at the top of a held follow-up ticket's description, so the
248
+ * agent who picks it up reads the hold before anything else.
249
+ *
250
+ * @param match - The held ticket
251
+ * @returns One paragraph
252
+ */
253
+ export function heldDescriptionNote(match) {
254
+ const root = match.hold.heldBy ?? match.ticketId;
255
+ return (`ON HOLD (${root}, matched on ${match.matchedOn.join(', ')}): "${match.hold.reason}". ` +
256
+ `Allowed actions: ${TICKET_HOLD_CONSTANTS.ALLOWED_ACTIONS} only. Do not merge it, and do not ask the owner to merge it.`);
257
+ }
258
+ /** Merge-style words: the card would move held work forward. */
259
+ const MERGE_WORDS = /\bmerg(?:e|es|ed|ing)\b|\bship(?:ping)? it\b|\bland(?:ing)? it\b|\bgo ahead\b|\bproceed\b|\bcontinue\b|\bresume\b|\bdeploy\b|合并|合入|合进|上线|继续|部署/iu;
260
+ /** Close-style words. */
261
+ const CLOSE_WORDS = /\bclos(?:e|es|ed|ing)\b|\bdrop\b|\babandon\b|\bdiscard\b|\bremove\b|\bdelete\b|关闭|关掉|关了|删掉|删除|放弃|丢掉/iu;
262
+ /** Negated merge phrases that a close question may quote ("you said do not merge"). */
263
+ const NEGATED_MERGE = /\b(?:do not|don't|dont|not|never|no|without)\s+(?:merg(?:e|ing)|ship(?:ping)?|land(?:ing)?)\b|(?:不要|别|不|没|先不|暂不)(?:要)?(?:合并|合入|合进)/giu;
264
+ /**
265
+ * Whether a card only asks to close / drop held work.
266
+ *
267
+ * @param text - Question plus option labels
268
+ * @returns True for "Close PR #1138?" with no merge option
269
+ */
270
+ export function isCloseOnlyAsk(text) {
271
+ const stripped = text.replace(NEGATED_MERGE, ' ');
272
+ return CLOSE_WORDS.test(stripped) && !MERGE_WORDS.test(stripped);
273
+ }
274
+ /**
275
+ * Why a decision card about held work is refused, or null when it may go up.
276
+ *
277
+ * @param text - Question, option labels and details
278
+ * @param matches - Held tickets it references
279
+ * @returns The refusal (quotes the hold), or null
280
+ */
281
+ export function decisionHoldRefusal(text, matches) {
282
+ if (matches.length === 0 || isCloseOnlyAsk(text))
283
+ return null;
284
+ const m = matches[0];
285
+ const root = m.hold.heldBy ?? m.ticketId;
286
+ return (`${root} is on hold (${m.matchedOn.join(', ')}): "${m.hold.reason}". ` +
287
+ `The only allowed action is to ${TICKET_HOLD_CONSTANTS.ALLOWED_ACTIONS}. Do not ask the owner to merge or continue it. ` +
288
+ `If you need the owner, ask whether to close it (e.g. "Close PR …? You put it on hold on ${root}."), or lift the hold on ${root} first if the owner said so.`);
289
+ }
290
+ /**
291
+ * The line the janitor's unmerged-worktree notice carries for held work.
292
+ *
293
+ * @param match - The held ticket
294
+ * @returns One sentence
295
+ */
296
+ export function heldWorktreeNoticeLine(match) {
297
+ const root = match.hold.heldBy ?? match.ticketId;
298
+ return (`This work is ON HOLD on ticket ${root}: "${match.hold.reason}". Do not merge it, do not open a new ticket about it ` +
299
+ `and do not ask the owner about merging: ${TICKET_HOLD_CONSTANTS.ALLOWED_ACTIONS} (log it on ${root}).`);
300
+ }
301
+ //# sourceMappingURL=ticket-hold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket-hold.js","sourceRoot":"","sources":["../../../../../../backend/src/services/project-tickets/ticket-hold.ts"],"names":[],"mappings":"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"}
@@ -302,9 +302,37 @@ export declare function detectOrphanWorkItems(workItems: WorkItem[], workItemMap
302
302
  * ```
303
303
  */
304
304
  export declare function pickTTLExpiryTarget(current: WorkItemStatus): WorkItemStatus | null;
305
+ /**
306
+ * An open owner decision card a WorkItem may be waiting on: the work item the
307
+ * asker was on when it asked, and the ticket the card is about.
308
+ */
309
+ export interface DecisionHoldLink {
310
+ workItemId?: string;
311
+ ticket?: {
312
+ projectPath: string;
313
+ id: string;
314
+ };
315
+ }
316
+ /**
317
+ * Whether a WorkItem waits on an open decision card (crewly#1369 §5): it is
318
+ * the work item the card was asked from, or it works on the card's ticket.
319
+ * Such an item is not TTL-cancelled — the owner's answer is what it waits for
320
+ * (two WorkItems on CREW-646 were cancelled while D-822 waited).
321
+ *
322
+ * @param holds - Open decision cards
323
+ * @returns Predicate over WorkItems
324
+ *
325
+ * @example
326
+ * ```typescript
327
+ * const held = decisionHoldPredicate([{ workItemId: 'wi-1' }]);
328
+ * held(wi); // true for wi-1
329
+ * ```
330
+ */
331
+ export declare function decisionHoldPredicate(holds: readonly DecisionHoldLink[]): (wi: Pick<WorkItem, 'id' | 'metadata' | 'projectTaskId'>) => boolean;
305
332
  /**
306
333
  * Detects WorkItems that have exceeded their time-to-live.
307
- * Default TTL is 24 hours.
334
+ * Default TTL is 24 hours. Items waiting on an open owner decision card
335
+ * ({@link decisionHoldPredicate}) are skipped while the card is open.
308
336
  *
309
337
  * Picks a state-machine-legal terminal target for each expired WI via
310
338
  * {@link pickTTLExpiryTarget}, so the correction never fails with
@@ -321,9 +349,10 @@ export declare function pickTTLExpiryTarget(current: WorkItemStatus): WorkItemSt
321
349
  *
322
350
  * @param workItems - All non-terminal WorkItems to check
323
351
  * @param ttlMs - Maximum age before auto-cancel (default: 24h)
352
+ * @param heldByDecision - Items waiting on an open decision card (never expired while it is open)
324
353
  * @returns Corrections for expired WorkItems
325
354
  */
326
- export declare function detectTTLExpiredWorkItems(workItems: WorkItem[], ttlMs?: number): {
355
+ export declare function detectTTLExpiredWorkItems(workItems: WorkItem[], ttlMs?: number, heldByDecision?: (wi: WorkItem) => boolean): {
327
356
  corrections: ReconcileCorrection[];
328
357
  expiredIds: string[];
329
358
  };
@@ -597,13 +626,14 @@ export interface PruningResult {
597
626
  * @param allWorkItems - All WorkItems in the system
598
627
  * @param ttlMs - TTL threshold (default: 24h)
599
628
  * @param staleThresholdMs - Stale queue threshold (default: 1h)
629
+ * @param heldByDecision - Items waiting on an open decision card, skipped by the TTL rule
600
630
  * @returns Aggregated pruning result. The TTL outcome is reported as two
601
631
  * separate counters — {@link PruningResult.ttlCancelledCount} (discarded)
602
632
  * and {@link PruningResult.ttlAutoVerifiedCount} (accepted) — because only
603
633
  * the former is "cleanup". Callers aggregating a cleaned-up total must sum
604
634
  * the cancel-shaped counters ONLY.
605
635
  */
606
- export declare function runPruningPass(allWorkItems: WorkItem[], ttlMs?: number, staleThresholdMs?: number): PruningResult;
636
+ export declare function runPruningPass(allWorkItems: WorkItem[], ttlMs?: number, staleThresholdMs?: number, heldByDecision?: (wi: WorkItem) => boolean): PruningResult;
607
637
  /** Default threshold for unclaimed task detection (2 minutes). */
608
638
  export declare const UNCLAIMED_THRESHOLD_MS: number;
609
639
  /** Maximum number of wake actions per reconcile pass (rate limit). */
@@ -1 +1 @@
1
- {"version":3,"file":"reconcile-rules.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/reconciler/reconcile-rules.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reconcile-rules.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/reconciler/reconcile-rules.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@ import { DISPOSITION_REQUIRED_STATUSES, isWorkItemDisposed, isExplicitlyBlocked,
13
13
  import { CLAIM_ACTIVITY_LIVENESS_WINDOW_MS } from '../../types/v2/claim.types.js';
14
14
  import { evaluateRequestCompletion } from '../v3/request-completion.js';
15
15
  import { AGENT_ATTENTION_CONSTANTS } from '../../constants.js';
16
+ import { readProjectTicketLink } from '../../types/project-ticket.types.js';
16
17
  // ---------------------------------------------------------------------------
17
18
  // Rule: Detect Stuck WorkItems
18
19
  // ---------------------------------------------------------------------------
@@ -617,9 +618,48 @@ export function pickTTLExpiryTarget(current) {
617
618
  }
618
619
  return null;
619
620
  }
621
+ /**
622
+ * Whether a WorkItem waits on an open decision card (crewly#1369 §5): it is
623
+ * the work item the card was asked from, or it works on the card's ticket.
624
+ * Such an item is not TTL-cancelled — the owner's answer is what it waits for
625
+ * (two WorkItems on CREW-646 were cancelled while D-822 waited).
626
+ *
627
+ * @param holds - Open decision cards
628
+ * @returns Predicate over WorkItems
629
+ *
630
+ * @example
631
+ * ```typescript
632
+ * const held = decisionHoldPredicate([{ workItemId: 'wi-1' }]);
633
+ * held(wi); // true for wi-1
634
+ * ```
635
+ */
636
+ export function decisionHoldPredicate(holds) {
637
+ const ids = new Set();
638
+ const tickets = new Set();
639
+ const bareTicketIds = new Set();
640
+ for (const h of holds) {
641
+ if (h.workItemId)
642
+ ids.add(h.workItemId);
643
+ if (h.ticket?.id) {
644
+ tickets.add(`${h.ticket.projectPath}#${h.ticket.id}`);
645
+ bareTicketIds.add(h.ticket.id);
646
+ }
647
+ }
648
+ if (ids.size === 0 && tickets.size === 0)
649
+ return () => false;
650
+ return (wi) => {
651
+ if (ids.has(wi.id))
652
+ return true;
653
+ const link = readProjectTicketLink(wi.metadata);
654
+ if (link)
655
+ return tickets.has(`${link.projectPath}#${link.id}`);
656
+ return !!wi.projectTaskId && bareTicketIds.has(wi.projectTaskId);
657
+ };
658
+ }
620
659
  /**
621
660
  * Detects WorkItems that have exceeded their time-to-live.
622
- * Default TTL is 24 hours.
661
+ * Default TTL is 24 hours. Items waiting on an open owner decision card
662
+ * ({@link decisionHoldPredicate}) are skipped while the card is open.
623
663
  *
624
664
  * Picks a state-machine-legal terminal target for each expired WI via
625
665
  * {@link pickTTLExpiryTarget}, so the correction never fails with
@@ -636,9 +676,10 @@ export function pickTTLExpiryTarget(current) {
636
676
  *
637
677
  * @param workItems - All non-terminal WorkItems to check
638
678
  * @param ttlMs - Maximum age before auto-cancel (default: 24h)
679
+ * @param heldByDecision - Items waiting on an open decision card (never expired while it is open)
639
680
  * @returns Corrections for expired WorkItems
640
681
  */
641
- export function detectTTLExpiredWorkItems(workItems, ttlMs = 24 * 60 * 60 * 1000) {
682
+ export function detectTTLExpiredWorkItems(workItems, ttlMs = 24 * 60 * 60 * 1000, heldByDecision) {
642
683
  const corrections = [];
643
684
  const expiredIds = [];
644
685
  const now = Date.now();
@@ -652,6 +693,10 @@ export function detectTTLExpiredWorkItems(workItems, ttlMs = 24 * 60 * 60 * 1000
652
693
  const anchorAt = new Date(getTtlAnchorAt(wi)).getTime();
653
694
  const age = now - anchorAt;
654
695
  if (age > ttlMs) {
696
+ // The holder waits on the owner's answer to an open card: that wait is
697
+ // the work, not a stale item (crewly#1369 §5).
698
+ if (heldByDecision?.(wi))
699
+ continue;
655
700
  const target = pickTTLExpiryTarget(wi.status);
656
701
  // No legal terminal edge from this status — skip rather than emit a
657
702
  // correction the state machine will reject on every single pass.
@@ -1096,16 +1141,17 @@ export function detectStaleQueuedWorkItems(workItems, staleThresholdMs = 60 * 60
1096
1141
  * @param allWorkItems - All WorkItems in the system
1097
1142
  * @param ttlMs - TTL threshold (default: 24h)
1098
1143
  * @param staleThresholdMs - Stale queue threshold (default: 1h)
1144
+ * @param heldByDecision - Items waiting on an open decision card, skipped by the TTL rule
1099
1145
  * @returns Aggregated pruning result. The TTL outcome is reported as two
1100
1146
  * separate counters — {@link PruningResult.ttlCancelledCount} (discarded)
1101
1147
  * and {@link PruningResult.ttlAutoVerifiedCount} (accepted) — because only
1102
1148
  * the former is "cleanup". Callers aggregating a cleaned-up total must sum
1103
1149
  * the cancel-shaped counters ONLY.
1104
1150
  */
1105
- export function runPruningPass(allWorkItems, ttlMs = 24 * 60 * 60 * 1000, staleThresholdMs = 60 * 60 * 1000) {
1151
+ export function runPruningPass(allWorkItems, ttlMs = 24 * 60 * 60 * 1000, staleThresholdMs = 60 * 60 * 1000, heldByDecision) {
1106
1152
  const workItemMap = new Map(allWorkItems.map(wi => [wi.id, wi]));
1107
1153
  // 1. TTL expiry
1108
- const ttl = detectTTLExpiredWorkItems(allWorkItems, ttlMs);
1154
+ const ttl = detectTTLExpiredWorkItems(allWorkItems, ttlMs, heldByDecision);
1109
1155
  // 2. Orphan detection
1110
1156
  const orphans = detectOrphanWorkItems(allWorkItems, workItemMap);
1111
1157
  // 3. Build cancelled set for cascade — only include parents that are