crewly 1.6.4 → 1.6.5

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 (795) hide show
  1. package/config/roles/architect/prompt.md +68 -2
  2. package/config/roles/auditor/prompt.md +68 -0
  3. package/config/roles/backend-developer/prompt.md +68 -2
  4. package/config/roles/content-strategist/prompt.md +73 -5
  5. package/config/roles/designer/prompt.md +69 -4
  6. package/config/roles/developer/prompt.md +231 -4
  7. package/config/roles/frontend-developer/prompt.md +68 -2
  8. package/config/roles/fullstack-dev/prompt.md +68 -2
  9. package/config/roles/generalist/prompt.md +68 -2
  10. package/config/roles/ops/prompt.md +69 -3
  11. package/config/roles/orchestrator/fragments/communication.md +27 -0
  12. package/config/roles/orchestrator/fragments/role-boundary.md +1 -1
  13. package/config/roles/orchestrator/prompt.md +215 -72
  14. package/config/roles/product-manager/prompt.md +140 -7
  15. package/config/roles/qa/prompt.md +70 -5
  16. package/config/roles/qa-engineer/prompt.md +70 -5
  17. package/config/roles/researcher/prompt.md +68 -2
  18. package/config/roles/sales/prompt.md +70 -5
  19. package/config/roles/support/prompt.md +69 -4
  20. package/config/roles/team-leader/prompt.md +87 -6
  21. package/config/roles/team-leader/role-boundaries.md +26 -0
  22. package/config/roles/team-leader/tl-addon.md +153 -1
  23. package/config/roles/tpm/prompt.md +68 -2
  24. package/config/roles/ux-designer/prompt.md +70 -5
  25. package/config/skills/_common/complete-body-shape.test.sh +249 -0
  26. package/config/skills/agent/core/accept-task/execute.sh +18 -15
  27. package/config/skills/agent/core/block-task/execute.sh +27 -9
  28. package/config/skills/agent/core/cancel-followup/SKILL.md +18 -0
  29. package/config/skills/agent/core/complete-task/execute.sh +45 -7
  30. package/config/skills/agent/core/create-task/execute.sh +40 -12
  31. package/config/skills/agent/core/get-my-active-work/SKILL.md +3 -1
  32. package/config/skills/agent/core/get-my-tasks/execute.sh +7 -5
  33. package/config/skills/agent/core/handoff-task/execute.sh +34 -48
  34. package/config/skills/agent/core/list-my-followups/SKILL.md +18 -0
  35. package/config/skills/agent/core/read-task/execute.sh +21 -8
  36. package/config/skills/agent/core/recall/SKILL.md +7 -0
  37. package/config/skills/agent/core/remember/SKILL.md +17 -1
  38. package/config/skills/agent/core/remember/execute.sh +5 -1
  39. package/config/skills/agent/core/reply-channel/SKILL.md +19 -0
  40. package/config/skills/agent/core/report-progress/execute.sh +39 -16
  41. package/config/skills/agent/core/report-status/execute.sh +36 -12
  42. package/config/skills/agent/core/save-working-state/execute.sh +17 -6
  43. package/config/skills/agent/core/schedule-followup/SKILL.md +19 -0
  44. package/config/skills/agent/core/send-message/SKILL.md +6 -0
  45. package/config/skills/agent/core/supersede-memory/SKILL.md +76 -0
  46. package/config/skills/agent/core/supersede-memory/execute.sh +108 -0
  47. package/config/skills/agent/core/watch-for-event/SKILL.md +19 -0
  48. package/config/skills/agent/onboarding/materialize-team/SKILL.md +94 -0
  49. package/config/skills/agent/onboarding/materialize-team/execute.sh +98 -0
  50. package/config/skills/agent/onboarding/recommend-team/SKILL.md +90 -0
  51. package/config/skills/agent/onboarding/recommend-team/execute.sh +96 -0
  52. package/config/skills/agent/xhs-article-to-image/SKILL.md +20 -0
  53. package/config/skills/auditor/score-task/SKILL.md +15 -0
  54. package/config/skills/orchestrator/assign-task/execute.sh +28 -4
  55. package/config/skills/orchestrator/cancel-all-schedules/SKILL.md +15 -1
  56. package/config/skills/orchestrator/complete-task/execute.sh +45 -4
  57. package/config/skills/orchestrator/delegate-task/SKILL.md +1 -0
  58. package/config/skills/orchestrator/delegate-task/execute.sh +41 -2
  59. package/config/skills/orchestrator/get-tasks/execute.sh +22 -18
  60. package/config/skills/orchestrator/list-schedules/SKILL.md +15 -1
  61. package/config/skills/orchestrator/update-team-member/SKILL.md +20 -0
  62. package/config/skills/team-leader/decompose-goal/execute.sh +51 -20
  63. package/config/skills/team-leader/delegate-task/execute.sh +67 -26
  64. package/config/skills/team-leader/delegate-task/execute.test.sh +117 -0
  65. package/config/skills/team-leader/verify-output/execute.sh +19 -20
  66. package/config/slack-app-manifest.json +2 -1
  67. package/config/sops/common/dev-process-tiers.md +181 -0
  68. package/config/sops/common/owner-facing-communication.md +131 -0
  69. package/config/souls/orchestrator.md +8 -0
  70. package/config/souls/team-leader.md +77 -0
  71. package/dist/backend/backend/src/controllers/active-work/active-work.controller.d.ts.map +1 -1
  72. package/dist/backend/backend/src/controllers/active-work/active-work.controller.js +4 -1
  73. package/dist/backend/backend/src/controllers/active-work/active-work.controller.js.map +1 -1
  74. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.d.ts +8 -1
  75. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.d.ts.map +1 -1
  76. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.js +30 -26
  77. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.js.map +1 -1
  78. package/dist/backend/backend/src/controllers/api.controller.d.ts +0 -9
  79. package/dist/backend/backend/src/controllers/api.controller.d.ts.map +1 -1
  80. package/dist/backend/backend/src/controllers/api.controller.js +4 -32
  81. package/dist/backend/backend/src/controllers/api.controller.js.map +1 -1
  82. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  83. package/dist/backend/backend/src/controllers/chat/chat.controller.js +5 -2
  84. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  85. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -1
  86. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +5 -2
  87. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -1
  88. package/dist/backend/backend/src/controllers/checklist/checklist.controller.d.ts +45 -0
  89. package/dist/backend/backend/src/controllers/checklist/checklist.controller.d.ts.map +1 -0
  90. package/dist/backend/backend/src/controllers/checklist/checklist.controller.js +122 -0
  91. package/dist/backend/backend/src/controllers/checklist/checklist.controller.js.map +1 -0
  92. package/dist/backend/backend/src/controllers/memory/memory.controller.d.ts +24 -0
  93. package/dist/backend/backend/src/controllers/memory/memory.controller.d.ts.map +1 -1
  94. package/dist/backend/backend/src/controllers/memory/memory.controller.js +69 -1
  95. package/dist/backend/backend/src/controllers/memory/memory.controller.js.map +1 -1
  96. package/dist/backend/backend/src/controllers/memory/memory.routes.d.ts +1 -0
  97. package/dist/backend/backend/src/controllers/memory/memory.routes.d.ts.map +1 -1
  98. package/dist/backend/backend/src/controllers/memory/memory.routes.js +3 -1
  99. package/dist/backend/backend/src/controllers/memory/memory.routes.js.map +1 -1
  100. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
  101. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +80 -5
  102. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
  103. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.d.ts +1 -0
  104. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.d.ts.map +1 -1
  105. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.js +30 -0
  106. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.js.map +1 -1
  107. package/dist/backend/backend/src/controllers/orchestrator-onboarding/orchestrator-onboarding.controller.d.ts +41 -0
  108. package/dist/backend/backend/src/controllers/orchestrator-onboarding/orchestrator-onboarding.controller.d.ts.map +1 -0
  109. package/dist/backend/backend/src/controllers/orchestrator-onboarding/orchestrator-onboarding.controller.js +213 -0
  110. package/dist/backend/backend/src/controllers/orchestrator-onboarding/orchestrator-onboarding.controller.js.map +1 -0
  111. package/dist/backend/backend/src/controllers/orchestrator-onboarding/orchestrator-onboarding.routes.d.ts +21 -0
  112. package/dist/backend/backend/src/controllers/orchestrator-onboarding/orchestrator-onboarding.routes.d.ts.map +1 -0
  113. package/dist/backend/backend/src/controllers/orchestrator-onboarding/orchestrator-onboarding.routes.js +27 -0
  114. package/dist/backend/backend/src/controllers/orchestrator-onboarding/orchestrator-onboarding.routes.js.map +1 -0
  115. package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
  116. package/dist/backend/backend/src/controllers/slack/slack.controller.js +97 -0
  117. package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
  118. package/dist/backend/backend/src/controllers/task-management/in-progress-tasks.controller.d.ts +13 -3
  119. package/dist/backend/backend/src/controllers/task-management/in-progress-tasks.controller.d.ts.map +1 -1
  120. package/dist/backend/backend/src/controllers/task-management/in-progress-tasks.controller.js +29 -24
  121. package/dist/backend/backend/src/controllers/task-management/in-progress-tasks.controller.js.map +1 -1
  122. package/dist/backend/backend/src/controllers/task-management/tasks.controller.d.ts.map +1 -1
  123. package/dist/backend/backend/src/controllers/task-management/tasks.controller.js +61 -13
  124. package/dist/backend/backend/src/controllers/task-management/tasks.controller.js.map +1 -1
  125. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts +159 -7
  126. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
  127. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +421 -37
  128. package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
  129. package/dist/backend/backend/src/controllers/task-pool/task-pool.routes.d.ts.map +1 -1
  130. package/dist/backend/backend/src/controllers/task-pool/task-pool.routes.js +15 -1
  131. package/dist/backend/backend/src/controllers/task-pool/task-pool.routes.js.map +1 -1
  132. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  133. package/dist/backend/backend/src/controllers/team/team.controller.js +221 -10
  134. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  135. package/dist/backend/backend/src/controllers/teams-backup/teams-backup.controller.d.ts +22 -0
  136. package/dist/backend/backend/src/controllers/teams-backup/teams-backup.controller.d.ts.map +1 -1
  137. package/dist/backend/backend/src/controllers/teams-backup/teams-backup.controller.js +92 -0
  138. package/dist/backend/backend/src/controllers/teams-backup/teams-backup.controller.js.map +1 -1
  139. package/dist/backend/backend/src/controllers/teams-backup/teams-backup.routes.d.ts.map +1 -1
  140. package/dist/backend/backend/src/controllers/teams-backup/teams-backup.routes.js +6 -2
  141. package/dist/backend/backend/src/controllers/teams-backup/teams-backup.routes.js.map +1 -1
  142. package/dist/backend/backend/src/controllers/types.d.ts +1 -2
  143. package/dist/backend/backend/src/controllers/types.d.ts.map +1 -1
  144. package/dist/backend/backend/src/index.d.ts +4 -1
  145. package/dist/backend/backend/src/index.d.ts.map +1 -1
  146. package/dist/backend/backend/src/index.js +291 -64
  147. package/dist/backend/backend/src/index.js.map +1 -1
  148. package/dist/backend/backend/src/models/Project.d.ts +2 -0
  149. package/dist/backend/backend/src/models/Project.d.ts.map +1 -1
  150. package/dist/backend/backend/src/models/Project.js +10 -1
  151. package/dist/backend/backend/src/models/Project.js.map +1 -1
  152. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  153. package/dist/backend/backend/src/routes/api.routes.js +4 -1
  154. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  155. package/dist/backend/backend/src/routes/modules/task-management.routes.d.ts +15 -0
  156. package/dist/backend/backend/src/routes/modules/task-management.routes.d.ts.map +1 -1
  157. package/dist/backend/backend/src/routes/modules/task-management.routes.js +23 -43
  158. package/dist/backend/backend/src/routes/modules/task-management.routes.js.map +1 -1
  159. package/dist/backend/backend/src/scripts/cleanup-stale-pool.lib.d.ts +87 -0
  160. package/dist/backend/backend/src/scripts/cleanup-stale-pool.lib.d.ts.map +1 -0
  161. package/dist/backend/backend/src/scripts/cleanup-stale-pool.lib.js +116 -0
  162. package/dist/backend/backend/src/scripts/cleanup-stale-pool.lib.js.map +1 -0
  163. package/dist/backend/backend/src/services/agent/active-work-briefing.service.d.ts +46 -6
  164. package/dist/backend/backend/src/services/agent/active-work-briefing.service.d.ts.map +1 -1
  165. package/dist/backend/backend/src/services/agent/active-work-briefing.service.js +56 -13
  166. package/dist/backend/backend/src/services/agent/active-work-briefing.service.js.map +1 -1
  167. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +9 -0
  168. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  169. package/dist/backend/backend/src/services/agent/agent-registration.service.js +28 -3
  170. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  171. package/dist/backend/backend/src/services/agent/context-window-monitor.service.d.ts +31 -5
  172. package/dist/backend/backend/src/services/agent/context-window-monitor.service.d.ts.map +1 -1
  173. package/dist/backend/backend/src/services/agent/context-window-monitor.service.js +69 -29
  174. package/dist/backend/backend/src/services/agent/context-window-monitor.service.js.map +1 -1
  175. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts.map +1 -1
  176. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js +113 -75
  177. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js.map +1 -1
  178. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.d.ts.map +1 -1
  179. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js +5 -3
  180. package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js.map +1 -1
  181. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts +35 -0
  182. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts.map +1 -1
  183. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js +127 -3
  184. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js.map +1 -1
  185. package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.d.ts +79 -0
  186. package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.d.ts.map +1 -0
  187. package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.js +145 -0
  188. package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.js.map +1 -0
  189. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts +64 -9
  190. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts.map +1 -1
  191. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js +125 -15
  192. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js.map +1 -1
  193. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts.map +1 -1
  194. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js +101 -33
  195. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js.map +1 -1
  196. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts +76 -1
  197. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -1
  198. package/dist/backend/backend/src/services/agent/crewly-agent/types.js +73 -1
  199. package/dist/backend/backend/src/services/agent/crewly-agent/types.js.map +1 -1
  200. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts +5 -5
  201. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
  202. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js +22 -8
  203. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
  204. package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts +10 -0
  205. package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -1
  206. package/dist/backend/backend/src/services/ai/prompt-builder.service.js +160 -4
  207. package/dist/backend/backend/src/services/ai/prompt-builder.service.js.map +1 -1
  208. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.d.ts +37 -0
  209. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.d.ts.map +1 -1
  210. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js +77 -3
  211. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js.map +1 -1
  212. package/dist/backend/backend/src/services/ai/prompt-modules/decision-rights.module.d.ts +59 -0
  213. package/dist/backend/backend/src/services/ai/prompt-modules/decision-rights.module.d.ts.map +1 -0
  214. package/dist/backend/backend/src/services/ai/prompt-modules/decision-rights.module.js +87 -0
  215. package/dist/backend/backend/src/services/ai/prompt-modules/decision-rights.module.js.map +1 -0
  216. package/dist/backend/backend/src/services/ai/prompt-modules/default-execution-loop.module.d.ts +67 -0
  217. package/dist/backend/backend/src/services/ai/prompt-modules/default-execution-loop.module.d.ts.map +1 -0
  218. package/dist/backend/backend/src/services/ai/prompt-modules/default-execution-loop.module.js +84 -0
  219. package/dist/backend/backend/src/services/ai/prompt-modules/default-execution-loop.module.js.map +1 -0
  220. package/dist/backend/backend/src/services/ai/prompt-modules/index.d.ts +4 -0
  221. package/dist/backend/backend/src/services/ai/prompt-modules/index.d.ts.map +1 -1
  222. package/dist/backend/backend/src/services/ai/prompt-modules/index.js +4 -0
  223. package/dist/backend/backend/src/services/ai/prompt-modules/index.js.map +1 -1
  224. package/dist/backend/backend/src/services/ai/prompt-modules/lazy-anti-patterns.module.d.ts +65 -0
  225. package/dist/backend/backend/src/services/ai/prompt-modules/lazy-anti-patterns.module.d.ts.map +1 -0
  226. package/dist/backend/backend/src/services/ai/prompt-modules/lazy-anti-patterns.module.js +79 -0
  227. package/dist/backend/backend/src/services/ai/prompt-modules/lazy-anti-patterns.module.js.map +1 -0
  228. package/dist/backend/backend/src/services/ai/prompt-modules/mission-context.module.d.ts +60 -0
  229. package/dist/backend/backend/src/services/ai/prompt-modules/mission-context.module.d.ts.map +1 -0
  230. package/dist/backend/backend/src/services/ai/prompt-modules/mission-context.module.js +104 -0
  231. package/dist/backend/backend/src/services/ai/prompt-modules/mission-context.module.js.map +1 -0
  232. package/dist/backend/backend/src/services/ai/prompt-modules/prompt-assembly.service.d.ts.map +1 -1
  233. package/dist/backend/backend/src/services/ai/prompt-modules/prompt-assembly.service.js +45 -0
  234. package/dist/backend/backend/src/services/ai/prompt-modules/prompt-assembly.service.js.map +1 -1
  235. package/dist/backend/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts +16 -0
  236. package/dist/backend/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts.map +1 -1
  237. package/dist/backend/backend/src/services/ai/prompt-modules/prompt-module.interface.js.map +1 -1
  238. package/dist/backend/backend/src/services/ai/prompt-modules/request-contract.module.d.ts +106 -0
  239. package/dist/backend/backend/src/services/ai/prompt-modules/request-contract.module.d.ts.map +1 -0
  240. package/dist/backend/backend/src/services/ai/prompt-modules/request-contract.module.js +167 -0
  241. package/dist/backend/backend/src/services/ai/prompt-modules/request-contract.module.js.map +1 -0
  242. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.d.ts.map +1 -1
  243. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.js +28 -0
  244. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.js.map +1 -1
  245. package/dist/backend/backend/src/services/ai/prompt-modules/soul.module.d.ts +38 -6
  246. package/dist/backend/backend/src/services/ai/prompt-modules/soul.module.d.ts.map +1 -1
  247. package/dist/backend/backend/src/services/ai/prompt-modules/soul.module.js +73 -10
  248. package/dist/backend/backend/src/services/ai/prompt-modules/soul.module.js.map +1 -1
  249. package/dist/backend/backend/src/services/ai/prompt-modules/working-memory.module.d.ts +91 -0
  250. package/dist/backend/backend/src/services/ai/prompt-modules/working-memory.module.d.ts.map +1 -0
  251. package/dist/backend/backend/src/services/ai/prompt-modules/working-memory.module.js +136 -0
  252. package/dist/backend/backend/src/services/ai/prompt-modules/working-memory.module.js.map +1 -0
  253. package/dist/backend/backend/src/services/autonomous/index.d.ts +7 -3
  254. package/dist/backend/backend/src/services/autonomous/index.d.ts.map +1 -1
  255. package/dist/backend/backend/src/services/autonomous/index.js +7 -3
  256. package/dist/backend/backend/src/services/autonomous/index.js.map +1 -1
  257. package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts.map +1 -1
  258. package/dist/backend/backend/src/services/browser/browser-bridge.service.js +16 -22
  259. package/dist/backend/backend/src/services/browser/browser-bridge.service.js.map +1 -1
  260. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts +13 -0
  261. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -1
  262. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js +15 -0
  263. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js.map +1 -1
  264. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts +11 -0
  265. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts.map +1 -1
  266. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js +51 -19
  267. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js.map +1 -1
  268. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts +18 -0
  269. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -1
  270. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js +23 -0
  271. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -1
  272. package/dist/backend/backend/src/services/core/config.service.d.ts.map +1 -1
  273. package/dist/backend/backend/src/services/core/config.service.js +8 -1
  274. package/dist/backend/backend/src/services/core/config.service.js.map +1 -1
  275. package/dist/backend/backend/src/services/core/crewly-home.utils.d.ts +51 -0
  276. package/dist/backend/backend/src/services/core/crewly-home.utils.d.ts.map +1 -0
  277. package/dist/backend/backend/src/services/core/crewly-home.utils.js +59 -0
  278. package/dist/backend/backend/src/services/core/crewly-home.utils.js.map +1 -0
  279. package/dist/backend/backend/src/services/core/state-invariant.types.d.ts +53 -0
  280. package/dist/backend/backend/src/services/core/state-invariant.types.d.ts.map +1 -0
  281. package/dist/backend/backend/src/services/core/state-invariant.types.js +61 -0
  282. package/dist/backend/backend/src/services/core/state-invariant.types.js.map +1 -0
  283. package/dist/backend/backend/src/services/core/storage.service.d.ts +20 -0
  284. package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
  285. package/dist/backend/backend/src/services/core/storage.service.js +96 -8
  286. package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
  287. package/dist/backend/backend/src/services/core/teams-backup.service.d.ts +94 -4
  288. package/dist/backend/backend/src/services/core/teams-backup.service.d.ts.map +1 -1
  289. package/dist/backend/backend/src/services/core/teams-backup.service.js +172 -10
  290. package/dist/backend/backend/src/services/core/teams-backup.service.js.map +1 -1
  291. package/dist/backend/backend/src/services/index.d.ts +0 -2
  292. package/dist/backend/backend/src/services/index.d.ts.map +1 -1
  293. package/dist/backend/backend/src/services/index.js +0 -2
  294. package/dist/backend/backend/src/services/index.js.map +1 -1
  295. package/dist/backend/backend/src/services/intent-task/intent-classifier.fixture.d.ts +78 -0
  296. package/dist/backend/backend/src/services/intent-task/intent-classifier.fixture.d.ts.map +1 -0
  297. package/dist/backend/backend/src/services/intent-task/intent-classifier.fixture.js +209 -0
  298. package/dist/backend/backend/src/services/intent-task/intent-classifier.fixture.js.map +1 -0
  299. package/dist/backend/backend/src/services/intent-task/intent-classifier.rules.d.ts +331 -0
  300. package/dist/backend/backend/src/services/intent-task/intent-classifier.rules.d.ts.map +1 -0
  301. package/dist/backend/backend/src/services/intent-task/intent-classifier.rules.js +413 -0
  302. package/dist/backend/backend/src/services/intent-task/intent-classifier.rules.js.map +1 -0
  303. package/dist/backend/backend/src/services/intent-task/intent-task.service.d.ts.map +1 -1
  304. package/dist/backend/backend/src/services/intent-task/intent-task.service.js +13 -4
  305. package/dist/backend/backend/src/services/intent-task/intent-task.service.js.map +1 -1
  306. package/dist/backend/backend/src/services/knowledge/fts5-index.service.d.ts.map +1 -1
  307. package/dist/backend/backend/src/services/knowledge/fts5-index.service.js +18 -13
  308. package/dist/backend/backend/src/services/knowledge/fts5-index.service.js.map +1 -1
  309. package/dist/backend/backend/src/services/knowledge/fts5-query-sanitizer.d.ts +102 -0
  310. package/dist/backend/backend/src/services/knowledge/fts5-query-sanitizer.d.ts.map +1 -0
  311. package/dist/backend/backend/src/services/knowledge/fts5-query-sanitizer.js +118 -0
  312. package/dist/backend/backend/src/services/knowledge/fts5-query-sanitizer.js.map +1 -0
  313. package/dist/backend/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
  314. package/dist/backend/backend/src/services/knowledge/vector-store.service.js +11 -15
  315. package/dist/backend/backend/src/services/knowledge/vector-store.service.js.map +1 -1
  316. package/dist/backend/backend/src/services/memory/agent-memory.service.d.ts +20 -0
  317. package/dist/backend/backend/src/services/memory/agent-memory.service.d.ts.map +1 -1
  318. package/dist/backend/backend/src/services/memory/agent-memory.service.js +27 -2
  319. package/dist/backend/backend/src/services/memory/agent-memory.service.js.map +1 -1
  320. package/dist/backend/backend/src/services/memory/memory-supersession.service.d.ts +104 -0
  321. package/dist/backend/backend/src/services/memory/memory-supersession.service.d.ts.map +1 -0
  322. package/dist/backend/backend/src/services/memory/memory-supersession.service.js +127 -0
  323. package/dist/backend/backend/src/services/memory/memory-supersession.service.js.map +1 -0
  324. package/dist/backend/backend/src/services/memory/memory.service.d.ts +48 -17
  325. package/dist/backend/backend/src/services/memory/memory.service.d.ts.map +1 -1
  326. package/dist/backend/backend/src/services/memory/memory.service.js +65 -35
  327. package/dist/backend/backend/src/services/memory/memory.service.js.map +1 -1
  328. package/dist/backend/backend/src/services/memory/mission-context.service.d.ts +168 -0
  329. package/dist/backend/backend/src/services/memory/mission-context.service.d.ts.map +1 -0
  330. package/dist/backend/backend/src/services/memory/mission-context.service.js +365 -0
  331. package/dist/backend/backend/src/services/memory/mission-context.service.js.map +1 -0
  332. package/dist/backend/backend/src/services/memory/role-knowledge-eligibility.d.ts +138 -0
  333. package/dist/backend/backend/src/services/memory/role-knowledge-eligibility.d.ts.map +1 -0
  334. package/dist/backend/backend/src/services/memory/role-knowledge-eligibility.js +183 -0
  335. package/dist/backend/backend/src/services/memory/role-knowledge-eligibility.js.map +1 -0
  336. package/dist/backend/backend/src/services/memory/vector-store.service.d.ts.map +1 -1
  337. package/dist/backend/backend/src/services/memory/vector-store.service.js +7 -11
  338. package/dist/backend/backend/src/services/memory/vector-store.service.js.map +1 -1
  339. package/dist/backend/backend/src/services/memory/working-memory.service.d.ts +232 -0
  340. package/dist/backend/backend/src/services/memory/working-memory.service.d.ts.map +1 -0
  341. package/dist/backend/backend/src/services/memory/working-memory.service.js +417 -0
  342. package/dist/backend/backend/src/services/memory/working-memory.service.js.map +1 -0
  343. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  344. package/dist/backend/backend/src/services/messaging/queue-processor.service.js +23 -2
  345. package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  346. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js +2 -2
  347. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
  348. package/dist/backend/backend/src/services/monitoring/team-activity-websocket.service.d.ts +27 -7
  349. package/dist/backend/backend/src/services/monitoring/team-activity-websocket.service.d.ts.map +1 -1
  350. package/dist/backend/backend/src/services/monitoring/team-activity-websocket.service.js +66 -27
  351. package/dist/backend/backend/src/services/monitoring/team-activity-websocket.service.js.map +1 -1
  352. package/dist/backend/backend/src/services/monitoring/teams-json-watcher.service.d.ts.map +1 -1
  353. package/dist/backend/backend/src/services/monitoring/teams-json-watcher.service.js +2 -2
  354. package/dist/backend/backend/src/services/monitoring/teams-json-watcher.service.js.map +1 -1
  355. package/dist/backend/backend/src/services/observability/agent-behavior-log.service.d.ts +132 -0
  356. package/dist/backend/backend/src/services/observability/agent-behavior-log.service.d.ts.map +1 -0
  357. package/dist/backend/backend/src/services/observability/agent-behavior-log.service.js +284 -0
  358. package/dist/backend/backend/src/services/observability/agent-behavior-log.service.js.map +1 -0
  359. package/dist/backend/backend/src/services/observability/agent-behavior-log.singleton.d.ts +70 -0
  360. package/dist/backend/backend/src/services/observability/agent-behavior-log.singleton.d.ts.map +1 -0
  361. package/dist/backend/backend/src/services/observability/agent-behavior-log.singleton.js +121 -0
  362. package/dist/backend/backend/src/services/observability/agent-behavior-log.singleton.js.map +1 -0
  363. package/dist/backend/backend/src/services/observability/agent-behavior-log.types.d.ts +130 -0
  364. package/dist/backend/backend/src/services/observability/agent-behavior-log.types.d.ts.map +1 -0
  365. package/dist/backend/backend/src/services/observability/agent-behavior-log.types.js +48 -0
  366. package/dist/backend/backend/src/services/observability/agent-behavior-log.types.js.map +1 -0
  367. package/dist/backend/backend/src/services/observability/observability-db.d.ts +84 -0
  368. package/dist/backend/backend/src/services/observability/observability-db.d.ts.map +1 -0
  369. package/dist/backend/backend/src/services/observability/observability-db.js +165 -0
  370. package/dist/backend/backend/src/services/observability/observability-db.js.map +1 -0
  371. package/dist/backend/backend/src/services/onboarding/onboarding.service.d.ts +22 -0
  372. package/dist/backend/backend/src/services/onboarding/onboarding.service.d.ts.map +1 -1
  373. package/dist/backend/backend/src/services/onboarding/onboarding.service.js +36 -0
  374. package/dist/backend/backend/src/services/onboarding/onboarding.service.js.map +1 -1
  375. package/dist/backend/backend/src/services/onboarding/onboarding.types.d.ts +21 -2
  376. package/dist/backend/backend/src/services/onboarding/onboarding.types.d.ts.map +1 -1
  377. package/dist/backend/backend/src/services/orchestrator/improvement-marker.service.d.ts.map +1 -1
  378. package/dist/backend/backend/src/services/orchestrator/improvement-marker.service.js +12 -3
  379. package/dist/backend/backend/src/services/orchestrator/improvement-marker.service.js.map +1 -1
  380. package/dist/backend/backend/src/services/orchestrator/onboarding/materialize-team.d.ts +108 -0
  381. package/dist/backend/backend/src/services/orchestrator/onboarding/materialize-team.d.ts.map +1 -0
  382. package/dist/backend/backend/src/services/orchestrator/onboarding/materialize-team.js +165 -0
  383. package/dist/backend/backend/src/services/orchestrator/onboarding/materialize-team.js.map +1 -0
  384. package/dist/backend/backend/src/services/orchestrator/onboarding/recommend-team.d.ts +114 -0
  385. package/dist/backend/backend/src/services/orchestrator/onboarding/recommend-team.d.ts.map +1 -0
  386. package/dist/backend/backend/src/services/orchestrator/onboarding/recommend-team.js +299 -0
  387. package/dist/backend/backend/src/services/orchestrator/onboarding/recommend-team.js.map +1 -0
  388. package/dist/backend/backend/src/services/orchestrator/onboarding-bootstrap.service.d.ts +128 -0
  389. package/dist/backend/backend/src/services/orchestrator/onboarding-bootstrap.service.d.ts.map +1 -0
  390. package/dist/backend/backend/src/services/orchestrator/onboarding-bootstrap.service.js +195 -0
  391. package/dist/backend/backend/src/services/orchestrator/onboarding-bootstrap.service.js.map +1 -0
  392. package/dist/backend/backend/src/services/orchestrator/onboarding-mode-loader.d.ts +66 -0
  393. package/dist/backend/backend/src/services/orchestrator/onboarding-mode-loader.d.ts.map +1 -0
  394. package/dist/backend/backend/src/services/orchestrator/onboarding-mode-loader.js +145 -0
  395. package/dist/backend/backend/src/services/orchestrator/onboarding-mode-loader.js.map +1 -0
  396. package/dist/backend/backend/src/services/orchestrator/onboarding-mode.skill-allowlist.d.ts +59 -0
  397. package/dist/backend/backend/src/services/orchestrator/onboarding-mode.skill-allowlist.d.ts.map +1 -0
  398. package/dist/backend/backend/src/services/orchestrator/onboarding-mode.skill-allowlist.js +68 -0
  399. package/dist/backend/backend/src/services/orchestrator/onboarding-mode.skill-allowlist.js.map +1 -0
  400. package/dist/backend/backend/src/services/orchestrator/prompts/onboarding-mode.prompt.d.ts +67 -0
  401. package/dist/backend/backend/src/services/orchestrator/prompts/onboarding-mode.prompt.d.ts.map +1 -0
  402. package/dist/backend/backend/src/services/orchestrator/prompts/onboarding-mode.prompt.js +290 -0
  403. package/dist/backend/backend/src/services/orchestrator/prompts/onboarding-mode.prompt.js.map +1 -0
  404. package/dist/backend/backend/src/services/orchestrator/state-persistence.service.d.ts +23 -1
  405. package/dist/backend/backend/src/services/orchestrator/state-persistence.service.d.ts.map +1 -1
  406. package/dist/backend/backend/src/services/orchestrator/state-persistence.service.js +64 -1
  407. package/dist/backend/backend/src/services/orchestrator/state-persistence.service.js.map +1 -1
  408. package/dist/backend/backend/src/services/project/active-projects.service.d.ts.map +1 -1
  409. package/dist/backend/backend/src/services/project/active-projects.service.js +2 -2
  410. package/dist/backend/backend/src/services/project/active-projects.service.js.map +1 -1
  411. package/dist/backend/backend/src/services/project/task-tracking.service.d.ts.map +1 -1
  412. package/dist/backend/backend/src/services/project/task-tracking.service.js +2 -2
  413. package/dist/backend/backend/src/services/project/task-tracking.service.js.map +1 -1
  414. package/dist/backend/backend/src/services/prompt/prompt-generator.service.d.ts.map +1 -1
  415. package/dist/backend/backend/src/services/prompt/prompt-generator.service.js +2 -2
  416. package/dist/backend/backend/src/services/prompt/prompt-generator.service.js.map +1 -1
  417. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts +51 -5
  418. package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts.map +1 -1
  419. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js +162 -15
  420. package/dist/backend/backend/src/services/reconciler/reconcile-rules.js.map +1 -1
  421. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts +15 -2
  422. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts.map +1 -1
  423. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js +153 -11
  424. package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js.map +1 -1
  425. package/dist/backend/backend/src/services/session/session-handoff.service.d.ts +31 -18
  426. package/dist/backend/backend/src/services/session/session-handoff.service.d.ts.map +1 -1
  427. package/dist/backend/backend/src/services/session/session-handoff.service.js +73 -80
  428. package/dist/backend/backend/src/services/session/session-handoff.service.js.map +1 -1
  429. package/dist/backend/backend/src/services/session/session-state-persistence.d.ts.map +1 -1
  430. package/dist/backend/backend/src/services/session/session-state-persistence.js +15 -4
  431. package/dist/backend/backend/src/services/session/session-state-persistence.js.map +1 -1
  432. package/dist/backend/backend/src/services/settings/settings.service.d.ts.map +1 -1
  433. package/dist/backend/backend/src/services/settings/settings.service.js +25 -0
  434. package/dist/backend/backend/src/services/settings/settings.service.js.map +1 -1
  435. package/dist/backend/backend/src/services/skill/skill-catalog.service.d.ts +14 -3
  436. package/dist/backend/backend/src/services/skill/skill-catalog.service.d.ts.map +1 -1
  437. package/dist/backend/backend/src/services/skill/skill-catalog.service.js +28 -3
  438. package/dist/backend/backend/src/services/skill/skill-catalog.service.js.map +1 -1
  439. package/dist/backend/backend/src/services/slack/cross-machine-message.service.d.ts.map +1 -1
  440. package/dist/backend/backend/src/services/slack/cross-machine-message.service.js +13 -18
  441. package/dist/backend/backend/src/services/slack/cross-machine-message.service.js.map +1 -1
  442. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +45 -0
  443. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  444. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +202 -19
  445. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  446. package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
  447. package/dist/backend/backend/src/services/slack/slack.service.js +21 -0
  448. package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
  449. package/dist/backend/backend/src/services/task-pool/pool-storage.d.ts +15 -1
  450. package/dist/backend/backend/src/services/task-pool/pool-storage.d.ts.map +1 -1
  451. package/dist/backend/backend/src/services/task-pool/pool-storage.js +31 -8
  452. package/dist/backend/backend/src/services/task-pool/pool-storage.js.map +1 -1
  453. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +183 -0
  454. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  455. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +404 -8
  456. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  457. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.d.ts +14 -1
  458. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.d.ts.map +1 -1
  459. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js +128 -17
  460. package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js.map +1 -1
  461. package/dist/backend/backend/src/services/v3/cascade-request-status.d.ts +95 -0
  462. package/dist/backend/backend/src/services/v3/cascade-request-status.d.ts.map +1 -0
  463. package/dist/backend/backend/src/services/v3/cascade-request-status.js +147 -0
  464. package/dist/backend/backend/src/services/v3/cascade-request-status.js.map +1 -0
  465. package/dist/backend/backend/src/services/v3/escalation-router.service.d.ts.map +1 -1
  466. package/dist/backend/backend/src/services/v3/escalation-router.service.js +42 -0
  467. package/dist/backend/backend/src/services/v3/escalation-router.service.js.map +1 -1
  468. package/dist/backend/backend/src/services/v3/mission-executor.service.d.ts.map +1 -1
  469. package/dist/backend/backend/src/services/v3/mission-executor.service.js +16 -4
  470. package/dist/backend/backend/src/services/v3/mission-executor.service.js.map +1 -1
  471. package/dist/backend/backend/src/services/v3/request-cascade.subscriber.d.ts +87 -0
  472. package/dist/backend/backend/src/services/v3/request-cascade.subscriber.d.ts.map +1 -0
  473. package/dist/backend/backend/src/services/v3/request-cascade.subscriber.js +152 -0
  474. package/dist/backend/backend/src/services/v3/request-cascade.subscriber.js.map +1 -0
  475. package/dist/backend/backend/src/services/v3/request-decompose.subscriber.d.ts +253 -0
  476. package/dist/backend/backend/src/services/v3/request-decompose.subscriber.d.ts.map +1 -0
  477. package/dist/backend/backend/src/services/v3/request-decompose.subscriber.js +476 -0
  478. package/dist/backend/backend/src/services/v3/request-decompose.subscriber.js.map +1 -0
  479. package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts +55 -0
  480. package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts.map +1 -1
  481. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js +257 -20
  482. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js.map +1 -1
  483. package/dist/backend/backend/src/services/v3/request-status-update.subscriber.d.ts +204 -0
  484. package/dist/backend/backend/src/services/v3/request-status-update.subscriber.d.ts.map +1 -0
  485. package/dist/backend/backend/src/services/v3/request-status-update.subscriber.js +575 -0
  486. package/dist/backend/backend/src/services/v3/request-status-update.subscriber.js.map +1 -0
  487. package/dist/backend/backend/src/services/v3/request.service.d.ts +107 -0
  488. package/dist/backend/backend/src/services/v3/request.service.d.ts.map +1 -1
  489. package/dist/backend/backend/src/services/v3/request.service.js +155 -2
  490. package/dist/backend/backend/src/services/v3/request.service.js.map +1 -1
  491. package/dist/backend/backend/src/services/v3/trigger-engine.service.d.ts +69 -1
  492. package/dist/backend/backend/src/services/v3/trigger-engine.service.d.ts.map +1 -1
  493. package/dist/backend/backend/src/services/v3/trigger-engine.service.js +157 -4
  494. package/dist/backend/backend/src/services/v3/trigger-engine.service.js.map +1 -1
  495. package/dist/backend/backend/src/services/v3/v3-data.service.d.ts +50 -26
  496. package/dist/backend/backend/src/services/v3/v3-data.service.d.ts.map +1 -1
  497. package/dist/backend/backend/src/services/v3/v3-data.service.js +126 -161
  498. package/dist/backend/backend/src/services/v3/v3-data.service.js.map +1 -1
  499. package/dist/backend/backend/src/services/v3/work-item-projection.d.ts +40 -0
  500. package/dist/backend/backend/src/services/v3/work-item-projection.d.ts.map +1 -0
  501. package/dist/backend/backend/src/services/v3/work-item-projection.js +115 -0
  502. package/dist/backend/backend/src/services/v3/work-item-projection.js.map +1 -0
  503. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts +121 -0
  504. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -0
  505. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +268 -0
  506. package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -0
  507. package/dist/backend/backend/src/services/whatsapp/whatsapp.service.d.ts.map +1 -1
  508. package/dist/backend/backend/src/services/whatsapp/whatsapp.service.js +11 -2
  509. package/dist/backend/backend/src/services/whatsapp/whatsapp.service.js.map +1 -1
  510. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
  511. package/dist/backend/backend/src/services/workflow/scheduler.service.js +68 -14
  512. package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
  513. package/dist/backend/backend/src/types/event-bus.types.d.ts +1 -1
  514. package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
  515. package/dist/backend/backend/src/types/event-bus.types.js +12 -0
  516. package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
  517. package/dist/backend/backend/src/types/index.d.ts +11 -1
  518. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  519. package/dist/backend/backend/src/types/index.js +0 -2
  520. package/dist/backend/backend/src/types/index.js.map +1 -1
  521. package/dist/backend/backend/src/types/intent-task.types.d.ts +22 -3
  522. package/dist/backend/backend/src/types/intent-task.types.d.ts.map +1 -1
  523. package/dist/backend/backend/src/types/intent-task.types.js +201 -40
  524. package/dist/backend/backend/src/types/intent-task.types.js.map +1 -1
  525. package/dist/backend/backend/src/types/memory.types.d.ts +53 -0
  526. package/dist/backend/backend/src/types/memory.types.d.ts.map +1 -1
  527. package/dist/backend/backend/src/types/memory.types.js.map +1 -1
  528. package/dist/backend/backend/src/types/orchestrator-state.types.d.ts +49 -0
  529. package/dist/backend/backend/src/types/orchestrator-state.types.d.ts.map +1 -1
  530. package/dist/backend/backend/src/types/orchestrator-state.types.js +27 -0
  531. package/dist/backend/backend/src/types/orchestrator-state.types.js.map +1 -1
  532. package/dist/backend/backend/src/types/settings.types.d.ts +38 -2
  533. package/dist/backend/backend/src/types/settings.types.d.ts.map +1 -1
  534. package/dist/backend/backend/src/types/settings.types.js +16 -2
  535. package/dist/backend/backend/src/types/settings.types.js.map +1 -1
  536. package/dist/backend/backend/src/types/v2/request.types.d.ts +5 -1
  537. package/dist/backend/backend/src/types/v2/request.types.d.ts.map +1 -1
  538. package/dist/backend/backend/src/types/v2/request.types.js +2 -2
  539. package/dist/backend/backend/src/types/v2/request.types.js.map +1 -1
  540. package/dist/backend/backend/src/types/v2/work-item.types.d.ts +40 -1
  541. package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  542. package/dist/backend/backend/src/types/v2/work-item.types.js +20 -0
  543. package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
  544. package/dist/backend/backend/src/utils/esm-require.utils.d.ts +111 -0
  545. package/dist/backend/backend/src/utils/esm-require.utils.d.ts.map +1 -0
  546. package/dist/backend/backend/src/utils/esm-require.utils.js +124 -0
  547. package/dist/backend/backend/src/utils/esm-require.utils.js.map +1 -0
  548. package/dist/backend/backend/src/utils/integrity-guarded-write.utils.d.ts +119 -0
  549. package/dist/backend/backend/src/utils/integrity-guarded-write.utils.d.ts.map +1 -0
  550. package/dist/backend/backend/src/utils/integrity-guarded-write.utils.js +212 -0
  551. package/dist/backend/backend/src/utils/integrity-guarded-write.utils.js.map +1 -0
  552. package/dist/backend/backend/src/utils/native-binding.utils.d.ts +128 -0
  553. package/dist/backend/backend/src/utils/native-binding.utils.d.ts.map +1 -0
  554. package/dist/backend/backend/src/utils/native-binding.utils.js +206 -0
  555. package/dist/backend/backend/src/utils/native-binding.utils.js.map +1 -0
  556. package/dist/backend/backend/src/utils/node-require.utils.d.ts +104 -0
  557. package/dist/backend/backend/src/utils/node-require.utils.d.ts.map +1 -0
  558. package/dist/backend/backend/src/utils/node-require.utils.js +111 -0
  559. package/dist/backend/backend/src/utils/node-require.utils.js.map +1 -0
  560. package/dist/cli/backend/src/models/Project.d.ts +2 -0
  561. package/dist/cli/backend/src/models/Project.d.ts.map +1 -1
  562. package/dist/cli/backend/src/models/Project.js +10 -1
  563. package/dist/cli/backend/src/models/Project.js.map +1 -1
  564. package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts +16 -0
  565. package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts.map +1 -1
  566. package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.js.map +1 -1
  567. package/dist/cli/backend/src/services/core/config.service.d.ts.map +1 -1
  568. package/dist/cli/backend/src/services/core/config.service.js +8 -1
  569. package/dist/cli/backend/src/services/core/config.service.js.map +1 -1
  570. package/dist/cli/backend/src/services/core/crewly-home.utils.d.ts +51 -0
  571. package/dist/cli/backend/src/services/core/crewly-home.utils.d.ts.map +1 -0
  572. package/dist/cli/backend/src/services/core/crewly-home.utils.js +59 -0
  573. package/dist/cli/backend/src/services/core/crewly-home.utils.js.map +1 -0
  574. package/dist/cli/backend/src/services/core/state-invariant.types.d.ts +53 -0
  575. package/dist/cli/backend/src/services/core/state-invariant.types.d.ts.map +1 -0
  576. package/dist/cli/backend/src/services/core/state-invariant.types.js +61 -0
  577. package/dist/cli/backend/src/services/core/state-invariant.types.js.map +1 -0
  578. package/dist/cli/backend/src/services/core/storage.service.d.ts +20 -0
  579. package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -1
  580. package/dist/cli/backend/src/services/core/storage.service.js +96 -8
  581. package/dist/cli/backend/src/services/core/storage.service.js.map +1 -1
  582. package/dist/cli/backend/src/services/core/teams-backup.service.d.ts +94 -4
  583. package/dist/cli/backend/src/services/core/teams-backup.service.d.ts.map +1 -1
  584. package/dist/cli/backend/src/services/core/teams-backup.service.js +172 -10
  585. package/dist/cli/backend/src/services/core/teams-backup.service.js.map +1 -1
  586. package/dist/cli/backend/src/services/event-bus/event-bus.service.d.ts +245 -0
  587. package/dist/cli/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -0
  588. package/dist/cli/backend/src/services/event-bus/event-bus.service.js +639 -0
  589. package/dist/cli/backend/src/services/event-bus/event-bus.service.js.map +1 -0
  590. package/dist/cli/backend/src/services/knowledge/fts5-index.service.d.ts.map +1 -1
  591. package/dist/cli/backend/src/services/knowledge/fts5-index.service.js +18 -13
  592. package/dist/cli/backend/src/services/knowledge/fts5-index.service.js.map +1 -1
  593. package/dist/cli/backend/src/services/knowledge/fts5-query-sanitizer.d.ts +102 -0
  594. package/dist/cli/backend/src/services/knowledge/fts5-query-sanitizer.d.ts.map +1 -0
  595. package/dist/cli/backend/src/services/knowledge/fts5-query-sanitizer.js +118 -0
  596. package/dist/cli/backend/src/services/knowledge/fts5-query-sanitizer.js.map +1 -0
  597. package/dist/cli/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
  598. package/dist/cli/backend/src/services/knowledge/vector-store.service.js +11 -15
  599. package/dist/cli/backend/src/services/knowledge/vector-store.service.js.map +1 -1
  600. package/dist/cli/backend/src/services/memory/agent-memory.service.d.ts +20 -0
  601. package/dist/cli/backend/src/services/memory/agent-memory.service.d.ts.map +1 -1
  602. package/dist/cli/backend/src/services/memory/agent-memory.service.js +27 -2
  603. package/dist/cli/backend/src/services/memory/agent-memory.service.js.map +1 -1
  604. package/dist/cli/backend/src/services/memory/memory.service.d.ts +48 -17
  605. package/dist/cli/backend/src/services/memory/memory.service.d.ts.map +1 -1
  606. package/dist/cli/backend/src/services/memory/memory.service.js +65 -35
  607. package/dist/cli/backend/src/services/memory/memory.service.js.map +1 -1
  608. package/dist/cli/backend/src/services/memory/role-knowledge-eligibility.d.ts +138 -0
  609. package/dist/cli/backend/src/services/memory/role-knowledge-eligibility.d.ts.map +1 -0
  610. package/dist/cli/backend/src/services/memory/role-knowledge-eligibility.js +183 -0
  611. package/dist/cli/backend/src/services/memory/role-knowledge-eligibility.js.map +1 -0
  612. package/dist/cli/backend/src/services/messaging/message-queue.service.d.ts +236 -0
  613. package/dist/cli/backend/src/services/messaging/message-queue.service.d.ts.map +1 -0
  614. package/dist/cli/backend/src/services/messaging/message-queue.service.js +581 -0
  615. package/dist/cli/backend/src/services/messaging/message-queue.service.js.map +1 -0
  616. package/dist/cli/backend/src/services/project/task-tracking.service.d.ts.map +1 -1
  617. package/dist/cli/backend/src/services/project/task-tracking.service.js +2 -2
  618. package/dist/cli/backend/src/services/project/task-tracking.service.js.map +1 -1
  619. package/dist/cli/backend/src/services/settings/settings.service.d.ts.map +1 -1
  620. package/dist/cli/backend/src/services/settings/settings.service.js +25 -0
  621. package/dist/cli/backend/src/services/settings/settings.service.js.map +1 -1
  622. package/dist/cli/backend/src/services/slack/slack-thread-store.service.d.ts +147 -0
  623. package/dist/cli/backend/src/services/slack/slack-thread-store.service.d.ts.map +1 -0
  624. package/dist/cli/backend/src/services/slack/slack-thread-store.service.js +258 -0
  625. package/dist/cli/backend/src/services/slack/slack-thread-store.service.js.map +1 -0
  626. package/dist/cli/backend/src/services/task-pool/pool-storage.d.ts +15 -1
  627. package/dist/cli/backend/src/services/task-pool/pool-storage.d.ts.map +1 -1
  628. package/dist/cli/backend/src/services/task-pool/pool-storage.js +31 -8
  629. package/dist/cli/backend/src/services/task-pool/pool-storage.js.map +1 -1
  630. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +459 -9
  631. package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  632. package/dist/cli/backend/src/services/task-pool/task-pool.service.js +1050 -126
  633. package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  634. package/dist/cli/backend/src/services/v3/work-item-projection.d.ts +40 -0
  635. package/dist/cli/backend/src/services/v3/work-item-projection.d.ts.map +1 -0
  636. package/dist/cli/backend/src/services/v3/work-item-projection.js +115 -0
  637. package/dist/cli/backend/src/services/v3/work-item-projection.js.map +1 -0
  638. package/dist/cli/backend/src/types/event-bus.types.d.ts +173 -0
  639. package/dist/cli/backend/src/types/event-bus.types.d.ts.map +1 -0
  640. package/dist/cli/backend/src/types/event-bus.types.js +218 -0
  641. package/dist/cli/backend/src/types/event-bus.types.js.map +1 -0
  642. package/dist/cli/backend/src/types/index.d.ts +11 -1
  643. package/dist/cli/backend/src/types/index.d.ts.map +1 -1
  644. package/dist/cli/backend/src/types/index.js +0 -2
  645. package/dist/cli/backend/src/types/index.js.map +1 -1
  646. package/dist/cli/backend/src/types/memory.types.d.ts +53 -0
  647. package/dist/cli/backend/src/types/memory.types.d.ts.map +1 -1
  648. package/dist/cli/backend/src/types/memory.types.js.map +1 -1
  649. package/dist/cli/backend/src/types/messaging.types.d.ts +223 -0
  650. package/dist/cli/backend/src/types/messaging.types.d.ts.map +1 -0
  651. package/dist/cli/backend/src/types/messaging.types.js +231 -0
  652. package/dist/cli/backend/src/types/messaging.types.js.map +1 -0
  653. package/dist/cli/backend/src/types/settings.types.d.ts +38 -2
  654. package/dist/cli/backend/src/types/settings.types.d.ts.map +1 -1
  655. package/dist/cli/backend/src/types/settings.types.js +16 -2
  656. package/dist/cli/backend/src/types/settings.types.js.map +1 -1
  657. package/dist/cli/backend/src/types/slack.types.d.ts +356 -0
  658. package/dist/cli/backend/src/types/slack.types.d.ts.map +1 -0
  659. package/dist/cli/backend/src/types/slack.types.js +66 -0
  660. package/dist/cli/backend/src/types/slack.types.js.map +1 -0
  661. package/dist/cli/backend/src/types/v2/claim.types.d.ts +2 -5
  662. package/dist/cli/backend/src/types/v2/claim.types.d.ts.map +1 -1
  663. package/dist/cli/backend/src/types/v2/claim.types.js +2 -5
  664. package/dist/cli/backend/src/types/v2/claim.types.js.map +1 -1
  665. package/dist/cli/backend/src/types/v2/work-item.types.d.ts +40 -1
  666. package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  667. package/dist/cli/backend/src/types/v2/work-item.types.js +20 -0
  668. package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
  669. package/dist/cli/backend/src/utils/format-error.d.ts +8 -0
  670. package/dist/cli/backend/src/utils/format-error.d.ts.map +1 -0
  671. package/dist/cli/backend/src/utils/format-error.js +10 -0
  672. package/dist/cli/backend/src/utils/format-error.js.map +1 -0
  673. package/dist/cli/backend/src/utils/integrity-guarded-write.utils.d.ts +119 -0
  674. package/dist/cli/backend/src/utils/integrity-guarded-write.utils.d.ts.map +1 -0
  675. package/dist/cli/backend/src/utils/integrity-guarded-write.utils.js +212 -0
  676. package/dist/cli/backend/src/utils/integrity-guarded-write.utils.js.map +1 -0
  677. package/dist/cli/backend/src/utils/node-require.utils.d.ts +104 -0
  678. package/dist/cli/backend/src/utils/node-require.utils.d.ts.map +1 -0
  679. package/dist/cli/backend/src/utils/node-require.utils.js +111 -0
  680. package/dist/cli/backend/src/utils/node-require.utils.js.map +1 -0
  681. package/frontend/dist/assets/{index-7a4e7df5.js → index-698305f3.js} +337 -337
  682. package/frontend/dist/index.html +1 -1
  683. package/package.json +6 -2
  684. package/dist/backend/backend/src/controllers/eval/eval.controller.d.ts +0 -63
  685. package/dist/backend/backend/src/controllers/eval/eval.controller.d.ts.map +0 -1
  686. package/dist/backend/backend/src/controllers/eval/eval.controller.js +0 -228
  687. package/dist/backend/backend/src/controllers/eval/eval.controller.js.map +0 -1
  688. package/dist/backend/backend/src/controllers/eval/eval.routes.d.ts +0 -23
  689. package/dist/backend/backend/src/controllers/eval/eval.routes.d.ts.map +0 -1
  690. package/dist/backend/backend/src/controllers/eval/eval.routes.js +0 -37
  691. package/dist/backend/backend/src/controllers/eval/eval.routes.js.map +0 -1
  692. package/dist/backend/backend/src/controllers/knowledge-v3/index.d.ts +0 -8
  693. package/dist/backend/backend/src/controllers/knowledge-v3/index.d.ts.map +0 -1
  694. package/dist/backend/backend/src/controllers/knowledge-v3/index.js +0 -8
  695. package/dist/backend/backend/src/controllers/knowledge-v3/index.js.map +0 -1
  696. package/dist/backend/backend/src/controllers/knowledge-v3/knowledge-v3.controller.d.ts +0 -63
  697. package/dist/backend/backend/src/controllers/knowledge-v3/knowledge-v3.controller.d.ts.map +0 -1
  698. package/dist/backend/backend/src/controllers/knowledge-v3/knowledge-v3.controller.js +0 -179
  699. package/dist/backend/backend/src/controllers/knowledge-v3/knowledge-v3.controller.js.map +0 -1
  700. package/dist/backend/backend/src/controllers/knowledge-v3/knowledge-v3.routes.d.ts +0 -22
  701. package/dist/backend/backend/src/controllers/knowledge-v3/knowledge-v3.routes.d.ts.map +0 -1
  702. package/dist/backend/backend/src/controllers/knowledge-v3/knowledge-v3.routes.js +0 -34
  703. package/dist/backend/backend/src/controllers/knowledge-v3/knowledge-v3.routes.js.map +0 -1
  704. package/dist/backend/backend/src/services/agent/crewly-agent/eval/adapters/cli-adapter.d.ts +0 -130
  705. package/dist/backend/backend/src/services/agent/crewly-agent/eval/adapters/cli-adapter.d.ts.map +0 -1
  706. package/dist/backend/backend/src/services/agent/crewly-agent/eval/adapters/cli-adapter.js +0 -406
  707. package/dist/backend/backend/src/services/agent/crewly-agent/eval/adapters/cli-adapter.js.map +0 -1
  708. package/dist/backend/backend/src/services/agent/crewly-agent/eval/adapters/crewly-agent-adapter.d.ts +0 -68
  709. package/dist/backend/backend/src/services/agent/crewly-agent/eval/adapters/crewly-agent-adapter.d.ts.map +0 -1
  710. package/dist/backend/backend/src/services/agent/crewly-agent/eval/adapters/crewly-agent-adapter.js +0 -206
  711. package/dist/backend/backend/src/services/agent/crewly-agent/eval/adapters/crewly-agent-adapter.js.map +0 -1
  712. package/dist/backend/backend/src/services/agent/crewly-agent/eval/adapters/index.d.ts +0 -32
  713. package/dist/backend/backend/src/services/agent/crewly-agent/eval/adapters/index.d.ts.map +0 -1
  714. package/dist/backend/backend/src/services/agent/crewly-agent/eval/adapters/index.js +0 -46
  715. package/dist/backend/backend/src/services/agent/crewly-agent/eval/adapters/index.js.map +0 -1
  716. package/dist/backend/backend/src/services/agent/crewly-agent/eval/context-generator.d.ts +0 -87
  717. package/dist/backend/backend/src/services/agent/crewly-agent/eval/context-generator.d.ts.map +0 -1
  718. package/dist/backend/backend/src/services/agent/crewly-agent/eval/context-generator.js +0 -299
  719. package/dist/backend/backend/src/services/agent/crewly-agent/eval/context-generator.js.map +0 -1
  720. package/dist/backend/backend/src/services/agent/crewly-agent/eval/eval-runner.d.ts +0 -59
  721. package/dist/backend/backend/src/services/agent/crewly-agent/eval/eval-runner.d.ts.map +0 -1
  722. package/dist/backend/backend/src/services/agent/crewly-agent/eval/eval-runner.js +0 -218
  723. package/dist/backend/backend/src/services/agent/crewly-agent/eval/eval-runner.js.map +0 -1
  724. package/dist/backend/backend/src/services/agent/crewly-agent/eval/eval-scorer.d.ts +0 -203
  725. package/dist/backend/backend/src/services/agent/crewly-agent/eval/eval-scorer.d.ts.map +0 -1
  726. package/dist/backend/backend/src/services/agent/crewly-agent/eval/eval-scorer.js +0 -467
  727. package/dist/backend/backend/src/services/agent/crewly-agent/eval/eval-scorer.js.map +0 -1
  728. package/dist/backend/backend/src/services/agent/crewly-agent/eval/eval-types.d.ts +0 -313
  729. package/dist/backend/backend/src/services/agent/crewly-agent/eval/eval-types.d.ts.map +0 -1
  730. package/dist/backend/backend/src/services/agent/crewly-agent/eval/eval-types.js +0 -45
  731. package/dist/backend/backend/src/services/agent/crewly-agent/eval/eval-types.js.map +0 -1
  732. package/dist/backend/backend/src/services/agent/crewly-agent/eval/index.d.ts +0 -21
  733. package/dist/backend/backend/src/services/agent/crewly-agent/eval/index.d.ts.map +0 -1
  734. package/dist/backend/backend/src/services/agent/crewly-agent/eval/index.js +0 -21
  735. package/dist/backend/backend/src/services/agent/crewly-agent/eval/index.js.map +0 -1
  736. package/dist/backend/backend/src/services/agent/crewly-agent/eval/run-eval-cli.d.ts +0 -15
  737. package/dist/backend/backend/src/services/agent/crewly-agent/eval/run-eval-cli.d.ts.map +0 -1
  738. package/dist/backend/backend/src/services/agent/crewly-agent/eval/run-eval-cli.js +0 -349
  739. package/dist/backend/backend/src/services/agent/crewly-agent/eval/run-eval-cli.js.map +0 -1
  740. package/dist/backend/backend/src/services/agent/crewly-agent/eval/run-eval-l4.d.ts +0 -97
  741. package/dist/backend/backend/src/services/agent/crewly-agent/eval/run-eval-l4.d.ts.map +0 -1
  742. package/dist/backend/backend/src/services/agent/crewly-agent/eval/run-eval-l4.js +0 -414
  743. package/dist/backend/backend/src/services/agent/crewly-agent/eval/run-eval-l4.js.map +0 -1
  744. package/dist/backend/backend/src/services/agent/crewly-agent/eval/run-eval-standalone.d.ts +0 -42
  745. package/dist/backend/backend/src/services/agent/crewly-agent/eval/run-eval-standalone.d.ts.map +0 -1
  746. package/dist/backend/backend/src/services/agent/crewly-agent/eval/run-eval-standalone.js +0 -403
  747. package/dist/backend/backend/src/services/agent/crewly-agent/eval/run-eval-standalone.js.map +0 -1
  748. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/index.d.ts +0 -41
  749. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/index.d.ts.map +0 -1
  750. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/index.js +0 -58
  751. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/index.js.map +0 -1
  752. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/l1-tasks.d.ts +0 -15
  753. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/l1-tasks.d.ts.map +0 -1
  754. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/l1-tasks.js +0 -396
  755. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/l1-tasks.js.map +0 -1
  756. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/l2-tasks.d.ts +0 -14
  757. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/l2-tasks.d.ts.map +0 -1
  758. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/l2-tasks.js +0 -564
  759. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/l2-tasks.js.map +0 -1
  760. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/l3-tasks.d.ts +0 -13
  761. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/l3-tasks.d.ts.map +0 -1
  762. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/l3-tasks.js +0 -634
  763. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/l3-tasks.js.map +0 -1
  764. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/l4-tasks.d.ts +0 -21
  765. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/l4-tasks.d.ts.map +0 -1
  766. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/l4-tasks.js +0 -1036
  767. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tasks/l4-tasks.js.map +0 -1
  768. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tool-log-parser.d.ts +0 -100
  769. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tool-log-parser.d.ts.map +0 -1
  770. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tool-log-parser.js +0 -187
  771. package/dist/backend/backend/src/services/agent/crewly-agent/eval/tool-log-parser.js.map +0 -1
  772. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts +0 -79
  773. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts.map +0 -1
  774. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js +0 -118
  775. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js.map +0 -1
  776. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.d.ts +0 -113
  777. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.d.ts.map +0 -1
  778. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.js +0 -179
  779. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.js.map +0 -1
  780. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.d.ts +0 -131
  781. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.d.ts.map +0 -1
  782. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.js +0 -227
  783. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.js.map +0 -1
  784. package/dist/backend/backend/src/services/knowledge/fts5-search-strategy.d.ts +0 -56
  785. package/dist/backend/backend/src/services/knowledge/fts5-search-strategy.d.ts.map +0 -1
  786. package/dist/backend/backend/src/services/knowledge/fts5-search-strategy.js +0 -91
  787. package/dist/backend/backend/src/services/knowledge/fts5-search-strategy.js.map +0 -1
  788. package/dist/backend/backend/src/services/memory/learning-format.validator.d.ts +0 -97
  789. package/dist/backend/backend/src/services/memory/learning-format.validator.d.ts.map +0 -1
  790. package/dist/backend/backend/src/services/memory/learning-format.validator.js +0 -209
  791. package/dist/backend/backend/src/services/memory/learning-format.validator.js.map +0 -1
  792. /package/dist/{backend → cli}/backend/src/services/knowledge/learnings-index.service.d.ts +0 -0
  793. /package/dist/{backend → cli}/backend/src/services/knowledge/learnings-index.service.d.ts.map +0 -0
  794. /package/dist/{backend → cli}/backend/src/services/knowledge/learnings-index.service.js +0 -0
  795. /package/dist/{backend → cli}/backend/src/services/knowledge/learnings-index.service.js.map +0 -0
