crewly 1.6.1 → 1.6.2

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 (363) hide show
  1. package/config/roles/orchestrator/prompt.md +16 -0
  2. package/config/skills/agent/core/get-my-active-work/SKILL.md +101 -0
  3. package/config/skills/agent/core/get-my-active-work/execute.sh +122 -0
  4. package/config/skills/agent/core/record-learning/SKILL.md +29 -0
  5. package/config/skills/agent/core/reply-channel/SKILL.md +41 -0
  6. package/config/skills/agent/core/reply-channel/execute.sh +165 -0
  7. package/config/skills/agent/core/reply-channel/execute.test.sh +148 -0
  8. package/config/skills/agent/remote-browser/execute.sh +296 -14
  9. package/config/skills/agent/remote-browser/execute.test.sh +482 -0
  10. package/config/skills/orchestrator/send-message/SKILL.md +30 -7
  11. package/config/skills/orchestrator/team-health-scan/SKILL.md +98 -0
  12. package/config/skills/orchestrator/team-health-scan/execute.sh +44 -0
  13. package/config/skills/registry.json +62 -1
  14. package/config/sops/developer/git-workflow.md +38 -3
  15. package/dist/backend/backend/src/constants.d.ts +69 -1
  16. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  17. package/dist/backend/backend/src/constants.js +69 -2
  18. package/dist/backend/backend/src/constants.js.map +1 -1
  19. package/dist/backend/backend/src/controllers/active-work/active-work.controller.d.ts +53 -0
  20. package/dist/backend/backend/src/controllers/active-work/active-work.controller.d.ts.map +1 -0
  21. package/dist/backend/backend/src/controllers/active-work/active-work.controller.js +92 -0
  22. package/dist/backend/backend/src/controllers/active-work/active-work.controller.js.map +1 -0
  23. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.d.ts.map +1 -1
  24. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.js +18 -1
  25. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.js.map +1 -1
  26. package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts +68 -0
  27. package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts.map +1 -1
  28. package/dist/backend/backend/src/controllers/browser/browser.controller.js +233 -5
  29. package/dist/backend/backend/src/controllers/browser/browser.controller.js.map +1 -1
  30. package/dist/backend/backend/src/controllers/browser/browser.routes.d.ts.map +1 -1
  31. package/dist/backend/backend/src/controllers/browser/browser.routes.js +10 -1
  32. package/dist/backend/backend/src/controllers/browser/browser.routes.js.map +1 -1
  33. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  34. package/dist/backend/backend/src/controllers/chat/chat.controller.js +8 -3
  35. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  36. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts +132 -0
  37. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -0
  38. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +401 -0
  39. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -0
  40. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.d.ts +29 -0
  41. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.d.ts.map +1 -0
  42. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.js +39 -0
  43. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.routes.js.map +1 -0
  44. package/dist/backend/backend/src/controllers/chat-v2/index.d.ts +8 -0
  45. package/dist/backend/backend/src/controllers/chat-v2/index.d.ts.map +1 -0
  46. package/dist/backend/backend/src/controllers/chat-v2/index.js +8 -0
  47. package/dist/backend/backend/src/controllers/chat-v2/index.js.map +1 -0
  48. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.d.ts +13 -13
  49. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.d.ts.map +1 -1
  50. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.js +74 -234
  51. package/dist/backend/backend/src/controllers/onboarding/onboarding.routes.js.map +1 -1
  52. package/dist/backend/backend/src/controllers/request/request.controller.d.ts.map +1 -1
  53. package/dist/backend/backend/src/controllers/request/request.controller.js +4 -6
  54. package/dist/backend/backend/src/controllers/request/request.controller.js.map +1 -1
  55. package/dist/backend/backend/src/controllers/task-management/tasks.controller.d.ts +43 -0
  56. package/dist/backend/backend/src/controllers/task-management/tasks.controller.d.ts.map +1 -1
  57. package/dist/backend/backend/src/controllers/task-management/tasks.controller.js +200 -72
  58. package/dist/backend/backend/src/controllers/task-management/tasks.controller.js.map +1 -1
  59. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  60. package/dist/backend/backend/src/controllers/team/team.controller.js +46 -0
  61. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  62. package/dist/backend/backend/src/controllers/team-health/team-health.controller.d.ts +59 -0
  63. package/dist/backend/backend/src/controllers/team-health/team-health.controller.d.ts.map +1 -0
  64. package/dist/backend/backend/src/controllers/team-health/team-health.controller.js +127 -0
  65. package/dist/backend/backend/src/controllers/team-health/team-health.controller.js.map +1 -0
  66. package/dist/backend/backend/src/controllers/team-health/team-health.routes.d.ts +13 -0
  67. package/dist/backend/backend/src/controllers/team-health/team-health.routes.d.ts.map +1 -0
  68. package/dist/backend/backend/src/controllers/team-health/team-health.routes.js +20 -0
  69. package/dist/backend/backend/src/controllers/team-health/team-health.routes.js.map +1 -0
  70. package/dist/backend/backend/src/index.d.ts +9 -0
  71. package/dist/backend/backend/src/index.d.ts.map +1 -1
  72. package/dist/backend/backend/src/index.js +233 -0
  73. package/dist/backend/backend/src/index.js.map +1 -1
  74. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  75. package/dist/backend/backend/src/routes/api.routes.js +40 -6
  76. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  77. package/dist/backend/backend/src/services/agent/active-work-briefing.service.d.ts +498 -0
  78. package/dist/backend/backend/src/services/agent/active-work-briefing.service.d.ts.map +1 -0
  79. package/dist/backend/backend/src/services/agent/active-work-briefing.service.js +759 -0
  80. package/dist/backend/backend/src/services/agent/active-work-briefing.service.js.map +1 -0
  81. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +25 -0
  82. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  83. package/dist/backend/backend/src/services/agent/agent-registration.service.js +193 -57
  84. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  85. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts +9 -2
  86. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts.map +1 -1
  87. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js +35 -2
  88. package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js.map +1 -1
  89. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts +8 -2
  90. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -1
  91. package/dist/backend/backend/src/services/agent/crewly-agent/types.js +1 -0
  92. package/dist/backend/backend/src/services/agent/crewly-agent/types.js.map +1 -1
  93. package/dist/backend/backend/src/services/agent/tmux-command.service.d.ts.map +1 -1
  94. package/dist/backend/backend/src/services/agent/tmux-command.service.js +2 -1
  95. package/dist/backend/backend/src/services/agent/tmux-command.service.js.map +1 -1
  96. package/dist/backend/backend/src/services/agent/tmux.service.d.ts.map +1 -1
  97. package/dist/backend/backend/src/services/agent/tmux.service.js +2 -1
  98. package/dist/backend/backend/src/services/agent/tmux.service.js.map +1 -1
  99. package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts +148 -3
  100. package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -1
  101. package/dist/backend/backend/src/services/ai/prompt-builder.service.js +241 -2
  102. package/dist/backend/backend/src/services/ai/prompt-builder.service.js.map +1 -1
  103. package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.d.ts.map +1 -1
  104. package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.js +13 -0
  105. package/dist/backend/backend/src/services/ai/prompt-modules/recovery.module.js.map +1 -1
  106. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.d.ts.map +1 -1
  107. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.js +26 -1
  108. package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.js.map +1 -1
  109. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts +79 -0
  110. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.d.ts.map +1 -0
  111. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js +118 -0
  112. package/dist/backend/backend/src/services/ai/prompt-modules/sop-norm-distinction.module.js.map +1 -0
  113. package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts +161 -0
  114. package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts.map +1 -1
  115. package/dist/backend/backend/src/services/browser/browser-bridge.service.js +382 -2
  116. package/dist/backend/backend/src/services/browser/browser-bridge.service.js.map +1 -1
  117. package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts +105 -0
  118. package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts.map +1 -1
  119. package/dist/backend/backend/src/services/browser/browser-proxy.service.js +232 -13
  120. package/dist/backend/backend/src/services/browser/browser-proxy.service.js.map +1 -1
  121. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +178 -0
  122. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -0
  123. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +254 -0
  124. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -0
  125. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.d.ts +134 -0
  126. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.d.ts.map +1 -0
  127. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.js +232 -0
  128. package/dist/backend/backend/src/services/chat-v2/chat-v2.mention-resolver.js.map +1 -0
  129. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.d.ts +25 -0
  130. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.d.ts.map +1 -0
  131. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.js +23 -0
  132. package/dist/backend/backend/src/services/chat-v2/chat-v2.realtime-holder.js.map +1 -0
  133. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts +254 -0
  134. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -0
  135. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js +467 -0
  136. package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js.map +1 -0
  137. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.d.ts +27 -0
  138. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.d.ts.map +1 -0
  139. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.js +57 -0
  140. package/dist/backend/backend/src/services/chat-v2/chat-v2.singleton.js.map +1 -0
  141. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.d.ts +43 -0
  142. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.d.ts.map +1 -0
  143. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.js +54 -0
  144. package/dist/backend/backend/src/services/chat-v2/chat-v2.team-membership.js.map +1 -0
  145. package/dist/backend/backend/src/services/chat-v2/config.d.ts +100 -0
  146. package/dist/backend/backend/src/services/chat-v2/config.d.ts.map +1 -0
  147. package/dist/backend/backend/src/services/chat-v2/config.js +174 -0
  148. package/dist/backend/backend/src/services/chat-v2/config.js.map +1 -0
  149. package/dist/backend/backend/src/services/chat-v2/index.d.ts +11 -0
  150. package/dist/backend/backend/src/services/chat-v2/index.d.ts.map +1 -0
  151. package/dist/backend/backend/src/services/chat-v2/index.js +12 -0
  152. package/dist/backend/backend/src/services/chat-v2/index.js.map +1 -0
  153. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.d.ts +114 -0
  154. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.d.ts.map +1 -0
  155. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.js +194 -0
  156. package/dist/backend/backend/src/services/chat-v2/sqlite/channel.store.js.map +1 -0
  157. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts +100 -0
  158. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.d.ts.map +1 -0
  159. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js +351 -0
  160. package/dist/backend/backend/src/services/chat-v2/sqlite/chat-db.js.map +1 -0
  161. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts +132 -0
  162. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.d.ts.map +1 -0
  163. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js +281 -0
  164. package/dist/backend/backend/src/services/chat-v2/sqlite/message.store.js.map +1 -0
  165. package/dist/backend/backend/src/services/chat-v2/types.d.ts +295 -0
  166. package/dist/backend/backend/src/services/chat-v2/types.d.ts.map +1 -0
  167. package/dist/backend/backend/src/services/chat-v2/types.js +61 -0
  168. package/dist/backend/backend/src/services/chat-v2/types.js.map +1 -0
  169. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.d.ts +113 -0
  170. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.d.ts.map +1 -0
  171. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.js +179 -0
  172. package/dist/backend/backend/src/services/cloud/cloud-event-bridge.service.js.map +1 -0
  173. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.d.ts +131 -0
  174. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.d.ts.map +1 -0
  175. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.js +227 -0
  176. package/dist/backend/backend/src/services/cloud/cloud-event-forwarder.service.js.map +1 -0
  177. package/dist/backend/backend/src/services/core/config.service.js +3 -3
  178. package/dist/backend/backend/src/services/core/config.service.js.map +1 -1
  179. package/dist/backend/backend/src/services/core/storage.service.d.ts +7 -0
  180. package/dist/backend/backend/src/services/core/storage.service.d.ts.map +1 -1
  181. package/dist/backend/backend/src/services/core/storage.service.js +15 -0
  182. package/dist/backend/backend/src/services/core/storage.service.js.map +1 -1
  183. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts +69 -1
  184. package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
  185. package/dist/backend/backend/src/services/event-bus/event-bus.service.js +118 -0
  186. package/dist/backend/backend/src/services/event-bus/event-bus.service.js.map +1 -1
  187. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts +275 -0
  188. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.d.ts.map +1 -0
  189. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js +736 -0
  190. package/dist/backend/backend/src/services/event-bus/event-to-workitem-bridge.service.js.map +1 -0
  191. package/dist/backend/backend/src/services/knowledge/fts5-index.service.d.ts.map +1 -1
  192. package/dist/backend/backend/src/services/knowledge/fts5-index.service.js +18 -2
  193. package/dist/backend/backend/src/services/knowledge/fts5-index.service.js.map +1 -1
  194. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts +49 -13
  195. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
  196. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js +123 -29
  197. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
  198. package/dist/backend/backend/src/services/knowledge/learnings-index.service.d.ts +159 -0
  199. package/dist/backend/backend/src/services/knowledge/learnings-index.service.d.ts.map +1 -0
  200. package/dist/backend/backend/src/services/knowledge/learnings-index.service.js +304 -0
  201. package/dist/backend/backend/src/services/knowledge/learnings-index.service.js.map +1 -0
  202. package/dist/backend/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
  203. package/dist/backend/backend/src/services/knowledge/vector-store.service.js +24 -4
  204. package/dist/backend/backend/src/services/knowledge/vector-store.service.js.map +1 -1
  205. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts +174 -0
  206. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.d.ts.map +1 -0
  207. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js +375 -0
  208. package/dist/backend/backend/src/services/memory/auto-learning.subscriber.js.map +1 -0
  209. package/dist/backend/backend/src/services/memory/learning-format.validator.d.ts +97 -0
  210. package/dist/backend/backend/src/services/memory/learning-format.validator.d.ts.map +1 -0
  211. package/dist/backend/backend/src/services/memory/learning-format.validator.js +209 -0
  212. package/dist/backend/backend/src/services/memory/learning-format.validator.js.map +1 -0
  213. package/dist/backend/backend/src/services/memory/vector-store.service.d.ts.map +1 -1
  214. package/dist/backend/backend/src/services/memory/vector-store.service.js +19 -4
  215. package/dist/backend/backend/src/services/memory/vector-store.service.js.map +1 -1
  216. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.d.ts +16 -5
  217. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.d.ts.map +1 -1
  218. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.js +32 -5
  219. package/dist/backend/backend/src/services/onboarding/onboarding-provision.service.js.map +1 -1
  220. package/dist/backend/backend/src/services/onboarding/onboarding.service.d.ts +157 -0
  221. package/dist/backend/backend/src/services/onboarding/onboarding.service.d.ts.map +1 -0
  222. package/dist/backend/backend/src/services/onboarding/onboarding.service.js +229 -0
  223. package/dist/backend/backend/src/services/onboarding/onboarding.service.js.map +1 -0
  224. package/dist/backend/backend/src/services/onboarding/onboarding.types.d.ts +141 -0
  225. package/dist/backend/backend/src/services/onboarding/onboarding.types.d.ts.map +1 -0
  226. package/dist/backend/backend/src/services/onboarding/onboarding.types.js +18 -0
  227. package/dist/backend/backend/src/services/onboarding/onboarding.types.js.map +1 -0
  228. package/dist/backend/backend/src/services/pr-review/pr-review.service.d.ts.map +1 -1
  229. package/dist/backend/backend/src/services/pr-review/pr-review.service.js +1 -1
  230. package/dist/backend/backend/src/services/pr-review/pr-review.service.js.map +1 -1
  231. package/dist/backend/backend/src/services/slack/cross-machine-message.service.d.ts.map +1 -1
  232. package/dist/backend/backend/src/services/slack/cross-machine-message.service.js +17 -1
  233. package/dist/backend/backend/src/services/slack/cross-machine-message.service.js.map +1 -1
  234. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +39 -1
  235. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  236. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +158 -26
  237. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  238. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +248 -6
  239. package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
  240. package/dist/backend/backend/src/services/task-pool/task-pool.service.js +531 -51
  241. package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
  242. package/dist/backend/backend/src/services/team-health/index.d.ts +16 -0
  243. package/dist/backend/backend/src/services/team-health/index.d.ts.map +1 -0
  244. package/dist/backend/backend/src/services/team-health/index.js +16 -0
  245. package/dist/backend/backend/src/services/team-health/index.js.map +1 -0
  246. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.d.ts +52 -0
  247. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.d.ts.map +1 -0
  248. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.js +161 -0
  249. package/dist/backend/backend/src/services/team-health/live-team-health-data-provider.js.map +1 -0
  250. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.d.ts +53 -0
  251. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.d.ts.map +1 -0
  252. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.js +88 -0
  253. package/dist/backend/backend/src/services/team-health/lost-dispatch-detector.js.map +1 -0
  254. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.d.ts +44 -0
  255. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.d.ts.map +1 -0
  256. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.js +83 -0
  257. package/dist/backend/backend/src/services/team-health/stale-trigger-detector.js.map +1 -0
  258. package/dist/backend/backend/src/services/team-health/team-health-alert-router.d.ts +92 -0
  259. package/dist/backend/backend/src/services/team-health/team-health-alert-router.d.ts.map +1 -0
  260. package/dist/backend/backend/src/services/team-health/team-health-alert-router.js +328 -0
  261. package/dist/backend/backend/src/services/team-health/team-health-alert-router.js.map +1 -0
  262. package/dist/backend/backend/src/services/team-health/team-health-config.d.ts +41 -0
  263. package/dist/backend/backend/src/services/team-health/team-health-config.d.ts.map +1 -0
  264. package/dist/backend/backend/src/services/team-health/team-health-config.js +213 -0
  265. package/dist/backend/backend/src/services/team-health/team-health-config.js.map +1 -0
  266. package/dist/backend/backend/src/services/team-health/team-health-detector.d.ts +46 -0
  267. package/dist/backend/backend/src/services/team-health/team-health-detector.d.ts.map +1 -0
  268. package/dist/backend/backend/src/services/team-health/team-health-detector.js +347 -0
  269. package/dist/backend/backend/src/services/team-health/team-health-detector.js.map +1 -0
  270. package/dist/backend/backend/src/services/team-health/team-health-types.d.ts +154 -0
  271. package/dist/backend/backend/src/services/team-health/team-health-types.d.ts.map +1 -0
  272. package/dist/backend/backend/src/services/team-health/team-health-types.js +94 -0
  273. package/dist/backend/backend/src/services/team-health/team-health-types.js.map +1 -0
  274. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.d.ts +111 -0
  275. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.d.ts.map +1 -0
  276. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.js +226 -0
  277. package/dist/backend/backend/src/services/team-health/team-health-watchdog.service.js.map +1 -0
  278. package/dist/backend/backend/src/services/v3/mission-reminder.service.d.ts +148 -0
  279. package/dist/backend/backend/src/services/v3/mission-reminder.service.d.ts.map +1 -0
  280. package/dist/backend/backend/src/services/v3/mission-reminder.service.js +545 -0
  281. package/dist/backend/backend/src/services/v3/mission-reminder.service.js.map +1 -0
  282. package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts +499 -0
  283. package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts.map +1 -0
  284. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js +1105 -0
  285. package/dist/backend/backend/src/services/v3/request-sla.subscriber.js.map +1 -0
  286. package/dist/backend/backend/src/services/v3/request.service.d.ts +22 -0
  287. package/dist/backend/backend/src/services/v3/request.service.d.ts.map +1 -1
  288. package/dist/backend/backend/src/services/v3/request.service.js +71 -0
  289. package/dist/backend/backend/src/services/v3/request.service.js.map +1 -1
  290. package/dist/backend/backend/src/services/v3/v3-data.service.d.ts +1 -0
  291. package/dist/backend/backend/src/services/v3/v3-data.service.d.ts.map +1 -1
  292. package/dist/backend/backend/src/services/v3/v3-data.service.js +22 -6
  293. package/dist/backend/backend/src/services/v3/v3-data.service.js.map +1 -1
  294. package/dist/backend/backend/src/types/event-bus.types.d.ts +19 -1
  295. package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
  296. package/dist/backend/backend/src/types/event-bus.types.js +43 -0
  297. package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
  298. package/dist/backend/backend/src/types/index.d.ts +22 -1
  299. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  300. package/dist/backend/backend/src/types/index.js.map +1 -1
  301. package/dist/backend/backend/src/types/review-reason.types.d.ts +63 -0
  302. package/dist/backend/backend/src/types/review-reason.types.d.ts.map +1 -0
  303. package/dist/backend/backend/src/types/review-reason.types.js +50 -0
  304. package/dist/backend/backend/src/types/review-reason.types.js.map +1 -0
  305. package/dist/backend/backend/src/types/slack.types.d.ts +4 -1
  306. package/dist/backend/backend/src/types/slack.types.d.ts.map +1 -1
  307. package/dist/backend/backend/src/types/slack.types.js.map +1 -1
  308. package/dist/backend/backend/src/types/v2/mission.types.d.ts +18 -0
  309. package/dist/backend/backend/src/types/v2/mission.types.d.ts.map +1 -1
  310. package/dist/backend/backend/src/types/v2/mission.types.js +1 -0
  311. package/dist/backend/backend/src/types/v2/mission.types.js.map +1 -1
  312. package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  313. package/dist/backend/backend/src/types/v2/work-item.types.js +25 -1
  314. package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
  315. package/dist/backend/backend/src/utils/team.utils.d.ts +38 -0
  316. package/dist/backend/backend/src/utils/team.utils.d.ts.map +1 -0
  317. package/dist/backend/backend/src/utils/team.utils.js +45 -0
  318. package/dist/backend/backend/src/utils/team.utils.js.map +1 -0
  319. package/dist/backend/backend/src/websocket/chat-v2.gateway.d.ts +195 -0
  320. package/dist/backend/backend/src/websocket/chat-v2.gateway.d.ts.map +1 -0
  321. package/dist/backend/backend/src/websocket/chat-v2.gateway.js +401 -0
  322. package/dist/backend/backend/src/websocket/chat-v2.gateway.js.map +1 -0
  323. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts +37 -2
  324. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts.map +1 -1
  325. package/dist/backend/backend/src/websocket/terminal.gateway.js +106 -5
  326. package/dist/backend/backend/src/websocket/terminal.gateway.js.map +1 -1
  327. package/dist/cli/backend/src/constants.d.ts +69 -1
  328. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  329. package/dist/cli/backend/src/constants.js +69 -2
  330. package/dist/cli/backend/src/constants.js.map +1 -1
  331. package/dist/cli/backend/src/services/core/config.service.js +3 -3
  332. package/dist/cli/backend/src/services/core/config.service.js.map +1 -1
  333. package/dist/cli/backend/src/services/core/storage.service.d.ts +7 -0
  334. package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -1
  335. package/dist/cli/backend/src/services/core/storage.service.js +15 -0
  336. package/dist/cli/backend/src/services/core/storage.service.js.map +1 -1
  337. package/dist/cli/backend/src/services/knowledge/fts5-index.service.d.ts.map +1 -1
  338. package/dist/cli/backend/src/services/knowledge/fts5-index.service.js +18 -2
  339. package/dist/cli/backend/src/services/knowledge/fts5-index.service.js.map +1 -1
  340. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts +49 -13
  341. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
  342. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js +123 -29
  343. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
  344. package/dist/cli/backend/src/services/knowledge/vector-store.service.d.ts.map +1 -1
  345. package/dist/cli/backend/src/services/knowledge/vector-store.service.js +24 -4
  346. package/dist/cli/backend/src/services/knowledge/vector-store.service.js.map +1 -1
  347. package/dist/cli/backend/src/types/index.d.ts +22 -1
  348. package/dist/cli/backend/src/types/index.d.ts.map +1 -1
  349. package/dist/cli/backend/src/types/index.js.map +1 -1
  350. package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  351. package/dist/cli/backend/src/types/v2/work-item.types.js +25 -1
  352. package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
  353. package/frontend/dist/assets/{index-70356616.js → index-7a4e7df5.js} +328 -326
  354. package/frontend/dist/assets/index-b7e59b2b.css +33 -0
  355. package/frontend/dist/index.html +2 -2
  356. package/package.json +2 -1
  357. package/config/skills/orchestrator/recall/SKILL.md +0 -47
  358. package/config/skills/orchestrator/recall/execute.sh +0 -13
  359. package/config/skills/orchestrator/record-learning/SKILL.md +0 -47
  360. package/config/skills/orchestrator/record-learning/execute.sh +0 -13
  361. package/config/skills/orchestrator/remember/SKILL.md +0 -55
  362. package/config/skills/orchestrator/remember/execute.sh +0 -15
  363. package/frontend/dist/assets/index-6aaa0630.css +0 -33
