@jungjaehoon/mama-os 0.77.0 → 0.79.0

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 (338) hide show
  1. package/CHANGELOG.md +446 -0
  2. package/README.md +59 -30
  3. package/db/migrations/002-model-runs-parent-index.sql +11 -0
  4. package/db/migrations/003-upkeep-settled.sql +15 -0
  5. package/dist/api/google-read-actions.d.ts +30 -0
  6. package/dist/api/google-read-actions.d.ts.map +1 -0
  7. package/dist/api/google-read-actions.js +256 -0
  8. package/dist/api/google-read-actions.js.map +1 -0
  9. package/dist/api/record-actions.d.ts.map +1 -1
  10. package/dist/api/record-actions.js +23 -5
  11. package/dist/api/record-actions.js.map +1 -1
  12. package/dist/api/report-handler.d.ts +0 -6
  13. package/dist/api/report-handler.d.ts.map +1 -1
  14. package/dist/api/report-handler.js +0 -54
  15. package/dist/api/report-handler.js.map +1 -1
  16. package/dist/api/security-events.d.ts +1 -1
  17. package/dist/api/security-events.d.ts.map +1 -1
  18. package/dist/api/security-events.js +10 -1
  19. package/dist/api/security-events.js.map +1 -1
  20. package/dist/api/source-actions.d.ts +9 -0
  21. package/dist/api/source-actions.d.ts.map +1 -1
  22. package/dist/api/source-actions.js +49 -0
  23. package/dist/api/source-actions.js.map +1 -1
  24. package/dist/api/viewer-request-security.d.ts +14 -1
  25. package/dist/api/viewer-request-security.d.ts.map +1 -1
  26. package/dist/api/viewer-request-security.js +26 -3
  27. package/dist/api/viewer-request-security.js.map +1 -1
  28. package/dist/api/viewer-server.d.ts +8 -0
  29. package/dist/api/viewer-server.d.ts.map +1 -1
  30. package/dist/api/viewer-server.js +66 -0
  31. package/dist/api/viewer-server.js.map +1 -1
  32. package/dist/api/work-actions.d.ts +19 -2
  33. package/dist/api/work-actions.d.ts.map +1 -1
  34. package/dist/api/work-actions.js +42 -2
  35. package/dist/api/work-actions.js.map +1 -1
  36. package/dist/cli/commands/backfill.d.ts.map +1 -1
  37. package/dist/cli/commands/backfill.js +1 -0
  38. package/dist/cli/commands/backfill.js.map +1 -1
  39. package/dist/cli/commands/backup.d.ts +14 -0
  40. package/dist/cli/commands/backup.d.ts.map +1 -0
  41. package/dist/cli/commands/backup.js +174 -0
  42. package/dist/cli/commands/backup.js.map +1 -0
  43. package/dist/cli/commands/control.d.ts +44 -0
  44. package/dist/cli/commands/control.d.ts.map +1 -0
  45. package/dist/cli/commands/control.js +354 -0
  46. package/dist/cli/commands/control.js.map +1 -0
  47. package/dist/cli/commands/daemon.d.ts +60 -3
  48. package/dist/cli/commands/daemon.d.ts.map +1 -1
  49. package/dist/cli/commands/daemon.js +454 -78
  50. package/dist/cli/commands/daemon.js.map +1 -1
  51. package/dist/cli/commands/doctor.d.ts +13 -0
  52. package/dist/cli/commands/doctor.d.ts.map +1 -0
  53. package/dist/cli/commands/doctor.js +216 -0
  54. package/dist/cli/commands/doctor.js.map +1 -0
  55. package/dist/cli/commands/init-questions.d.ts +98 -0
  56. package/dist/cli/commands/init-questions.d.ts.map +1 -0
  57. package/dist/cli/commands/init-questions.js +420 -0
  58. package/dist/cli/commands/init-questions.js.map +1 -0
  59. package/dist/cli/commands/init-section.d.ts +13 -0
  60. package/dist/cli/commands/init-section.d.ts.map +1 -0
  61. package/dist/cli/commands/init-section.js +375 -0
  62. package/dist/cli/commands/init-section.js.map +1 -0
  63. package/dist/cli/commands/init.d.ts +56 -2
  64. package/dist/cli/commands/init.d.ts.map +1 -1
  65. package/dist/cli/commands/init.js +562 -350
  66. package/dist/cli/commands/init.js.map +1 -1
  67. package/dist/cli/commands/logs.d.ts +9 -0
  68. package/dist/cli/commands/logs.d.ts.map +1 -0
  69. package/dist/cli/commands/logs.js +109 -0
  70. package/dist/cli/commands/logs.js.map +1 -0
  71. package/dist/cli/commands/node-move.d.ts +20 -0
  72. package/dist/cli/commands/node-move.d.ts.map +1 -0
  73. package/dist/cli/commands/node-move.js +289 -0
  74. package/dist/cli/commands/node-move.js.map +1 -0
  75. package/dist/cli/commands/register-owner.d.ts +3 -0
  76. package/dist/cli/commands/register-owner.d.ts.map +1 -1
  77. package/dist/cli/commands/register-owner.js +14 -0
  78. package/dist/cli/commands/register-owner.js.map +1 -1
  79. package/dist/cli/commands/restore.d.ts +16 -0
  80. package/dist/cli/commands/restore.d.ts.map +1 -0
  81. package/dist/cli/commands/restore.js +137 -0
  82. package/dist/cli/commands/restore.js.map +1 -0
  83. package/dist/cli/commands/service.d.ts +44 -0
  84. package/dist/cli/commands/service.d.ts.map +1 -0
  85. package/dist/cli/commands/service.js +306 -0
  86. package/dist/cli/commands/service.js.map +1 -0
  87. package/dist/cli/commands/tools.d.ts +1 -1
  88. package/dist/cli/commands/tools.d.ts.map +1 -1
  89. package/dist/cli/commands/tools.js +8 -3
  90. package/dist/cli/commands/tools.js.map +1 -1
  91. package/dist/cli/commands/uninstall.d.ts +7 -0
  92. package/dist/cli/commands/uninstall.d.ts.map +1 -0
  93. package/dist/cli/commands/uninstall.js +335 -0
  94. package/dist/cli/commands/uninstall.js.map +1 -0
  95. package/dist/cli/commands/update.d.ts +59 -0
  96. package/dist/cli/commands/update.d.ts.map +1 -0
  97. package/dist/cli/commands/update.js +948 -0
  98. package/dist/cli/commands/update.js.map +1 -0
  99. package/dist/cli/index.js +74 -23
  100. package/dist/cli/index.js.map +1 -1
  101. package/dist/cli/launch-files.d.ts +119 -0
  102. package/dist/cli/launch-files.d.ts.map +1 -1
  103. package/dist/cli/launch-files.js +324 -15
  104. package/dist/cli/launch-files.js.map +1 -1
  105. package/dist/cli/prompt.d.ts +2 -1
  106. package/dist/cli/prompt.d.ts.map +1 -1
  107. package/dist/cli/prompt.js +5 -2
  108. package/dist/cli/prompt.js.map +1 -1
  109. package/dist/cli/runtime/backend-probe.d.ts +34 -0
  110. package/dist/cli/runtime/backend-probe.d.ts.map +1 -0
  111. package/dist/cli/runtime/backend-probe.js +83 -0
  112. package/dist/cli/runtime/backend-probe.js.map +1 -0
  113. package/dist/cli/runtime/backup.d.ts +130 -0
  114. package/dist/cli/runtime/backup.d.ts.map +1 -0
  115. package/dist/cli/runtime/backup.js +592 -0
  116. package/dist/cli/runtime/backup.js.map +1 -0
  117. package/dist/cli/runtime/daemon-control.d.ts +169 -0
  118. package/dist/cli/runtime/daemon-control.d.ts.map +1 -0
  119. package/dist/cli/runtime/daemon-control.js +441 -0
  120. package/dist/cli/runtime/daemon-control.js.map +1 -0
  121. package/dist/cli/runtime/default-roots.d.ts +27 -0
  122. package/dist/cli/runtime/default-roots.d.ts.map +1 -0
  123. package/dist/cli/runtime/default-roots.js +61 -0
  124. package/dist/cli/runtime/default-roots.js.map +1 -0
  125. package/dist/cli/runtime/diagnostics.d.ts +68 -0
  126. package/dist/cli/runtime/diagnostics.d.ts.map +1 -0
  127. package/dist/cli/runtime/diagnostics.js +1139 -0
  128. package/dist/cli/runtime/diagnostics.js.map +1 -0
  129. package/dist/cli/runtime/init-state.d.ts +20 -0
  130. package/dist/cli/runtime/init-state.d.ts.map +1 -0
  131. package/dist/cli/runtime/init-state.js +51 -0
  132. package/dist/cli/runtime/init-state.js.map +1 -0
  133. package/dist/cli/runtime/install-kind.d.ts +54 -0
  134. package/dist/cli/runtime/install-kind.d.ts.map +1 -0
  135. package/dist/cli/runtime/install-kind.js +164 -0
  136. package/dist/cli/runtime/install-kind.js.map +1 -0
  137. package/dist/cli/runtime/node-move-journal.d.ts +44 -0
  138. package/dist/cli/runtime/node-move-journal.d.ts.map +1 -0
  139. package/dist/cli/runtime/node-move-journal.js +48 -0
  140. package/dist/cli/runtime/node-move-journal.js.map +1 -0
  141. package/dist/cli/runtime/release-check.d.ts +94 -0
  142. package/dist/cli/runtime/release-check.d.ts.map +1 -0
  143. package/dist/cli/runtime/release-check.js +316 -0
  144. package/dist/cli/runtime/release-check.js.map +1 -0
  145. package/dist/cli/runtime/restore.d.ts +98 -0
  146. package/dist/cli/runtime/restore.d.ts.map +1 -0
  147. package/dist/cli/runtime/restore.js +756 -0
  148. package/dist/cli/runtime/restore.js.map +1 -0
  149. package/dist/cli/runtime/setup-page.d.ts +57 -0
  150. package/dist/cli/runtime/setup-page.d.ts.map +1 -0
  151. package/dist/cli/runtime/setup-page.js +266 -0
  152. package/dist/cli/runtime/setup-page.js.map +1 -0
  153. package/dist/cli/runtime/source-tools.d.ts +60 -0
  154. package/dist/cli/runtime/source-tools.d.ts.map +1 -0
  155. package/dist/cli/runtime/source-tools.js +170 -0
  156. package/dist/cli/runtime/source-tools.js.map +1 -0
  157. package/dist/cli/runtime/systemd-service.d.ts +13 -0
  158. package/dist/cli/runtime/systemd-service.d.ts.map +1 -0
  159. package/dist/cli/runtime/systemd-service.js +32 -0
  160. package/dist/cli/runtime/systemd-service.js.map +1 -0
  161. package/dist/cli/runtime/telegram-pairing.d.ts +73 -0
  162. package/dist/cli/runtime/telegram-pairing.d.ts.map +1 -0
  163. package/dist/cli/runtime/telegram-pairing.js +184 -0
  164. package/dist/cli/runtime/telegram-pairing.js.map +1 -0
  165. package/dist/cli/runtime/update-journal.d.ts +135 -0
  166. package/dist/cli/runtime/update-journal.d.ts.map +1 -0
  167. package/dist/cli/runtime/update-journal.js +144 -0
  168. package/dist/cli/runtime/update-journal.js.map +1 -0
  169. package/dist/cli/runtime/update-progress.d.ts +95 -0
  170. package/dist/cli/runtime/update-progress.d.ts.map +1 -0
  171. package/dist/cli/runtime/update-progress.js +154 -0
  172. package/dist/cli/runtime/update-progress.js.map +1 -0
  173. package/dist/cli/runtime/update-request.d.ts +58 -0
  174. package/dist/cli/runtime/update-request.d.ts.map +1 -0
  175. package/dist/cli/runtime/update-request.js +172 -0
  176. package/dist/cli/runtime/update-request.js.map +1 -0
  177. package/dist/connectors/calendar/index.d.ts +5 -1
  178. package/dist/connectors/calendar/index.d.ts.map +1 -1
  179. package/dist/connectors/calendar/index.js +19 -28
  180. package/dist/connectors/calendar/index.js.map +1 -1
  181. package/dist/connectors/chatwork/index.d.ts.map +1 -1
  182. package/dist/connectors/chatwork/index.js +7 -3
  183. package/dist/connectors/chatwork/index.js.map +1 -1
  184. package/dist/connectors/config-loader.d.ts +7 -1
  185. package/dist/connectors/config-loader.d.ts.map +1 -1
  186. package/dist/connectors/config-loader.js +11 -2
  187. package/dist/connectors/config-loader.js.map +1 -1
  188. package/dist/connectors/discord/index.d.ts.map +1 -1
  189. package/dist/connectors/discord/index.js +4 -3
  190. package/dist/connectors/discord/index.js.map +1 -1
  191. package/dist/connectors/drive/index.d.ts.map +1 -1
  192. package/dist/connectors/drive/index.js +15 -13
  193. package/dist/connectors/drive/index.js.map +1 -1
  194. package/dist/connectors/framework/gws-utils.d.ts +62 -0
  195. package/dist/connectors/framework/gws-utils.d.ts.map +1 -1
  196. package/dist/connectors/framework/gws-utils.js +133 -3
  197. package/dist/connectors/framework/gws-utils.js.map +1 -1
  198. package/dist/connectors/framework/polling-scheduler.d.ts.map +1 -1
  199. package/dist/connectors/framework/polling-scheduler.js +12 -11
  200. package/dist/connectors/framework/polling-scheduler.js.map +1 -1
  201. package/dist/connectors/framework/types.d.ts +24 -0
  202. package/dist/connectors/framework/types.d.ts.map +1 -1
  203. package/dist/connectors/framework/types.js +9 -0
  204. package/dist/connectors/framework/types.js.map +1 -1
  205. package/dist/connectors/gmail/index.d.ts.map +1 -1
  206. package/dist/connectors/gmail/index.js +14 -13
  207. package/dist/connectors/gmail/index.js.map +1 -1
  208. package/dist/connectors/imessage/index.d.ts.map +1 -1
  209. package/dist/connectors/imessage/index.js +2 -1
  210. package/dist/connectors/imessage/index.js.map +1 -1
  211. package/dist/connectors/index.d.ts +4 -4
  212. package/dist/connectors/index.d.ts.map +1 -1
  213. package/dist/connectors/index.js +4 -10
  214. package/dist/connectors/index.js.map +1 -1
  215. package/dist/connectors/notion/index.d.ts.map +1 -1
  216. package/dist/connectors/notion/index.js +5 -3
  217. package/dist/connectors/notion/index.js.map +1 -1
  218. package/dist/connectors/sheets/index.d.ts.map +1 -1
  219. package/dist/connectors/sheets/index.js +17 -12
  220. package/dist/connectors/sheets/index.js.map +1 -1
  221. package/dist/connectors/slack/index.d.ts.map +1 -1
  222. package/dist/connectors/slack/index.js +9 -3
  223. package/dist/connectors/slack/index.js.map +1 -1
  224. package/dist/connectors/telegram/index.d.ts.map +1 -1
  225. package/dist/connectors/telegram/index.js +4 -3
  226. package/dist/connectors/telegram/index.js.map +1 -1
  227. package/dist/connectors/trello/index.d.ts +1 -1
  228. package/dist/connectors/trello/index.d.ts.map +1 -1
  229. package/dist/connectors/trello/index.js +10 -5
  230. package/dist/connectors/trello/index.js.map +1 -1
  231. package/dist/gateways/discord.d.ts +6 -0
  232. package/dist/gateways/discord.d.ts.map +1 -1
  233. package/dist/gateways/discord.js +38 -27
  234. package/dist/gateways/discord.js.map +1 -1
  235. package/dist/gateways/slack.d.ts +6 -0
  236. package/dist/gateways/slack.d.ts.map +1 -1
  237. package/dist/gateways/slack.js +38 -27
  238. package/dist/gateways/slack.js.map +1 -1
  239. package/dist/gateways/telegram-commands.d.ts +124 -0
  240. package/dist/gateways/telegram-commands.d.ts.map +1 -0
  241. package/dist/gateways/telegram-commands.js +131 -0
  242. package/dist/gateways/telegram-commands.js.map +1 -0
  243. package/dist/gateways/telegram.d.ts +20 -0
  244. package/dist/gateways/telegram.d.ts.map +1 -1
  245. package/dist/gateways/telegram.js +138 -34
  246. package/dist/gateways/telegram.js.map +1 -1
  247. package/dist/gateways/turn-contract.d.ts +11 -0
  248. package/dist/gateways/turn-contract.d.ts.map +1 -1
  249. package/dist/runtime/action-surface.d.ts +1 -1
  250. package/dist/runtime/action-surface.d.ts.map +1 -1
  251. package/dist/runtime/action-surface.js +10 -0
  252. package/dist/runtime/action-surface.js.map +1 -1
  253. package/dist/runtime/backend-security.d.ts +26 -2
  254. package/dist/runtime/backend-security.d.ts.map +1 -1
  255. package/dist/runtime/backend-security.js +63 -10
  256. package/dist/runtime/backend-security.js.map +1 -1
  257. package/dist/runtime/config.d.ts +3 -0
  258. package/dist/runtime/config.d.ts.map +1 -1
  259. package/dist/runtime/config.js +4 -4
  260. package/dist/runtime/config.js.map +1 -1
  261. package/dist/runtime/connectors.d.ts +21 -1
  262. package/dist/runtime/connectors.d.ts.map +1 -1
  263. package/dist/runtime/connectors.js +28 -17
  264. package/dist/runtime/connectors.js.map +1 -1
  265. package/dist/runtime/core-db.d.ts.map +1 -1
  266. package/dist/runtime/core-db.js +2 -0
  267. package/dist/runtime/core-db.js.map +1 -1
  268. package/dist/runtime/member-paths.d.ts +15 -7
  269. package/dist/runtime/member-paths.d.ts.map +1 -1
  270. package/dist/runtime/member-paths.js +64 -12
  271. package/dist/runtime/member-paths.js.map +1 -1
  272. package/dist/runtime/member-session.d.ts +4 -0
  273. package/dist/runtime/member-session.d.ts.map +1 -1
  274. package/dist/runtime/member-session.js +23 -2
  275. package/dist/runtime/member-session.js.map +1 -1
  276. package/dist/runtime/native-session.d.ts +2 -0
  277. package/dist/runtime/native-session.d.ts.map +1 -1
  278. package/dist/runtime/native-session.js +1 -0
  279. package/dist/runtime/native-session.js.map +1 -1
  280. package/dist/runtime/owner-runtime.d.ts +63 -1
  281. package/dist/runtime/owner-runtime.d.ts.map +1 -1
  282. package/dist/runtime/owner-runtime.js +180 -3
  283. package/dist/runtime/owner-runtime.js.map +1 -1
  284. package/dist/runtime/owner-system-prompt.d.ts.map +1 -1
  285. package/dist/runtime/owner-system-prompt.js +6 -5
  286. package/dist/runtime/owner-system-prompt.js.map +1 -1
  287. package/dist/runtime/principal-access.d.ts +2 -0
  288. package/dist/runtime/principal-access.d.ts.map +1 -1
  289. package/dist/runtime/principal-access.js +7 -0
  290. package/dist/runtime/principal-access.js.map +1 -1
  291. package/dist/runtime/principal-sessions.d.ts.map +1 -1
  292. package/dist/runtime/principal-sessions.js +8 -1
  293. package/dist/runtime/principal-sessions.js.map +1 -1
  294. package/dist/runtime/record-orders.d.ts.map +1 -1
  295. package/dist/runtime/record-orders.js +3 -29
  296. package/dist/runtime/record-orders.js.map +1 -1
  297. package/dist/runtime/report-scheduler.d.ts +9 -2
  298. package/dist/runtime/report-scheduler.d.ts.map +1 -1
  299. package/dist/runtime/report-scheduler.js +37 -10
  300. package/dist/runtime/report-scheduler.js.map +1 -1
  301. package/dist/runtime/rotating-log.d.ts +44 -0
  302. package/dist/runtime/rotating-log.d.ts.map +1 -0
  303. package/dist/runtime/rotating-log.js +124 -0
  304. package/dist/runtime/rotating-log.js.map +1 -0
  305. package/dist/runtime/stimulus-delivery.d.ts +3 -0
  306. package/dist/runtime/stimulus-delivery.d.ts.map +1 -1
  307. package/dist/runtime/stimulus-delivery.js +19 -3
  308. package/dist/runtime/stimulus-delivery.js.map +1 -1
  309. package/dist/runtime/tools-paths.d.ts +7 -0
  310. package/dist/runtime/tools-paths.d.ts.map +1 -1
  311. package/dist/runtime/tools-paths.js +11 -5
  312. package/dist/runtime/tools-paths.js.map +1 -1
  313. package/dist/runtime/upkeep-close.d.ts +17 -0
  314. package/dist/runtime/upkeep-close.d.ts.map +1 -0
  315. package/dist/runtime/upkeep-close.js +127 -0
  316. package/dist/runtime/upkeep-close.js.map +1 -0
  317. package/dist/runtime/upkeep-orders.d.ts +124 -0
  318. package/dist/runtime/upkeep-orders.d.ts.map +1 -0
  319. package/dist/runtime/upkeep-orders.js +310 -0
  320. package/dist/runtime/upkeep-orders.js.map +1 -0
  321. package/dist/runtime/upkeep-reconcile.d.ts +25 -0
  322. package/dist/runtime/upkeep-reconcile.d.ts.map +1 -0
  323. package/dist/runtime/upkeep-reconcile.js +231 -0
  324. package/dist/runtime/upkeep-reconcile.js.map +1 -0
  325. package/dist/runtime/upkeep-writeback.d.ts +22 -0
  326. package/dist/runtime/upkeep-writeback.d.ts.map +1 -0
  327. package/dist/runtime/upkeep-writeback.js +203 -0
  328. package/dist/runtime/upkeep-writeback.js.map +1 -0
  329. package/dist/tools/document-toolkit.d.ts +2 -0
  330. package/dist/tools/document-toolkit.d.ts.map +1 -1
  331. package/dist/tools/document-toolkit.js +2 -0
  332. package/dist/tools/document-toolkit.js.map +1 -1
  333. package/dist/utils/untrusted-content.d.ts.map +1 -1
  334. package/dist/utils/untrusted-content.js +8 -1
  335. package/dist/utils/untrusted-content.js.map +1 -1
  336. package/install/install.sh +457 -0
  337. package/install/node.json +9 -0
  338. package/package.json +5 -5
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CLOSE_ORDER_CHANNEL = void 0;
4
+ exports.closeUpkeepKind = closeUpkeepKind;
5
+ const knowledge_1 = require("@jungjaehoon/mama-core/knowledge");
6
+ const untrusted_content_js_1 = require("../utils/untrusted-content.js");
7
+ const timezone_js_1 = require("./timezone.js");
8
+ const upkeep_orders_js_1 = require("./upkeep-orders.js");
9
+ exports.CLOSE_ORDER_CHANNEL = 'operator:close';
10
+ const CLOSED_STATUSES = ['done', 'cancelled'];
11
+ /**
12
+ * U1, closing summaries. A subject is one closing revision: a reopened item that closes again is
13
+ * a new subject. It is checked by a revision from the order's runs that sets a description, or by
14
+ * a work.no_update naming the item; a revision that only sets the status again does not count.
15
+ */
16
+ function closeUpkeepKind(options) {
17
+ return {
18
+ name: 'close',
19
+ channel: exports.CLOSE_ORDER_CHANNEL,
20
+ intervalMs: 60 * 60 * 1000,
21
+ maxPerOrder: 10,
22
+ scan: (adapter, now, page) => {
23
+ const scopes = (0, knowledge_1.readableScopeIds)(options.access());
24
+ // Visibility as core's readWork applies it: an unbound head, or one bound to a read scope.
25
+ const visible = `(NOT EXISTS (SELECT 1 FROM memory_scope_bindings b WHERE b.memory_id = c.head_record_id)${scopes.length === 0
26
+ ? ''
27
+ : ` OR EXISTS (SELECT 1 FROM memory_scope_bindings b WHERE b.memory_id = c.head_record_id
28
+ AND b.scope_id IN (${scopes.map(() => '?').join(',')}))`})`;
29
+ const closed = CLOSED_STATUSES.map(() => '?').join(',');
30
+ const rows = adapter
31
+ .prepare(
32
+ // Core folds revisions in the order they were written and drops one whose applies_until
33
+ // has passed; a revision that clears the status leaves the item without one. The subject
34
+ // is the transition: the first closed revision after the last one that was not closed,
35
+ // so a later revision that sets the status to done again is not a new subject.
36
+ `WITH live AS (
37
+ SELECT * FROM commitment_assignments WHERE applies_until IS NULL OR applies_until > ?),
38
+ statuses AS (
39
+ SELECT commitment_id, revision, created_at,
40
+ CASE WHEN EXISTS (SELECT 1 FROM json_each(live.clear_json) WHERE value = 'status')
41
+ THEN NULL ELSE json_extract(set_json, '$.status') END AS status
42
+ FROM live
43
+ WHERE json_extract(set_json, '$.status') IS NOT NULL
44
+ OR EXISTS (SELECT 1 FROM json_each(live.clear_json) WHERE value = 'status')),
45
+ latest AS (
46
+ SELECT commitment_id, MAX(revision) AS revision FROM statuses GROUP BY commitment_id),
47
+ reopened AS (
48
+ SELECT commitment_id, MAX(revision) AS revision FROM statuses
49
+ WHERE status IS NULL OR status NOT IN (${closed}) GROUP BY commitment_id),
50
+ closing AS (
51
+ SELECT s.commitment_id, MIN(s.revision) AS revision FROM statuses s
52
+ LEFT JOIN reopened o ON o.commitment_id = s.commitment_id
53
+ WHERE s.status IN (${closed}) AND s.revision > coalesce(o.revision, 0)
54
+ GROUP BY s.commitment_id),
55
+ titles AS (
56
+ SELECT x.commitment_id, json_extract(x.set_json, '$.title') AS title FROM live x
57
+ WHERE x.revision = (SELECT MAX(y.revision) FROM live y
58
+ WHERE y.commitment_id = x.commitment_id
59
+ AND json_extract(y.set_json, '$.title') IS NOT NULL))
60
+ SELECT k.commitment_id, k.revision, s.created_at, now.status, coalesce(t.title, '') AS title
61
+ FROM closing k
62
+ JOIN latest l ON l.commitment_id = k.commitment_id
63
+ JOIN statuses now ON now.commitment_id = l.commitment_id AND now.revision = l.revision
64
+ JOIN statuses s ON s.commitment_id = k.commitment_id AND s.revision = k.revision
65
+ JOIN commitments c ON c.commitment_id = k.commitment_id AND c.withdrawn = 0
66
+ LEFT JOIN titles t ON t.commitment_id = k.commitment_id
67
+ WHERE now.status IN (${closed}) AND s.created_at >= ? AND ${visible}
68
+ ORDER BY s.created_at, k.commitment_id
69
+ LIMIT ? OFFSET ?`)
70
+ .all(now, ...CLOSED_STATUSES, ...CLOSED_STATUSES, ...CLOSED_STATUSES,
71
+ // A subject older than the attempt window would count its attempts from zero again.
72
+ Math.max(options.since, now - upkeep_orders_js_1.UPKEEP_WINDOW_MS), ...scopes, upkeep_orders_js_1.UPKEEP_SCAN_PAGE, page * upkeep_orders_js_1.UPKEEP_SCAN_PAGE);
73
+ return rows.map((row) => ({
74
+ key: `${row.commitment_id}:${row.revision}`,
75
+ commitmentId: row.commitment_id,
76
+ revision: row.revision,
77
+ title: row.title,
78
+ status: row.status,
79
+ closedAt: row.created_at,
80
+ }));
81
+ },
82
+ checked: (adapter, subject, runIds) => {
83
+ const { commitmentId, revision } = subject;
84
+ if (runIds.length === 0)
85
+ return false;
86
+ // The description as core folds it now: the latest live revision that sets or clears it.
87
+ // The summary counts when that revision is the order's own, after the closing revision,
88
+ // and leaves text there.
89
+ const current = adapter
90
+ .prepare(`SELECT revision, model_run_id,
91
+ CASE WHEN EXISTS (SELECT 1 FROM json_each(clear_json) WHERE value = 'description')
92
+ THEN '' ELSE coalesce(json_extract(set_json, '$.description'), '') END AS text
93
+ FROM commitment_assignments
94
+ WHERE commitment_id = ? AND (applies_until IS NULL OR applies_until > ?)
95
+ AND (json_extract(set_json, '$.description') IS NOT NULL
96
+ OR EXISTS (SELECT 1 FROM json_each(clear_json) WHERE value = 'description'))
97
+ ORDER BY revision DESC LIMIT 1`)
98
+ .get(commitmentId, Date.now());
99
+ const summarized = current !== undefined &&
100
+ current.revision > revision &&
101
+ current.text.trim() !== '' &&
102
+ current.model_run_id !== null &&
103
+ runIds.includes(current.model_run_id);
104
+ return (summarized ||
105
+ (0, upkeep_orders_js_1.noUpdateCites)(adapter, runIds, { field: 'commitmentIds', values: [commitmentId] }));
106
+ },
107
+ render: (subjects, now) => {
108
+ const zone = options.timeZone();
109
+ // Titles come from stored work, which sources can shape: they are data, never instructions.
110
+ const ids = subjects.map((subject) => `- ${subject.commitmentId} (${subject.status} ${(0, timezone_js_1.localNow)(subject.closedAt, zone)})`);
111
+ const titles = subjects.map((subject) => `${subject.commitmentId}: ${subject.title.replace(/\s+/g, ' ').slice(0, 200)}`);
112
+ return [
113
+ `[upkeep_close] ${subjects.length} closed work item${subjects.length === 1 ? '' : 's'}`,
114
+ `Current time: ${(0, timezone_js_1.localNow)(now.getTime(), zone)} (${zone})`,
115
+ "Write each item's closing summary, so a later question about it reads one place:",
116
+ '1. Read each item with its history: work.list view=detail with ids (up to 4 per call); page older revisions with history_offset until the first one.',
117
+ "2. Write one work.revise per item that sets description to the summary: the rounds (each submission, each round of outside feedback with the points raised, each internal review, with dates), who did what, how it ended, and what is worth reusing. Link the revisions' evidence with derived_from. Do not change its status, stage or other fields.",
118
+ '3. An item whose description is already such a summary: work.no_update with commitmentIds naming it and the reason.',
119
+ '4. The order is checked when it ends: each item needs step 2 or 3. Correct a refused write (help gives its contract) and write it again.',
120
+ '5. Reply exactly [ack].',
121
+ ...ids,
122
+ (0, untrusted_content_js_1.wrapUntrustedContent)('work_titles', titles.join('\n')),
123
+ ].join('\n');
124
+ },
125
+ };
126
+ }
127
+ //# sourceMappingURL=upkeep-close.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upkeep-close.js","sourceRoot":"","sources":["../../src/runtime/upkeep-close.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,124 @@
1
+ import type { DatabaseAdapter } from '@jungjaehoon/mama-core/db-manager';
2
+ import type { JsonValue } from '@jungjaehoon/mama-core/knowledge';
3
+ import type { MailboxRow, Stimulus } from '@jungjaehoon/mama-core/runtime/mailbox';
4
+ import type { StimulusReceipt } from '@jungjaehoon/mama-core/runtime/runtime';
5
+ /**
6
+ * Ledger upkeep orders (docs/development/work/ledger-upkeep.md). The host chooses the subjects,
7
+ * the agent judges and writes in the common session, and the host checks each subject when the
8
+ * order's run ends. Record orders (record-orders.ts) stay a separate lane: they follow live deltas
9
+ * and carry batches; upkeep follows the ledger's own state.
10
+ *
11
+ * tick(kind) ── scan ──> subjects not checked, not in an open order, under the attempt limit
12
+ * │ │
13
+ * │ accept(order on kind.channel)
14
+ * ▼ ▼
15
+ * onResult / onLost ──> per subject: checked │ waiting (picked by the next tick) │ lost
16
+ *
17
+ * Checked and lost subjects are also written to upkeep_settled: the mailbox deletes acked order
18
+ * rows after seven days, and a settled subject must never be ordered again.
19
+ */
20
+ /** A subject is ordered at most this many times; then it is reported lost and left alone. */
21
+ export declare const UPKEEP_MAX_ATTEMPTS = 3;
22
+ /** How far back stored orders are read to count a subject's attempts. */
23
+ export declare const UPKEEP_WINDOW_MS: number;
24
+ /** Candidates per scan page. */
25
+ export declare const UPKEEP_SCAN_PAGE = 200;
26
+ /** Every order of a kind has an id with this prefix; its runs carry it as sourceMessageRef. */
27
+ export declare function upkeepOrderIdPrefix(kindName: string): string;
28
+ export interface UpkeepSubject {
29
+ /** Stable per subject: the same fact always gets the same key. */
30
+ key: string;
31
+ [field: string]: JsonValue;
32
+ }
33
+ export interface UpkeepKind {
34
+ name: string;
35
+ /** The order's mailbox channel, `operator:<name>`. */
36
+ channel: string;
37
+ /** How often the host scans. */
38
+ intervalMs: number;
39
+ maxPerOrder: number;
40
+ /**
41
+ * The subject's group, when the kind's subjects come in kinds of their own: maxPerOrder then
42
+ * bounds each group, so one group never starves the other.
43
+ */
44
+ group?(subject: UpkeepSubject): string;
45
+ /**
46
+ * Candidate subjects, oldest first, one page at a time: the runner reads further pages while
47
+ * settled subjects fill the earlier ones.
48
+ */
49
+ scan(adapter: DatabaseAdapter, now: number, page: number): UpkeepSubject[];
50
+ /** Whether the subject's work is done, judged from the runs of the orders that carried it. */
51
+ checked(adapter: DatabaseAdapter, subject: UpkeepSubject, runIds: readonly string[]): boolean;
52
+ render(subjects: readonly UpkeepSubject[], now: Date): string;
53
+ }
54
+ export interface UpkeepOrderPayload {
55
+ order: 'upkeep';
56
+ kind: string;
57
+ subjects: UpkeepSubject[];
58
+ }
59
+ export type UpkeepEvent = {
60
+ type: 'ordered';
61
+ kind: string;
62
+ order: string;
63
+ subjects: number;
64
+ } | {
65
+ type: 'checked';
66
+ kind: string;
67
+ subject: string;
68
+ }
69
+ /** The subject is picked again by the kind's next tick. */
70
+ | {
71
+ type: 'waiting';
72
+ kind: string;
73
+ subject: string;
74
+ attempt: number;
75
+ reason: string;
76
+ } | {
77
+ type: 'lost';
78
+ kind: string;
79
+ subject: string;
80
+ attempt: number;
81
+ reason: string;
82
+ };
83
+ export interface UpkeepOrdersOptions {
84
+ adapter: DatabaseAdapter;
85
+ accept(stimulus: Omit<Stimulus, 'principalId'>): StimulusReceipt;
86
+ kinds: readonly UpkeepKind[];
87
+ /** When this daemon process started: runs begun earlier can no longer write. */
88
+ processStartedAt: number;
89
+ onEvent?(event: UpkeepEvent): void;
90
+ /** How long to wait for an order run's child runs to end before checking. */
91
+ childWaitMs?: number;
92
+ sleep?(ms: number): Promise<void>;
93
+ now?(): number;
94
+ /** The first scan after start, so work closed while the daemon was down is not left an hour. */
95
+ firstTickDelayMs?: number;
96
+ }
97
+ export interface UpkeepOrders {
98
+ isUpkeepRow(row: Pick<MailboxRow, 'kind' | 'channelKey'>): boolean;
99
+ render(row: MailboxRow, now: Date): string;
100
+ onResult(row: MailboxRow, modelRunId: string | null): void;
101
+ /** An order row that went uncertain or dead: the same check, run at once. */
102
+ onLost(row: MailboxRow, reason: string): void;
103
+ /** Scan one kind and place its next order; at most one open order per kind. */
104
+ tick(kindName: string): void;
105
+ start(): void;
106
+ stop(): void;
107
+ }
108
+ export declare function parseUpkeepOrder(payload: JsonValue | undefined): UpkeepOrderPayload;
109
+ /** The runs an order produced: its own turn and the child runs that turn started. */
110
+ export declare function orderRunIds(adapter: DatabaseAdapter, orderIds: readonly string[]): string[];
111
+ /**
112
+ * A completed work.no_update in these runs. With `cites`, the no-update must name one of the
113
+ * values in that input field (`commitmentIds` for a work item, `observationRefs` for a source);
114
+ * with `cites` null, any no-update in the runs counts. The field name is a fixed union, never
115
+ * caller text, so it interpolates into the json path safely.
116
+ */
117
+ export declare function noUpdateCites(adapter: DatabaseAdapter, runIds: readonly string[], cites: {
118
+ field: 'commitmentIds' | 'observationRefs';
119
+ values: readonly string[];
120
+ } | null): boolean;
121
+ /** Child runs of an order run that this process started and that have not ended yet. */
122
+ export declare function runningChildren(adapter: DatabaseAdapter, modelRunId: string, startedAt: number): number;
123
+ export declare function createUpkeepOrders(options: UpkeepOrdersOptions): UpkeepOrders;
124
+ //# sourceMappingURL=upkeep-orders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upkeep-orders.d.ts","sourceRoot":"","sources":["../../src/runtime/upkeep-orders.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,310 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UPKEEP_SCAN_PAGE = exports.UPKEEP_WINDOW_MS = exports.UPKEEP_MAX_ATTEMPTS = void 0;
4
+ exports.upkeepOrderIdPrefix = upkeepOrderIdPrefix;
5
+ exports.parseUpkeepOrder = parseUpkeepOrder;
6
+ exports.orderRunIds = orderRunIds;
7
+ exports.noUpdateCites = noUpdateCites;
8
+ exports.runningChildren = runningChildren;
9
+ exports.createUpkeepOrders = createUpkeepOrders;
10
+ const node_crypto_1 = require("node:crypto");
11
+ /**
12
+ * Ledger upkeep orders (docs/development/work/ledger-upkeep.md). The host chooses the subjects,
13
+ * the agent judges and writes in the common session, and the host checks each subject when the
14
+ * order's run ends. Record orders (record-orders.ts) stay a separate lane: they follow live deltas
15
+ * and carry batches; upkeep follows the ledger's own state.
16
+ *
17
+ * tick(kind) ── scan ──> subjects not checked, not in an open order, under the attempt limit
18
+ * │ │
19
+ * │ accept(order on kind.channel)
20
+ * ▼ ▼
21
+ * onResult / onLost ──> per subject: checked │ waiting (picked by the next tick) │ lost
22
+ *
23
+ * Checked and lost subjects are also written to upkeep_settled: the mailbox deletes acked order
24
+ * rows after seven days, and a settled subject must never be ordered again.
25
+ */
26
+ /** A subject is ordered at most this many times; then it is reported lost and left alone. */
27
+ exports.UPKEEP_MAX_ATTEMPTS = 3;
28
+ /** How far back stored orders are read to count a subject's attempts. */
29
+ exports.UPKEEP_WINDOW_MS = 7 * 24 * 60 * 60 * 1000;
30
+ /** Candidates per scan page. */
31
+ exports.UPKEEP_SCAN_PAGE = 200;
32
+ /** Every order of a kind has an id with this prefix; its runs carry it as sourceMessageRef. */
33
+ function upkeepOrderIdPrefix(kindName) {
34
+ return `upkeep:${kindName}:`;
35
+ }
36
+ function parseUpkeepOrder(payload) {
37
+ const value = payload;
38
+ if (!value ||
39
+ value.order !== 'upkeep' ||
40
+ typeof value.kind !== 'string' ||
41
+ !Array.isArray(value.subjects) ||
42
+ value.subjects.length === 0 ||
43
+ value.subjects.some((subject) => typeof subject?.key !== 'string' || subject.key === ''))
44
+ throw new Error('Upkeep order requires { order: upkeep, kind, subjects: [{ key }] }');
45
+ return value;
46
+ }
47
+ /** The runs an order produced: its own turn and the child runs that turn started. */
48
+ function orderRunIds(adapter, orderIds) {
49
+ if (orderIds.length === 0)
50
+ return [];
51
+ const marks = orderIds.map(() => '?').join(',');
52
+ return adapter
53
+ .prepare(`SELECT r.model_run_id AS id FROM model_runs r
54
+ WHERE json_extract(r.input_refs_json, '$.sourceMessageRef') IN (${marks})
55
+ UNION
56
+ SELECT c.model_run_id FROM model_runs c JOIN model_runs p ON c.parent_model_run_id = p.model_run_id
57
+ WHERE json_extract(p.input_refs_json, '$.sourceMessageRef') IN (${marks})`)
58
+ .all(...orderIds, ...orderIds).map((row) => row.id);
59
+ }
60
+ /**
61
+ * A completed work.no_update in these runs. With `cites`, the no-update must name one of the
62
+ * values in that input field (`commitmentIds` for a work item, `observationRefs` for a source);
63
+ * with `cites` null, any no-update in the runs counts. The field name is a fixed union, never
64
+ * caller text, so it interpolates into the json path safely.
65
+ */
66
+ function noUpdateCites(adapter, runIds, cites) {
67
+ if (runIds.length === 0)
68
+ return false;
69
+ if (cites !== null && cites.values.length === 0)
70
+ return false;
71
+ const citing = cites === null
72
+ ? ''
73
+ : `AND EXISTS (
74
+ SELECT 1 FROM json_each(CASE WHEN json_valid(t.input_summary)
75
+ THEN json_extract(t.input_summary, '$.${cites.field}') END) ref
76
+ WHERE ref.value IN (${cites.values.map(() => '?').join(',')}))`;
77
+ return (adapter
78
+ .prepare(`SELECT 1 FROM tool_traces t
79
+ WHERE t.tool_name = 'work.no_update' AND t.execution_status = 'completed'
80
+ AND t.model_run_id IN (${runIds.map(() => '?').join(',')})
81
+ ${citing}
82
+ LIMIT 1`)
83
+ .get(...runIds, ...(cites?.values ?? [])) !== undefined);
84
+ }
85
+ /** The kind's subjects as its stored orders of the last week show them. */
86
+ function storedSubjects(adapter, kind, now) {
87
+ const rows = adapter
88
+ .prepare(`SELECT m.stimulus_id, m.payload_json, m.status, n.state AS native_state
89
+ FROM mailbox_inputs m LEFT JOIN native_input_deliveries n ON n.input_id = m.id
90
+ WHERE m.kind = 'scheduled' AND m.channel_key = ? AND m.created_at >= ?
91
+ ORDER BY m.created_at, m.id`)
92
+ .all(kind.channel, now - exports.UPKEEP_WINDOW_MS);
93
+ const states = new Map();
94
+ let anyOpen = false;
95
+ for (const row of rows) {
96
+ const order = parseUpkeepOrder(JSON.parse(row.payload_json));
97
+ // A row parked uncertain stays claimed; it is settled through onLost, not left open.
98
+ const open = (row.status === 'pending' || row.status === 'claimed') && row.native_state !== 'uncertain';
99
+ anyOpen ||= open;
100
+ for (const subject of order.subjects) {
101
+ const current = states.get(subject.key);
102
+ states.set(subject.key, {
103
+ subject,
104
+ orders: [...(current?.orders ?? []), row.stimulus_id],
105
+ open: (current?.open ?? false) || open,
106
+ });
107
+ }
108
+ }
109
+ return { states, anyOpen };
110
+ }
111
+ /** A subject settled for good (upkeep_settled); a later write keeps the latest state. */
112
+ function recordSettled(adapter) {
113
+ return adapter.prepare(`INSERT OR REPLACE INTO upkeep_settled (kind, subject_key, state, settled_at) VALUES (?, ?, ?, ?)`);
114
+ }
115
+ /** Child runs of an order run that this process started and that have not ended yet. */
116
+ function runningChildren(adapter, modelRunId, startedAt) {
117
+ const row = adapter
118
+ .prepare(`SELECT count(*) AS n FROM model_runs
119
+ WHERE parent_model_run_id = ? AND status NOT IN ('committed', 'failed') AND created_at >= ?`)
120
+ .get(modelRunId, startedAt);
121
+ return row?.n ?? 0;
122
+ }
123
+ function createUpkeepOrders(options) {
124
+ const now = options.now ?? Date.now;
125
+ const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
126
+ const childWaitMs = options.childWaitMs ?? 10 * 60 * 1000;
127
+ const byName = new Map(options.kinds.map((kind) => [kind.name, kind]));
128
+ const byChannel = new Map(options.kinds.map((kind) => [kind.channel, kind]));
129
+ const timers = [];
130
+ // Orders whose check is still waiting for child runs: their subjects are not ordered again yet.
131
+ const checking = new Set();
132
+ // An order is settled once: a row parked uncertain and then closed reports here twice.
133
+ const settledOrders = new Set();
134
+ let stopped = false;
135
+ const kindOf = (row) => {
136
+ const kind = byChannel.get(row.channelKey);
137
+ if (!kind)
138
+ throw new Error(`No upkeep kind serves channel ${row.channelKey}`);
139
+ return kind;
140
+ };
141
+ const settle = (kind, orderId, order, reason) => {
142
+ if (settledOrders.has(orderId))
143
+ return;
144
+ settledOrders.add(orderId);
145
+ const at = now();
146
+ const { states } = storedSubjects(options.adapter, kind, at);
147
+ const record = recordSettled(options.adapter);
148
+ for (const subject of order.subjects) {
149
+ const orders = states.get(subject.key)?.orders ?? [];
150
+ if (kind.checked(options.adapter, subject, orderRunIds(options.adapter, orders))) {
151
+ record.run(kind.name, subject.key, 'checked', at);
152
+ options.onEvent?.({ type: 'checked', kind: kind.name, subject: subject.key });
153
+ continue;
154
+ }
155
+ const attempt = orders.length;
156
+ if (attempt >= exports.UPKEEP_MAX_ATTEMPTS) {
157
+ record.run(kind.name, subject.key, 'lost', at);
158
+ options.onEvent?.({ type: 'lost', kind: kind.name, subject: subject.key, attempt, reason });
159
+ }
160
+ else
161
+ options.onEvent?.({
162
+ type: 'waiting',
163
+ kind: kind.name,
164
+ subject: subject.key,
165
+ attempt,
166
+ reason,
167
+ });
168
+ }
169
+ };
170
+ const tick = (kindName) => {
171
+ const kind = byName.get(kindName);
172
+ if (!kind)
173
+ throw new Error(`Unknown upkeep kind ${kindName}`);
174
+ if (stopped)
175
+ return;
176
+ const at = now();
177
+ const { states, anyOpen } = storedSubjects(options.adapter, kind, at);
178
+ // One order of a kind at a time keeps the common session's queue for the owner; an order whose
179
+ // child runs may still write is not over yet.
180
+ if (anyOpen || [...checking].some((id) => id.startsWith(upkeepOrderIdPrefix(kind.name))))
181
+ return;
182
+ const settled = new Set(options.adapter
183
+ .prepare(`SELECT subject_key FROM upkeep_settled WHERE kind = ?`)
184
+ .all(kind.name).map((row) => row.subject_key));
185
+ const record = recordSettled(options.adapter);
186
+ const due = [];
187
+ const perGroup = new Map();
188
+ const candidates = function* () {
189
+ for (let page = 0;; page += 1) {
190
+ const rows = kind.scan(options.adapter, at, page);
191
+ yield* rows;
192
+ if (rows.length < exports.UPKEEP_SCAN_PAGE)
193
+ return;
194
+ }
195
+ };
196
+ for (const subject of candidates()) {
197
+ if (kind.group === undefined && due.length >= kind.maxPerOrder)
198
+ break;
199
+ const group = kind.group?.(subject);
200
+ if (group !== undefined && (perGroup.get(group) ?? 0) >= kind.maxPerOrder)
201
+ continue;
202
+ if (settled.has(subject.key))
203
+ continue;
204
+ const state = states.get(subject.key);
205
+ const orders = state?.orders ?? [];
206
+ // No order of the kind is open here, so these orders are over. Their settlement is recorded
207
+ // again: a stop during the child-run wait, a failed check or a crash in settle() leaves it
208
+ // unwritten, and the stored orders that show it are deleted after seven days.
209
+ if (orders.length > 0 &&
210
+ kind.checked(options.adapter, subject, orderRunIds(options.adapter, orders))) {
211
+ record.run(kind.name, subject.key, 'checked', at);
212
+ continue;
213
+ }
214
+ // Reported lost when its last order was settled; it is never ordered again.
215
+ if (orders.length >= exports.UPKEEP_MAX_ATTEMPTS) {
216
+ record.run(kind.name, subject.key, 'lost', at);
217
+ continue;
218
+ }
219
+ due.push(subject);
220
+ if (group !== undefined)
221
+ perGroup.set(group, (perGroup.get(group) ?? 0) + 1);
222
+ }
223
+ if (due.length === 0)
224
+ return;
225
+ const id = `${upkeepOrderIdPrefix(kind.name)}${at}:${(0, node_crypto_1.randomUUID)().slice(0, 8)}`;
226
+ const payload = { order: 'upkeep', kind: kind.name, subjects: due };
227
+ const receipt = options.accept({
228
+ id,
229
+ kind: 'scheduled',
230
+ channelKey: kind.channel,
231
+ occurredAt: at,
232
+ payload: payload,
233
+ });
234
+ if (receipt.state !== 'duplicate')
235
+ options.onEvent?.({ type: 'ordered', kind: kind.name, order: id, subjects: due.length });
236
+ };
237
+ return {
238
+ isUpkeepRow: (row) => row.kind === 'scheduled' && byChannel.has(row.channelKey),
239
+ render: (row, at) => kindOf(row).render(parseUpkeepOrder(row.payload).subjects, at),
240
+ // The check waits for child runs in the background so the owner's queue is never held.
241
+ onResult: (row, modelRunId) => {
242
+ const kind = kindOf(row);
243
+ const order = parseUpkeepOrder(row.payload);
244
+ checking.add(row.stimulusId);
245
+ void (async () => {
246
+ if (modelRunId !== null) {
247
+ const deadline = Date.now() + childWaitMs;
248
+ while (!stopped &&
249
+ runningChildren(options.adapter, modelRunId, options.processStartedAt) > 0 &&
250
+ Date.now() < deadline)
251
+ await sleep(5_000);
252
+ }
253
+ if (stopped)
254
+ return;
255
+ settle(kind, row.stimulusId, order, 'the order ended without the expected write or a no-update naming it');
256
+ })()
257
+ .catch((error) => {
258
+ // A check cut off by shutdown is not a loss: the next tick finds the subject again.
259
+ if (stopped)
260
+ return;
261
+ for (const subject of order.subjects)
262
+ options.onEvent?.({
263
+ type: 'lost',
264
+ kind: kind.name,
265
+ subject: subject.key,
266
+ attempt: 0,
267
+ reason: `upkeep check failed: ${error instanceof Error ? error.message : String(error)}`,
268
+ });
269
+ })
270
+ .finally(() => checking.delete(row.stimulusId));
271
+ },
272
+ onLost: (row, reason) => {
273
+ const kind = kindOf(row);
274
+ settle(kind, row.stimulusId, parseUpkeepOrder(row.payload), reason);
275
+ },
276
+ tick,
277
+ start: () => {
278
+ if (timers.length > 0 || stopped)
279
+ return;
280
+ for (const kind of options.kinds) {
281
+ const run = () => {
282
+ try {
283
+ tick(kind.name);
284
+ }
285
+ catch (error) {
286
+ // A scan that fails names its kind; no subject was ordered, so the next scan retries.
287
+ options.onEvent?.({
288
+ type: 'lost',
289
+ kind: kind.name,
290
+ subject: '*',
291
+ attempt: 0,
292
+ reason: `upkeep scan failed: ${error instanceof Error ? error.message : String(error)}`,
293
+ });
294
+ }
295
+ };
296
+ const first = setTimeout(run, options.firstTickDelayMs ?? 60_000);
297
+ const every = setInterval(run, kind.intervalMs);
298
+ first.unref?.();
299
+ every.unref?.();
300
+ timers.push({ cancel: () => clearTimeout(first) }, { cancel: () => clearInterval(every) });
301
+ }
302
+ },
303
+ stop: () => {
304
+ stopped = true;
305
+ for (const timer of timers.splice(0))
306
+ timer.cancel();
307
+ },
308
+ };
309
+ }
310
+ //# sourceMappingURL=upkeep-orders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upkeep-orders.js","sourceRoot":"","sources":["../../src/runtime/upkeep-orders.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { JudgmentAccess } from '@jungjaehoon/mama-core/knowledge';
2
+ import { type WorkListViewContext } from '../api/work-actions.js';
3
+ import { type UpkeepKind } from './upkeep-orders.js';
4
+ export declare const RECONCILE_ORDER_CHANNEL = "operator:reconcile";
5
+ export interface ReconcileKindOptions {
6
+ knowledge: WorkListViewContext['knowledge'];
7
+ /** The common session's access: only work it can read is chosen. */
8
+ access: () => JudgmentAccess;
9
+ timeZone: () => string;
10
+ /** reports.full_report_hours, read at each scan: the first after midnight is the morning one. */
11
+ fullReportHours: () => readonly number[];
12
+ }
13
+ /**
14
+ * U3, board reconcile. Once a day before the morning report the host orders two groups of
15
+ * subject, at most ten of each:
16
+ * - an open item with cited cards that moved after the item's latest revision, all its moved cards
17
+ * in one subject keyed by the item and its latest move, so a new move is a new subject;
18
+ * - an item in progress or in review whose latest source event is over 30 days old, chosen the way
19
+ * work.list lastEventBefore chooses it, oldest first, keyed by the item and its latest revision
20
+ * from outside the reconcile orders.
21
+ * A subject is checked by a revision on the item from the order's runs, or a work.no_update
22
+ * naming it. The runner keeps settled subjects past the mailbox's retention (upkeep_settled).
23
+ */
24
+ export declare function reconcileUpkeepKind(options: ReconcileKindOptions): UpkeepKind;
25
+ //# sourceMappingURL=upkeep-reconcile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upkeep-reconcile.d.ts","sourceRoot":"","sources":["../../src/runtime/upkeep-reconcile.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAkB,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvF,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAKL,KAAK,UAAU,EAEhB,MAAM,oBAAoB,CAAC;AAE5B,eAAO,MAAM,uBAAuB,uBAAuB,CAAC;AAO5D,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC5C,oEAAoE;IACpE,MAAM,EAAE,MAAM,cAAc,CAAC;IAC7B,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,iGAAiG;IACjG,eAAe,EAAE,MAAM,SAAS,MAAM,EAAE,CAAC;CAC1C;AAoID;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,UAAU,CAsI7E"}