@@ -11,8 +11,28 @@
11
11
  import { PoolStorage } from './pool-storage.js';
12
12
  import { ClaimService } from './claim.service.js';
13
13
  import { LoggerService } from '../core/logger.service.js';
14
- import { isWorkItem, isValidWorkItemTransition } from '../../types/v2/work-item.types.js';
15
- import { createTaskClaim, PROJECT_TASK_LEASE_DURATION_MS, } from '../../types/v2/claim.types.js';
14
+ import { formatError } from '../../utils/format-error.js';
15
+ import { isWorkItem, isValidWorkItemTransition, isTransitionPermitted } from '../../types/v2/work-item.types.js';
16
+ import { createTaskClaim, } from '../../types/v2/claim.types.js';
17
+ /**
18
+ * Structured error thrown by {@link TaskPoolService.removeFromPool}
19
+ * when an active claim exists and `force: true` was not passed.
20
+ */
21
+ export class WorkItemClaimedError extends Error {
22
+ workItemId;
23
+ claimId;
24
+ claimedBy;
25
+ constructor(args) {
26
+ super(`WorkItem '${args.workItemId}' has an active claim ` +
27
+ `(claimId='${args.claimId}', claimedBy='${args.claimedBy}'). ` +
28
+ `Pass { force: true } to delete anyway (will revoke the claim).`);
29
+ this.name = 'WorkItemClaimedError';
30
+ this.workItemId = args.workItemId;
31
+ this.claimId = args.claimId;
32
+ this.claimedBy = args.claimedBy;
33
+ Object.setPrototypeOf(this, WorkItemClaimedError.prototype);
34
+ }
35
+ }
16
36
  // ---------------------------------------------------------------------------
