wicked-crew 0.7.40 → 0.7.46

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 (361) hide show
  1. package/dist/api/audit.d.ts +3 -0
  2. package/dist/api/audit.d.ts.map +1 -1
  3. package/dist/api/audit.js +2 -0
  4. package/dist/api/audit.js.map +1 -1
  5. package/dist/api/capture.d.ts +149 -0
  6. package/dist/api/capture.d.ts.map +1 -0
  7. package/dist/api/capture.js +330 -0
  8. package/dist/api/capture.js.map +1 -0
  9. package/dist/api/chat-citations.d.ts +174 -0
  10. package/dist/api/chat-citations.d.ts.map +1 -0
  11. package/dist/api/chat-citations.js +528 -0
  12. package/dist/api/chat-citations.js.map +1 -0
  13. package/dist/api/chat-transcripts.d.ts +20 -1
  14. package/dist/api/chat-transcripts.d.ts.map +1 -1
  15. package/dist/api/chat-transcripts.js +29 -0
  16. package/dist/api/chat-transcripts.js.map +1 -1
  17. package/dist/api/delivery-cache.d.ts +2 -2
  18. package/dist/api/delivery-freeze.d.ts +66 -0
  19. package/dist/api/delivery-freeze.d.ts.map +1 -0
  20. package/dist/api/delivery-freeze.js +104 -0
  21. package/dist/api/delivery-freeze.js.map +1 -0
  22. package/dist/api/delivery-index.d.ts +53 -9
  23. package/dist/api/delivery-index.d.ts.map +1 -1
  24. package/dist/api/delivery-index.js +115 -22
  25. package/dist/api/delivery-index.js.map +1 -1
  26. package/dist/api/demo.d.ts +90 -0
  27. package/dist/api/demo.d.ts.map +1 -0
  28. package/dist/api/demo.js +492 -0
  29. package/dist/api/demo.js.map +1 -0
  30. package/dist/api/diagnostics.d.ts +64 -1
  31. package/dist/api/diagnostics.d.ts.map +1 -1
  32. package/dist/api/diagnostics.js +129 -1
  33. package/dist/api/diagnostics.js.map +1 -1
  34. package/dist/api/eval-sample.d.ts +6 -6
  35. package/dist/api/governance-steering.d.ts +2 -2
  36. package/dist/api/mcp.d.ts +282 -0
  37. package/dist/api/mcp.d.ts.map +1 -0
  38. package/dist/api/mcp.js +521 -0
  39. package/dist/api/mcp.js.map +1 -0
  40. package/dist/api/plan-schema.d.ts +56 -0
  41. package/dist/api/plan-schema.d.ts.map +1 -0
  42. package/dist/api/plan-schema.js +26 -0
  43. package/dist/api/plan-schema.js.map +1 -0
  44. package/dist/api/roster-standing.d.ts +15 -2
  45. package/dist/api/roster-standing.d.ts.map +1 -1
  46. package/dist/api/roster-standing.js +59 -3
  47. package/dist/api/roster-standing.js.map +1 -1
  48. package/dist/api/routes.d.ts +630 -51
  49. package/dist/api/routes.d.ts.map +1 -1
  50. package/dist/api/routes.js +738 -127
  51. package/dist/api/routes.js.map +1 -1
  52. package/dist/api/run-files.d.ts.map +1 -1
  53. package/dist/api/run-files.js +31 -2
  54. package/dist/api/run-files.js.map +1 -1
  55. package/dist/api/run-liveness.d.ts +41 -0
  56. package/dist/api/run-liveness.d.ts.map +1 -0
  57. package/dist/api/run-liveness.js +166 -0
  58. package/dist/api/run-liveness.js.map +1 -0
  59. package/dist/api/seat-health.d.ts +35 -0
  60. package/dist/api/seat-health.d.ts.map +1 -1
  61. package/dist/api/seat-health.js +92 -4
  62. package/dist/api/seat-health.js.map +1 -1
  63. package/dist/api/seat-probe.d.ts +141 -0
  64. package/dist/api/seat-probe.d.ts.map +1 -0
  65. package/dist/api/seat-probe.js +257 -0
  66. package/dist/api/seat-probe.js.map +1 -0
  67. package/dist/api/seat-record.d.ts +40 -0
  68. package/dist/api/seat-record.d.ts.map +1 -0
  69. package/dist/api/seat-record.js +218 -0
  70. package/dist/api/seat-record.js.map +1 -0
  71. package/dist/api/seat-signin.d.ts.map +1 -1
  72. package/dist/api/seat-signin.js +3 -1
  73. package/dist/api/seat-signin.js.map +1 -1
  74. package/dist/api/seat-standing.d.ts +25 -5
  75. package/dist/api/seat-standing.d.ts.map +1 -1
  76. package/dist/api/seat-standing.js +76 -9
  77. package/dist/api/seat-standing.js.map +1 -1
  78. package/dist/api/server.d.ts +34 -48
  79. package/dist/api/server.d.ts.map +1 -1
  80. package/dist/api/server.js +283 -107
  81. package/dist/api/server.js.map +1 -1
  82. package/dist/api/skills.d.ts +3 -1
  83. package/dist/api/skills.d.ts.map +1 -1
  84. package/dist/api/skills.js +7 -2
  85. package/dist/api/skills.js.map +1 -1
  86. package/dist/api/stall-watchdog.d.ts +34 -3
  87. package/dist/api/stall-watchdog.d.ts.map +1 -1
  88. package/dist/api/stall-watchdog.js +107 -8
  89. package/dist/api/stall-watchdog.js.map +1 -1
  90. package/dist/api/steering-landing.d.ts +6 -6
  91. package/dist/api/steering-landing.d.ts.map +1 -1
  92. package/dist/api/steering-landing.js +7 -9
  93. package/dist/api/steering-landing.js.map +1 -1
  94. package/dist/api/testing.d.ts +6 -4
  95. package/dist/api/testing.d.ts.map +1 -1
  96. package/dist/api/testing.js +82 -47
  97. package/dist/api/testing.js.map +1 -1
  98. package/dist/campaign/boot-resume.d.ts +34 -0
  99. package/dist/campaign/boot-resume.d.ts.map +1 -0
  100. package/dist/campaign/boot-resume.js +45 -0
  101. package/dist/campaign/boot-resume.js.map +1 -0
  102. package/dist/campaigns/rollup.d.ts +4 -1
  103. package/dist/campaigns/rollup.d.ts.map +1 -1
  104. package/dist/campaigns/rollup.js +6 -1
  105. package/dist/campaigns/rollup.js.map +1 -1
  106. package/dist/campaigns/routes.d.ts +2 -2
  107. package/dist/cli/bearer.d.ts +27 -1
  108. package/dist/cli/bearer.d.ts.map +1 -1
  109. package/dist/cli/bearer.js +62 -2
  110. package/dist/cli/bearer.js.map +1 -1
  111. package/dist/cli/governance.d.ts +11 -0
  112. package/dist/cli/governance.d.ts.map +1 -1
  113. package/dist/cli/governance.js +8 -2
  114. package/dist/cli/governance.js.map +1 -1
  115. package/dist/cli/index.d.ts.map +1 -1
  116. package/dist/cli/index.js +140 -75
  117. package/dist/cli/index.js.map +1 -1
  118. package/dist/cli/mcp.d.ts +11 -0
  119. package/dist/cli/mcp.d.ts.map +1 -1
  120. package/dist/cli/mcp.js +40 -9
  121. package/dist/cli/mcp.js.map +1 -1
  122. package/dist/cli/service.d.ts +78 -0
  123. package/dist/cli/service.d.ts.map +1 -0
  124. package/dist/cli/service.js +334 -0
  125. package/dist/cli/service.js.map +1 -0
  126. package/dist/core/adapter.d.ts +238 -12
  127. package/dist/core/adapter.d.ts.map +1 -1
  128. package/dist/core/adapter.js +619 -157
  129. package/dist/core/adapter.js.map +1 -1
  130. package/dist/core/bridge-reaper.d.ts +4 -1
  131. package/dist/core/bridge-reaper.d.ts.map +1 -1
  132. package/dist/core/bridge-reaper.js +15 -1
  133. package/dist/core/bridge-reaper.js.map +1 -1
  134. package/dist/core/bus-notice.d.ts +27 -0
  135. package/dist/core/bus-notice.d.ts.map +1 -0
  136. package/dist/core/bus-notice.js +24 -0
  137. package/dist/core/bus-notice.js.map +1 -0
  138. package/dist/core/bus.d.ts +99 -0
  139. package/dist/core/bus.d.ts.map +1 -0
  140. package/dist/core/bus.js +176 -0
  141. package/dist/core/bus.js.map +1 -0
  142. package/dist/core/deliver-exclusions.d.ts +71 -0
  143. package/dist/core/deliver-exclusions.d.ts.map +1 -0
  144. package/dist/core/deliver-exclusions.js +110 -0
  145. package/dist/core/deliver-exclusions.js.map +1 -0
  146. package/dist/core/deliver-text.d.ts +61 -14
  147. package/dist/core/deliver-text.d.ts.map +1 -1
  148. package/dist/core/deliver-text.js +178 -30
  149. package/dist/core/deliver-text.js.map +1 -1
  150. package/dist/core/deliver-triage.d.ts +11 -2
  151. package/dist/core/deliver-triage.d.ts.map +1 -1
  152. package/dist/core/deliver-triage.js +19 -1
  153. package/dist/core/deliver-triage.js.map +1 -1
  154. package/dist/core/deliver.d.ts +161 -3
  155. package/dist/core/deliver.d.ts.map +1 -1
  156. package/dist/core/deliver.js +463 -25
  157. package/dist/core/deliver.js.map +1 -1
  158. package/dist/core/deliverable-floor.d.ts.map +1 -1
  159. package/dist/core/deliverable-floor.js +5 -7
  160. package/dist/core/deliverable-floor.js.map +1 -1
  161. package/dist/core/engine-bus.d.ts +40 -0
  162. package/dist/core/engine-bus.d.ts.map +1 -0
  163. package/dist/core/engine-bus.js +27 -0
  164. package/dist/core/engine-bus.js.map +1 -0
  165. package/dist/core/estate-mcp-client.d.ts +87 -5
  166. package/dist/core/estate-mcp-client.d.ts.map +1 -1
  167. package/dist/core/estate-mcp-client.js +90 -11
  168. package/dist/core/estate-mcp-client.js.map +1 -1
  169. package/dist/core/linked-issues.d.ts +46 -0
  170. package/dist/core/linked-issues.d.ts.map +1 -0
  171. package/dist/core/linked-issues.js +123 -0
  172. package/dist/core/linked-issues.js.map +1 -0
  173. package/dist/core/run-identity.d.ts +100 -0
  174. package/dist/core/run-identity.d.ts.map +1 -0
  175. package/dist/core/run-identity.js +178 -0
  176. package/dist/core/run-identity.js.map +1 -0
  177. package/dist/core/shutdown.d.ts +16 -0
  178. package/dist/core/shutdown.d.ts.map +1 -0
  179. package/dist/core/shutdown.js +39 -0
  180. package/dist/core/shutdown.js.map +1 -0
  181. package/dist/core/types.d.ts +15 -1
  182. package/dist/core/types.d.ts.map +1 -1
  183. package/dist/core/types.js +4 -0
  184. package/dist/core/types.js.map +1 -1
  185. package/dist/interactive/bridge-pool.d.ts +67 -3
  186. package/dist/interactive/bridge-pool.d.ts.map +1 -1
  187. package/dist/interactive/bridge-pool.js +129 -13
  188. package/dist/interactive/bridge-pool.js.map +1 -1
  189. package/dist/interactive/bridge-root.d.ts +9 -0
  190. package/dist/interactive/bridge-root.d.ts.map +1 -1
  191. package/dist/interactive/bridge-root.js +11 -4
  192. package/dist/interactive/bridge-root.js.map +1 -1
  193. package/dist/interactive/chat-events.d.ts +14 -9
  194. package/dist/interactive/chat-events.d.ts.map +1 -1
  195. package/dist/interactive/chat-events.js +55 -57
  196. package/dist/interactive/chat-events.js.map +1 -1
  197. package/dist/interactive/council-outcome.d.ts +1 -0
  198. package/dist/interactive/council-outcome.d.ts.map +1 -1
  199. package/dist/interactive/council-outcome.js +33 -0
  200. package/dist/interactive/council-outcome.js.map +1 -1
  201. package/dist/interactive/draft-events.d.ts +36 -17
  202. package/dist/interactive/draft-events.d.ts.map +1 -1
  203. package/dist/interactive/draft-events.js +121 -92
  204. package/dist/interactive/draft-events.js.map +1 -1
  205. package/dist/interactive/draft-skill.d.ts +59 -0
  206. package/dist/interactive/draft-skill.d.ts.map +1 -1
  207. package/dist/interactive/draft-skill.js +233 -0
  208. package/dist/interactive/draft-skill.js.map +1 -1
  209. package/dist/interactive/edit-events.d.ts +1 -14
  210. package/dist/interactive/edit-events.d.ts.map +1 -1
  211. package/dist/interactive/edit-events.js +37 -70
  212. package/dist/interactive/edit-events.js.map +1 -1
  213. package/dist/interactive/proxy-routes.d.ts +2 -2
  214. package/dist/interactive/proxy-routes.d.ts.map +1 -1
  215. package/dist/interactive/proxy-routes.js +4 -13
  216. package/dist/interactive/proxy-routes.js.map +1 -1
  217. package/dist/interactive/ws-relay.d.ts +9 -10
  218. package/dist/interactive/ws-relay.d.ts.map +1 -1
  219. package/dist/interactive/ws-relay.js +23 -50
  220. package/dist/interactive/ws-relay.js.map +1 -1
  221. package/dist/mcp/broker.d.ts +88 -0
  222. package/dist/mcp/broker.d.ts.map +1 -0
  223. package/dist/mcp/broker.js +307 -0
  224. package/dist/mcp/broker.js.map +1 -0
  225. package/dist/mcp/call-records.d.ts +61 -0
  226. package/dist/mcp/call-records.d.ts.map +1 -0
  227. package/dist/mcp/call-records.js +135 -0
  228. package/dist/mcp/call-records.js.map +1 -0
  229. package/dist/mcp/classify.d.ts +45 -0
  230. package/dist/mcp/classify.d.ts.map +1 -0
  231. package/dist/mcp/classify.js +83 -0
  232. package/dist/mcp/classify.js.map +1 -0
  233. package/dist/mcp/discovery.d.ts +24 -0
  234. package/dist/mcp/discovery.d.ts.map +1 -0
  235. package/dist/mcp/discovery.js +78 -0
  236. package/dist/mcp/discovery.js.map +1 -0
  237. package/dist/mcp/invoke.d.ts +36 -0
  238. package/dist/mcp/invoke.d.ts.map +1 -0
  239. package/dist/mcp/invoke.js +80 -0
  240. package/dist/mcp/invoke.js.map +1 -0
  241. package/dist/mcp/policies.d.ts +110 -0
  242. package/dist/mcp/policies.d.ts.map +1 -0
  243. package/dist/mcp/policies.js +400 -0
  244. package/dist/mcp/policies.js.map +1 -0
  245. package/dist/mcp/probe.d.ts +66 -0
  246. package/dist/mcp/probe.d.ts.map +1 -0
  247. package/dist/mcp/probe.js +116 -0
  248. package/dist/mcp/probe.js.map +1 -0
  249. package/dist/mcp/redact.d.ts +34 -0
  250. package/dist/mcp/redact.d.ts.map +1 -0
  251. package/dist/mcp/redact.js +84 -0
  252. package/dist/mcp/redact.js.map +1 -0
  253. package/dist/mcp/registry-store.d.ts +69 -0
  254. package/dist/mcp/registry-store.d.ts.map +1 -0
  255. package/dist/mcp/registry-store.js +82 -0
  256. package/dist/mcp/registry-store.js.map +1 -0
  257. package/dist/mcp/registry.d.ts +147 -0
  258. package/dist/mcp/registry.d.ts.map +1 -0
  259. package/dist/mcp/registry.js +509 -0
  260. package/dist/mcp/registry.js.map +1 -0
  261. package/dist/mcp/rest.d.ts +111 -0
  262. package/dist/mcp/rest.d.ts.map +1 -0
  263. package/dist/mcp/rest.js +606 -0
  264. package/dist/mcp/rest.js.map +1 -0
  265. package/dist/mcp/secrets.d.ts +66 -0
  266. package/dist/mcp/secrets.d.ts.map +1 -0
  267. package/dist/mcp/secrets.js +180 -0
  268. package/dist/mcp/secrets.js.map +1 -0
  269. package/dist/mcp/tool-list.d.ts +25 -0
  270. package/dist/mcp/tool-list.d.ts.map +1 -0
  271. package/dist/mcp/tool-list.js +62 -0
  272. package/dist/mcp/tool-list.js.map +1 -0
  273. package/dist/mcp/upstream-error.d.ts +12 -0
  274. package/dist/mcp/upstream-error.d.ts.map +1 -0
  275. package/dist/mcp/upstream-error.js +14 -0
  276. package/dist/mcp/upstream-error.js.map +1 -0
  277. package/dist/mcp/usage.d.ts +31 -0
  278. package/dist/mcp/usage.d.ts.map +1 -0
  279. package/dist/mcp/usage.js +159 -0
  280. package/dist/mcp/usage.js.map +1 -0
  281. package/dist/presets/routes.d.ts +53 -0
  282. package/dist/presets/routes.d.ts.map +1 -0
  283. package/dist/presets/routes.js +115 -0
  284. package/dist/presets/routes.js.map +1 -0
  285. package/dist/projects/activity.d.ts +6 -18
  286. package/dist/projects/activity.d.ts.map +1 -1
  287. package/dist/projects/activity.js +17 -60
  288. package/dist/projects/activity.js.map +1 -1
  289. package/dist/projects/events.d.ts +6 -5
  290. package/dist/projects/events.d.ts.map +1 -1
  291. package/dist/projects/events.js +33 -58
  292. package/dist/projects/events.js.map +1 -1
  293. package/dist/projects/routes.d.ts.map +1 -1
  294. package/dist/projects/routes.js +19 -0
  295. package/dist/projects/routes.js.map +1 -1
  296. package/dist/projects/state-home-preflight.d.ts.map +1 -1
  297. package/dist/projects/state-home-preflight.js +7 -0
  298. package/dist/projects/state-home-preflight.js.map +1 -1
  299. package/dist/projects/state-home-registry.d.ts.map +1 -1
  300. package/dist/projects/state-home-registry.js +9 -1
  301. package/dist/projects/state-home-registry.js.map +1 -1
  302. package/dist/qe/acceptance.d.ts +28 -28
  303. package/dist/qe/acceptance.d.ts.map +1 -1
  304. package/dist/qe/acceptance.js +60 -61
  305. package/dist/qe/acceptance.js.map +1 -1
  306. package/dist/qe/test-sets.d.ts +3 -5
  307. package/dist/qe/test-sets.d.ts.map +1 -1
  308. package/dist/qe/test-sets.js +5 -7
  309. package/dist/qe/test-sets.js.map +1 -1
  310. package/dist/skills/installed.d.ts +51 -0
  311. package/dist/skills/installed.d.ts.map +1 -0
  312. package/dist/skills/installed.js +46 -0
  313. package/dist/skills/installed.js.map +1 -0
  314. package/dist/standing-orders/evaluator.d.ts +113 -0
  315. package/dist/standing-orders/evaluator.d.ts.map +1 -0
  316. package/dist/standing-orders/evaluator.js +225 -0
  317. package/dist/standing-orders/evaluator.js.map +1 -0
  318. package/dist/standing-orders/history.d.ts +58 -0
  319. package/dist/standing-orders/history.d.ts.map +1 -0
  320. package/dist/standing-orders/history.js +117 -0
  321. package/dist/standing-orders/history.js.map +1 -0
  322. package/dist/standing-orders/parse.d.ts +19 -0
  323. package/dist/standing-orders/parse.d.ts.map +1 -0
  324. package/dist/standing-orders/parse.js +75 -0
  325. package/dist/standing-orders/parse.js.map +1 -0
  326. package/dist/standing-orders/routes.d.ts +180 -0
  327. package/dist/standing-orders/routes.d.ts.map +1 -0
  328. package/dist/standing-orders/routes.js +95 -0
  329. package/dist/standing-orders/routes.js.map +1 -0
  330. package/dist/standing-orders/store.d.ts +154 -0
  331. package/dist/standing-orders/store.d.ts.map +1 -0
  332. package/dist/standing-orders/store.js +189 -0
  333. package/dist/standing-orders/store.js.map +1 -0
  334. package/dist/studio/assets/index-CvV5qITf.css +32 -0
  335. package/dist/studio/assets/index-jCOy6Ns7.js +568 -0
  336. package/dist/studio/index.html +3 -3
  337. package/dist/studio/testid-inventory.json +3274 -894
  338. package/dist/team/key.d.ts +5 -0
  339. package/dist/team/key.d.ts.map +1 -0
  340. package/dist/team/key.js +21 -0
  341. package/dist/team/key.js.map +1 -0
  342. package/dist/team/routes.d.ts +196 -0
  343. package/dist/team/routes.d.ts.map +1 -0
  344. package/dist/team/routes.js +274 -0
  345. package/dist/team/routes.js.map +1 -0
  346. package/dist/team/ws-relay.d.ts +39 -0
  347. package/dist/team/ws-relay.d.ts.map +1 -0
  348. package/dist/team/ws-relay.js +63 -0
  349. package/dist/team/ws-relay.js.map +1 -0
  350. package/endpoint-manifest.json +502 -6
  351. package/package.json +6 -6
  352. package/dist/interactive/demo-events.d.ts +0 -367
  353. package/dist/interactive/demo-events.d.ts.map +0 -1
  354. package/dist/interactive/demo-events.js +0 -1293
  355. package/dist/interactive/demo-events.js.map +0 -1
  356. package/dist/qe/gate-events.d.ts +0 -113
  357. package/dist/qe/gate-events.d.ts.map +0 -1
  358. package/dist/qe/gate-events.js +0 -172
  359. package/dist/qe/gate-events.js.map +0 -1
  360. package/dist/studio/assets/index-Bg7Z3BR-.css +0 -32
  361. package/dist/studio/assets/index-BvOFMjf9.js +0 -554