@@ -0,0 +1,174 @@
1
+ /**
2
+ * AutoLearningSubscriber (LEARN-1)
3
+ *
4
+ * Subscribes to terminal WorkItem and mission lifecycle events on the
5
+ * EventBus and auto-records a learning entry via the existing
6
+ * {@link MemoryService.recordLearning} entrypoint. Closes the
7
+ * "agents-forget-to-record" gap noted in `.crewly/tmp/autonomy-doc-review-2026-04-26.md`
8
+ * §4 item 6 without introducing the rejected new "L-Event" type (Arch Veto V7,
9
+ * promoted from canonical V2 per the V-numbering map of 2026-04-27) and
10
+ * without expanding the 3-scope memory model into the rejected 5-scope shape
11
+ * (Arch Veto V9, promoted from canonical V3).
12
+ *
13
+ * Subscribed events:
14
+ * - `task:verified` → `pattern` (a passed verification — what worked)
15
+ * - `task:done` → `pattern` (a completion — what worked)
16
+ * - `task:rejected` → `gotcha` (TL rejected — what didn't work)
17
+ * - `task:failed` → `gotcha` (worker failed — what broke)
18
+ * - `mission:replanned`→ `sop_update` (strategy changed — operating practice)
19
+ *
20
+ * Idempotency contract (Arch Veto V1):
21
+ * Each handler dedupe-checks `${eventType}:${workItemId}` (or
22
+ * `${eventType}:${missionId}:${eventId}` for mission events) against an
23
+ * in-memory bounded LRU. The underlying `recordLearning()` is append-only
24
+ * (no native dedup), so the subscriber owns idempotency. The LRU is capped
25
+ * at {@link DEDUP_LRU_CAPACITY} entries to bound growth across long-lived
26
+ * processes.
27
+ *
28
+ * No new event types (Arch Veto V7):
29
+ * The subscriber listens to event types that already exist in `EVENT_TYPES`
30
+ * (added by BRIDGE-1.1). It does NOT introduce a new event class or any
31
+ * `learning:*` vocabulary. The implementation-detector grep at PR time —
32
+ * class/interface/type/new declarations — yields empty.
33
+ *
34
+ * No memory-scope expansion (Arch Veto V9):
35
+ * `recordLearning()` is called with the existing scope model. No new
36
+ * `team` / `user` scope members are added, and no `Skill`-prefixed candidate
37
+ * type is introduced. The implementation-detector grep at PR time yields
38
+ * empty.
39
+ *
40
+ * Fire-and-forget:
41
+ * Subscribers are called synchronously by the EventBus (in-process) but
42
+ * `recordLearning` itself is async; we wrap each dispatch so a thrown
43
+ * error is logged without affecting other subscribers or the publisher
44
+ * call site (mirrors {@link EventToWorkItemBridge.safeDispatch}).
45
+ *
46
+ * @module services/memory/auto-learning.subscriber
47
+ */
48
+ import { type ComponentLogger } from '../core/logger.service.js';
49
+ import type { IMemoryService } from './memory.service.js';
50
+ import type { EventBusService } from '../event-bus/event-bus.service.js';
51
+ import type { EventType } from '../../types/event-bus.types.js';
52
+ /**
53
+ * Tag prefix appended to the auto-recorded learning string. This is **not**
54
+ * the {@link RememberCategory} enum used by the unified remember operation —
55
+ * `recordLearning` writes free-form text to the project learnings log
56
+ * (no `category` field), so this string prefix exists purely for human/grep
57
+ * downstream filtering. Keeping it local avoids a forced extension of
58
+ * `RememberCategory` (Arch Veto V9 forbids enum sprawl).
59
+ */
60
+ export type AutoLearningTag = 'pattern' | 'gotcha' | 'sop_update';
61
+ /**
62
+ * Event types this subscriber listens to. Order mirrors the dispatch table
63
+ * inside {@link AutoLearningSubscriber.start} for easy audit.
64
+ *
65
+ * **Closed-set rationale (Arch N1, 2026-04-27):** This list is deliberately
66
+ * *closed* — only events that mark a terminal/quasi-terminal transition with
67
+ * a learning-worthy outcome are members. Adding a new entry requires:
68
+ * 1. The event type already exists in `EVENT_TYPES` (no V7 violation).
69
+ * 2. A corresponding entry in {@link EVENT_CATEGORY_MAP} (otherwise the
70
+ * handler defensively skips with a warn — see {@link handle}).
71
+ * 3. A new spec in `auto-learning.subscriber.test.ts` covering the
72
+ * category mapping and dedup key shape for the new event.
73
+ * The closed-set property is enforced at runtime by the export-allowlist
74
+ * check in the V7 self-check spec — adding a member without updating the
75
+ * allowlist fails CI.
76
+ *
77
+ * NOTE: All five exist in `EVENT_TYPES` already (added by BRIDGE-1.1). LEARN-1
78
+ * adds zero new event types — Arch Veto V7 holds.
79
+ */
80
+ export declare const LEARN_SUBSCRIBED_EVENTS: readonly EventType[];
81
+ /**
82
+ * Stable identity used as the `agentId` on every auto-recorded learning.
83
+ * Distinct from any human/agent session so the project learnings log makes
84
+ * the system origin visible (`### [system/system:auto-learning] hh:mm:ss`).
85
+ */
86
+ export declare const AUTO_LEARNING_AGENT_ID = "system:auto-learning";
87
+ export declare const AUTO_LEARNING_AGENT_ROLE = "system";
88
+ /**
89
+ * Maximum entries retained in the dedup LRU. Sized for ~hours of typical
90
+ * event volume; the dominant cost is map memory which is negligible at 1k.
91
+ */
92
+ export declare const DEDUP_LRU_CAPACITY = 1000;
93
+ /**
94
+ * Optional dependency container so tests can supply fakes for the event bus
95
+ * and memory service without touching singletons.
96
+ */
97
+ export interface AutoLearningSubscriberDependencies {
98
+ /** Live event bus. */
99
+ eventBus: EventBusService;
100
+ /** Memory service that owns `recordLearning`. */
101
+ memoryService: IMemoryService;
102
+ /** Project path used for the project-learnings log. Defaults to {@link process.cwd}. */
103
+ projectPath?: string;
104
+ /** Optional logger (defaults to component logger). */
105
+ logger?: ComponentLogger;
106
+ /** Optional dedup LRU capacity override (defaults to {@link DEDUP_LRU_CAPACITY}). */
107
+ dedupCapacity?: number;
108
+ }
109
+ /**
110
+ * AutoLearningSubscriber — the LEARN-1 deliverable.
111
+ *
112
+ * Wired in `backend/src/index.ts` via {@link AutoLearningSubscriber.boot}; tests
113
+ * construct via the constructor directly with fake dependencies.
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * const subscriber = AutoLearningSubscriber.boot(eventBus);
118
+ * subscriber.start();
119
+ * // … later, on shutdown:
120
+ * subscriber.stop();
121
+ * ```
122
+ */
123
+ export declare class AutoLearningSubscriber {
124
+ private readonly eventBus;
125
+ private readonly memoryService;
126
+ private readonly projectPath;
127
+ private readonly logger;
128
+ private readonly dedup;
129
+ private unsubscribers;
130
+ private started;
131
+ /**
132
+ * In-flight async dispatch promises. Test code calls
133
+ * {@link flushPending} to await every in-flight call deterministically.
134
+ */
135
+ private pendingDispatches;
136
+ constructor(deps: AutoLearningSubscriberDependencies);
137
+ /**
138
+ * Production wiring helper. Tests should use the constructor directly.
139
+ *
140
+ * @param eventBus - The live event bus
141
+ * @param projectPath - Optional override for the project-learnings target path
142
+ * @returns A subscriber instance ready to `start()`
143
+ */
144
+ static boot(eventBus: EventBusService, projectPath?: string): AutoLearningSubscriber;
145
+ /**
146
+ * Subscribe to all configured events. Idempotent — calling twice is a no-op.
147
+ */
148
+ start(): void;
149
+ /**
150
+ * Wait for every in-flight dispatch to settle. Test affordance.
151
+ */
152
+ flushPending(): Promise<void>;
153
+ /**
154
+ * Detach all subscriptions. Safe to call more than once.
155
+ */
156
+ stop(): void;
157
+ /**
158
+ * Snapshot of the dedup state (test affordance — production code never
159
+ * reads this).
160
+ */
161
+ get dedupSize(): number;
162
+ /**
163
+ * Core handler. Resolves the idempotency key, dedupes, picks the category,
164
+ * builds the templated summary, and calls `memoryService.recordLearning()`.
165
+ */
166
+ private handle;
167
+ /**
168
+ * Wrap a dispatch so a thrown error is logged without poisoning other
169
+ * subscribers or the publisher. Mirrors
170
+ * {@link EventToWorkItemBridge.safeDispatch}.
171
+ */
172
+ private safeDispatch;
173
+ }
174
+ //# sourceMappingURL=auto-learning.subscriber.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-learning.subscriber.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/memory/auto-learning.subscriber.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,eAAe,EAAwB,MAAM,mCAAmC,CAAC;AAC/F,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAO5E;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,CAAC;AAMlE;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,SAAS,EAM9C,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,yBAAyB,CAAC;AAC7D,eAAO,MAAM,wBAAwB,WAAW,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAoHvC;;;GAGG;AACH,MAAM,WAAW,kCAAkC;IACjD,sBAAsB;IACtB,QAAQ,EAAE,eAAe,CAAC;IAC1B,iDAAiD;IACjD,aAAa,EAAE,cAAc,CAAC;IAC9B,wFAAwF;IACxF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiB;IAC/C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,OAAO,CAAS;IACxB;;;OAGG;IACH,OAAO,CAAC,iBAAiB,CAAiC;gBAE9C,IAAI,EAAE,kCAAkC;IASpD;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,sBAAsB;IAQpF;;OAEG;IACH,KAAK,IAAI,IAAI;IAgBb;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAOnC;;OAEG;IACH,IAAI,IAAI,IAAI;IAaZ;;;OAGG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;IAMD;;;OAGG;IACH,OAAO,CAAC,MAAM,CAmDZ;IAEF;;;;OAIG;IACH,OAAO,CAAC,YAAY;CAwBrB"}
@@ -0,0 +1,375 @@
1
+ /**
2
+ * AutoLearningSubscriber (LEARN-1)
3
+ *
4
+ * Subscribes to terminal WorkItem and mission lifecycle events on the
5
+ * EventBus and auto-records a learning entry via the existing
6
+ * {@link MemoryService.recordLearning} entrypoint. Closes the
7
+ * "agents-forget-to-record" gap noted in `.crewly/tmp/autonomy-doc-review-2026-04-26.md`
8
+ * §4 item 6 without introducing the rejected new "L-Event" type (Arch Veto V7,
9
+ * promoted from canonical V2 per the V-numbering map of 2026-04-27) and
10
+ * without expanding the 3-scope memory model into the rejected 5-scope shape
11
+ * (Arch Veto V9, promoted from canonical V3).
12
+ *
13
+ * Subscribed events:
14
+ * - `task:verified` → `pattern` (a passed verification — what worked)
15
+ * - `task:done` → `pattern` (a completion — what worked)
16
+ * - `task:rejected` → `gotcha` (TL rejected — what didn't work)
17
+ * - `task:failed` → `gotcha` (worker failed — what broke)
18
+ * - `mission:replanned`→ `sop_update` (strategy changed — operating practice)
19
+ *
20
+ * Idempotency contract (Arch Veto V1):
21
+ * Each handler dedupe-checks `${eventType}:${workItemId}` (or
22
+ * `${eventType}:${missionId}:${eventId}` for mission events) against an
23
+ * in-memory bounded LRU. The underlying `recordLearning()` is append-only
24
+ * (no native dedup), so the subscriber owns idempotency. The LRU is capped
25
+ * at {@link DEDUP_LRU_CAPACITY} entries to bound growth across long-lived
26
+ * processes.
27
+ *
28
+ * No new event types (Arch Veto V7):
29
+ * The subscriber listens to event types that already exist in `EVENT_TYPES`
30
+ * (added by BRIDGE-1.1). It does NOT introduce a new event class or any
31
+ * `learning:*` vocabulary. The implementation-detector grep at PR time —
32
+ * class/interface/type/new declarations — yields empty.
33
+ *
34
+ * No memory-scope expansion (Arch Veto V9):
35
+ * `recordLearning()` is called with the existing scope model. No new
36
+ * `team` / `user` scope members are added, and no `Skill`-prefixed candidate
37
+ * type is introduced. The implementation-detector grep at PR time yields
38
+ * empty.
39
+ *
40
+ * Fire-and-forget:
41
+ * Subscribers are called synchronously by the EventBus (in-process) but
42
+ * `recordLearning` itself is async; we wrap each dispatch so a thrown
43
+ * error is logged without affecting other subscribers or the publisher
44
+ * call site (mirrors {@link EventToWorkItemBridge.safeDispatch}).
45
+ *
46
+ * @module services/memory/auto-learning.subscriber
47
+ */
48
+ import { LoggerService } from '../core/logger.service.js';
49
+ import { MemoryService } from './memory.service.js';
50
+ import { formatError } from '../../utils/format-error.js';
51
+ // ---------------------------------------------------------------------------
52
+ // Constants
53
+ // ---------------------------------------------------------------------------
54
+ /**
55
+ * Event types this subscriber listens to. Order mirrors the dispatch table
56
+ * inside {@link AutoLearningSubscriber.start} for easy audit.
57
+ *
58
+ * **Closed-set rationale (Arch N1, 2026-04-27):** This list is deliberately
59
+ * *closed* — only events that mark a terminal/quasi-terminal transition with
60
+ * a learning-worthy outcome are members. Adding a new entry requires:
61
+ * 1. The event type already exists in `EVENT_TYPES` (no V7 violation).
62
+ * 2. A corresponding entry in {@link EVENT_CATEGORY_MAP} (otherwise the
63
+ * handler defensively skips with a warn — see {@link handle}).
64
+ * 3. A new spec in `auto-learning.subscriber.test.ts` covering the
65
+ * category mapping and dedup key shape for the new event.
66
+ * The closed-set property is enforced at runtime by the export-allowlist
67
+ * check in the V7 self-check spec — adding a member without updating the
68
+ * allowlist fails CI.
69
+ *
70
+ * NOTE: All five exist in `EVENT_TYPES` already (added by BRIDGE-1.1). LEARN-1
71
+ * adds zero new event types — Arch Veto V7 holds.
72
+ */
73
+ export const LEARN_SUBSCRIBED_EVENTS = [
74
+ 'task:verified',
75
+ 'task:done',
76
+ 'task:rejected',
77
+ 'task:failed',
78
+ 'mission:replanned',
79
+ ];
80
+ /**
81
+ * Stable identity used as the `agentId` on every auto-recorded learning.
82
+ * Distinct from any human/agent session so the project learnings log makes
83
+ * the system origin visible (`### [system/system:auto-learning] hh:mm:ss`).
84
+ */
85
+ export const AUTO_LEARNING_AGENT_ID = 'system:auto-learning';
86
+ export const AUTO_LEARNING_AGENT_ROLE = 'system';
87
+ /**
88
+ * Maximum entries retained in the dedup LRU. Sized for ~hours of typical
89
+ * event volume; the dominant cost is map memory which is negligible at 1k.
90
+ */
91
+ export const DEDUP_LRU_CAPACITY = 1000;
92
+ /**
93
+ * Mapping from event type to the {@link AutoLearningTag} the auto-recorder
94
+ * stamps onto the learning string. Kept as a runtime object so a missing
95
+ * entry yields `undefined` and the dispatcher can default rather than crash.
96
+ */
97
+ const EVENT_CATEGORY_MAP = {
98
+ 'task:verified': 'pattern',
99
+ 'task:done': 'pattern',
100
+ 'task:rejected': 'gotcha',
101
+ 'task:failed': 'gotcha',
102
+ 'mission:replanned': 'sop_update',
103
+ };
104
+ // ---------------------------------------------------------------------------
105
+ // Helpers
106
+ // ---------------------------------------------------------------------------
107
+ /**
108
+ * Bounded set with FIFO eviction. Used as a cheap LRU-ish dedup cache for the
109
+ * subscriber's idempotency key set. We don't strictly need recency ordering
110
+ * (events arrive in roughly chronological order), so FIFO is fine and avoids
111
+ * the per-access mutation cost of a true LRU.
112
+ */
113
+ class BoundedSet {
114
+ capacity;
115
+ data = new Set();
116
+ constructor(capacity) {
117
+ if (capacity <= 0) {
118
+ throw new Error('BoundedSet capacity must be positive');
119
+ }
120
+ this.capacity = capacity;
121
+ }
122
+ has(key) {
123
+ return this.data.has(key);
124
+ }
125
+ /**
126
+ * Add a key; evict the oldest insertion when the set is at capacity.
127
+ * Returns `true` if the key was newly added, `false` if it was already
128
+ * present (caller-side idempotency check piggy-backs on this).
129
+ */
130
+ add(key) {
131
+ if (this.data.has(key))
132
+ return false;
133
+ if (this.data.size >= this.capacity) {
134
+ // Set iteration is insertion-ordered → first iter step yields the oldest.
135
+ const oldest = this.data.values().next().value;
136
+ if (oldest !== undefined)
137
+ this.data.delete(oldest);
138
+ }
139
+ this.data.add(key);
140
+ return true;
141
+ }
142
+ get size() {
143
+ return this.data.size;
144
+ }
145
+ clear() {
146
+ this.data.clear();
147
+ }
148
+ }
149
+ /**
150
+ * Build the deterministic idempotency key for an event. Task events key on
151
+ * `workItemId` (or `taskId` fallback) so a single WI-lifecycle transition
152
+ * dedupes across replays. Mission events key on `missionId:eventId` so each
153
+ * replan produces one learning even if the mission has many.
154
+ *
155
+ * @param event - The event being handled
156
+ * @returns A stable key, or null if the event doesn't carry enough identity
157
+ */
158
+ function buildIdempotencyKey(event) {
159
+ if (event.type === 'mission:replanned') {
160
+ if (!event.missionId)
161
+ return null;
162
+ return `${event.type}:${event.missionId}:${event.id}`;
163
+ }
164
+ const wiKey = event.workItemId ?? event.taskId;
165
+ if (!wiKey)
166
+ return null;
167
+ return `${event.type}:${wiKey}`;
168
+ }
169
+ /**
170
+ * Format a templated learning summary. Includes the WorkItem id, transition
171
+ * (previous→new), resolver session, mission/team context, and timestamp —
172
+ * everything an operator skimming the learnings log needs to find the
173
+ * underlying WorkItem without re-running a query.
174
+ *
175
+ * Uses the `[[Entity]]` Karpathy-lite convention so the auto-recorded
176
+ * learnings live in the same shape as agent-recorded ones.
177
+ *
178
+ * @param event - The event being summarized
179
+ * @returns A single-line markdown-safe summary
180
+ */
181
+ function buildLearningSummary(event) {
182
+ const entity = event.workItemId ?? event.taskId ?? event.missionId ?? 'unknown';
183
+ const entityKind = event.type.startsWith('mission:') ? 'Mission' : 'WorkItem';
184
+ const transition = event.previousValue && event.newValue
185
+ ? `${event.previousValue}→${event.newValue}`
186
+ : event.newValue || event.type;
187
+ const teamCtx = event.teamId ? ` team=${event.teamId}` : '';
188
+ const missionCtx = event.missionId ? ` mission=${event.missionId}` : '';
189
+ const resolverCtx = event.sessionName ? ` resolver=${event.sessionName}` : '';
190
+ return (`[[${entityKind}-${entity}]] ${event.type} ${transition}.` +
191
+ `${teamCtx}${missionCtx}${resolverCtx} timestamp=${event.timestamp}. Source: ${event.id}.`);
192
+ }
193
+ /**
194
+ * AutoLearningSubscriber — the LEARN-1 deliverable.
195
+ *
196
+ * Wired in `backend/src/index.ts` via {@link AutoLearningSubscriber.boot}; tests
197
+ * construct via the constructor directly with fake dependencies.
198
+ *
199
+ * @example
200
+ * ```typescript
201
+ * const subscriber = AutoLearningSubscriber.boot(eventBus);
202
+ * subscriber.start();
203
+ * // … later, on shutdown:
204
+ * subscriber.stop();
205
+ * ```
206
+ */
207
+ export class AutoLearningSubscriber {
208
+ eventBus;
209
+ memoryService;
210
+ projectPath;
211
+ logger;
212
+ dedup;
213
+ unsubscribers = [];
214
+ started = false;
215
+ /**
216
+ * In-flight async dispatch promises. Test code calls
217
+ * {@link flushPending} to await every in-flight call deterministically.
218
+ */
219
+ pendingDispatches = new Set();
220
+ constructor(deps) {
221
+ this.eventBus = deps.eventBus;
222
+ this.memoryService = deps.memoryService;
223
+ this.projectPath = deps.projectPath ?? process.cwd();
224
+ this.logger =
225
+ deps.logger ?? LoggerService.getInstance().createComponentLogger('AutoLearningSubscriber');
226
+ this.dedup = new BoundedSet(deps.dedupCapacity ?? DEDUP_LRU_CAPACITY);
227
+ }
228
+ /**
229
+ * Production wiring helper. Tests should use the constructor directly.
230
+ *
231
+ * @param eventBus - The live event bus
232
+ * @param projectPath - Optional override for the project-learnings target path
233
+ * @returns A subscriber instance ready to `start()`
234
+ */
235
+ static boot(eventBus, projectPath) {
236
+ return new AutoLearningSubscriber({
237
+ eventBus,
238
+ memoryService: MemoryService.getInstance(),
239
+ projectPath,
240
+ });
241
+ }
242
+ /**
243
+ * Subscribe to all configured events. Idempotent — calling twice is a no-op.
244
+ */
245
+ start() {
246
+ if (this.started)
247
+ return;
248
+ this.started = true;
249
+ for (const eventType of LEARN_SUBSCRIBED_EVENTS) {
250
+ this.unsubscribers.push(this.eventBus.onInProcess(eventType, (e) => this.safeDispatch(eventType, e)));
251
+ }
252
+ this.logger.info('AutoLearningSubscriber subscribed', {
253
+ eventTypes: LEARN_SUBSCRIBED_EVENTS,
254
+ projectPath: this.projectPath,
255
+ });
256
+ }
257
+ /**
258
+ * Wait for every in-flight dispatch to settle. Test affordance.
259
+ */
260
+ async flushPending() {
261
+ while (this.pendingDispatches.size > 0) {
262
+ const inFlight = Array.from(this.pendingDispatches);
263
+ await Promise.allSettled(inFlight);
264
+ }
265
+ }
266
+ /**
267
+ * Detach all subscriptions. Safe to call more than once.
268
+ */
269
+ stop() {
270
+ for (const unsubscribe of this.unsubscribers) {
271
+ try {
272
+ unsubscribe();
273
+ }
274
+ catch (err) {
275
+ this.logger.warn('AutoLearning unsubscribe threw', { error: formatError(err) });
276
+ }
277
+ }
278
+ this.unsubscribers = [];
279
+ this.started = false;
280
+ this.logger.info('AutoLearningSubscriber stopped');
281
+ }
282
+ /**
283
+ * Snapshot of the dedup state (test affordance — production code never
284
+ * reads this).
285
+ */
286
+ get dedupSize() {
287
+ return this.dedup.size;
288
+ }
289
+ // -------------------------------------------------------------------------
290
+ // Internals
291
+ // -------------------------------------------------------------------------
292
+ /**
293
+ * Core handler. Resolves the idempotency key, dedupes, picks the category,
294
+ * builds the templated summary, and calls `memoryService.recordLearning()`.
295
+ */
296
+ handle = async (eventType, event) => {
297
+ const key = buildIdempotencyKey(event);
298
+ if (!key) {
299
+ this.logger.debug('AutoLearning skipping event without identifying key', {
300
+ eventType,
301
+ eventId: event.id,
302
+ });
303
+ return;
304
+ }
305
+ // Pre-add the dedup key BEFORE awaiting recordLearning. Tradeoff (Arch N2,
306
+ // 2026-04-27): a recordLearning failure leaves the key claimed, so a
307
+ // subsequent retry of the same event is suppressed — we lose one
308
+ // learning entry. The alternative — add-on-success — opens a TOCTOU race
309
+ // where two near-simultaneous deliveries of the same event each pass the
310
+ // .has() check and produce a duplicate. We pick "lose-one-on-failure"
311
+ // because (a) recordLearning is best-effort and append-only by design,
312
+ // (b) the BRIDGE-1.4 V1 contract similarly favours dedup-correctness over
313
+ // delivery-completeness, and (c) the loss is logged at error level so an
314
+ // operator can manually re-record if needed.
315
+ if (!this.dedup.add(key)) {
316
+ this.logger.debug('AutoLearning dedup hit — skipping replay', { key, eventId: event.id });
317
+ return;
318
+ }
319
+ const category = EVENT_CATEGORY_MAP[eventType];
320
+ if (!category) {
321
+ // Defensive: an unknown event slipped past the subscription filter.
322
+ // Skip rather than recording a category-less learning.
323
+ this.logger.warn('AutoLearning got unmapped event — skipping', { eventType });
324
+ return;
325
+ }
326
+ const summary = buildLearningSummary(event);
327
+ const relatedTask = event.workItemId ?? event.taskId;
328
+ await this.memoryService.recordLearning({
329
+ agentId: AUTO_LEARNING_AGENT_ID,
330
+ agentRole: AUTO_LEARNING_AGENT_ROLE,
331
+ projectPath: this.projectPath,
332
+ // Prefix the learning with category so downstream readers (and grep
333
+ // audits) can filter without parsing the structured metadata.
334
+ learning: `[${category}] ${summary}`,
335
+ relatedTask,
336
+ });
337
+ this.logger.info('AutoLearning recorded', {
338
+ eventType,
339
+ category,
340
+ key,
341
+ relatedTask,
342
+ });
343
+ };
344
+ /**
345
+ * Wrap a dispatch so a thrown error is logged without poisoning other
346
+ * subscribers or the publisher. Mirrors
347
+ * {@link EventToWorkItemBridge.safeDispatch}.
348
+ */
349
+ safeDispatch(eventType, event) {
350
+ const dispatch = (async () => {
351
+ try {
352
+ await this.handle(eventType, event);
353
+ }
354
+ catch (err) {
355
+ this.logger.error('AutoLearning handler threw', {
356
+ eventType,
357
+ eventId: event.id,
358
+ error: formatError(err),
359
+ });
360
+ }
361
+ })();
362
+ this.pendingDispatches.add(dispatch);
363
+ dispatch
364
+ .finally(() => {
365
+ this.pendingDispatches.delete(dispatch);
366
+ })
367
+ .catch(() => {
368
+ // Suppress unhandled-rejection warning — flushPending callers see
369
+ // the outcome via Promise.allSettled, and the logger.error has
370
+ // already recorded the throw.
371
+ });
372
+ return dispatch;
373
+ }
374
+ }
375
+ //# sourceMappingURL=auto-learning.subscriber.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-learning.subscriber.js","sourceRoot":"","sources":["../../../../../../backend/src/services/memory/auto-learning.subscriber.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Learning format validator (Karpathy-lite / Entity-Centric)
3
+ *
4
+ * Implements the 4-rule preflight defined by ARCHIVIST-V2.f1
5
+ * (`.crewly/tasks/autonomy_v1/follow-up/archivist-v2-record-learning-preflight.md`).
6
+ *
7
+ * Rules:
8
+ * 1. Entity opener — text MUST start with `[[Entity Name]]` (one bracketed token).
9
+ * 2. Sentence count — 1..3 sentences (split on `[.!?]+\s+`, filter empties).
10
+ * 3. Linked or sourced — at minimum one of:
11
+ * - a second `[[Entity]]` link, OR
12
+ * - a `PR #...`, `Task #...`, `Issue #...`, `#NNN`, `Ref:`, `See:`, `Log:` source citation.
13
+ * 4. No log-style anti-pattern — soft check: warn (don't reject) if text begins
14
+ * with a personal pronoun ("I fixed", "I tried", "We added", etc.).
15
+ *
16
+ * Default mode (`strict: false`):
17
+ * - Rule 1 → hard error (the entity opener is the joinability hook for
18
+ * Archivist v2 cross-doc synthesis; without it the learning has no anchor).
19
+ * - Rules 2..4 → soft warnings (accept the learning, surface the violation).
20
+ *
21
+ * Strict mode (`strict: true`):
22
+ * - All 4 rules emit hard errors. Used by CI / Archivist v2 callers that
23
+ * enforce full conformance.
24
+ *
25
+ * Lax-by-controller policy (v1.5 / convention-only):
26
+ * The controller wiring is deferred. The validator is shipped as a
27
+ * reusable utility so callers (CLI, tests, future Archivist v2 synthesizer,
28
+ * future controller integration) can opt into enforcement as needed.
29
+ * See `archivist-v2-record-learning-preflight.md` § Validator behavior and
30
+ * the orc note ("Convention-only enforcement is OK in v1.5").
31
+ *
32
+ * @module services/memory/learning-format.validator
33
+ */
34
+ /** A single rule violation produced by {@link validateLearningFormat}. */
35
+ export interface LearningValidationIssue {
36
+ /** Numeric rule id (1..4) */
37
+ rule: 1 | 2 | 3 | 4;
38
+ /** Stable machine-readable rule name */
39
+ ruleName: 'entity_opener' | 'sentence_count' | 'linked_or_sourced' | 'no_log_style';
40
+ /** Human-readable description of the violation */
41
+ message: string;
42
+ /** Optional suggested fix (entity opener / shortening / link insertion) */
43
+ suggestion?: string;
44
+ /** Pointer to the SKILL.md mandate section */
45
+ skillRef: string;
46
+ }
47
+ /** Result returned by {@link validateLearningFormat}. */
48
+ export interface LearningValidationResult {
49
+ /** True when no errors (warnings are not failure). */
50
+ pass: boolean;
51
+ /** Hard violations — caller MUST reject when `pass === false`. */
52
+ errors: LearningValidationIssue[];
53
+ /** Soft violations — caller SHOULD log/surface but MAY accept. */
54
+ warnings: LearningValidationIssue[];
55
+ }
56
+ /** Options for {@link validateLearningFormat}. */
57
+ export interface LearningValidationOptions {
58
+ /**
59
+ * When true, escalate all soft warnings (rules 2..4) to hard errors.
60
+ * Rule 1 is always a hard error regardless of this flag.
61
+ * @default false
62
+ */
63
+ strict?: boolean;
64
+ }
65
+ /**
66
+ * Validate a learning text against the Karpathy-lite format rules.
67
+ *
68
+ * @param rawText - The learning text submitted to `record-learning`.
69
+ * @param options - Validator options ({@link LearningValidationOptions}).
70
+ * @returns A {@link LearningValidationResult} with errors and warnings split.
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * const result = validateLearningFormat('I fixed the bug today', { strict: false });
75
+ * // → { pass: false, errors: [<rule 1>], warnings: [<rule 3>, <rule 4>] }
76
+ * ```
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * const result = validateLearningFormat(
81
+ * '[[Fts5IndexService]] FTS5 rank is negative; invert. PR #320',
82
+ * { strict: true }
83
+ * );
84
+ * // → { pass: true, errors: [], warnings: [] }
85
+ * ```
86
+ */
87
+ export declare function validateLearningFormat(rawText: string, options?: LearningValidationOptions): LearningValidationResult;
88
+ /**
89
+ * Format a {@link LearningValidationIssue} as a multi-line string suitable
90
+ * for stderr / log output. Includes the offending text snippet and SKILL ref.
91
+ *
92
+ * @param issue - The issue to format.
93
+ * @param rawText - The full learning text (for snippet context).
94
+ * @returns A multi-line formatted string.
95
+ */
96
+ export declare function formatValidationMessage(issue: LearningValidationIssue, rawText: string): string;
97
+ //# sourceMappingURL=learning-format.validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learning-format.validator.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/memory/learning-format.validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,0EAA0E;AAC1E,MAAM,WAAW,uBAAuB;IACvC,6BAA6B;IAC7B,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,wCAAwC;IACxC,QAAQ,EAAE,eAAe,GAAG,gBAAgB,GAAG,mBAAmB,GAAG,cAAc,CAAC;IACpF,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,yDAAyD;AACzD,MAAM,WAAW,wBAAwB;IACxC,sDAAsD;IACtD,IAAI,EAAE,OAAO,CAAC;IACd,kEAAkE;IAClE,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAClC,kEAAkE;IAClE,QAAQ,EAAE,uBAAuB,EAAE,CAAC;CACpC;AAED,kDAAkD;AAClD,MAAM,WAAW,yBAAyB;IACzC;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AAwBD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,sBAAsB,CACrC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,yBAA8B,GACrC,wBAAwB,CAyE1B;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACtC,KAAK,EAAE,uBAAuB,EAC9B,OAAO,EAAE,MAAM,GACb,MAAM,CAWR"}