17
37
  // Service
18
38
  // ---------------------------------------------------------------------------
@@ -42,11 +62,87 @@ export class TaskPoolService {
42
62
  storage;
43
63
  claimService;
44
64
  logger;
65
+ /**
66
+ * Optional EventBus reference — wired via {@link setEventBusService} from
67
+ * the boot path. When set, {@link addToPool} publishes a `workitem:queued`
68
+ * event so subscribers (notably {@link RequestSlaSubscriber}) can react to
69
+ * queue mutations. Optional because singleton callers (tests, CLI) bring
70
+ * up the pool before the bus exists; missing bus is treated as a no-op
71
+ * publish at warn level.
72
+ */
73
+ eventBus = null;
74
+ /**
75
+ * Optional Request-linker reference — wired via {@link setRequestService}
76
+ * from the boot path. When set, {@link addToPool} pushes the new WI's id
77
+ * into the parent `Request.workItemIds[]` immediately after the storage
78
+ * flush, independent of any downstream subscriber.
79
+ *
80
+ * P1 Bug B (Pool umbrella WI 72ca743a) intrinsic-link contract:
81
+ * - The pre-fix path relied on `workitem:queued` / `task:delegated`
82
+ * subscribers (request-sla.subscriber, V3DataService) to backfill
83
+ * `Request.workItemIds[]`. Manual / programmatic / cron callers that
84
+ * bypass the standard event chain left Requests with
85
+ * `workItemIds=[]` even though their WIs were in the pool.
86
+ * - The intrinsic path here is the source-of-truth link and runs on
87
+ * every `addToPool`. Subscriber-driven linking remains as
88
+ * belt-and-suspenders (idempotent — see request.service.ts:328
89
+ * short-circuit on duplicate id).
90
+ * - Optional because singleton callers (tests, CLI) bring up the pool
91
+ * before RequestService exists; missing linker is a no-op debug log.
92
+ */
93
+ requestService = null;
94
+ /**
95
+ * Serializes claim operations to prevent the race where two concurrent
96
+ * claimFromPool / claimSpecificItem calls both select the same queued
97
+ * WorkItem between their read and write phases. In-process only — does
98
+ * not protect against cross-process races, but the backend runs as a
99
+ * single process today.
100
+ */
101
+ claimMutex = Promise.resolve();
45
102
  constructor(storage) {
46
103
  this.storage = storage ?? new PoolStorage();
47
104
  this.claimService = new ClaimService(this.storage);
48
105
  this.logger = LoggerService.getInstance().createComponentLogger('TaskPoolService');
49
106
  }
107
+ /**
108
+ * Wire the EventBus reference used by {@link addToPool} to publish
109
+ * `workitem:queued` events (INBOUND-1.f1). Called from the backend boot
110
+ * path after both services have been constructed. Idempotent and may be
111
+ * called with `null` to disable publishing (testing).
112
+ *
113
+ * @param bus - The EventBus instance, or null to clear
114
+ */
115
+ setEventBusService(bus) {
116
+ this.eventBus = bus;
117
+ }
118
+ /**
119
+ * Wire the Request-linker reference used by {@link addToPool} to
120
+ * intrinsically link the new WI into its parent `Request.workItemIds[]`
121
+ * (P1 Bug B — Pool umbrella WI 72ca743a).
122
+ *
123
+ * Called from the backend boot path after both services exist.
124
+ * Idempotent and may be called with `null` to disable intrinsic
125
+ * linking (testing). Mirrors the {@link setEventBusService} setter
126
+ * pattern so the dependency wiring stays uniform and grep-able.
127
+ *
128
+ * @param svc - The RequestService instance (or any object satisfying
129
+ * {@link IRequestWorkItemLinker}), or null to clear.
130
+ */
131
+ setRequestService(svc) {
132
+ this.requestService = svc;
133
+ }
134
+ /**
135
+ * Chains the given critical section after any in-flight claim operation.
136
+ * Guarantees FIFO ordering even under concurrent invocation.
137
+ */
138
+ withClaimLock(fn) {
139
+ const prev = this.claimMutex;
140
+ let release;
141
+ this.claimMutex = new Promise((r) => {
142
+ release = r;
143
+ });
144
+ return prev.then(fn).finally(() => release());
145
+ }
50
146
  /**
51
147
  * Get singleton instance of TaskPoolService.
52
148
  *
@@ -70,18 +166,20 @@ export class TaskPoolService {
70
166
  /**
71
167
  * Adds an execution-ready WorkItem to the pool.
72
168
  *
73
- * The item must have status 'queued' to be added. Items with other
74
- * statuses are rejected.
169
+ * Accepted statuses:
170
+ * - `queued` — ready to run
171
+ * - `blocked` — waiting on unresolved dependsOn; the resolver will promote
172
+ * it to `queued` when every upstream dep reaches terminal success.
75
173
  *
76
174
  * @param workItem - The work item to add
77
- * @throws Error if workItem is not valid or not in 'queued' status
175
+ * @throws Error if workItem is invalid or in an ineligible status
78
176
  */
79
177
  async addToPool(workItem) {
80
178
  if (!isWorkItem(workItem)) {
81
179
  throw new Error('Invalid WorkItem: does not conform to WorkItem interface');
82
180
  }
83
- if (workItem.status !== 'queued') {
84
- throw new Error(`Cannot add WorkItem to pool: status must be 'queued', got '${workItem.status}'`);
181
+ if (workItem.status !== 'queued' && workItem.status !== 'blocked') {
182
+ throw new Error(`Cannot add WorkItem to pool: status must be 'queued' or 'blocked', got '${workItem.status}'`);
85
183
  }
86
184
  // Check for duplicates
87
185
  const existing = await this.storage.findWorkItem(workItem.id);
@@ -96,6 +194,287 @@ export class TaskPoolService {
96
194
  type: workItem.type,
97
195
  title: workItem.title,
98
196
  });
197
+ // P1 Bug B (Pool umbrella WI 72ca743a): intrinsically link the new
198
+ // WI into its parent `Request.workItemIds[]` if a linker is wired
199
+ // and the WI carries a requestId. This is the SOURCE-OF-TRUTH link
200
+ // and runs unconditionally on every successful addToPool, fixing
201
+ // the bug where manual / programmatic / cron / orchestrator-script
202
+ // callers that bypass the standard event chain left Requests with
203
+ // empty `workItemIds[]`.
204
+ //
205
+ // Subscriber-driven linking (request-sla.subscriber.ts on
206
+ // workitem:queued, V3DataService.onTaskDelegated on task:delegated)
207
+ // continues to run as belt-and-suspenders — `linkWorkItem` is
208
+ // idempotent (request.service.ts:328 short-circuits on duplicate id),
209
+ // so double-link is safe.
210
+ //
211
+ // Failure isolation: pool mutation is the source of truth. Link
212
+ // failures are warn-logged and swallowed; subscriber path remains
213
+ // as a backup, and a future addToPool of the same WI is a no-op
214
+ // (storage dedup) so retry comes via natural traffic.
215
+ await this.linkWorkItemToRequest(workItem);
216
+ // INBOUND-1.f1: announce the queue mutation so subscribers (notably the
217
+ // RequestSlaSubscriber) can react. We publish AFTER the storage flush
218
+ // so any subscriber that re-reads via taskPool.findWorkItem sees the
219
+ // committed item. Publish failures are logged-but-isolated — the pool
220
+ // mutation is the source of truth, the event is informational.
221
+ this.publishWorkItemQueued(workItem);
222
+ }
223
+ /**
224
+ * P1 Bug B helper: intrinsically link a freshly-added WI into its
225
+ * parent `Request.workItemIds[]`.
226
+ *
227
+ * Stays a separate method (vs inlining) so:
228
+ * 1. The dependency on RequestService stays explicit and grep-able,
229
+ * mirroring {@link publishWorkItemQueued}.
230
+ * 2. Future enqueue paths (e.g. a batch addAll) can route through
231
+ * the same linker for consistent behaviour.
232
+ * 3. Error handling stays in one place — a thrown linker must NOT
233
+ * back out the pool mutation (the storage write already committed).
234
+ *
235
+ * @param workItem - The WI just persisted into the pool.
236
+ */
237
+ async linkWorkItemToRequest(workItem) {
238
+ if (!workItem.requestId) {
239
+ // No parent Request — nothing to link.
240
+ return;
241
+ }
242
+ if (!this.requestService) {
243
+ this.logger.debug('No RequestService wired — skipping intrinsic Request link', { workItemId: workItem.id, requestId: workItem.requestId });
244
+ return;
245
+ }
246
+ try {
247
+ await this.requestService.linkWorkItem(workItem.requestId, workItem.id);
248
+ }
249
+ catch (linkError) {
250
+ this.logger.warn('Bug B intrinsic link failed (subscriber path remains as fallback)', {
251
+ requestId: workItem.requestId,
252
+ workItemId: workItem.id,
253
+ error: formatError(linkError),
254
+ });
255
+ }
256
+ }
257
+ /**
258
+ * INBOUND-1.f1 helper: publish a `workitem:queued` event with correlation
259
+ * ids the SLA subscriber needs (`requestId`, `missionId`, plus the new
260
+ * `workItemId`). Called by {@link addToPool} after the storage flush.
261
+ *
262
+ * Stays a separate method (vs inlining) so:
263
+ * 1. The dependency on EventBus stays explicit and grep-able.
264
+ * 2. A future caller adding an alternate enqueue path (e.g. a batch
265
+ * addAll) can route through the same publisher for consistent
266
+ * observability.
267
+ * 3. Error handling stays in one place — a thrown publisher must NOT
268
+ * back out the pool mutation (the storage write already committed).
269
+ */
270
+ publishWorkItemQueued(workItem) {
271
+ if (!this.eventBus) {
272
+ this.logger.debug('No EventBus wired — skipping workitem:queued publish', {
273
+ workItemId: workItem.id,
274
+ });
275
+ return;
276
+ }
277
+ try {
278
+ this.eventBus.publish({
279
+ // Deterministic event id keyed on the WI id so a redelivered storage
280
+ // path (theoretical) collapses through the bus's per-(type,session)
281
+ // debounce window without firing the SLA handler twice.
282
+ id: `workitem:queued:${workItem.id}`,
283
+ type: 'workitem:queued',
284
+ timestamp: new Date().toISOString(),
285
+ teamId: '',
286
+ teamName: '',
287
+ memberId: '',
288
+ memberName: '',
289
+ // sessionName is empty — `workitem:queued` is a system-level event
290
+ // not attributable to a specific agent session. The bus's dedup key
291
+ // is `${type}:${sessionName}` so a unique sessionName per WI would
292
+ // defeat the dedup; an empty sessionName scoped per-id is fine since
293
+ // the event id already encodes the WI uniquely.
294
+ sessionName: '',
295
+ previousValue: '',
296
+ newValue: workItem.status,
297
+ changedField: 'taskStatus',
298
+ // INBOUND-1.f1 correlation fields. Mandatory: workItemId. Optional:
299
+ // requestId, missionId — populated when the WI carries them. The SLA
300
+ // subscriber no-ops when requestId is undefined (per spec), so we
301
+ // don't need a fallback chain here.
302
+ workItemId: workItem.id,
303
+ requestId: workItem.requestId,
304
+ missionId: workItem.missionId,
305
+ });
306
+ }
307
+ catch (err) {
308
+ this.logger.warn('workitem:queued publish threw', {
309
+ workItemId: workItem.id,
310
+ error: formatError(err),
311
+ });
312
+ }
313
+ }
314
+ /**
315
+ * F1-BRIDGE-1 helper: publish `task:done_by_worker` after a successful
316
+ * `submitForVerification` transition. The {@link EventToWorkItemBridge}
317
+ * subscribes to this event and creates a verification WorkItem for the
318
+ * resolved team-lead session.
319
+ *
320
+ * Stays a separate method (mirrors {@link publishWorkItemQueued}) so:
321
+ * 1. The dependency on EventBus stays explicit and grep-able — Arch's
322
+ * grep guard checks both the type declaration AND a publish call
323
+ * site for `task:done_by_worker`.
324
+ * 2. Error handling is uniform with the other publishers — a thrown
325
+ * bus must NOT back out the verified state transition; the storage
326
+ * flush has already committed.
327
+ * 3. A future caller adding an alternate verification-submission path
328
+ * (e.g. an admin endpoint or a CLI) routes through the same publisher.
329
+ *
330
+ * The deterministic event id (`task:done_by_worker:${workItemId}`) keys
331
+ * dedup so a redelivered submitForVerification (theoretical) collapses
332
+ * through the bus without firing the bridge handler twice.
333
+ */
334
+ publishTaskDoneByWorker(workItem) {
335
+ if (!this.eventBus) {
336
+ this.logger.debug('No EventBus wired — skipping task:done_by_worker publish', {
337
+ workItemId: workItem.id,
338
+ });
339
+ return;
340
+ }
341
+ try {
342
+ this.eventBus.publish({
343
+ id: `task:done_by_worker:${workItem.id}`,
344
+ type: 'task:done_by_worker',
345
+ timestamp: new Date().toISOString(),
346
+ teamId: '',
347
+ teamName: '',
348
+ memberId: '',
349
+ memberName: '',
350
+ // sessionName is empty — `task:done_by_worker` is published from the
351
+ // pool layer which doesn't carry the worker's PTY session. The bridge
352
+ // uses `workItemId` (and falls back to `taskId`) to resolve the
353
+ // source WI; sessionName is informational. Empty matches the
354
+ // workitem:queued publish convention.
355
+ sessionName: '',
356
+ // The state machine just landed at done_by_worker. Carry both ends
357
+ // so any subscriber filtering on (previousValue, newValue) sees
358
+ // the canonical transition.
359
+ previousValue: 'running',
360
+ newValue: 'done_by_worker',
361
+ changedField: 'taskStatus',
362
+ // BRIDGE-1.1 hybrid extension. `workItemId` is mandatory for the
363
+ // bridge handler; the `taskId` fallback path is unused here because
364
+ // WorkItem itself does not carry a taskId (the bridge resolves the
365
+ // source WI by id alone via taskPool.findWorkItem).
366
+ workItemId: workItem.id,
367
+ missionId: workItem.missionId,
368
+ requestId: workItem.requestId,
369
+ });
370
+ }
371
+ catch (err) {
372
+ this.logger.warn('task:done_by_worker publish threw', {
373
+ workItemId: workItem.id,
374
+ error: formatError(err),
375
+ });
376
+ }
377
+ }
378
+ /**
379
+ * F1-BRIDGE-1 helper: publish `task:rejected` after a successful
380
+ * `verifyItem` transition with verdict='rejected'. The
381
+ * {@link EventToWorkItemBridge} subscribes and either creates a retry
382
+ * WI (`retryCount < maxRetries`) or escalates to a TL review WI with
383
+ * `reviewReason='max_retries_exceeded'` at the cap.
384
+ *
385
+ * Mirrors {@link publishTaskDoneByWorker} for symmetry. Only the
386
+ * verdict='rejected' branch reaches this publisher — `verdict='verified'`
387
+ * does NOT publish (terminal-success path goes through
388
+ * {@link resolveBlockedDependents}, which is not a bridge trigger).
389
+ */
390
+ publishTaskRejected(workItem) {
391
+ if (!this.eventBus) {
392
+ this.logger.debug('No EventBus wired — skipping task:rejected publish', {
393
+ workItemId: workItem.id,
394
+ });
395
+ return;
396
+ }
397
+ try {
398
+ this.eventBus.publish({
399
+ id: `task:rejected:${workItem.id}`,
400
+ type: 'task:rejected',
401
+ timestamp: new Date().toISOString(),
402
+ teamId: '',
403
+ teamName: '',
404
+ memberId: '',
405
+ memberName: '',
406
+ sessionName: '',
407
+ previousValue: 'done_by_worker',
408
+ newValue: 'rejected',
409
+ changedField: 'taskStatus',
410
+ workItemId: workItem.id,
411
+ missionId: workItem.missionId,
412
+ requestId: workItem.requestId,
413
+ });
414
+ }
415
+ catch (err) {
416
+ this.logger.warn('task:rejected publish threw', {
417
+ workItemId: workItem.id,
418
+ error: formatError(err),
419
+ });
420
+ }
421
+ }
422
+ /**
423
+ * Publish `task:cancelled` whenever a WorkItem transitions to the
424
+ * cancelled status via {@link updateItemStatus} or {@link transitionStatus}.
425
+ *
426
+ * **Why this exists.** 2026-05-09 dogfood: 4 child WIs of a Slack-
427
+ * originated Request all landed in `cancelled` (orc-not-in-health-map
428
+ * loop, fixed in #531) but the Request stayed in `ready` for hours.
429
+ * `cascadeRequestStatus` only fires from V3DataService's task
430
+ * handlers, which are wired to the retired `v3:task_*` events
431
+ * (`mission-executor.service.ts:152` v1-cleanup comment) — so out-of-
432
+ * band cancellations never reached cascade. The heartbeat sweep
433
+ * eventually caught it (#533), but with up-to-30-min latency that
434
+ * showed up as a misleading "0/4 in every bucket" ping in the user's
435
+ * Slack thread.
436
+ *
437
+ * Publishing `task:cancelled` lets `RequestCascadeSubscriber` close
438
+ * the Request within seconds of the last child cancelling, instead
439
+ * of waiting for the heartbeat catch.
440
+ *
441
+ * Mirrors {@link publishTaskDoneByWorker} / {@link publishTaskRejected}
442
+ * so the EventBus surface stays uniform.
443
+ *
444
+ * @param workItem - The WI snapshot AFTER the cancelled transition committed
445
+ * @param previousStatus - The status it transitioned from (for the event payload)
446
+ */
447
+ publishTaskCancelled(workItem, previousStatus) {
448
+ if (!this.eventBus) {
449
+ this.logger.debug('No EventBus wired — skipping task:cancelled publish', {
450
+ workItemId: workItem.id,
451
+ });
452
+ return;
453
+ }
454
+ try {
455
+ this.eventBus.publish({
456
+ id: `task:cancelled:${workItem.id}`,
457
+ type: 'task:cancelled',
458
+ timestamp: new Date().toISOString(),
459
+ teamId: '',
460
+ teamName: '',
461
+ memberId: '',
462
+ memberName: '',
463
+ sessionName: '',
464
+ previousValue: previousStatus,
465
+ newValue: 'cancelled',
466
+ changedField: 'taskStatus',
467
+ workItemId: workItem.id,
468
+ missionId: workItem.missionId,
469
+ requestId: workItem.requestId,
470
+ });
471
+ }
472
+ catch (err) {
473
+ this.logger.warn('task:cancelled publish threw', {
474
+ workItemId: workItem.id,
475
+ error: formatError(err),
476
+ });
477
+ }
99
478
  }
100
479
  /**
101
480
  * Claims the next available WorkItem from the pool for an agent.
@@ -111,62 +490,87 @@ export class TaskPoolService {
111
490
  if (!agentId || typeof agentId !== 'string') {
112
491
  throw new Error('agentId is required and must be a non-empty string');
113
492
  }
114
- // Check if agent already has an active claim
115
- const existingClaim = await this.storage.findActiveClaimByAgent(agentId);
116
- if (existingClaim) {
117
- this.logger.warn('Agent already has an active claim', {
493
+ return this.withClaimLock(async () => {
494
+ // Check if agent already has an active claim
495
+ const existingClaim = await this.storage.findActiveClaimByAgent(agentId);
496
+ if (existingClaim) {
497
+ this.logger.warn('Agent already has an active claim', {
498
+ agentId,
499
+ existingClaimId: existingClaim.id,
500
+ existingWorkItemId: existingClaim.workItemId,
501
+ });
502
+ return null;
503
+ }
504
+ const workItems = await this.storage.getWorkItems();
505
+ const claims = await this.storage.getClaims();
506
+ // Set of work item IDs that have active claims
507
+ const claimedIds = new Set(claims
508
+ .filter((c) => c.status === 'active')
509
+ .map((c) => c.workItemId));
510
+ // Hygiene #3 — target-respect gate. Before this filter, claimFromPool
511
+ // would FIFO-pick the oldest queued+unclaimed item regardless of
512
+ // its existing `target` field, then unconditionally rewrite
513
+ // `wi.target = agentId` in the transitionStatus mutator. That
514
+ // produced the target-rotation bug observed in the 5/9 wave (WIs
515
+ // rotating through Quinn → Sam, Leo → Quinn, etc.).
516
+ //
517
+ // After this filter:
518
+ // - WIs with an explicit target are claimable ONLY by that target.
519
+ // - WIs with no target (broadcast pool) remain claimable by any agent.
520
+ // The defensive identity check in the transitionStatus mutator
521
+ // below ensures we never accidentally overwrite an existing target
522
+ // even if a future code path bypasses this filter.
523
+ const targetRespectingCandidates = workItems
524
+ .filter((wi) => wi.status === 'queued' && !claimedIds.has(wi.id))
525
+ .filter((wi) => !wi.target || wi.target === agentId);
526
+ // Find first matching unclaimed queued item (FIFO by createdAt)
527
+ const candidates = targetRespectingCandidates
528
+ .filter((wi) => matchesFilters(wi, filters))
529
+ .sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
530
+ if (candidates.length === 0) {
531
+ return null;
532
+ }
533
+ const selected = candidates[0];
534
+ // TRANS-2: route the queued → running flip through the guarded
535
+ // transitionStatus helper so internal callers are subject to the
536
+ // same V3 actor-role + state-machine gates as external callers.
537
+ // `startedAt` is set automatically by transitionStatus when
538
+ // newStatus === 'running'; the mutator carries the agent target.
539
+ //
540
+ // Hygiene #3 — target-respect (defensive). The candidate filter
541
+ // above already excludes WIs whose target ≠ agentId, so the only
542
+ // remaining cases here are (a) wi.target === agentId (no-op assign)
543
+ // and (b) wi.target === undefined (broadcast claim). Either way we
544
+ // refuse to overwrite a non-matching existing target.
545
+ const claimedItem = await this.transitionStatus(selected.id, 'running', 'system', (wi) => {
546
+ if (!wi.target) {
547
+ wi.target = agentId;
548
+ }
549
+ // else: target already === agentId per the filter; leave as-is.
550
+ });
551
+ if (!claimedItem) {
552
+ this.logger.warn('Failed to update WorkItem during claim', { workItemId: selected.id });
553
+ return null;
554
+ }
555
+ // Create the claim
556
+ const claimInput = {
557
+ workItemId: selected.id,
558
+ agentId,
559
+ };
560
+ const claim = createTaskClaim(claimInput);
561
+ await this.storage.addClaim(claim);
562
+ await this.storage.flush();
563
+ this.logger.info('WorkItem claimed', {
564
+ workItemId: selected.id,
118
565
  agentId,
119
- existingClaimId: existingClaim.id,
120
- existingWorkItemId: existingClaim.workItemId,
566
+ claimId: claim.id,
567
+ title: selected.title,
121
568
  });
122
- return null;
123
- }
124
- const workItems = await this.storage.getWorkItems();
125
- const claims = await this.storage.getClaims();
126
- // Set of work item IDs that have active claims
127
- const claimedIds = new Set(claims
128
- .filter((c) => c.status === 'active')
129
- .map((c) => c.workItemId));
130
- // Find first matching unclaimed queued item (FIFO by createdAt)
131
- const candidates = workItems
132
- .filter((wi) => wi.status === 'queued' && !claimedIds.has(wi.id))
133
- .filter((wi) => matchesFilters(wi, filters))
134
- .sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
135
- if (candidates.length === 0) {
136
- return null;
137
- }
138
- const selected = candidates[0];
139
- // Transition item to 'running'
140
- const updated = await this.storage.updateWorkItem(selected.id, (wi) => {
141
- wi.status = 'running';
142
- wi.startedAt = new Date().toISOString();
143
- wi.target = agentId;
144
- });
145
- if (!updated) {
146
- this.logger.warn('Failed to update WorkItem during claim', { workItemId: selected.id });
147
- return null;
148
- }
149
- // Create the claim (project_task gets extended lease to avoid premature revocation)
150
- const claimInput = {
151
- workItemId: selected.id,
152
- agentId,
153
- ...(selected.type === 'project_task' ? { leaseDurationMs: PROJECT_TASK_LEASE_DURATION_MS } : {}),
154
- };
155
- const claim = createTaskClaim(claimInput);
156
- await this.storage.addClaim(claim);
157
- await this.storage.flush();
158
- this.logger.info('WorkItem claimed', {
159
- workItemId: selected.id,
160
- agentId,
161
- claimId: claim.id,
162
- title: selected.title,
569
+ return {
570
+ workItem: claimedItem,
571
+ claim,
572
+ };
163
573
  });
164
- // Return the updated item
165
- const claimedItem = await this.storage.findWorkItem(selected.id);
166
- return {
167
- workItem: claimedItem,
168
- claim,
169
- };
170
574
  }
171
575
  /**
172
576
  * Claims a specific WorkItem by ID for an agent.
@@ -181,33 +585,49 @@ export class TaskPoolService {
181
585
  if (!agentId || typeof agentId !== 'string') {
182
586
  throw new Error('agentId is required and must be a non-empty string');
183
587
  }
184
- const existingClaim = await this.storage.findActiveClaimByAgent(agentId);
185
- if (existingClaim)
186
- return null;
187
- const workItem = await this.storage.findWorkItem(workItemId);
188
- if (!workItem || workItem.status !== 'queued')
189
- return null;
190
- const claims = await this.storage.getClaims();
191
- if (claims.some((c) => c.workItemId === workItemId && c.status === 'active'))
192
- return null;
193
- const updated = await this.storage.updateWorkItem(workItemId, (wi) => {
194
- wi.status = 'running';
195
- wi.startedAt = new Date().toISOString();
196
- wi.target = agentId;
588
+ return this.withClaimLock(async () => {
589
+ const existingClaim = await this.storage.findActiveClaimByAgent(agentId);
590
+ if (existingClaim)
591
+ return null;
592
+ const workItem = await this.storage.findWorkItem(workItemId);
593
+ if (!workItem || workItem.status !== 'queued')
594
+ return null;
595
+ // Hygiene #3 — target-respect gate. Refuse to claim a WI whose
596
+ // existing target is set to a different agent. This prevents the
597
+ // claimSpecificItem path (used by AgentAutoClaimService for
598
+ // score-based selection) from rotating target onto an idle agent
599
+ // when another agent is the actual target. Same rule as
600
+ // claimFromPool: target=undefined (broadcast) is claimable by any
601
+ // agent; target=agentId is claimable only by that agent.
602
+ if (workItem.target && workItem.target !== agentId) {
603
+ this.logger.debug('claimSpecificItem refused — target mismatch', {
604
+ workItemId,
605
+ existingTarget: workItem.target,
606
+ requestingAgent: agentId,
607
+ });
608
+ return null;
609
+ }
610
+ const claims = await this.storage.getClaims();
611
+ if (claims.some((c) => c.workItemId === workItemId && c.status === 'active'))
612
+ return null;
613
+ // TRANS-2: route the queued → running flip through transitionStatus
614
+ // (mirrors claimFromPool — same V3 + state-machine gates).
615
+ // Hygiene #3 defensive: only assign target when it's currently
616
+ // undefined; never overwrite an existing target.
617
+ const claimedItem = await this.transitionStatus(workItemId, 'running', 'system', (wi) => {
618
+ if (!wi.target) {
619
+ wi.target = agentId;
620
+ }
621
+ });
622
+ if (!claimedItem)
623
+ return null;
624
+ const claimInput = { workItemId, agentId };
625
+ const claim = createTaskClaim(claimInput);
626
+ await this.storage.addClaim(claim);
627
+ await this.storage.flush();
628
+ this.logger.info('WorkItem claimed (specific)', { workItemId, agentId, claimId: claim.id });
629
+ return { workItem: claimedItem, claim };
197
630
  });
198
- if (!updated)
199
- return null;
200
- const claimInput = {
201
- workItemId,
202
- agentId,
203
- ...(workItem.type === 'project_task' ? { leaseDurationMs: PROJECT_TASK_LEASE_DURATION_MS } : {}),
204
- };
205
- const claim = createTaskClaim(claimInput);
206
- await this.storage.addClaim(claim);
207
- await this.storage.flush();
208
- this.logger.info('WorkItem claimed (specific)', { workItemId, agentId, claimId: claim.id });
209
- const claimedItem = await this.storage.findWorkItem(workItemId);
210
- return claimedItem ? { workItem: claimedItem, claim } : null;
211
631
  }
212
632
  /**
213
633
  * Releases a claimed WorkItem back to the pool.
@@ -235,11 +655,14 @@ export class TaskPoolService {
235
655
  c.endReason = reason;
236
656
  });
237
657
  }
238
- // Revert item to queued. Preserve target when unblocking so the
239
- // same agent can re-claim via target filter.
658
+ // TRANS-2: route the (running|blocked) queued flip through the
659
+ // guarded transitionStatus helper. The state-machine entry for
660
+ // `running → queued` is a TRANS-2 addition, gated to system/TL/orc;
661
+ // `blocked → queued` was already TL/orc/system-gated by TRANS-1.
662
+ // Side-effect mutations (startedAt clear, target preservation when
663
+ // unblocking, retryCount bump) move into the atomic mutator.
240
664
  const wasBlocked = workItem.status === 'blocked';
241
- await this.storage.updateWorkItem(workItemId, (wi) => {
242
- wi.status = 'queued';
665
+ await this.transitionStatus(workItemId, 'queued', 'system', (wi) => {
243
666
  wi.startedAt = undefined;
244
667
  if (!wasBlocked) {
245
668
  wi.target = undefined;
@@ -254,38 +677,239 @@ export class TaskPoolService {
254
677
  });
255
678
  }
256
679
  /**
257
- * Marks a work item as completed ('done').
680
+ * Decide whether a WorkItem requires TL verification before reaching a
681
+ * terminal-success status.
258
682
  *
259
- * @param workItemId - ID of the work item
260
- * @param result - Optional result data
261
- * @throws Error if work item not found or not in 'running' status
683
+ * Default policy (VERIF-1):
684
+ * - `delegate` items default to *requires verification* — a worker
685
+ * marking their own delegated work as "done" should produce
686
+ * `done_by_worker` and wake the TL for sign-off.
687
+ * - All other types (`cron_run`, `notify`, `reconcile`, `check`,
688
+ * `confirm`, `review`, ...) default to simple completion (`done`).
689
+ *
690
+ * The default is overridable via `wi.metadata.requiresVerification`:
691
+ * - `true` — force verification path even for non-delegate types
692
+ * - `false` — skip verification even for delegate types (this is the
693
+ * F-H affordance REVIEW-1 needs: review WIs are themselves the
694
+ * verification step, so they must NOT loop back to TL self-verify)
695
+ *
696
+ * @param wi - The WorkItem under inspection
697
+ * @returns true when the verification path should fire
698
+ */
699
+ requiresVerification(wi) {
700
+ const metaFlag = wi.metadata?.requiresVerification;
701
+ if (metaFlag === true)
702
+ return true;
703
+ if (metaFlag === false)
704
+ return false;
705
+ return wi.type === 'delegate';
706
+ }
707
+ /**
708
+ * Internal: release the active claim on a WorkItem (if any). Shared by
709
+ * `completeSimpleItem` and `submitForVerification` because both
710
+ * represent the worker handing the item back to the system.
711
+ *
712
+ * @param workItemId - WorkItem whose claim should be released
713
+ * @param endReason - Reason recorded on the claim (`completed` /
714
+ * `submitted_for_verification`) for auditability
715
+ */
716
+ async releaseClaim(workItemId, endReason) {
717
+ const claim = await this.storage.findActiveClaimByWorkItem(workItemId);
718
+ if (!claim)
719
+ return;
720
+ await this.storage.updateClaim(claim.id, (c) => {
721
+ c.status = 'released';
722
+ c.endedAt = new Date().toISOString();
723
+ c.endReason = endReason;
724
+ });
725
+ }
726
+ /**
727
+ * Worker reports a delegated WorkItem as done and submits it for TL
728
+ * verification.
729
+ *
730
+ * Transitions `running → done_by_worker` via {@link transitionStatus},
731
+ * which enforces the V3 actor-role gate (`'agent'` is allowed; any
732
+ * other role throws). The active claim is released as
733
+ * `submitted_for_verification` so the TL queue is the only thing
734
+ * blocking forward progress.
735
+ *
736
+ * Used by the `completeItem` facade for `delegate`-type items and any
737
+ * item whose `metadata.requiresVerification === true`.
738
+ *
739
+ * @param workItemId - WorkItem id
740
+ * @param actorRole - Role of the caller (`'agent'` for normal worker
741
+ * submissions; passed through to `isTransitionPermitted`)
742
+ * @param result - Optional result payload to attach to the WorkItem
743
+ * @returns The updated WorkItem, or `null` if the WI was deleted
744
+ * between the find and the update (race window)
745
+ * @throws When the WorkItem is missing, the transition is invalid, or
746
+ * the actor is not permitted to perform `running → done_by_worker`.
747
+ */
748
+ async submitForVerification(workItemId, actorRole, result) {
749
+ await this.releaseClaim(workItemId, 'submitted_for_verification');
750
+ const updated = await this.transitionStatus(workItemId, 'done_by_worker', actorRole, (wi) => {
751
+ if (result)
752
+ wi.result = result;
753
+ });
754
+ await this.storage.flush();
755
+ this.logger.info('WorkItem submitted for verification', {
756
+ workItemId,
757
+ actorRole,
758
+ // BRIDGE-1 turns this into a real `task:done_by_worker` event below
759
+ // (F1-BRIDGE-1). The log line is preserved as a wake signal for any
760
+ // tail-based TL-watching subscriber that still greps it.
761
+ tlWakeRequested: true,
762
+ });
763
+ // F1-BRIDGE-1: publish AFTER the storage flush so any subscriber that
764
+ // re-reads via taskPool.findWorkItem sees the committed `done_by_worker`
765
+ // status. `updated` is null only on race-window deletion — skip the
766
+ // publish in that case (no source WI for the bridge to resolve).
767
+ if (updated) {
768
+ this.publishTaskDoneByWorker(updated);
769
+ }
770
+ return updated;
771
+ }
772
+ /**
773
+ * Worker (or system) marks a non-delegated WorkItem as fully done.
774
+ *
775
+ * Transitions `running → done` via {@link transitionStatus}. Used by
776
+ * the `completeItem` facade for `cron_run`, `notify`, `reconcile`,
777
+ * `check`, `confirm`, `review` types — anything whose lifecycle does
778
+ * NOT include a TL verification step.
779
+ *
780
+ * The Reconciler service is the only system-actor caller and uses
781
+ * `actorRole='system'`, which bypasses the actor check while still
782
+ * respecting the state-machine legality check.
783
+ *
784
+ * @param workItemId - WorkItem id
785
+ * @param actorRole - Role of the caller (`'agent'`, `'system'`, etc.)
786
+ * @param result - Optional result payload to attach
787
+ * @returns The updated WorkItem, or `null` if the WI was deleted
788
+ * between the find and the update (race window)
789
+ * @throws When the WorkItem is missing, the transition is invalid, or
790
+ * the actor is not permitted to perform `running → done`.
791
+ */
792
+ async completeSimpleItem(workItemId, actorRole, result) {
793
+ await this.releaseClaim(workItemId, 'completed');
794
+ const updated = await this.transitionStatus(workItemId, 'done', actorRole, (wi) => {
795
+ if (result)
796
+ wi.result = result;
797
+ });
798
+ // Promote any blocked dependents whose deps are now all satisfied.
799
+ await this.resolveBlockedDependents(workItemId);
800
+ await this.storage.flush();
801
+ this.logger.info('WorkItem completed', { workItemId, actorRole });
802
+ return updated;
803
+ }
804
+ /**
805
+ * TL records a verdict on a WorkItem in `done_by_worker` status.
806
+ *
807
+ * `verified` advances to terminal success and unblocks dependents;
808
+ * `rejected` parks the item until the TL re-queues it (which TRANS-1
809
+ * gates to TL/orchestrator/system actors). Worker-actor calls throw
810
+ * automatically via {@link transitionStatus}'s permission gate — we
811
+ * do NOT need to add an explicit role check here, the matrix in
812
+ * `TRANSITION_PERMISSIONS` handles it.
813
+ *
814
+ * @param workItemId - WorkItem id (must currently be `done_by_worker`)
815
+ * @param actorRole - Role of the caller (`'team_lead'` or `'orchestrator'`
816
+ * for verify/reject; worker calls throw)
817
+ * @param verdict - `'verified'` or `'rejected'`
818
+ * @param comment - Optional reviewer comment recorded in `wi.error`
819
+ * (the field is reused — the WorkItem schema does not yet have a
820
+ * dedicated `verifierComment` slot; keeping this on `error` lets
821
+ * downstream UIs render TL feedback alongside failure causes)
822
+ * @returns The updated WorkItem, or `null` on race-window deletion
823
+ * @throws When the WorkItem is missing, the verdict is invalid, the
824
+ * transition is illegal, or the actor is not permitted to verify.
825
+ */
826
+ async verifyItem(workItemId, actorRole, verdict, comment) {
827
+ if (verdict !== 'verified' && verdict !== 'rejected') {
828
+ throw new Error(`Invalid verdict: "${verdict}". Must be "verified" or "rejected".`);
829
+ }
830
+ const updated = await this.transitionStatus(workItemId, verdict, actorRole, (wi) => {
831
+ if (comment)
832
+ wi.error = comment;
833
+ });
834
+ if (verdict === 'verified') {
835
+ await this.resolveBlockedDependents(workItemId);
836
+ }
837
+ await this.storage.flush();
838
+ this.logger.info('WorkItem verdict recorded', { workItemId, verdict, actorRole });
839
+ // F1-BRIDGE-1: only the `rejected` branch publishes. The bridge's
840
+ // task:rejected handler creates the retry-or-escalate WI; the `verified`
841
+ // branch is terminal-success and unblocks dependents above without any
842
+ // bridge involvement. Skip the publish on race-window deletion.
843
+ if (verdict === 'rejected' && updated) {
844
+ this.publishTaskRejected(updated);
845
+ }
846
+ return updated;
847
+ }
848
+ /**
849
+ * Legacy facade — picks the verification path for the caller.
850
+ *
851
+ * Existing call sites (REST controller, task-management controllers,
852
+ * V3 data service) invoke `completeItem(id, result)` without an
853
+ * explicit actor role. The facade reads the WorkItem, applies the
854
+ * {@link requiresVerification} policy, and dispatches to either
855
+ * {@link submitForVerification} (delegate items / explicit opt-in)
856
+ * or {@link completeSimpleItem} (everything else).
857
+ *
858
+ * The legacy actor role for these implicit callers is `'agent'`.
859
+ * Migrations to explicit-actor calls can land in follow-up tickets
860
+ * without touching the five call sites in this PR.
861
+ *
862
+ * @param workItemId - WorkItem id
863
+ * @param result - Optional result payload
864
+ * @throws When the WorkItem is missing or the underlying transition
865
+ * is rejected (invalid state, forbidden actor).
262
866
  */
263
867
  async completeItem(workItemId, result) {
264
868
  const workItem = await this.storage.findWorkItem(workItemId);
265
869
  if (!workItem) {
266
870
  throw new Error(`WorkItem not found: ${workItemId}`);
267
871
  }
268
- if (workItem.status !== 'running') {
269
- throw new Error(`Cannot complete WorkItem: status must be 'running', got '${workItem.status}'`);
872
+ if (this.requiresVerification(workItem)) {
873
+ await this.submitForVerification(workItemId, 'agent', result);
270
874
  }
271
- // Release the claim
272
- const claim = await this.storage.findActiveClaimByWorkItem(workItemId);
273
- if (claim) {
274
- await this.storage.updateClaim(claim.id, (c) => {
275
- c.status = 'released';
276
- c.endedAt = new Date().toISOString();
277
- c.endReason = 'completed';
278
- });
875
+ else {
876
+ await this.completeSimpleItem(workItemId, 'agent', result);
279
877
  }
280
- // Mark item done
281
- await this.storage.updateWorkItem(workItemId, (wi) => {
282
- wi.status = 'done';
283
- wi.completedAt = new Date().toISOString();
284
- if (result)
285
- wi.result = result;
878
+ }
879
+ /**
880
+ * Scans blocked WorkItems that list `completedId` in their `dependsOn` and
881
+ * promotes each to `queued` if every one of their deps has reached terminal
882
+ * success (`done` or `verified`). Idempotent and safe to call on any terminal
883
+ * success transition.
884
+ *
885
+ * Serialized via the claim mutex — a concurrent claimFromPool call must not
886
+ * observe a half-promoted item.
887
+ */
888
+ async resolveBlockedDependents(completedId) {
889
+ await this.withClaimLock(async () => {
890
+ const items = await this.storage.getWorkItems();
891
+ const terminalSuccess = new Set(items
892
+ .filter((wi) => wi.status === 'done' || wi.status === 'verified')
893
+ .map((wi) => wi.id));
894
+ const candidates = items.filter((wi) => wi.status === 'blocked' &&
895
+ Array.isArray(wi.dependsOn) &&
896
+ wi.dependsOn.includes(completedId));
897
+ for (const candidate of candidates) {
898
+ const allSatisfied = (candidate.dependsOn ?? []).every((depId) => terminalSuccess.has(depId));
899
+ if (!allSatisfied)
900
+ continue;
901
+ // TRANS-2: route the blocked → queued promotion through
902
+ // transitionStatus. The 'system' actor matches both the V3
903
+ // permission gate (blocked→queued requires TL/orc/system) and
904
+ // the existing intent — dependency resolution is server-side
905
+ // bookkeeping, not a user-initiated action.
906
+ await this.transitionStatus(candidate.id, 'queued', 'system');
907
+ this.logger.info('WorkItem unblocked — all deps satisfied', {
908
+ workItemId: candidate.id,
909
+ via: completedId,
910
+ });
911
+ }
286
912
  });
287
- await this.storage.flush();
288
- this.logger.info('WorkItem completed', { workItemId });
289
913
  }
290
914
  /**
291
915
  * Marks a work item as failed.
@@ -311,10 +935,10 @@ export class TaskPoolService {
311
935
  c.endReason = `failed: ${error}`;
312
936
  });
313
937
  }
314
- // Mark item failed
315
- await this.storage.updateWorkItem(workItemId, (wi) => {
316
- wi.status = 'failed';
317
- wi.completedAt = new Date().toISOString();
938
+ // TRANS-2: route the running → failed flip through transitionStatus.
939
+ // `completedAt` is set automatically when newStatus === 'failed'; the
940
+ // mutator only needs to attach the error description.
941
+ await this.transitionStatus(workItemId, 'failed', 'system', (wi) => {
318
942
  wi.error = error;
319
943
  });
320
944
  await this.storage.flush();
@@ -459,6 +1083,104 @@ export class TaskPoolService {
459
1083
  async getAllItems() {
460
1084
  return this.storage.getWorkItems();
461
1085
  }
1086
+ /**
1087
+ * Find a WorkItem by id without mutating it.
1088
+ *
1089
+ * Public read accessor used by callers that need to inspect a
1090
+ * specific item — for example REVIEW-1's reentrancy lock checks the
1091
+ * status of a Mission's `pendingReviewWorkItemId` to decide whether
1092
+ * to clear the lock. Returns `null` (not `undefined`) so callers can
1093
+ * use a uniform null-fallthrough idiom shared with
1094
+ * `getWorkItemSnapshot` and `transitionStatus`.
1095
+ *
1096
+ * @param workItemId - WorkItem id to look up
1097
+ * @returns The WorkItem, or `null` if no item has that id
1098
+ */
1099
+ async findWorkItem(workItemId) {
1100
+ return (await this.storage.findWorkItem(workItemId)) ?? null;
1101
+ }
1102
+ /**
1103
+ * Stores worker-supplied structured output on a WorkItem.
1104
+ *
1105
+ * Replaces the v1 `<taskId>.output.json` filesystem store with an
1106
+ * in-pool field (see {@link WorkItem.output}). Used by the worker
1107
+ * `complete-task` flow and read back by the TL `verify-output` skill.
1108
+ *
1109
+ * @param workItemId - WorkItem id to attach output to
1110
+ * @param output - Arbitrary task-specific output object
1111
+ * @returns The updated WorkItem, or null if not found
1112
+ */
1113
+ async setOutput(workItemId, output) {
1114
+ const ok = await this.storage.updateWorkItem(workItemId, (wi) => {
1115
+ wi.output = output;
1116
+ });
1117
+ if (!ok)
1118
+ return null;
1119
+ return (await this.storage.findWorkItem(workItemId)) ?? null;
1120
+ }
1121
+ /**
1122
+ * Reassigns a WorkItem to a different target agent.
1123
+ *
1124
+ * Replaces the v1 `/task-management/handoff` filesystem reassign with a
1125
+ * direct `target` field update on the WorkItem.
1126
+ *
1127
+ * Allowed transitions:
1128
+ * - `target` must be a non-empty string
1129
+ * - WI must not be in a terminal state (done/cancelled/failed-final)
1130
+ *
1131
+ * @param workItemId - WorkItem to reassign
1132
+ * @param newTarget - Session name of the new target agent
1133
+ * @param fromAgent - Session name of the agent handing off (for audit)
1134
+ * @param reason - Human-readable reason recorded as a working-note
1135
+ * @returns The updated WorkItem, or null if not found
1136
+ */
1137
+ async handoff(workItemId, newTarget, fromAgent, reason) {
1138
+ if (!newTarget || newTarget.trim() === '') {
1139
+ throw new Error('handoff: newTarget is required');
1140
+ }
1141
+ const wi = await this.storage.findWorkItem(workItemId);
1142
+ if (!wi)
1143
+ return null;
1144
+ if (wi.status === 'done' || wi.status === 'cancelled') {
1145
+ throw new Error(`handoff refused: WorkItem ${workItemId} is in terminal state '${wi.status}'`);
1146
+ }
1147
+ const handoffNote = `[HANDOFF] ${fromAgent} → ${newTarget}: ${reason || '(no reason)'}`;
1148
+ await this.storage.updateWorkItem(workItemId, (item) => {
1149
+ item.target = newTarget;
1150
+ const existing = (item.metadata && typeof item.metadata === 'object' ? item.metadata : {});
1151
+ const notes = Array.isArray(existing.notes) ? existing.notes : [];
1152
+ notes.push(`${new Date().toISOString()} ${handoffNote}`);
1153
+ item.metadata = { ...existing, notes };
1154
+ });
1155
+ this.logger.info('WorkItem handoff', { workItemId, fromAgent, newTarget });
1156
+ return (await this.storage.findWorkItem(workItemId)) ?? null;
1157
+ }
1158
+ /**
1159
+ * Appends a working-state note to a WorkItem's metadata.notes array.
1160
+ *
1161
+ * Replaces v1 `/task-management/sync` and `/task-management/save-working-notes`,
1162
+ * both of which appended progress notes to the `.md` task body. With v1
1163
+ * retired, notes live on the WorkItem itself under `metadata.notes[]`.
1164
+ *
1165
+ * @param workItemId - WorkItem id
1166
+ * @param author - Session name of note author
1167
+ * @param note - Note content (free-form)
1168
+ * @returns The updated WorkItem, or null if not found
1169
+ */
1170
+ async appendNote(workItemId, author, note) {
1171
+ if (!note || note.trim() === '') {
1172
+ throw new Error('appendNote: note is required');
1173
+ }
1174
+ const ok = await this.storage.updateWorkItem(workItemId, (wi) => {
1175
+ const existing = (wi.metadata && typeof wi.metadata === 'object' ? wi.metadata : {});
1176
+ const notes = Array.isArray(existing.notes) ? existing.notes : [];
1177
+ notes.push(`${new Date().toISOString()} [${author}] ${note}`);
1178
+ wi.metadata = { ...existing, notes };
1179
+ });
1180
+ if (!ok)
1181
+ return null;
1182
+ return (await this.storage.findWorkItem(workItemId)) ?? null;
1183
+ }
462
1184
  /**
463
1185
  * Removes a WorkItem from the pool entirely.
464
1186
  * Used for purging old completed/cancelled items.
@@ -468,6 +1190,63 @@ export class TaskPoolService {
468
1190
  async removeItem(workItemId) {
469
1191
  await this.storage.removeWorkItem(workItemId);
470
1192
  }
1193
+ // -------------------------------------------------------------------------
1194
+ // P1 1ffffb84(a) — Bulk-DELETE stale WorkItems
1195
+ // -------------------------------------------------------------------------
1196
+ /**
1197
+ * Public delete API used by the bulk-cleanup script and the new
1198
+ * `DELETE /api/task-pool/:id` HTTP endpoint (P1 umbrella WI 1ffffb84
1199
+ * component a, Steve directive 2026-05-06: just-DELETE-not-backfill).
1200
+ *
1201
+ * Three guarantees over {@link removeItem}:
1202
+ * 1. Idempotent — `not_found` is a no-op return, not a throw.
1203
+ * 2. Claim-safety — refuses claimed delete unless `opts.force`.
1204
+ * 3. Audit log — single info-level log per removal.
1205
+ *
1206
+ * Force path also revokes the orphaned claim (status='revoked',
1207
+ * endedAt, endReason).
1208
+ */
1209
+ async removeFromPool(workItemId, opts = {}) {
1210
+ const wi = await this.storage.findWorkItem(workItemId);
1211
+ if (!wi) {
1212
+ this.logger.debug('removeFromPool: item not found (idempotent)', { workItemId });
1213
+ return { removed: false, reason: 'not_found' };
1214
+ }
1215
+ const activeClaim = await this.storage.findActiveClaimByWorkItem(workItemId);
1216
+ const hadActiveClaim = !!activeClaim;
1217
+ if (hadActiveClaim && activeClaim && !opts.force) {
1218
+ this.logger.warn('removeFromPool refused: active claim exists', {
1219
+ workItemId,
1220
+ claimId: activeClaim.id,
1221
+ claimedBy: activeClaim.agentId,
1222
+ });
1223
+ throw new WorkItemClaimedError({
1224
+ workItemId,
1225
+ claimId: activeClaim.id,
1226
+ claimedBy: activeClaim.agentId,
1227
+ });
1228
+ }
1229
+ const removed = await this.storage.removeWorkItem(workItemId);
1230
+ if (hadActiveClaim && activeClaim) {
1231
+ await this.storage.updateClaim(activeClaim.id, (c) => {
1232
+ c.status = 'revoked';
1233
+ c.endedAt = new Date().toISOString();
1234
+ c.endReason = `WorkItem deleted via removeFromPool (force=${opts.force === true})`;
1235
+ });
1236
+ }
1237
+ this.logger.info('removeFromPool: WorkItem removed', {
1238
+ workItemId,
1239
+ status: wi.status,
1240
+ target: wi.target,
1241
+ force: opts.force === true,
1242
+ hadActiveClaim,
1243
+ });
1244
+ return {
1245
+ removed: removed === true,
1246
+ workItem: wi,
1247
+ hadActiveClaim,
1248
+ };
1249
+ }
471
1250
  /**
472
1251
  * Forces an immediate flush of pool data to disk.
473
1252
  * Called during graceful shutdown to prevent data loss.
@@ -488,41 +1267,186 @@ export class TaskPoolService {
488
1267
  * Updates a work item's status directly.
489
1268
  * Used by the Reconciler for corrections (e.g., stuck → blocked).
490
1269
  *
1270
+ * Reconciler invocations pass through `actorRole='system'` (default) which
1271
+ * bypasses the per-role gate at {@link isTransitionPermitted} but still
1272
+ * enforces the state-machine via {@link isValidWorkItemTransition}. Other
1273
+ * callers MUST supply the actor's role so TRANS-1 V3 enforcement applies.
1274
+ *
491
1275
  * @param workItemId - The work item ID
492
1276
  * @param newStatus - The target status
493
- * @throws Error if work item not found or transition is invalid
1277
+ * @param actorRole - Role of the caller (defaults to `'system'` for Reconciler)
1278
+ * @throws Error if work item not found
1279
+ * @throws Error if transition is invalid (state machine — see WORK_ITEM_TRANSITIONS)
1280
+ * @throws Error if actor is not permitted (role check — see TRANSITION_PERMISSIONS)
494
1281
  */
495
- async updateItemStatus(workItemId, newStatus) {
1282
+ async updateItemStatus(workItemId, newStatus, actorRole = 'system') {
496
1283
  const items = await this.storage.getWorkItems();
497
1284
  const item = items.find((wi) => wi.id === workItemId);
498
1285
  if (!item) {
499
1286
  throw new Error(`WorkItem not found: ${workItemId}`);
500
1287
  }
501
- if (item.status === newStatus) {
502
- this.logger.debug('Work item status update is a no-op, skipping', {
503
- workItemId,
504
- status: newStatus,
505
- });
506
- return;
507
- }
508
1288
  if (!isValidWorkItemTransition(item.status, newStatus)) {
509
1289
  throw new Error(`Invalid status transition for WorkItem ${workItemId}: ${item.status} → ${newStatus}`);
510
1290
  }
1291
+ // TRANS-1 V3: enforce per-role permissions. system role always passes.
1292
+ if (!isTransitionPermitted(item.status, newStatus, actorRole)) {
1293
+ throw new Error(`Forbidden transition for WorkItem ${workItemId}: actor='${actorRole}' ` +
1294
+ `not permitted to perform ${item.status} → ${newStatus}.`);
1295
+ }
511
1296
  await this.storage.updateWorkItem(workItemId, (wi) => {
512
1297
  wi.status = newStatus;
513
- // Use startedAt for running, completedAt for done/failed
1298
+ // P1 1ffffb84 component (b): mirror the transitionStatus
1299
+ // atomic-timestamp contract so the older updateItemStatus path
1300
+ // never produces a status↔completedAt mismatch either. See
1301
+ // transitionStatus below for the full root-cause writeup
1302
+ // (b7840fe8 partial-write bug).
514
1303
  if (newStatus === 'running') {
515
1304
  wi.startedAt = new Date().toISOString();
1305
+ wi.completedAt = undefined;
516
1306
  }
517
1307
  else if (newStatus === 'done' || newStatus === 'failed') {
518
1308
  wi.completedAt = new Date().toISOString();
519
1309
  }
1310
+ else {
1311
+ wi.completedAt = undefined;
1312
+ }
520
1313
  });
521
1314
  this.logger.info('Work item status updated', {
522
1315
  workItemId,
523
1316
  from: item.status,
524
1317
  to: newStatus,
1318
+ actorRole,
525
1319
  });
1320
+ // Cascade signal — let RequestCascadeSubscriber close the parent
1321
+ // Request without waiting for the heartbeat catch. See
1322
+ // {@link publishTaskCancelled} for the full bug writeup.
1323
+ if (newStatus === 'cancelled') {
1324
+ const post = await this.storage.findWorkItem(workItemId);
1325
+ if (post)
1326
+ this.publishTaskCancelled(post, item.status);
1327
+ }
1328
+ }
1329
+ /**
1330
+ * Public guarded transition helper — TRANS-1's canonical entrypoint.
1331
+ *
1332
+ * Routes any externally-initiated WorkItem status change through the
1333
+ * combined state-machine + actor-role gates. Designed as the public API
1334
+ * VERIF-1 will call from `submitForVerification` / `verifyItem`, and as
1335
+ * the recommended path for any future caller that previously reached
1336
+ * for `storage.updateWorkItem` to flip status.
1337
+ *
1338
+ * Differences vs {@link updateItemStatus}:
1339
+ * - Requires `actorRole` explicitly (no default) — forces the caller to
1340
+ * decide the trust posture rather than silently inheriting `'system'`.
1341
+ * - Accepts an optional `mutator` so callers can carry additional field
1342
+ * updates (e.g. `result`, `error`, `completedAt`) atomically with the
1343
+ * status flip — preventing races between status update and metadata
1344
+ * attachment that direct `storage.updateWorkItem` callers risked.
1345
+ *
1346
+ * @param workItemId - The work item ID
1347
+ * @param newStatus - The target status
1348
+ * @param actorRole - Role of the caller (REQUIRED; pass `'system'` for trusted server-internal paths)
1349
+ * @param mutator - Optional additional WorkItem field updates applied atomically with the status change
1350
+ * @returns The updated WorkItem after the transition
1351
+ * @throws Error if work item not found
1352
+ * @throws Error if transition is invalid (state machine)
1353
+ * @throws Error if actor is not permitted (role check)
1354
+ *
1355
+ * @example
1356
+ * ```typescript
1357
+ * // VERIF-1 worker submitting for verification
1358
+ * await pool.transitionStatus(wiId, 'done_by_worker', 'agent', (wi) => {
1359
+ * wi.result = output;
1360
+ * });
1361
+ *
1362
+ * // VERIF-1 TL verifying
1363
+ * await pool.transitionStatus(wiId, 'verified', 'team_lead');
1364
+ *
1365
+ * // VERIF-1 TL rejecting (allowed for TL only)
1366
+ * await pool.transitionStatus(wiId, 'rejected', 'team_lead', (wi) => {
1367
+ * wi.error = 'Did not meet acceptance criteria';
1368
+ * });
1369
+ * ```
1370
+ */
1371
+ async transitionStatus(workItemId, newStatus, actorRole, mutator) {
1372
+ const item = await this.storage.findWorkItem(workItemId);
1373
+ if (!item) {
1374
+ throw new Error(`WorkItem not found: ${workItemId}`);
1375
+ }
1376
+ if (!isValidWorkItemTransition(item.status, newStatus)) {
1377
+ throw new Error(`Invalid status transition for WorkItem ${workItemId}: ${item.status} → ${newStatus}`);
1378
+ }
1379
+ if (!isTransitionPermitted(item.status, newStatus, actorRole)) {
1380
+ throw new Error(`Forbidden transition for WorkItem ${workItemId}: actor='${actorRole}' ` +
1381
+ `not permitted to perform ${item.status} → ${newStatus}.`);
1382
+ }
1383
+ const ok = await this.storage.updateWorkItem(workItemId, (wi) => {
1384
+ wi.status = newStatus;
1385
+ // Atomic timestamp side-effects enforce the invariant
1386
+ // `completedAt is set IFF status ∈ {done, failed, verified,
1387
+ // done_by_worker, rejected}`.
1388
+ //
1389
+ // P1 1ffffb84 component (b): the prior code only SET completedAt
1390
+ // on terminal transitions; non-terminal landings (queued, running,
1391
+ // blocked, scheduled, proposed, accepted, escalated, cancelled)
1392
+ // inherited a stale completedAt from a prior terminal trip via
1393
+ // - `rejected → queued` (TL re-queue)
1394
+ // - `failed → queued` (BRIDGE-1 retry)
1395
+ // - `running → queued` (releaseBack abandon path)
1396
+ // WorkItem b7840fe8 reproduced the bug — status=queued AND
1397
+ // completedAt=2026-05-06T00:47:59Z AND retryCount=1 AND no
1398
+ // startedAt/target, which is the exact fingerprint of a
1399
+ // `failed → queued` retry leaving stale completedAt. The else
1400
+ // branch below closes the gap atomically with the status flip.
1401
+ if (newStatus === 'running') {
1402
+ wi.startedAt = new Date().toISOString();
1403
+ // Resuming work — clear stale completedAt from a prior failed/
1404
+ // rejected attempt so a re-claim never carries forward a
1405
+ // completion timestamp from an earlier terminal trip.
1406
+ wi.completedAt = undefined;
1407
+ }
1408
+ else if (newStatus === 'done' ||
1409
+ newStatus === 'failed' ||
1410
+ newStatus === 'verified' ||
1411
+ newStatus === 'done_by_worker' ||
1412
+ newStatus === 'rejected') {
1413
+ wi.completedAt = new Date().toISOString();
1414
+ }
1415
+ else {
1416
+ // Non-terminal-with-result landings: clear completedAt so the
1417
+ // invariant holds. (`cancelled` is technically terminal but
1418
+ // historically never carried completedAt — preserving that
1419
+ // shape here to keep the change minimal; the `cancelled`
1420
+ // semantics are out of scope.)
1421
+ wi.completedAt = undefined;
1422
+ }
1423
+ if (mutator)
1424
+ mutator(wi);
1425
+ });
1426
+ if (!ok) {
1427
+ // Race window: someone else removed the WorkItem between findWorkItem
1428
+ // and updateWorkItem. Surface as null so callers can distinguish from
1429
+ // a thrown invalid-transition / forbidden-transition error.
1430
+ return null;
1431
+ }
1432
+ this.logger.info('WorkItem transitioned', {
1433
+ workItemId,
1434
+ from: item.status,
1435
+ to: newStatus,
1436
+ actorRole,
1437
+ });
1438
+ // Return the post-update WorkItem snapshot so callers can chain on the
1439
+ // resolved value rather than re-fetching. Coerce `undefined` (item
1440
+ // removed during the race window) to `null` to match the declared
1441
+ // return type.
1442
+ const post = (await this.storage.findWorkItem(workItemId)) ?? null;
1443
+ // Cascade signal — let RequestCascadeSubscriber close the parent
1444
+ // Request without waiting for the heartbeat catch. See
1445
+ // {@link publishTaskCancelled} for the full bug writeup.
1446
+ if (newStatus === 'cancelled' && post) {
1447
+ this.publishTaskCancelled(post, item.status);
1448
+ }
1449
+ return post;
526
1450
  }
527
1451
  /**
528
1452
  * Update token usage and cost on a WorkItem.