@@ -0,0 +1,225 @@
1
+ /**
2
+ * Standing orders (Studio OS behaviour 10) — the daemon evaluator.
3
+ *
4
+ * Fed by the daemon's single CoreEvent subscription (`awaitingHuman`) and the team relay
5
+ * (`wicked.team.finding.raised`), and re-swept over the engine's open gate rows when the away flag
6
+ * turns on or an order is added. For each gate or finding it finds the ACTIVE orders that match
7
+ * (away gating, project scope, the reviewed phase or the finding's severity) and acts:
8
+ *
9
+ * hold — the gate stays open; `standing-order.held` says an order is keeping it for you.
10
+ * A hold wins over an approve on the same gate.
11
+ * approve — answers the gate through `decideGate`, THE gate decision path `POST /runs/:id/gate`
12
+ * uses (ord check, 409 gate_changed / gate_unknown, confirmGate, `gate.decided` audit).
13
+ * The actor is the order. A refusal (a person got there first) is logged, never retried.
14
+ * notify — the message is QUEUED: the store records `standing-order.notified` (its outbox).
15
+ * Nothing is sent: outbound always waits.
16
+ *
17
+ * THE INVARIANT: an order approves only a phase-review gate (`def`, `run_level`, `terminal`), or —
18
+ * as a TRUST RECEIPT (brainstorm idea 13) — the plan approval of a run in its own project, of its
19
+ * own preset, whose OPEN plan gate reports band `0-19` and no high risk (read off the gate's own
20
+ * `gate.opened` row; unreadable = fail closed). The deliver gate, an escalation, a failure and a
21
+ * triage are never answered by an order, and neither is any gate of a steering-author run (its
22
+ * approval lands doctrine).
23
+ *
24
+ * A gate's PHASE, for matching, is the reviewed unit's `phase_ref` (the upcoming unit's when
25
+ * nothing has run). The gate before the run's first unit, with nothing to review, is also
26
+ * `intake` — the name studio and operators use for it (`IntakePlan.isIntakeGate`).
27
+ */
28
+ import { orderActor, PLAN_APPROVAL_PHASE, TRUSTED_PLAN_BAND, } from './store.js';
29
+ /** The only gate kinds an order may approve. */
30
+ export const APPROVABLE_GATE_KINDS = new Set(['def', 'run_level', 'terminal']);
31
+ /** Whether an order may answer this plan gate: the trust receipt's every condition, re-read. */
32
+ export function planOrderMayApprove(rule, run, risk) {
33
+ if (rule.trigger.kind !== 'gate' || rule.trigger.phase !== PLAN_APPROVAL_PHASE)
34
+ return false;
35
+ if (rule.scope.kind !== 'project' || rule.scope.projectId !== run.projectId)
36
+ return false;
37
+ if (rule.trigger.band !== TRUSTED_PLAN_BAND || rule.trigger.preset === undefined)
38
+ return false;
39
+ if (run.preset === undefined || rule.trigger.preset !== run.preset || run.landsDoctrine)
40
+ return false;
41
+ return risk !== undefined && !risk.highRisk && risk.band === TRUSTED_PLAN_BAND;
42
+ }
43
+ /**
44
+ * The phase a gate is matched on: `intake` for the gate before the run's first unit with nothing
45
+ * to review, else the reviewed unit's phase (the upcoming unit's when nothing has run). `unitPhase`
46
+ * is the unit's own phase either way. The ONE reading, shared with the decided-gate history.
47
+ */
48
+ export function gatePhase(run, ord, reviewingOrd) {
49
+ const unitPhase = run.phaseOf(reviewingOrd ?? ord) ?? '';
50
+ const intake = reviewingOrd === null && ord === run.firstOrd;
51
+ return { phase: intake ? 'intake' : unitPhase, unitPhase };
52
+ }
53
+ /** THE INVARIANT as a predicate: an order may approve only a phase-review gate of a run whose
54
+ * approval lands no doctrine. */
55
+ export function orderMayApprove(gateKind, run) {
56
+ return APPROVABLE_GATE_KINDS.has(gateKind) && !run.landsDoctrine;
57
+ }
58
+ export class StandingOrderEvaluator {
59
+ deps;
60
+ /** `<subject>:<order or action>` keys already acted on — one action per gate/finding per order. */
61
+ done = new Set();
62
+ log;
63
+ constructor(deps) {
64
+ this.deps = deps;
65
+ this.log = deps.log ?? (() => undefined);
66
+ }
67
+ /** Every settled action, for tests: resolves when the evaluation it started is finished. */
68
+ onEvent(event) {
69
+ if (event.type !== 'awaitingHuman')
70
+ return Promise.resolve();
71
+ const e = event;
72
+ if (typeof e['session'] !== 'string' || typeof e['ord'] !== 'number')
73
+ return Promise.resolve();
74
+ return this.considerGate({
75
+ runId: e['session'],
76
+ ord: e['ord'],
77
+ reviewingOrd: typeof e['reviewingOrd'] === 'number' ? e['reviewingOrd'] : null,
78
+ gateKind: typeof e['gateKind'] === 'string' ? e['gateKind'] : '',
79
+ prompt: typeof e['prompt'] === 'string' ? e['prompt'] : '',
80
+ }).catch((err) => this.log(`[standing-orders] gate evaluation failed: ${String(err)}`));
81
+ }
82
+ /** A team relay frame (`{ type: 'teamEvent', event: <bus row> }`). */
83
+ onTeamFrame(frame) {
84
+ const row = frame.event;
85
+ if (row?.event_type !== 'wicked.team.finding.raised' || row.payload === undefined)
86
+ return Promise.resolve();
87
+ const p = row.payload;
88
+ if (typeof p['run_id'] !== 'string' || typeof p['severity'] !== 'string')
89
+ return Promise.resolve();
90
+ return this.considerFinding({
91
+ runId: p['run_id'],
92
+ findingId: typeof p['finding_id'] === 'string' ? p['finding_id'] : String(p['raise_seq'] ?? ''),
93
+ severity: p['severity'],
94
+ claim: typeof p['claim'] === 'string' ? p['claim'] : '',
95
+ }).catch((err) => this.log(`[standing-orders] finding evaluation failed: ${String(err)}`));
96
+ }
97
+ /** Re-read the engine's open gates (the away flag turned on, or an order was added). */
98
+ async sweep() {
99
+ // No active gate order, nothing a sweep could do: never touch the engine for it.
100
+ if (!this.deps.store.orders().some((o) => this.active(o) && o.rule.trigger.kind === 'gate'))
101
+ return;
102
+ let gates;
103
+ try {
104
+ gates = await this.deps.openGates();
105
+ }
106
+ catch (err) {
107
+ this.log(`[standing-orders] cannot read the open gates: ${String(err)}`);
108
+ return;
109
+ }
110
+ for (const g of gates)
111
+ await this.considerGate(g);
112
+ }
113
+ active(o) {
114
+ return o.rule.activeWhen === 'always' || this.deps.store.away;
115
+ }
116
+ inScope(o, projectId) {
117
+ return o.rule.scope.kind === 'all' || o.rule.scope.projectId === projectId;
118
+ }
119
+ once(key) {
120
+ if (this.done.has(key))
121
+ return false;
122
+ this.done.add(key);
123
+ return true;
124
+ }
125
+ async considerGate(g) {
126
+ const orders = this.deps.store.orders().filter((o) => this.active(o) && o.rule.trigger.kind === 'gate');
127
+ if (orders.length === 0)
128
+ return;
129
+ const run = await this.deps.runFacts(g.runId);
130
+ if (run === undefined)
131
+ return;
132
+ const { phase, unitPhase } = gatePhase(run, g.ord, g.reviewingOrd);
133
+ // A plan gate is also matched by a plan-approval order (the trust receipt), on the band of the
134
+ // plan the gate holds — at the first plan gate the run has no accepted band yet.
135
+ const planGate = g.gateKind === PLAN_APPROVAL_PHASE;
136
+ const planOrder = (o) => o.rule.trigger.kind === 'gate' && o.rule.trigger.phase === PLAN_APPROVAL_PHASE;
137
+ const risk = planGate && orders.some(planOrder) ? await this.planRisk(g.runId) : undefined;
138
+ const matching = orders.filter((o) => {
139
+ if (!this.inScope(o, run.projectId) || o.rule.trigger.kind !== 'gate')
140
+ return false;
141
+ const t = o.rule.trigger;
142
+ if (planOrder(o)) {
143
+ return planGate && (t.band === undefined || t.band === risk?.band) && (t.preset === undefined || t.preset === run.preset);
144
+ }
145
+ return ((t.phase === '*' || t.phase === phase || t.phase === unitPhase) &&
146
+ // A band-scoped order matches only a run scored into that band; an unscored run never does.
147
+ (t.band === undefined || t.band === run.band) &&
148
+ (t.preset === undefined || t.preset === run.preset));
149
+ });
150
+ const subject = `gate:${g.runId}:${g.ord}`;
151
+ const holds = matching.filter((o) => o.rule.action === 'hold');
152
+ const approves = matching.filter((o) => o.rule.action === 'approve');
153
+ for (const o of holds) {
154
+ if (!this.once(`${subject}:${o.id}`))
155
+ continue;
156
+ this.deps.audit.record('standing-order.held', orderActor(o), {
157
+ runId: g.runId,
158
+ detail: { standingOrder: { id: o.id, text: o.text }, ord: g.ord, gateKind: g.gateKind, phase },
159
+ });
160
+ }
161
+ for (const o of matching.filter((x) => x.rule.action === 'notify')) {
162
+ if (!this.once(`${subject}:${o.id}`))
163
+ continue;
164
+ this.notify(o, g.runId, `${run.problem}: the ${phase || g.gateKind} gate is waiting on you`);
165
+ }
166
+ // THE INVARIANT: only a phase-review gate — or a plan gate the trust receipt covers in full —
167
+ // and never under a hold.
168
+ const approver = planGate
169
+ ? approves.find((o) => planOrderMayApprove(o.rule, run, risk))
170
+ : orderMayApprove(g.gateKind, run)
171
+ ? approves[0]
172
+ : undefined;
173
+ if (approver === undefined || holds.length > 0)
174
+ return;
175
+ if (!this.once(`${subject}:approve`))
176
+ return;
177
+ const out = await this.deps.decideGate(g.runId, { approve: true, ord: g.ord }, orderActor(approver), {
178
+ standingOrder: { id: approver.id, text: approver.text },
179
+ });
180
+ if (out.code !== 200) {
181
+ this.log(`[standing-orders] order ${approver.id} did not answer the gate before unit ${g.ord} on ${g.runId}: ` +
182
+ `${out.code} ${JSON.stringify(out.body)}`);
183
+ }
184
+ }
185
+ /** The open plan gate's band and risk; undefined (fail closed) when it cannot be read. */
186
+ async planRisk(runId) {
187
+ if (this.deps.planGate === undefined)
188
+ return undefined;
189
+ try {
190
+ return await this.deps.planGate(runId);
191
+ }
192
+ catch (err) {
193
+ this.log(`[standing-orders] cannot read the plan gate of ${runId}: ${String(err)}`);
194
+ return undefined;
195
+ }
196
+ }
197
+ async considerFinding(f) {
198
+ const orders = this.deps.store
199
+ .orders()
200
+ .filter((o) => this.active(o) &&
201
+ o.rule.trigger.kind === 'finding' &&
202
+ (o.rule.trigger.severity === '*' || o.rule.trigger.severity === f.severity));
203
+ if (orders.length === 0)
204
+ return;
205
+ const run = await this.deps.runFacts(f.runId);
206
+ for (const o of orders.filter((x) => this.inScope(x, run?.projectId))) {
207
+ if (!this.once(`finding:${f.runId}:${f.findingId}:${o.id}`))
208
+ continue;
209
+ if (o.rule.action === 'notify') {
210
+ this.notify(o, f.runId, `${f.severity.toUpperCase()} finding on ${run?.problem ?? f.runId}: ${f.claim}`);
211
+ }
212
+ else if (o.rule.action === 'hold') {
213
+ this.deps.audit.record('standing-order.held', orderActor(o), {
214
+ runId: f.runId,
215
+ detail: { standingOrder: { id: o.id, text: o.text }, findingId: f.findingId, severity: f.severity },
216
+ });
217
+ }
218
+ }
219
+ }
220
+ /** The store records it (`standing-order.notified`, the order as actor) — queued, never sent. */
221
+ notify(o, runId, text) {
222
+ this.deps.store.queue(o, runId, text);
223
+ }
224
+ }
225
+ //# sourceMappingURL=evaluator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluator.js","sourceRoot":"","sources":["../../src/standing-orders/evaluator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * The decided-gate history — `GET /gates/decided?since=<unix ms>`.
3
+ *
4
+ * What a skin needs to show a seat's track record on a kind of step (brainstorm-actionable idea 7)
5
+ * and to offer "make it a rule" with a preview of what the order would have done (idea 8). Read,
6
+ * never stored: every row is one `gate.decided` line of the daemon's audit trail (WHO decided, and
7
+ * what), joined to the engine's gate row for the same `(run, ord)` (the gate's kind and the unit it
8
+ * reviewed) and to the run (its project, its accepted plan band, the seat that created the work).
9
+ *
10
+ * `phase` and `orderApprovable` are the standing-order evaluator's own readings (`gatePhase`,
11
+ * `orderMayApprove`), so a preview counts exactly the gates an order would have matched.
12
+ */
13
+ import type { FastifyInstance } from 'fastify';
14
+ import type { AuditLog } from '../api/audit.js';
15
+ import type { SessionView } from '../core/types.js';
16
+ /** One engine gate row, as far as the history reads it. */
17
+ export interface GateRowFact {
18
+ session_id: string;
19
+ ord: number | null;
20
+ reviewing_ord: number | null;
21
+ [k: string]: unknown;
22
+ }
23
+ export interface DecidedGateRow {
24
+ runId: string;
25
+ ord: number | null;
26
+ decidedAt: number;
27
+ decision: 'approve' | 'request_changes' | 'reject' | 'edit_plan';
28
+ actor: string;
29
+ byOrder: boolean;
30
+ gateKind: string | null;
31
+ phase: string | null;
32
+ projectId: string | null;
33
+ band: string | null;
34
+ creator: {
35
+ seat: string;
36
+ phase: string | null;
37
+ ord: number;
38
+ } | null;
39
+ orderApprovable: boolean;
40
+ }
41
+ export interface GateHistoryDeps {
42
+ audit: Pick<AuditLog, 'read'>;
43
+ views: () => Promise<SessionView[]>;
44
+ /** Every engine gate row (any status); `null`/`[]` when the engine cannot say. */
45
+ gateRows: () => Promise<GateRowFact[] | null>;
46
+ projectOf: (runId: string) => string | undefined;
47
+ /** Approving this run's gate would land doctrine (a steering-author run). */
48
+ landsDoctrine: (view: SessionView) => boolean;
49
+ }
50
+ /** The band the run's accepted plan landed in (`team_plan.accepted.band`), or undefined. */
51
+ export declare function runBand(view: SessionView): string | undefined;
52
+ /** The preset the run's launch named (`team_plan.preset`); undefined on a user plan or a workflow. */
53
+ export declare function runPreset(view: SessionView): string | undefined;
54
+ /** The run's project: its own filing, else the membership index (the evaluator's reading). */
55
+ export declare function runProject(view: SessionView | undefined, runId: string, projectOf: (id: string) => string | undefined): string | undefined;
56
+ export declare function decidedGates(deps: GateHistoryDeps, since: number | undefined): Promise<DecidedGateRow[]>;
57
+ export declare function registerGateHistoryRoute(app: FastifyInstance, deps: GateHistoryDeps): void;
58
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/standing-orders/history.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGhE,2DAA2D;AAC3D,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,SAAS,GAAG,iBAAiB,GAAG,QAAQ,GAAG,WAAW,CAAC;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACpE,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC9B,KAAK,EAAE,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACpC,kFAAkF;IAClF,QAAQ,EAAE,MAAM,OAAO,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,CAAC;IAC9C,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACjD,6EAA6E;IAC7E,aAAa,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC;CAC/C;AAED,4FAA4F;AAC5F,wBAAgB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAI7D;AAED,sGAAsG;AACtG,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAG/D;AAED,8FAA8F;AAC9F,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAG1I;AAoBD,wBAAsB,YAAY,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAqD9G;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI,CAkB1F"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * The decided-gate history — `GET /gates/decided?since=<unix ms>`.
3
+ *
4
+ * What a skin needs to show a seat's track record on a kind of step (brainstorm-actionable idea 7)
5
+ * and to offer "make it a rule" with a preview of what the order would have done (idea 8). Read,
6
+ * never stored: every row is one `gate.decided` line of the daemon's audit trail (WHO decided, and
7
+ * what), joined to the engine's gate row for the same `(run, ord)` (the gate's kind and the unit it
8
+ * reviewed) and to the run (its project, its accepted plan band, the seat that created the work).
9
+ *
10
+ * `phase` and `orderApprovable` are the standing-order evaluator's own readings (`gatePhase`,
11
+ * `orderMayApprove`), so a preview counts exactly the gates an order would have matched.
12
+ */
13
+ import { API_PREFIX } from '../api/api-prefix.js';
14
+ import { gatePhase, orderMayApprove } from './evaluator.js';
15
+ /** The band the run's accepted plan landed in (`team_plan.accepted.band`), or undefined. */
16
+ export function runBand(view) {
17
+ const plan = view.session.team_plan;
18
+ const band = plan?.accepted?.band;
19
+ return typeof band === 'string' && band !== '' ? band : undefined;
20
+ }
21
+ /** The preset the run's launch named (`team_plan.preset`); undefined on a user plan or a workflow. */
22
+ export function runPreset(view) {
23
+ const preset = view.session.team_plan?.preset;
24
+ return typeof preset === 'string' && preset !== '' ? preset : undefined;
25
+ }
26
+ /** The run's project: its own filing, else the membership index (the evaluator's reading). */
27
+ export function runProject(view, runId, projectOf) {
28
+ const own = view?.session.project_id;
29
+ return typeof own === 'string' && own !== 'default' ? own : projectOf(runId);
30
+ }
31
+ /**
32
+ * The unit whose work a gate before `ord` judges: the newest unit before it whose role is
33
+ * `creator`, else the newest non-evaluator `build`-stage unit before it (studio's `creatorUnitBefore`).
34
+ */
35
+ function creatorBefore(units, ord) {
36
+ const before = units.filter((u) => u.ord < ord).sort((a, b) => b.ord - a.ord);
37
+ return (before.find((u) => u.role === 'creator') ??
38
+ before.find((u) => u.stage === 'build' && u.role !== 'evaluator'));
39
+ }
40
+ function decisionOf(detail) {
41
+ const action = detail['action'];
42
+ if (action === 'request_changes' || action === 'reject' || action === 'edit_plan' || action === 'approve')
43
+ return action;
44
+ return detail['approve'] === true ? 'approve' : 'reject';
45
+ }
46
+ export async function decidedGates(deps, since) {
47
+ const entries = await deps.audit.read({
48
+ action: 'gate.decided',
49
+ limit: 1000,
50
+ ...(since !== undefined ? { since } : {}),
51
+ });
52
+ if (entries.length === 0)
53
+ return [];
54
+ const [views, rows] = await Promise.all([deps.views(), deps.gateRows().catch(() => null)]);
55
+ const byRun = new Map(views.map((v) => [v.session.id, v]));
56
+ const rowOf = new Map();
57
+ for (const r of rows ?? [])
58
+ if (typeof r.ord === 'number')
59
+ rowOf.set(`${r.session_id}:${r.ord}`, r);
60
+ return entries
61
+ .filter((e) => typeof e.runId === 'string')
62
+ .map((e) => {
63
+ const runId = e.runId;
64
+ const detail = (e.detail ?? {});
65
+ const ord = typeof detail['ord'] === 'number' ? detail['ord'] : null;
66
+ const decision = decisionOf(detail);
67
+ const view = byRun.get(runId);
68
+ const row = ord !== null ? rowOf.get(`${runId}:${ord}`) : undefined;
69
+ const kind = typeof row?.['gate_kind'] === 'string' && row['gate_kind'] !== '' ? row['gate_kind'] : null;
70
+ // A plan edit is only ever a plan gate's answer, and it names no ord.
71
+ const gateKind = kind ?? (decision === 'edit_plan' || detail['planSteps'] !== undefined ? 'plan_approval' : null);
72
+ const units = view?.units ?? [];
73
+ const facts = {
74
+ phaseOf: (o) => units.find((u) => u.ord === o)?.phase_ref ?? undefined,
75
+ firstOrd: units.length === 0 ? undefined : Math.min(...units.map((u) => u.ord)),
76
+ landsDoctrine: view !== undefined && deps.landsDoctrine(view),
77
+ };
78
+ // Without the engine's row the reviewed unit is unknown, so the phase is too (never guessed
79
+ // from the gate's own ord, which would name the NEXT phase).
80
+ const phase = row !== undefined && ord !== null && view !== undefined ? gatePhase(facts, ord, row.reviewing_ord).phase || null : null;
81
+ const creatorUnit = ord !== null && gateKind !== 'plan_approval' ? creatorBefore(units, ord) : undefined;
82
+ const actorId = e.actor?.id ?? '';
83
+ return {
84
+ runId,
85
+ ord,
86
+ decidedAt: e.ts,
87
+ decision,
88
+ actor: actorId,
89
+ byOrder: actorId.startsWith('standing-order:'),
90
+ gateKind,
91
+ phase,
92
+ projectId: runProject(view, runId, deps.projectOf) ?? null,
93
+ band: view !== undefined ? runBand(view) ?? null : null,
94
+ creator: creatorUnit !== undefined && typeof creatorUnit.assigned_cli === 'string' && creatorUnit.assigned_cli !== ''
95
+ ? { seat: creatorUnit.assigned_cli, phase: creatorUnit.phase_ref ?? null, ord: creatorUnit.ord }
96
+ : null,
97
+ orderApprovable: gateKind !== null && view !== undefined && orderMayApprove(gateKind, facts),
98
+ };
99
+ });
100
+ }
101
+ export function registerGateHistoryRoute(app, deps) {
102
+ app.get(`${API_PREFIX}/gates/decided`, { config: { manifest: { responseType: 'DecidedGatesResponse', statusCodes: [200, 400, 500] } } }, async (req, reply) => {
103
+ const raw = req.query.since;
104
+ const sinceRaw = (Array.isArray(raw) ? raw[0] : raw)?.trim() || undefined;
105
+ const since = sinceRaw !== undefined ? Number(sinceRaw) : undefined;
106
+ if (sinceRaw !== undefined && (!Number.isInteger(since) || since < 0)) {
107
+ return reply.code(400).send({ error: '`since` must be a non-negative integer (unix millis)' });
108
+ }
109
+ try {
110
+ return { gates: await decidedGates(deps, since) };
111
+ }
112
+ catch (err) {
113
+ return reply.code(500).send({ error: err instanceof Error ? err.message : String(err) });
114
+ }
115
+ });
116
+ }
117
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/standing-orders/history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Standing orders — the seat's parse of plain words into a rule (behaviour 10).
3
+ *
4
+ * ONE seat, ONE turn: an unscoped chat in a scratch directory, the prompt, the first `chatReply`
5
+ * for that chat, then the chat is closed and the scratch removed. The answer is a proposal the
6
+ * person confirms — crew stores only the confirmed rule — so a seat that answers badly costs a
7
+ * retry, never a wrong order.
8
+ */
9
+ import type { CoreAdapter } from '../core/adapter.js';
10
+ import type { RosterSeat } from '../core/types.js';
11
+ import { type ParseOutcome } from './routes.js';
12
+ export interface SeatParserDeps {
13
+ adapter: Pick<CoreAdapter, 'chatOpen' | 'chatSend' | 'chatClose' | 'onEvent' | 'projectsSupported' | 'projectList'>;
14
+ roster: () => RosterSeat[];
15
+ /** How long the seat has to answer (default 120 s). */
16
+ timeoutMs?: number;
17
+ }
18
+ export declare function seatParser(deps: SeatParserDeps): (text: string) => Promise<ParseOutcome>;
19
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/standing-orders/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAa,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAA+B,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAE7E,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,GAAG,mBAAmB,GAAG,aAAa,CAAC,CAAC;IACpH,MAAM,EAAE,MAAM,UAAU,EAAE,CAAC;IAC3B,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAmDxF"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Standing orders — the seat's parse of plain words into a rule (behaviour 10).
3
+ *
4
+ * ONE seat, ONE turn: an unscoped chat in a scratch directory, the prompt, the first `chatReply`
5
+ * for that chat, then the chat is closed and the scratch removed. The answer is a proposal the
6
+ * person confirms — crew stores only the confirmed rule — so a seat that answers badly costs a
7
+ * retry, never a wrong order.
8
+ */
9
+ import { randomUUID } from 'node:crypto';
10
+ import { mkdtempSync, rmSync } from 'node:fs';
11
+ import { tmpdir } from 'node:os';
12
+ import { join } from 'node:path';
13
+ import { parsePrompt, ruleFromAnswer } from './routes.js';
14
+ /** The first seat the daemon would seat in an unscoped chat. */
15
+ function chatSeat(roster) {
16
+ const seat = roster.find((s) => s.chat_admission?.unscoped?.ok === true);
17
+ return seat === undefined ? undefined : String(seat.key);
18
+ }
19
+ export function seatParser(deps) {
20
+ const { adapter } = deps;
21
+ const timeoutMs = deps.timeoutMs ?? 120_000;
22
+ return async (text) => {
23
+ const seat = chatSeat(deps.roster());
24
+ if (seat === undefined) {
25
+ return { ok: false, code: 409, error: 'no seat can take a turn to read the order — sign a seat in from the System page' };
26
+ }
27
+ const chatId = `standing-order-parse-${randomUUID()}`;
28
+ const cwd = mkdtempSync(join(tmpdir(), 'crew-order-parse-'));
29
+ let off = () => undefined;
30
+ // Cleared in `finally`: an early return (the seat would not open) must not leave it armed.
31
+ let timer;
32
+ try {
33
+ const reply = new Promise((resolve) => {
34
+ timer = setTimeout(() => resolve(null), timeoutMs);
35
+ off = adapter.onEvent((e) => {
36
+ const ev = e;
37
+ if (ev.type === 'chatReply' && ev.chat === chatId) {
38
+ clearTimeout(timer);
39
+ resolve({ text: typeof ev.text === 'string' ? ev.text : '', ok: ev.ok === true });
40
+ }
41
+ });
42
+ });
43
+ // Inside the try: a project list that fails is the parse's 502, never an unhandled 500.
44
+ const projects = adapter.projectsSupported()
45
+ ? (await adapter.projectList()).map((p) => ({ id: p.id, name: p.name }))
46
+ : [];
47
+ const opened = await adapter.chatOpen(chatId, [seat], cwd);
48
+ if (!opened.some((s) => s.ok)) {
49
+ return { ok: false, code: 502, error: `the ${seat} seat could not open: ${opened[0]?.error ?? 'refused'}` };
50
+ }
51
+ await adapter.chatSend(chatId, parsePrompt(text, projects), [seat]);
52
+ const answer = await reply;
53
+ if (answer === null)
54
+ return { ok: false, code: 502, error: `the ${seat} seat did not answer in ${timeoutMs / 1000} s` };
55
+ // A failed turn is a failure, whatever its text holds — never a rule to confirm (codex on #686).
56
+ if (!answer.ok)
57
+ return { ok: false, code: 502, error: `the ${seat} seat's turn failed`, answer: answer.text };
58
+ const rule = ruleFromAnswer(answer.text);
59
+ if (rule === undefined) {
60
+ return { ok: false, code: 422, error: 'the seat could not turn the words into a rule — try plainer words', answer: answer.text };
61
+ }
62
+ return { ok: true, rule, seat };
63
+ }
64
+ catch (err) {
65
+ return { ok: false, code: 502, error: err instanceof Error ? err.message : String(err) };
66
+ }
67
+ finally {
68
+ clearTimeout(timer);
69
+ off();
70
+ await adapter.chatClose(chatId).catch(() => undefined);
71
+ rmSync(cwd, { recursive: true, force: true });
72
+ }
73
+ };
74
+ }
75
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/standing-orders/parse.ts"],"names":[],"mappings":"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"}