@openrig/cli 0.4.3 → 0.4.6

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 (634) hide show
  1. package/daemon/assets/guidance/openrig-start.md +6 -0
  2. package/daemon/assets/plugins/openrig-core/skills/mission-slice-sop/SKILL.md +47 -21
  3. package/daemon/assets/plugins/openrig-core/skills/openrig-cmux/SKILL.md +86 -0
  4. package/daemon/assets/plugins/openrig-core/skills/openrig-herdr/SKILL.md +158 -0
  5. package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +742 -94
  6. package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
  7. package/daemon/dist/adapters/codex-runtime-adapter.js +12 -8
  8. package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
  9. package/daemon/dist/adapters/pi-resume.d.ts +32 -0
  10. package/daemon/dist/adapters/pi-resume.d.ts.map +1 -0
  11. package/daemon/dist/adapters/pi-resume.js +125 -0
  12. package/daemon/dist/adapters/pi-resume.js.map +1 -0
  13. package/daemon/dist/adapters/pi-runner-protocol.d.ts +88 -0
  14. package/daemon/dist/adapters/pi-runner-protocol.d.ts.map +1 -0
  15. package/daemon/dist/adapters/pi-runner-protocol.js +153 -0
  16. package/daemon/dist/adapters/pi-runner-protocol.js.map +1 -0
  17. package/daemon/dist/adapters/pi-runner.d.ts +99 -0
  18. package/daemon/dist/adapters/pi-runner.d.ts.map +1 -0
  19. package/daemon/dist/adapters/pi-runner.js +519 -0
  20. package/daemon/dist/adapters/pi-runner.js.map +1 -0
  21. package/daemon/dist/adapters/pi-runtime-adapter.d.ts +61 -0
  22. package/daemon/dist/adapters/pi-runtime-adapter.d.ts.map +1 -0
  23. package/daemon/dist/adapters/pi-runtime-adapter.js +356 -0
  24. package/daemon/dist/adapters/pi-runtime-adapter.js.map +1 -0
  25. package/daemon/dist/adapters/tmux.d.ts +22 -1
  26. package/daemon/dist/adapters/tmux.d.ts.map +1 -1
  27. package/daemon/dist/adapters/tmux.js +40 -1
  28. package/daemon/dist/adapters/tmux.js.map +1 -1
  29. package/daemon/dist/build-info.d.ts +12 -0
  30. package/daemon/dist/build-info.d.ts.map +1 -0
  31. package/daemon/dist/build-info.js +11 -0
  32. package/daemon/dist/build-info.js.map +1 -0
  33. package/daemon/dist/builtins/workflow-specs/branched-remediation.yaml +31 -0
  34. package/daemon/dist/builtins/workflow-specs/factory-rsi.yaml +152 -0
  35. package/daemon/dist/builtins/workflow-specs/gated-release.yaml +26 -0
  36. package/daemon/dist/builtins/workflow-specs/linear-build.yaml +21 -0
  37. package/daemon/dist/db/migrations/048_queue_item_evidence_ref.d.ts +18 -0
  38. package/daemon/dist/db/migrations/048_queue_item_evidence_ref.d.ts.map +1 -0
  39. package/daemon/dist/db/migrations/048_queue_item_evidence_ref.js +22 -0
  40. package/daemon/dist/db/migrations/048_queue_item_evidence_ref.js.map +1 -0
  41. package/daemon/dist/db/migrations/049_workflow_instance_version.d.ts +20 -0
  42. package/daemon/dist/db/migrations/049_workflow_instance_version.d.ts.map +1 -0
  43. package/daemon/dist/db/migrations/049_workflow_instance_version.js +24 -0
  44. package/daemon/dist/db/migrations/049_workflow_instance_version.js.map +1 -0
  45. package/daemon/dist/db/migrations/050_workflow_spec_json.d.ts +22 -0
  46. package/daemon/dist/db/migrations/050_workflow_spec_json.d.ts.map +1 -0
  47. package/daemon/dist/db/migrations/050_workflow_spec_json.js +26 -0
  48. package/daemon/dist/db/migrations/050_workflow_spec_json.js.map +1 -0
  49. package/daemon/dist/db/migrations/051_workflow_resume.d.ts +22 -0
  50. package/daemon/dist/db/migrations/051_workflow_resume.d.ts.map +1 -0
  51. package/daemon/dist/db/migrations/051_workflow_resume.js +27 -0
  52. package/daemon/dist/db/migrations/051_workflow_resume.js.map +1 -0
  53. package/daemon/dist/db/migrations/052_workflow_instance_bound_rig.d.ts +26 -0
  54. package/daemon/dist/db/migrations/052_workflow_instance_bound_rig.d.ts.map +1 -0
  55. package/daemon/dist/db/migrations/052_workflow_instance_bound_rig.js +30 -0
  56. package/daemon/dist/db/migrations/052_workflow_instance_bound_rig.js.map +1 -0
  57. package/daemon/dist/db/migrations/053_sessions_node_id_index.d.ts +48 -0
  58. package/daemon/dist/db/migrations/053_sessions_node_id_index.d.ts.map +1 -0
  59. package/daemon/dist/db/migrations/053_sessions_node_id_index.js +53 -0
  60. package/daemon/dist/db/migrations/053_sessions_node_id_index.js.map +1 -0
  61. package/daemon/dist/db/migrations/054_queue_transitions_archive.d.ts +34 -0
  62. package/daemon/dist/db/migrations/054_queue_transitions_archive.d.ts.map +1 -0
  63. package/daemon/dist/db/migrations/054_queue_transitions_archive.js +49 -0
  64. package/daemon/dist/db/migrations/054_queue_transitions_archive.js.map +1 -0
  65. package/daemon/dist/domain/claim-service.d.ts +11 -0
  66. package/daemon/dist/domain/claim-service.d.ts.map +1 -1
  67. package/daemon/dist/domain/claim-service.js +3 -1
  68. package/daemon/dist/domain/claim-service.js.map +1 -1
  69. package/daemon/dist/domain/discovery-types.d.ts +1 -1
  70. package/daemon/dist/domain/discovery-types.d.ts.map +1 -1
  71. package/daemon/dist/domain/feed/attention-aggregator.d.ts +31 -0
  72. package/daemon/dist/domain/feed/attention-aggregator.d.ts.map +1 -0
  73. package/daemon/dist/domain/feed/attention-aggregator.js +119 -0
  74. package/daemon/dist/domain/feed/attention-aggregator.js.map +1 -0
  75. package/daemon/dist/domain/files/file-write-service.d.ts +11 -2
  76. package/daemon/dist/domain/files/file-write-service.d.ts.map +1 -1
  77. package/daemon/dist/domain/files/file-write-service.js +77 -0
  78. package/daemon/dist/domain/files/file-write-service.js.map +1 -1
  79. package/daemon/dist/domain/hosts/fanout-contract.d.ts +33 -0
  80. package/daemon/dist/domain/hosts/fanout-contract.d.ts.map +1 -0
  81. package/daemon/dist/domain/hosts/fanout-contract.js +23 -0
  82. package/daemon/dist/domain/hosts/fanout-contract.js.map +1 -0
  83. package/daemon/dist/domain/hosts/hosts-registry-reader.d.ts +50 -0
  84. package/daemon/dist/domain/hosts/hosts-registry-reader.d.ts.map +1 -0
  85. package/daemon/dist/domain/hosts/hosts-registry-reader.js +184 -0
  86. package/daemon/dist/domain/hosts/hosts-registry-reader.js.map +1 -0
  87. package/daemon/dist/domain/hosts/hosts-registry-writer.d.ts +11 -0
  88. package/daemon/dist/domain/hosts/hosts-registry-writer.d.ts.map +1 -0
  89. package/daemon/dist/domain/hosts/hosts-registry-writer.js +54 -0
  90. package/daemon/dist/domain/hosts/hosts-registry-writer.js.map +1 -0
  91. package/daemon/dist/domain/hosts/read-through.d.ts +28 -0
  92. package/daemon/dist/domain/hosts/read-through.d.ts.map +1 -0
  93. package/daemon/dist/domain/hosts/read-through.js +139 -0
  94. package/daemon/dist/domain/hosts/read-through.js.map +1 -0
  95. package/daemon/dist/domain/hosts/remote-daemon-http.d.ts +56 -0
  96. package/daemon/dist/domain/hosts/remote-daemon-http.d.ts.map +1 -0
  97. package/daemon/dist/domain/hosts/remote-daemon-http.js +154 -0
  98. package/daemon/dist/domain/hosts/remote-daemon-http.js.map +1 -0
  99. package/daemon/dist/domain/human-route-enforcer.d.ts +71 -0
  100. package/daemon/dist/domain/human-route-enforcer.d.ts.map +1 -0
  101. package/daemon/dist/domain/human-route-enforcer.js +80 -0
  102. package/daemon/dist/domain/human-route-enforcer.js.map +1 -0
  103. package/daemon/dist/domain/mission-control/audit-browse.d.ts +8 -0
  104. package/daemon/dist/domain/mission-control/audit-browse.d.ts.map +1 -1
  105. package/daemon/dist/domain/mission-control/audit-browse.js +19 -0
  106. package/daemon/dist/domain/mission-control/audit-browse.js.map +1 -1
  107. package/daemon/dist/domain/mission-control/mission-control-action-log.d.ts +1 -1
  108. package/daemon/dist/domain/mission-control/mission-control-action-log.d.ts.map +1 -1
  109. package/daemon/dist/domain/mission-control/mission-control-action-log.js +4 -0
  110. package/daemon/dist/domain/mission-control/mission-control-action-log.js.map +1 -1
  111. package/daemon/dist/domain/mission-control/mission-control-fleet-cli-capability.js +1 -1
  112. package/daemon/dist/domain/mission-control/mission-control-fleet-cli-capability.js.map +1 -1
  113. package/daemon/dist/domain/mission-control/mission-control-read-layer.js +1 -1
  114. package/daemon/dist/domain/mission-control/mission-control-read-layer.js.map +1 -1
  115. package/daemon/dist/domain/mission-control/mission-control-write-contract.d.ts +28 -0
  116. package/daemon/dist/domain/mission-control/mission-control-write-contract.d.ts.map +1 -1
  117. package/daemon/dist/domain/mission-control/mission-control-write-contract.js +125 -0
  118. package/daemon/dist/domain/mission-control/mission-control-write-contract.js.map +1 -1
  119. package/daemon/dist/domain/node-inventory.d.ts +18 -0
  120. package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
  121. package/daemon/dist/domain/node-inventory.js +206 -95
  122. package/daemon/dist/domain/node-inventory.js.map +1 -1
  123. package/daemon/dist/domain/node-launcher.d.ts +11 -0
  124. package/daemon/dist/domain/node-launcher.d.ts.map +1 -1
  125. package/daemon/dist/domain/node-launcher.js +10 -0
  126. package/daemon/dist/domain/node-launcher.js.map +1 -1
  127. package/daemon/dist/domain/policies/workflow-keepalive.d.ts +7 -0
  128. package/daemon/dist/domain/policies/workflow-keepalive.d.ts.map +1 -1
  129. package/daemon/dist/domain/policies/workflow-keepalive.js +93 -13
  130. package/daemon/dist/domain/policies/workflow-keepalive.js.map +1 -1
  131. package/daemon/dist/domain/ps-projection.d.ts +28 -1
  132. package/daemon/dist/domain/ps-projection.d.ts.map +1 -1
  133. package/daemon/dist/domain/ps-projection.js +76 -26
  134. package/daemon/dist/domain/ps-projection.js.map +1 -1
  135. package/daemon/dist/domain/queue-repository.d.ts +130 -1
  136. package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  137. package/daemon/dist/domain/queue-repository.js +304 -11
  138. package/daemon/dist/domain/queue-repository.js.map +1 -1
  139. package/daemon/dist/domain/queue-retention.d.ts +130 -0
  140. package/daemon/dist/domain/queue-retention.d.ts.map +1 -0
  141. package/daemon/dist/domain/queue-retention.js +224 -0
  142. package/daemon/dist/domain/queue-retention.js.map +1 -0
  143. package/daemon/dist/domain/restore-orchestrator.d.ts +5 -0
  144. package/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
  145. package/daemon/dist/domain/restore-orchestrator.js +29 -2
  146. package/daemon/dist/domain/restore-orchestrator.js.map +1 -1
  147. package/daemon/dist/domain/resume-token-capture.d.ts +13 -0
  148. package/daemon/dist/domain/resume-token-capture.d.ts.map +1 -1
  149. package/daemon/dist/domain/resume-token-capture.js +14 -1
  150. package/daemon/dist/domain/resume-token-capture.js.map +1 -1
  151. package/daemon/dist/domain/resume-token-validation.d.ts +1 -1
  152. package/daemon/dist/domain/resume-token-validation.d.ts.map +1 -1
  153. package/daemon/dist/domain/resume-token-validation.js +58 -10
  154. package/daemon/dist/domain/resume-token-validation.js.map +1 -1
  155. package/daemon/dist/domain/review/brief-spine.d.ts +19 -0
  156. package/daemon/dist/domain/review/brief-spine.d.ts.map +1 -0
  157. package/daemon/dist/domain/review/brief-spine.js +86 -0
  158. package/daemon/dist/domain/review/brief-spine.js.map +1 -0
  159. package/daemon/dist/domain/review/compose.d.ts +277 -0
  160. package/daemon/dist/domain/review/compose.d.ts.map +1 -0
  161. package/daemon/dist/domain/review/compose.js +862 -0
  162. package/daemon/dist/domain/review/compose.js.map +1 -0
  163. package/daemon/dist/domain/review/fleet-compose.d.ts +52 -0
  164. package/daemon/dist/domain/review/fleet-compose.d.ts.map +1 -0
  165. package/daemon/dist/domain/review/fleet-compose.js +294 -0
  166. package/daemon/dist/domain/review/fleet-compose.js.map +1 -0
  167. package/daemon/dist/domain/review/freeze.d.ts +31 -0
  168. package/daemon/dist/domain/review/freeze.d.ts.map +1 -0
  169. package/daemon/dist/domain/review/freeze.js +257 -0
  170. package/daemon/dist/domain/review/freeze.js.map +1 -0
  171. package/daemon/dist/domain/review/gather.d.ts +115 -0
  172. package/daemon/dist/domain/review/gather.d.ts.map +1 -0
  173. package/daemon/dist/domain/review/gather.js +812 -0
  174. package/daemon/dist/domain/review/gather.js.map +1 -0
  175. package/daemon/dist/domain/review/types.d.ts +361 -0
  176. package/daemon/dist/domain/review/types.d.ts.map +1 -0
  177. package/daemon/dist/domain/review/types.js +35 -0
  178. package/daemon/dist/domain/review/types.js.map +1 -0
  179. package/daemon/dist/domain/rig-expansion-service.d.ts.map +1 -1
  180. package/daemon/dist/domain/rig-expansion-service.js +3 -0
  181. package/daemon/dist/domain/rig-expansion-service.js.map +1 -1
  182. package/daemon/dist/domain/rig-repository.d.ts +7 -6
  183. package/daemon/dist/domain/rig-repository.d.ts.map +1 -1
  184. package/daemon/dist/domain/rig-repository.js +33 -11
  185. package/daemon/dist/domain/rig-repository.js.map +1 -1
  186. package/daemon/dist/domain/rigspec-codec.d.ts.map +1 -1
  187. package/daemon/dist/domain/rigspec-codec.js +3 -0
  188. package/daemon/dist/domain/rigspec-codec.js.map +1 -1
  189. package/daemon/dist/domain/rigspec-exporter.d.ts.map +1 -1
  190. package/daemon/dist/domain/rigspec-exporter.js +4 -0
  191. package/daemon/dist/domain/rigspec-exporter.js.map +1 -1
  192. package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
  193. package/daemon/dist/domain/rigspec-instantiator.js +11 -0
  194. package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
  195. package/daemon/dist/domain/rigspec-preflight.d.ts +6 -0
  196. package/daemon/dist/domain/rigspec-preflight.d.ts.map +1 -1
  197. package/daemon/dist/domain/rigspec-preflight.js +26 -1
  198. package/daemon/dist/domain/rigspec-preflight.js.map +1 -1
  199. package/daemon/dist/domain/rigspec-schema.d.ts.map +1 -1
  200. package/daemon/dist/domain/rigspec-schema.js +20 -1
  201. package/daemon/dist/domain/rigspec-schema.js.map +1 -1
  202. package/daemon/dist/domain/runtime-verifier.d.ts +7 -1
  203. package/daemon/dist/domain/runtime-verifier.d.ts.map +1 -1
  204. package/daemon/dist/domain/runtime-verifier.js +39 -1
  205. package/daemon/dist/domain/runtime-verifier.js.map +1 -1
  206. package/daemon/dist/domain/scope/scope-approve.d.ts +64 -0
  207. package/daemon/dist/domain/scope/scope-approve.d.ts.map +1 -0
  208. package/daemon/dist/domain/scope/scope-approve.js +153 -0
  209. package/daemon/dist/domain/scope/scope-approve.js.map +1 -0
  210. package/daemon/dist/domain/scope/scope-audit.d.ts +9 -1
  211. package/daemon/dist/domain/scope/scope-audit.d.ts.map +1 -1
  212. package/daemon/dist/domain/scope/scope-audit.js +173 -1
  213. package/daemon/dist/domain/scope/scope-audit.js.map +1 -1
  214. package/daemon/dist/domain/seat-handover-service.d.ts +9 -0
  215. package/daemon/dist/domain/seat-handover-service.d.ts.map +1 -1
  216. package/daemon/dist/domain/seat-handover-service.js +2 -0
  217. package/daemon/dist/domain/seat-handover-service.js.map +1 -1
  218. package/daemon/dist/domain/seat-identity-store.d.ts +7 -0
  219. package/daemon/dist/domain/seat-identity-store.d.ts.map +1 -1
  220. package/daemon/dist/domain/seat-identity-store.js +27 -0
  221. package/daemon/dist/domain/seat-identity-store.js.map +1 -1
  222. package/daemon/dist/domain/seat-status-service.d.ts.map +1 -1
  223. package/daemon/dist/domain/seat-status-service.js +6 -4
  224. package/daemon/dist/domain/seat-status-service.js.map +1 -1
  225. package/daemon/dist/domain/session-name.d.ts +22 -0
  226. package/daemon/dist/domain/session-name.d.ts.map +1 -1
  227. package/daemon/dist/domain/session-name.js +29 -0
  228. package/daemon/dist/domain/session-name.js.map +1 -1
  229. package/daemon/dist/domain/slices/slice-detail-projector.d.ts.map +1 -1
  230. package/daemon/dist/domain/slices/slice-detail-projector.js +4 -5
  231. package/daemon/dist/domain/slices/slice-detail-projector.js.map +1 -1
  232. package/daemon/dist/domain/spec-library-workflow-scanner.d.ts +18 -2
  233. package/daemon/dist/domain/spec-library-workflow-scanner.d.ts.map +1 -1
  234. package/daemon/dist/domain/spec-library-workflow-scanner.js +23 -1
  235. package/daemon/dist/domain/spec-library-workflow-scanner.js.map +1 -1
  236. package/daemon/dist/domain/startup-proof.d.ts +10 -6
  237. package/daemon/dist/domain/startup-proof.d.ts.map +1 -1
  238. package/daemon/dist/domain/startup-proof.js +35 -7
  239. package/daemon/dist/domain/startup-proof.js.map +1 -1
  240. package/daemon/dist/domain/successor-session-launcher.d.ts +16 -0
  241. package/daemon/dist/domain/successor-session-launcher.d.ts.map +1 -1
  242. package/daemon/dist/domain/successor-session-launcher.js +13 -0
  243. package/daemon/dist/domain/successor-session-launcher.js.map +1 -1
  244. package/daemon/dist/domain/terminal/cmux-provider-adapter.d.ts +27 -0
  245. package/daemon/dist/domain/terminal/cmux-provider-adapter.d.ts.map +1 -0
  246. package/daemon/dist/domain/terminal/cmux-provider-adapter.js +67 -0
  247. package/daemon/dist/domain/terminal/cmux-provider-adapter.js.map +1 -0
  248. package/daemon/dist/domain/terminal/herdr-adapter.d.ts +77 -0
  249. package/daemon/dist/domain/terminal/herdr-adapter.d.ts.map +1 -0
  250. package/daemon/dist/domain/terminal/herdr-adapter.js +266 -0
  251. package/daemon/dist/domain/terminal/herdr-adapter.js.map +1 -0
  252. package/daemon/dist/domain/terminal/herdr-transport.d.ts +50 -0
  253. package/daemon/dist/domain/terminal/herdr-transport.d.ts.map +1 -0
  254. package/daemon/dist/domain/terminal/herdr-transport.js +145 -0
  255. package/daemon/dist/domain/terminal/herdr-transport.js.map +1 -0
  256. package/daemon/dist/domain/terminal/terminal-provider.d.ts +88 -0
  257. package/daemon/dist/domain/terminal/terminal-provider.d.ts.map +1 -0
  258. package/daemon/dist/domain/terminal/terminal-provider.js +17 -0
  259. package/daemon/dist/domain/terminal/terminal-provider.js.map +1 -0
  260. package/daemon/dist/domain/terminal/terminal-service.d.ts +60 -0
  261. package/daemon/dist/domain/terminal/terminal-service.d.ts.map +1 -0
  262. package/daemon/dist/domain/terminal/terminal-service.js +174 -0
  263. package/daemon/dist/domain/terminal/terminal-service.js.map +1 -0
  264. package/daemon/dist/domain/terminal/terminal-views-store.d.ts +77 -0
  265. package/daemon/dist/domain/terminal/terminal-views-store.d.ts.map +1 -0
  266. package/daemon/dist/domain/terminal/terminal-views-store.js +146 -0
  267. package/daemon/dist/domain/terminal/terminal-views-store.js.map +1 -0
  268. package/daemon/dist/domain/terminal/view-composer.d.ts +42 -0
  269. package/daemon/dist/domain/terminal/view-composer.d.ts.map +1 -0
  270. package/daemon/dist/domain/terminal/view-composer.js +137 -0
  271. package/daemon/dist/domain/terminal/view-composer.js.map +1 -0
  272. package/daemon/dist/domain/tmux-option-defaults.d.ts +89 -0
  273. package/daemon/dist/domain/tmux-option-defaults.d.ts.map +1 -0
  274. package/daemon/dist/domain/tmux-option-defaults.js +132 -0
  275. package/daemon/dist/domain/tmux-option-defaults.js.map +1 -0
  276. package/daemon/dist/domain/topology/multi-rig-launcher.d.ts +49 -0
  277. package/daemon/dist/domain/topology/multi-rig-launcher.d.ts.map +1 -0
  278. package/daemon/dist/domain/topology/multi-rig-launcher.js +132 -0
  279. package/daemon/dist/domain/topology/multi-rig-launcher.js.map +1 -0
  280. package/daemon/dist/domain/topology/remote-up-leaf.d.ts +29 -0
  281. package/daemon/dist/domain/topology/remote-up-leaf.d.ts.map +1 -0
  282. package/daemon/dist/domain/topology/remote-up-leaf.js +60 -0
  283. package/daemon/dist/domain/topology/remote-up-leaf.js.map +1 -0
  284. package/daemon/dist/domain/topology/topology-manifest.d.ts +34 -0
  285. package/daemon/dist/domain/topology/topology-manifest.d.ts.map +1 -0
  286. package/daemon/dist/domain/topology/topology-manifest.js +195 -0
  287. package/daemon/dist/domain/topology/topology-manifest.js.map +1 -0
  288. package/daemon/dist/domain/types.d.ts +39 -1
  289. package/daemon/dist/domain/types.d.ts.map +1 -1
  290. package/daemon/dist/domain/types.js.map +1 -1
  291. package/daemon/dist/domain/up-command-router.d.ts +1 -1
  292. package/daemon/dist/domain/up-command-router.d.ts.map +1 -1
  293. package/daemon/dist/domain/up-command-router.js +34 -2
  294. package/daemon/dist/domain/up-command-router.js.map +1 -1
  295. package/daemon/dist/domain/user-settings/settings-store.d.ts +18 -1
  296. package/daemon/dist/domain/user-settings/settings-store.d.ts.map +1 -1
  297. package/daemon/dist/domain/user-settings/settings-store.js +201 -0
  298. package/daemon/dist/domain/user-settings/settings-store.js.map +1 -1
  299. package/daemon/dist/domain/workflow/slice-workflow-projection.d.ts.map +1 -1
  300. package/daemon/dist/domain/workflow/slice-workflow-projection.js +6 -2
  301. package/daemon/dist/domain/workflow/slice-workflow-projection.js.map +1 -1
  302. package/daemon/dist/domain/workflow-boot-sweep.d.ts +28 -0
  303. package/daemon/dist/domain/workflow-boot-sweep.d.ts.map +1 -0
  304. package/daemon/dist/domain/workflow-boot-sweep.js +102 -0
  305. package/daemon/dist/domain/workflow-boot-sweep.js.map +1 -0
  306. package/daemon/dist/domain/workflow-deadline.d.ts +74 -0
  307. package/daemon/dist/domain/workflow-deadline.d.ts.map +1 -0
  308. package/daemon/dist/domain/workflow-deadline.js +165 -0
  309. package/daemon/dist/domain/workflow-deadline.js.map +1 -0
  310. package/daemon/dist/domain/workflow-exception-escalation.d.ts +33 -0
  311. package/daemon/dist/domain/workflow-exception-escalation.d.ts.map +1 -0
  312. package/daemon/dist/domain/workflow-exception-escalation.js +104 -0
  313. package/daemon/dist/domain/workflow-exception-escalation.js.map +1 -0
  314. package/daemon/dist/domain/workflow-exception-router.d.ts +33 -0
  315. package/daemon/dist/domain/workflow-exception-router.d.ts.map +1 -0
  316. package/daemon/dist/domain/workflow-exception-router.js +96 -0
  317. package/daemon/dist/domain/workflow-exception-router.js.map +1 -0
  318. package/daemon/dist/domain/workflow-exception.d.ts +90 -0
  319. package/daemon/dist/domain/workflow-exception.d.ts.map +1 -0
  320. package/daemon/dist/domain/workflow-exception.js +122 -0
  321. package/daemon/dist/domain/workflow-exception.js.map +1 -0
  322. package/daemon/dist/domain/workflow-frontier-guard.d.ts +24 -0
  323. package/daemon/dist/domain/workflow-frontier-guard.d.ts.map +1 -0
  324. package/daemon/dist/domain/workflow-frontier-guard.js +30 -0
  325. package/daemon/dist/domain/workflow-frontier-guard.js.map +1 -0
  326. package/daemon/dist/domain/workflow-instance-store.d.ts +28 -0
  327. package/daemon/dist/domain/workflow-instance-store.d.ts.map +1 -1
  328. package/daemon/dist/domain/workflow-instance-store.js +66 -10
  329. package/daemon/dist/domain/workflow-instance-store.js.map +1 -1
  330. package/daemon/dist/domain/workflow-keepalive-arming.d.ts +35 -0
  331. package/daemon/dist/domain/workflow-keepalive-arming.d.ts.map +1 -0
  332. package/daemon/dist/domain/workflow-keepalive-arming.js +87 -0
  333. package/daemon/dist/domain/workflow-keepalive-arming.js.map +1 -0
  334. package/daemon/dist/domain/workflow-projector.d.ts +117 -2
  335. package/daemon/dist/domain/workflow-projector.d.ts.map +1 -1
  336. package/daemon/dist/domain/workflow-projector.js +672 -41
  337. package/daemon/dist/domain/workflow-projector.js.map +1 -1
  338. package/daemon/dist/domain/workflow-role-context.d.ts +57 -0
  339. package/daemon/dist/domain/workflow-role-context.d.ts.map +1 -0
  340. package/daemon/dist/domain/workflow-role-context.js +120 -0
  341. package/daemon/dist/domain/workflow-role-context.js.map +1 -0
  342. package/daemon/dist/domain/workflow-role-resolver.d.ts +65 -0
  343. package/daemon/dist/domain/workflow-role-resolver.d.ts.map +1 -0
  344. package/daemon/dist/domain/workflow-role-resolver.js +108 -0
  345. package/daemon/dist/domain/workflow-role-resolver.js.map +1 -0
  346. package/daemon/dist/domain/workflow-runtime.d.ts +157 -1
  347. package/daemon/dist/domain/workflow-runtime.d.ts.map +1 -1
  348. package/daemon/dist/domain/workflow-runtime.js +718 -11
  349. package/daemon/dist/domain/workflow-runtime.js.map +1 -1
  350. package/daemon/dist/domain/workflow-spec-cache.d.ts +26 -1
  351. package/daemon/dist/domain/workflow-spec-cache.d.ts.map +1 -1
  352. package/daemon/dist/domain/workflow-spec-cache.js +327 -13
  353. package/daemon/dist/domain/workflow-spec-cache.js.map +1 -1
  354. package/daemon/dist/domain/workflow-types.d.ts +143 -8
  355. package/daemon/dist/domain/workflow-types.d.ts.map +1 -1
  356. package/daemon/dist/domain/workflow-types.js +14 -1
  357. package/daemon/dist/domain/workflow-types.js.map +1 -1
  358. package/daemon/dist/domain/workflow-validator.d.ts +11 -1
  359. package/daemon/dist/domain/workflow-validator.d.ts.map +1 -1
  360. package/daemon/dist/domain/workflow-validator.js +246 -1
  361. package/daemon/dist/domain/workflow-validator.js.map +1 -1
  362. package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts.map +1 -1
  363. package/daemon/dist/domain/workspace/default-workspace-scaffold.js +51 -6
  364. package/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
  365. package/daemon/dist/domain/workspace/workspace-doctor.d.ts +11 -0
  366. package/daemon/dist/domain/workspace/workspace-doctor.d.ts.map +1 -1
  367. package/daemon/dist/domain/workspace/workspace-doctor.js +82 -0
  368. package/daemon/dist/domain/workspace/workspace-doctor.js.map +1 -1
  369. package/daemon/dist/index.d.ts +17 -0
  370. package/daemon/dist/index.d.ts.map +1 -1
  371. package/daemon/dist/index.js +44 -0
  372. package/daemon/dist/index.js.map +1 -1
  373. package/daemon/dist/routes/activity.js +22 -0
  374. package/daemon/dist/routes/activity.js.map +1 -1
  375. package/daemon/dist/routes/config.d.ts.map +1 -1
  376. package/daemon/dist/routes/config.js +15 -6
  377. package/daemon/dist/routes/config.js.map +1 -1
  378. package/daemon/dist/routes/files.d.ts.map +1 -1
  379. package/daemon/dist/routes/files.js +45 -1
  380. package/daemon/dist/routes/files.js.map +1 -1
  381. package/daemon/dist/routes/hosts.d.ts +5 -0
  382. package/daemon/dist/routes/hosts.d.ts.map +1 -0
  383. package/daemon/dist/routes/hosts.js +346 -0
  384. package/daemon/dist/routes/hosts.js.map +1 -0
  385. package/daemon/dist/routes/mission-control.d.ts.map +1 -1
  386. package/daemon/dist/routes/mission-control.js +67 -2
  387. package/daemon/dist/routes/mission-control.js.map +1 -1
  388. package/daemon/dist/routes/queue.d.ts +10 -9
  389. package/daemon/dist/routes/queue.d.ts.map +1 -1
  390. package/daemon/dist/routes/queue.js +305 -10
  391. package/daemon/dist/routes/queue.js.map +1 -1
  392. package/daemon/dist/routes/review.d.ts +3 -0
  393. package/daemon/dist/routes/review.d.ts.map +1 -0
  394. package/daemon/dist/routes/review.js +195 -0
  395. package/daemon/dist/routes/review.js.map +1 -0
  396. package/daemon/dist/routes/scope-approve.d.ts +3 -0
  397. package/daemon/dist/routes/scope-approve.d.ts.map +1 -0
  398. package/daemon/dist/routes/scope-approve.js +55 -0
  399. package/daemon/dist/routes/scope-approve.js.map +1 -0
  400. package/daemon/dist/routes/scope-audit.d.ts.map +1 -1
  401. package/daemon/dist/routes/scope-audit.js +28 -1
  402. package/daemon/dist/routes/scope-audit.js.map +1 -1
  403. package/daemon/dist/routes/seat.js +13 -0
  404. package/daemon/dist/routes/seat.js.map +1 -1
  405. package/daemon/dist/routes/slices.d.ts.map +1 -1
  406. package/daemon/dist/routes/slices.js +49 -9
  407. package/daemon/dist/routes/slices.js.map +1 -1
  408. package/daemon/dist/routes/terminal-ws.d.ts.map +1 -1
  409. package/daemon/dist/routes/terminal-ws.js +58 -21
  410. package/daemon/dist/routes/terminal-ws.js.map +1 -1
  411. package/daemon/dist/routes/terminal.d.ts +11 -0
  412. package/daemon/dist/routes/terminal.d.ts.map +1 -0
  413. package/daemon/dist/routes/terminal.js +104 -0
  414. package/daemon/dist/routes/terminal.js.map +1 -0
  415. package/daemon/dist/routes/up.d.ts.map +1 -1
  416. package/daemon/dist/routes/up.js +84 -0
  417. package/daemon/dist/routes/up.js.map +1 -1
  418. package/daemon/dist/routes/workflow.d.ts.map +1 -1
  419. package/daemon/dist/routes/workflow.js +102 -10
  420. package/daemon/dist/routes/workflow.js.map +1 -1
  421. package/daemon/dist/routes/workspace.js +2 -2
  422. package/daemon/dist/server.d.ts +6 -0
  423. package/daemon/dist/server.d.ts.map +1 -1
  424. package/daemon/dist/server.js +36 -1
  425. package/daemon/dist/server.js.map +1 -1
  426. package/daemon/dist/startup.d.ts.map +1 -1
  427. package/daemon/dist/startup.js +238 -14
  428. package/daemon/dist/startup.js.map +1 -1
  429. package/daemon/docs/reference/agent-startup-guide.md +1 -1
  430. package/daemon/docs/reference/product-factory-vps-runbook.md +132 -0
  431. package/daemon/docs/reference/sdlc-conventions.md +187 -0
  432. package/daemon/specs/agents/conveyor/builder/agent.yaml +1 -1
  433. package/daemon/specs/agents/conveyor/builder/guidance/role.md +1 -0
  434. package/daemon/specs/agents/conveyor/lead/agent.yaml +1 -1
  435. package/daemon/specs/agents/conveyor/lead/guidance/role.md +1 -0
  436. package/daemon/specs/agents/conveyor/planner/agent.yaml +1 -1
  437. package/daemon/specs/agents/conveyor/planner/guidance/role.md +1 -0
  438. package/daemon/specs/agents/conveyor/reviewer/agent.yaml +1 -1
  439. package/daemon/specs/agents/conveyor/reviewer/guidance/role.md +1 -0
  440. package/daemon/specs/agents/design/product-designer/agent.yaml +1 -1
  441. package/daemon/specs/agents/design/product-designer/guidance/role.md +1 -0
  442. package/daemon/specs/agents/development/implementer/agent.yaml +1 -1
  443. package/daemon/specs/agents/development/implementer/guidance/role.md +1 -0
  444. package/daemon/specs/agents/development/qa/agent.yaml +1 -1
  445. package/daemon/specs/agents/development/qa/guidance/role.md +1 -0
  446. package/daemon/specs/agents/factory-rsi/dogfood/agent.yaml +29 -0
  447. package/daemon/specs/agents/factory-rsi/dogfood/guidance/role.md +37 -0
  448. package/daemon/specs/agents/factory-rsi/release-manager/agent.yaml +29 -0
  449. package/daemon/specs/agents/factory-rsi/release-manager/guidance/role.md +40 -0
  450. package/daemon/specs/agents/orchestration/orchestrator/agent.yaml +1 -1
  451. package/daemon/specs/agents/orchestration/orchestrator/guidance/role.md +1 -0
  452. package/daemon/specs/agents/product-management/pm/agent.yaml +1 -0
  453. package/daemon/specs/agents/product-management/pm/guidance/role.md +13 -0
  454. package/daemon/specs/agents/review/independent-reviewer/agent.yaml +1 -1
  455. package/daemon/specs/agents/review/independent-reviewer/guidance/role.md +1 -0
  456. package/daemon/specs/agents/shared/agent.yaml +2 -0
  457. package/daemon/specs/agents/shared/skills/core/mission-slice-sop/SKILL.md +113 -0
  458. package/daemon/specs/agents/shared/skills/core/openrig-cmux/SKILL.md +86 -0
  459. package/daemon/specs/agents/shared/skills/core/openrig-herdr/SKILL.md +158 -0
  460. package/daemon/specs/agents/shared/skills/core/openrig-operator/SKILL.md +4 -4
  461. package/daemon/specs/agents/shared/skills/core/openrig-user/SKILL.md +75 -29
  462. package/daemon/specs/agents/shared/skills/pods/orchestration-team/SKILL.md +2 -2
  463. package/daemon/specs/rigs/focused/pm-team/CULTURE.md +4 -0
  464. package/daemon/specs/rigs/launch/factory-rsi/CULTURE.md +47 -0
  465. package/daemon/specs/rigs/launch/factory-rsi/rig.yaml +115 -0
  466. package/daemon/specs/rigs/launch/kernel/agents/operator/agent/guidance/role.md +1 -1
  467. package/daemon/specs/rigs/launch/kernel/agents/operator/agent/startup/context.md +1 -1
  468. package/daemon/specs/rigs/preview/product-team/CULTURE.md +4 -0
  469. package/dist/build-info.d.ts +8 -0
  470. package/dist/build-info.d.ts.map +1 -0
  471. package/dist/build-info.js +11 -0
  472. package/dist/build-info.js.map +1 -0
  473. package/dist/commands/broadcast.d.ts +6 -1
  474. package/dist/commands/broadcast.d.ts.map +1 -1
  475. package/dist/commands/broadcast.js +101 -15
  476. package/dist/commands/broadcast.js.map +1 -1
  477. package/dist/commands/capture.d.ts.map +1 -1
  478. package/dist/commands/capture.js +99 -8
  479. package/dist/commands/capture.js.map +1 -1
  480. package/dist/commands/config-init-workspace.d.ts.map +1 -1
  481. package/dist/commands/config-init-workspace.js +20 -4
  482. package/dist/commands/config-init-workspace.js.map +1 -1
  483. package/dist/commands/config.d.ts.map +1 -1
  484. package/dist/commands/config.js +4 -0
  485. package/dist/commands/config.js.map +1 -1
  486. package/dist/commands/doctor.js +2 -2
  487. package/dist/commands/doctor.js.map +1 -1
  488. package/dist/commands/down.d.ts.map +1 -1
  489. package/dist/commands/down.js +5 -0
  490. package/dist/commands/down.js.map +1 -1
  491. package/dist/commands/expand.js +1 -1
  492. package/dist/commands/expand.js.map +1 -1
  493. package/dist/commands/file.d.ts +7 -0
  494. package/dist/commands/file.d.ts.map +1 -0
  495. package/dist/commands/file.js +77 -0
  496. package/dist/commands/file.js.map +1 -0
  497. package/dist/commands/host.d.ts +48 -0
  498. package/dist/commands/host.d.ts.map +1 -0
  499. package/dist/commands/host.js +772 -0
  500. package/dist/commands/host.js.map +1 -0
  501. package/dist/commands/launch.d.ts.map +1 -1
  502. package/dist/commands/launch.js +5 -0
  503. package/dist/commands/launch.js.map +1 -1
  504. package/dist/commands/proof.d.ts +54 -0
  505. package/dist/commands/proof.d.ts.map +1 -0
  506. package/dist/commands/proof.js +311 -0
  507. package/dist/commands/proof.js.map +1 -0
  508. package/dist/commands/ps.d.ts +41 -7
  509. package/dist/commands/ps.d.ts.map +1 -1
  510. package/dist/commands/ps.js +353 -135
  511. package/dist/commands/ps.js.map +1 -1
  512. package/dist/commands/queue.d.ts +36 -0
  513. package/dist/commands/queue.d.ts.map +1 -1
  514. package/dist/commands/queue.js +149 -7
  515. package/dist/commands/queue.js.map +1 -1
  516. package/dist/commands/restore-packet.d.ts.map +1 -1
  517. package/dist/commands/restore-packet.js +13 -2
  518. package/dist/commands/restore-packet.js.map +1 -1
  519. package/dist/commands/scope.d.ts.map +1 -1
  520. package/dist/commands/scope.js +140 -3
  521. package/dist/commands/scope.js.map +1 -1
  522. package/dist/commands/send.d.ts.map +1 -1
  523. package/dist/commands/send.js +127 -13
  524. package/dist/commands/send.js.map +1 -1
  525. package/dist/commands/terminal.d.ts +6 -0
  526. package/dist/commands/terminal.d.ts.map +1 -0
  527. package/dist/commands/terminal.js +116 -0
  528. package/dist/commands/terminal.js.map +1 -0
  529. package/dist/commands/transcript.d.ts +6 -1
  530. package/dist/commands/transcript.d.ts.map +1 -1
  531. package/dist/commands/transcript.js +113 -30
  532. package/dist/commands/transcript.js.map +1 -1
  533. package/dist/commands/up.d.ts +2 -0
  534. package/dist/commands/up.d.ts.map +1 -1
  535. package/dist/commands/up.js +78 -2
  536. package/dist/commands/up.js.map +1 -1
  537. package/dist/commands/whoami.d.ts.map +1 -1
  538. package/dist/commands/whoami.js +11 -0
  539. package/dist/commands/whoami.js.map +1 -1
  540. package/dist/commands/workflow-errors.d.ts +23 -0
  541. package/dist/commands/workflow-errors.d.ts.map +1 -0
  542. package/dist/commands/workflow-errors.js +100 -0
  543. package/dist/commands/workflow-errors.js.map +1 -0
  544. package/dist/commands/workflow-follow.d.ts +71 -0
  545. package/dist/commands/workflow-follow.d.ts.map +1 -0
  546. package/dist/commands/workflow-follow.js +259 -0
  547. package/dist/commands/workflow-follow.js.map +1 -0
  548. package/dist/commands/workflow-render.d.ts +114 -0
  549. package/dist/commands/workflow-render.d.ts.map +1 -0
  550. package/dist/commands/workflow-render.js +223 -0
  551. package/dist/commands/workflow-render.js.map +1 -0
  552. package/dist/commands/workflow.d.ts +1 -0
  553. package/dist/commands/workflow.d.ts.map +1 -1
  554. package/dist/commands/workflow.js +278 -14
  555. package/dist/commands/workflow.js.map +1 -1
  556. package/dist/commands/workspace.js +6 -6
  557. package/dist/commands/workspace.js.map +1 -1
  558. package/dist/config-store.d.ts +19 -1
  559. package/dist/config-store.d.ts.map +1 -1
  560. package/dist/config-store.js +171 -0
  561. package/dist/config-store.js.map +1 -1
  562. package/dist/cross-host-cli-helpers.d.ts +13 -0
  563. package/dist/cross-host-cli-helpers.d.ts.map +1 -1
  564. package/dist/cross-host-cli-helpers.js +27 -0
  565. package/dist/cross-host-cli-helpers.js.map +1 -1
  566. package/dist/cross-host-executor.d.ts +1 -0
  567. package/dist/cross-host-executor.d.ts.map +1 -1
  568. package/dist/cross-host-executor.js +4 -1
  569. package/dist/cross-host-executor.js.map +1 -1
  570. package/dist/cross-host-target.d.ts +49 -0
  571. package/dist/cross-host-target.d.ts.map +1 -0
  572. package/dist/cross-host-target.js +35 -0
  573. package/dist/cross-host-target.js.map +1 -0
  574. package/dist/daemon-lifecycle.d.ts.map +1 -1
  575. package/dist/daemon-lifecycle.js +4 -1
  576. package/dist/daemon-lifecycle.js.map +1 -1
  577. package/dist/host-registry.d.ts +17 -0
  578. package/dist/host-registry.d.ts.map +1 -1
  579. package/dist/host-registry.js +64 -2
  580. package/dist/host-registry.js.map +1 -1
  581. package/dist/host-selection.d.ts +13 -0
  582. package/dist/host-selection.d.ts.map +1 -0
  583. package/dist/host-selection.js +54 -0
  584. package/dist/host-selection.js.map +1 -0
  585. package/dist/index.d.ts +2 -0
  586. package/dist/index.d.ts.map +1 -1
  587. package/dist/index.js +9 -0
  588. package/dist/index.js.map +1 -1
  589. package/dist/lib/file-transfer.d.ts +89 -0
  590. package/dist/lib/file-transfer.d.ts.map +1 -0
  591. package/dist/lib/file-transfer.js +300 -0
  592. package/dist/lib/file-transfer.js.map +1 -0
  593. package/dist/lib/hosts/fanout-contract.d.ts +33 -0
  594. package/dist/lib/hosts/fanout-contract.d.ts.map +1 -0
  595. package/dist/lib/hosts/fanout-contract.js +23 -0
  596. package/dist/lib/hosts/fanout-contract.js.map +1 -0
  597. package/dist/lib/scope/scope-audit.d.ts +9 -1
  598. package/dist/lib/scope/scope-audit.d.ts.map +1 -1
  599. package/dist/lib/scope/scope-audit.js +173 -1
  600. package/dist/lib/scope/scope-audit.js.map +1 -1
  601. package/dist/lib/scope/templates.d.ts +1 -0
  602. package/dist/lib/scope/templates.d.ts.map +1 -1
  603. package/dist/lib/scope/templates.js +9 -0
  604. package/dist/lib/scope/templates.js.map +1 -1
  605. package/dist/lib/scope-templates/backlog-deprecation.md +16 -0
  606. package/dist/lib/scope-templates/backlog-tech-debt.md +16 -0
  607. package/dist/lib/scope-templates/bug-fix.md +16 -0
  608. package/dist/lib/scope-templates/implementation-prd.md +33 -0
  609. package/dist/lib/scope-templates/mission-placeholder.md +1 -1
  610. package/dist/lib/scope-templates/mission-progress.md +1 -1
  611. package/dist/lib/scope-templates/mission-release.md +1 -1
  612. package/dist/lib/scope-templates/placeholder.md +11 -7
  613. package/dist/lib/scope-templates/proof.md +5 -1
  614. package/dist/lib/scope-templates/release-feature.md +14 -6
  615. package/dist/lib/scope-templates/research.md +16 -0
  616. package/dist/lib/scope-templates/slice-progress.md +1 -1
  617. package/dist/remote-host-ops.d.ts +1 -0
  618. package/dist/remote-host-ops.d.ts.map +1 -1
  619. package/dist/remote-host-ops.js +11 -4
  620. package/dist/remote-host-ops.js.map +1 -1
  621. package/dist/session-name.d.ts +23 -0
  622. package/dist/session-name.d.ts.map +1 -0
  623. package/dist/session-name.js +61 -0
  624. package/dist/session-name.js.map +1 -0
  625. package/dist/version.d.ts +5 -0
  626. package/dist/version.d.ts.map +1 -1
  627. package/dist/version.js +11 -1
  628. package/dist/version.js.map +1 -1
  629. package/package.json +1 -1
  630. package/ui/dist/assets/index-CFqxa0zW.css +32 -0
  631. package/ui/dist/assets/index-zrFqS7gL.js +623 -0
  632. package/ui/dist/index.html +2 -2
  633. package/ui/dist/assets/index-DYZniQcc.js +0 -597
  634. package/ui/dist/assets/index-trcb4Yf_.css +0 -32
@@ -0,0 +1,812 @@
1
+ // Living Notes Packet 2 — the input gatherer (OPR.0.4.4.20).
2
+ //
3
+ // The impure shell around the pure composer: reads slice docs + proof
4
+ // artifacts from disk, attention/agent rows from SQLite, approval stamps
5
+ // from frontmatter (cross-checked against the Packet-1 audit-target
6
+ // contract), and git facts from the workspace's default repo. Every source
7
+ // that cannot be read degrades honestly (nulls / "unknown") — the composer
8
+ // renders the named degrade, never invented content.
9
+ import * as fs from "node:fs";
10
+ import * as path from "node:path";
11
+ import { execFileSync } from "node:child_process";
12
+ import YAML from "yaml";
13
+ import { sessionMemberLabel } from "../session-name.js";
14
+ import { composeMissionReview, composeRecordedGreenForSlice, composeSliceReview, deriveCandidateSha, extractMediaRefs, extractSection, parseC1Header, } from "./compose.js";
15
+ import { composeAgentsBand, composeRigAgents } from "./compose.js";
16
+ import { evaluateStepDeadline } from "../workflow-deadline.js";
17
+ import { isHumanSeatSession } from "../human-route-enforcer.js";
18
+ const ACTIVE_STATES = ["pending", "in-progress", "claimed", "blocked", "handed-off"];
19
+ /** OPR.0.4.6.WF4 Q6 — the ● (agent-leg) workflow-identity stamp, derived from
20
+ * the item's OWN STRUCTURED TAGS (`workflow:<name>` / `instance:<id>` /
21
+ * `step:<id>` — the WF-5-ratified queryable identity), NEVER from summary /
22
+ * identity / evidenceRef prose. Returns the pointer only when BOTH required
23
+ * keys are present; a non-workflow row (no `instance:`/`workflow:` tag) →
24
+ * `undefined`, so its AttentionInput stays byte-identical (omit-when-absent).
25
+ * Pointer-only: the three identity keys, never status/deadline/class. */
26
+ export function workflowRefFromTags(tagsJson) {
27
+ if (!tagsJson)
28
+ return undefined;
29
+ let tags;
30
+ try {
31
+ tags = JSON.parse(tagsJson) ?? [];
32
+ }
33
+ catch {
34
+ return undefined;
35
+ }
36
+ let instanceId;
37
+ let workflowName;
38
+ let stepId;
39
+ for (const t of tags) {
40
+ if (t.startsWith("instance:"))
41
+ instanceId = t.slice("instance:".length);
42
+ else if (t.startsWith("workflow:"))
43
+ workflowName = t.slice("workflow:".length);
44
+ else if (t.startsWith("step:"))
45
+ stepId = t.slice("step:".length);
46
+ }
47
+ if (!instanceId || !workflowName)
48
+ return undefined;
49
+ return { instanceId, workflowName, ...(stepId ? { stepId } : {}) };
50
+ }
51
+ export class ReviewGatherer {
52
+ db;
53
+ indexer;
54
+ gitRepoPath;
55
+ activityStore;
56
+ now;
57
+ constructor(deps) {
58
+ this.db = deps.db;
59
+ this.indexer = deps.indexer;
60
+ this.gitRepoPath = deps.gitRepoPath ?? null;
61
+ this.activityStore = deps.activityStore ?? null;
62
+ this.now = deps.now ?? (() => new Date().toISOString());
63
+ }
64
+ composeSlice(name) {
65
+ const inputs = this.gatherSlice(name);
66
+ return inputs ? composeSliceReview(inputs) : null;
67
+ }
68
+ /** Composition plus the on-disk context the freeze renderer needs (FR-6). */
69
+ composeSliceWithContext(name) {
70
+ const slice = this.indexer.get(name);
71
+ const inputs = this.gatherSlice(name);
72
+ if (!slice || !inputs)
73
+ return null;
74
+ return { composed: composeSliceReview(inputs), sliceDir: slice.slicePath, mediaRefs: inputs.mediaRefs };
75
+ }
76
+ composeMission(mission) {
77
+ const slices = this.indexer.list().filter((s) => s.missionId === mission);
78
+ if (slices.length === 0 && !this.missionDirExists(mission))
79
+ return null;
80
+ const nowIso = this.now();
81
+ // The ledger's recorded-verdict green rides beside each composed review
82
+ // (FR-7): the gatherer holds the artifacts, so it derives the mission-
83
+ // altitude completion fact the slice contract no longer carries (§11).
84
+ const composed = slices
85
+ .map((s) => {
86
+ const inputs = this.gatherSlice(s.name);
87
+ if (!inputs)
88
+ return null;
89
+ return {
90
+ review: composeSliceReview(inputs),
91
+ green: composeRecordedGreenForSlice(inputs.artifacts).green,
92
+ };
93
+ })
94
+ .filter((s) => s !== null);
95
+ const missionMeta = this.readMissionMeta(mission);
96
+ return composeMissionReview({
97
+ mission: { name: mission, id: missionMeta.id, title: missionMeta.title, intent: missionMeta.intent },
98
+ slices: composed,
99
+ missionAttention: this.attentionForTag(`mission:${mission}`, `slice:`),
100
+ agents: this.agentsForSlices(slices.map((s) => s.name)),
101
+ nowIso,
102
+ });
103
+ }
104
+ /**
105
+ * OPR.0.4.4.22 — the composed rig-agents read root (FR-1..FR-4): NEEDS
106
+ * YOU + AGENTS (health line) + SETTLED at rig scope. Pure projection over
107
+ * queue + hook-activity; nothing contacts an agent. The roster is
108
+ * active-holders UNION recently-holding (transitions-on-scope-TODAY — the
109
+ * plan-review-ruled display window, named in provenance).
110
+ */
111
+ composeRig() {
112
+ const nowIso = this.now();
113
+ const todayStart = `${nowIso.slice(0, 10)}T00:00:00.000Z`;
114
+ const agents = this.withTelemetry(this.rigRoster(todayStart), nowIso);
115
+ const attention = this.attentionAll();
116
+ const overdue = this.overdueWork(nowIso);
117
+ const { settled, handoffsToday } = this.settledToday(todayStart);
118
+ return composeRigAgents({
119
+ agents,
120
+ overdue,
121
+ attention,
122
+ settled,
123
+ handoffsToday,
124
+ overdueCount: overdue.length,
125
+ rosterWindow: "today",
126
+ workflows: this.gatherWorkflowExceptions(nowIso),
127
+ nowIso,
128
+ });
129
+ }
130
+ /** The scope-parameterized agents projection — ONE contract, all consumers. */
131
+ composeAgents(scope) {
132
+ const nowIso = this.now();
133
+ if (scope === "rig") {
134
+ return composeAgentsBand(this.agentsForSlices(null), scope, [], nowIso);
135
+ }
136
+ if (scope.startsWith("slice:")) {
137
+ const name = scope.slice("slice:".length);
138
+ if (!this.indexer.get(name))
139
+ return null;
140
+ return composeAgentsBand(this.agentsForSlices([name]), scope, [], nowIso);
141
+ }
142
+ const mission = scope.slice("mission:".length);
143
+ const slices = this.indexer.list().filter((s) => s.missionId === mission);
144
+ if (slices.length === 0 && !this.missionDirExists(mission))
145
+ return null;
146
+ return composeAgentsBand(this.agentsForSlices(slices.map((s) => s.name)), scope, [], nowIso);
147
+ }
148
+ // -------------------------------------------------------------------------
149
+ gatherSlice(name) {
150
+ const slice = this.indexer.get(name);
151
+ if (!slice)
152
+ return null;
153
+ const readme = this.readFile(path.join(slice.slicePath, "README.md"));
154
+ const prd = this.readFile(path.join(slice.slicePath, "IMPLEMENTATION-PRD.md"));
155
+ const proofMd = this.readFile(path.join(slice.slicePath, "PROOF.md"));
156
+ const artifacts = this.readProofArtifacts(slice.slicePath);
157
+ const attention = this.attentionForTag(`slice:${name}`);
158
+ const agents = this.agentsForSlices([name]);
159
+ const frontmatter = this.parseFrontmatter(readme);
160
+ const approval = this.gatherApproval(slice, frontmatter);
161
+ const candidateRef = deriveCandidateSha(artifacts);
162
+ return {
163
+ slice: {
164
+ name: slice.name,
165
+ id: typeof frontmatter["id"] === "string" ? frontmatter["id"] : null,
166
+ title: slice.displayName,
167
+ missionId: slice.missionId,
168
+ },
169
+ readme,
170
+ prd,
171
+ proofMd,
172
+ artifacts,
173
+ lockedArtifacts: this.parseLockedArtifacts(frontmatter),
174
+ mediaRefs: this.collectMediaRefs([readme, prd, proofMd]),
175
+ proofDirExists: fs.existsSync(path.join(slice.slicePath, "proof")),
176
+ attention,
177
+ agents,
178
+ workflows: this.gatherWorkflowExceptions(this.now()),
179
+ activeQitemPresent: this.hasActiveQitem(name, slice),
180
+ git: this.gatherGitFacts(frontmatter, candidateRef),
181
+ approval,
182
+ nowIso: this.now(),
183
+ };
184
+ }
185
+ /** §3.1's ONLY genuinely new datum: the pinned plan set, a frontmatter READ
186
+ * (`locked-artifacts:` list on the slice README — the scope-fs pattern,
187
+ * zero new file kinds, zero new write machinery). Malformed entries are
188
+ * skipped, never invented. */
189
+ parseLockedArtifacts(fm) {
190
+ const raw = fm["locked-artifacts"];
191
+ if (!Array.isArray(raw))
192
+ return [];
193
+ const out = [];
194
+ for (const entry of raw) {
195
+ if (entry === null || typeof entry !== "object")
196
+ continue;
197
+ const e = entry;
198
+ const p = typeof e["path"] === "string" ? e["path"].trim() : "";
199
+ if (!p)
200
+ continue;
201
+ out.push({
202
+ name: typeof e["name"] === "string" && e["name"].trim() ? e["name"].trim() : p,
203
+ path: p,
204
+ kind: typeof e["kind"] === "string" && e["kind"].trim() ? e["kind"].trim() : "artifact",
205
+ });
206
+ }
207
+ return out;
208
+ }
209
+ readFile(p) {
210
+ try {
211
+ return fs.readFileSync(p, "utf8");
212
+ }
213
+ catch {
214
+ return null;
215
+ }
216
+ }
217
+ missionDirExists(mission) {
218
+ // The indexer knows slices; a slice-less mission still composes (empty board).
219
+ return this.indexer.list().some((s) => s.missionId === mission);
220
+ }
221
+ readMissionMeta(mission) {
222
+ const anySlice = this.indexer.list().find((s) => s.missionId === mission);
223
+ if (anySlice) {
224
+ const missionDir = path.dirname(path.dirname(anySlice.slicePath));
225
+ const readme = this.readFile(path.join(missionDir, "README.md"));
226
+ const fm = this.parseFrontmatter(readme);
227
+ // FR-8: the brief's "What & why" projects VERBATIM as the intent opener.
228
+ const brief = this.readFile(path.join(missionDir, "MISSION_BRIEF.md"));
229
+ return {
230
+ id: typeof fm["id"] === "string" ? fm["id"] : null,
231
+ title: typeof fm["title"] === "string" ? fm["title"] : mission,
232
+ intent: extractSection(brief, "What & why"),
233
+ missionDir,
234
+ };
235
+ }
236
+ return { id: null, title: mission, intent: null, missionDir: null };
237
+ }
238
+ /** FR-8 freeze-moment brief write target: {absolute path, current content}. */
239
+ missionBriefTarget(mission) {
240
+ const meta = this.readMissionMeta(mission);
241
+ if (!meta.missionDir)
242
+ return null;
243
+ const briefPath = path.join(meta.missionDir, "MISSION_BRIEF.md");
244
+ const content = this.readFile(briefPath);
245
+ return content === null ? null : { briefPath, content };
246
+ }
247
+ parseFrontmatter(content) {
248
+ if (!content)
249
+ return {};
250
+ const m = content.match(/^---\n([\s\S]*?)\n---/);
251
+ if (!m)
252
+ return {};
253
+ try {
254
+ return (YAML.parse(m[1]) ?? {});
255
+ }
256
+ catch {
257
+ return {};
258
+ }
259
+ }
260
+ readProofArtifacts(sliceDir) {
261
+ const proofDir = path.join(sliceDir, "proof");
262
+ let entries = [];
263
+ try {
264
+ entries = fs.readdirSync(proofDir).filter((f) => f.endsWith(".md"));
265
+ }
266
+ catch {
267
+ return [];
268
+ }
269
+ return entries
270
+ .sort()
271
+ .map((f) => {
272
+ const full = path.join(proofDir, f);
273
+ try {
274
+ const content = fs.readFileSync(full, "utf8");
275
+ const mtime = fs.statSync(full).mtime.toISOString();
276
+ return parseC1Header(content, `proof/${f}`, mtime);
277
+ }
278
+ catch {
279
+ return null;
280
+ }
281
+ })
282
+ .filter((a) => a !== null);
283
+ }
284
+ /** Markdown image/video refs across the composed sources (FR-5 defect scan). */
285
+ collectMediaRefs(sources) {
286
+ return sources.flatMap((s) => extractMediaRefs(s));
287
+ }
288
+ tableExists(name) {
289
+ try {
290
+ const row = this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(name);
291
+ return row !== undefined;
292
+ }
293
+ catch {
294
+ return false;
295
+ }
296
+ }
297
+ columnExists(table, column) {
298
+ try {
299
+ const rows = this.db.prepare(`PRAGMA table_info(${table})`).all();
300
+ return rows.some((r) => r.name === column);
301
+ }
302
+ catch {
303
+ return false;
304
+ }
305
+ }
306
+ /** Human-routed attention rows carrying the given tag (the §5 predicate is
307
+ * Packet 1's; until it lands, human-tier/human-dest/park-on-human rows are
308
+ * selected with the same shape). */
309
+ /** OPR.0.4.6.WF5 FR-3 — recorded workflow-instance views for the ▲
310
+ * band: failed + in-flight instances, the WF-1 evaluator verdict
311
+ * (consumed, never recomputed — the module import IS the single
312
+ * home), the open exception item by TAG QUERY (never summary
313
+ * parsing), and the non-open-frontier anomaly check. Read-only;
314
+ * absent tables (pre-workflow DBs) return []. */
315
+ gatherWorkflowExceptions(nowIso) {
316
+ try {
317
+ const instances = this.db
318
+ .prepare(`SELECT instance_id, workflow_name, status, current_step_id, current_frontier_json
319
+ FROM workflow_instances WHERE status IN ('failed','active','waiting')`)
320
+ .all();
321
+ const now = new Date(nowIso);
322
+ const out = [];
323
+ for (const row of instances) {
324
+ let frontier = [];
325
+ try {
326
+ frontier = JSON.parse(row.current_frontier_json) ?? [];
327
+ }
328
+ catch {
329
+ frontier = [];
330
+ }
331
+ const packets = frontier.map((id) => this.db
332
+ .prepare(`SELECT qitem_id, state, destination_session, ts_created, claimed_at, closure_required_at
333
+ FROM queue_items WHERE qitem_id = ?`)
334
+ .get(id));
335
+ const frontierRefsNonOpenPacket = (row.status === "active" || row.status === "waiting") &&
336
+ packets.some((p) => p && !["pending", "in-progress", "blocked"].includes(p.state));
337
+ const verdict = evaluateStepDeadline({
338
+ instanceId: row.instance_id,
339
+ status: row.status,
340
+ currentFrontier: frontier,
341
+ currentStepId: row.current_step_id,
342
+ }, packets.map((p) => p
343
+ ? {
344
+ qitemId: p.qitem_id,
345
+ state: p.state,
346
+ destinationSession: p.destination_session,
347
+ tsCreated: p.ts_created,
348
+ claimedAt: p.claimed_at,
349
+ closureRequiredAt: p.closure_required_at,
350
+ }
351
+ : null), now);
352
+ const item = this.db
353
+ .prepare(`SELECT qitem_id, destination_session, tier, ts_created, summary
354
+ FROM queue_items
355
+ WHERE state IN ('pending','in-progress','blocked')
356
+ AND tags LIKE ? AND tags LIKE ?
357
+ ORDER BY ts_created DESC LIMIT 1`)
358
+ .get(`%"instance:${row.instance_id}"%`, `%"workflow-exception"%`);
359
+ out.push({
360
+ instanceId: row.instance_id,
361
+ workflowName: row.workflow_name,
362
+ status: row.status,
363
+ currentStepId: row.current_step_id,
364
+ deadlineState: verdict.state,
365
+ deadlineEvidence: verdict.evidence
366
+ ? `step ${verdict.evidence.stepId ?? "?"} packet ${verdict.evidence.packetId} held by ${verdict.evidence.ownerSession} — ${verdict.evidence.overdueBySeconds}s past the ${verdict.evidence.anchor} anchor`
367
+ : null,
368
+ frontierRefsNonOpenPacket,
369
+ openItem: item
370
+ ? {
371
+ qitemId: item.qitem_id,
372
+ destinationSession: item.destination_session,
373
+ humanRouted: item.tier === "human-gate" || /^human(?:-[A-Za-z0-9._-]+)?@(kernel|host)$/.test(item.destination_session),
374
+ createdAtIso: item.ts_created,
375
+ summary: item.summary,
376
+ }
377
+ : null,
378
+ });
379
+ }
380
+ return out;
381
+ }
382
+ catch (err) {
383
+ // Pre-workflow DBs (no tables) compose byte-identically to
384
+ // pre-WF-5; anything else fails LOUD (the WF-3 narrowed-catch
385
+ // lesson — a broad catch here would silently blind the band).
386
+ if (err instanceof Error && /no such table/i.test(err.message))
387
+ return [];
388
+ throw err;
389
+ }
390
+ }
391
+ attentionForTag(tag, excludeTagPrefix) {
392
+ if (!this.tableExists("queue_items"))
393
+ return [];
394
+ const hasEvidenceRef = this.columnExists("queue_items", "evidence_ref");
395
+ const summaryCol = this.columnExists("queue_items", "summary") ? "summary" : "NULL AS summary";
396
+ const rows = this.db
397
+ .prepare(`SELECT qitem_id, ts_created, ts_updated, destination_session, state, priority, tier, tags, ${summaryCol},
398
+ blocked_on, closure_required_at${hasEvidenceRef ? ", evidence_ref" : ""}
399
+ FROM queue_items
400
+ WHERE state IN (${ACTIVE_STATES.map(() => "?").join(",")})
401
+ AND tags LIKE ?
402
+ AND (tier = 'human-gate'
403
+ OR destination_session LIKE 'human%'
404
+ OR (state = 'blocked' AND blocked_on LIKE 'human%'))`)
405
+ .all(...ACTIVE_STATES, `%"${tag}"%`);
406
+ return rows
407
+ .filter((r) => {
408
+ if (!excludeTagPrefix)
409
+ return true;
410
+ try {
411
+ const tags = JSON.parse(r.tags ?? "[]") ?? [];
412
+ return !tags.some((t) => t.startsWith(excludeTagPrefix));
413
+ }
414
+ catch {
415
+ return true;
416
+ }
417
+ })
418
+ .map((r) => {
419
+ // OPR.0.4.6.WF4 Q6 — stamp the ● workflow pointer from the item's own
420
+ // tags; OMITTED for non-workflow rows (byte-identity-by-omission).
421
+ const workflow = workflowRefFromTags(r.tags);
422
+ return {
423
+ qitemId: r.qitem_id,
424
+ summary: r.summary,
425
+ leg: r.state === "blocked" ? "park-on-human" : "human-routed",
426
+ where: r.destination_session,
427
+ createdAtIso: r.ts_created,
428
+ priority: r.priority,
429
+ tier: r.tier,
430
+ evidenceRef: r.evidence_ref ?? null,
431
+ unblocks: r.state === "blocked" ? r.qitem_id : null,
432
+ destinationSession: r.destination_session,
433
+ closureRequiredAtIso: r.closure_required_at,
434
+ ...(workflow ? { workflow } : {}),
435
+ };
436
+ });
437
+ }
438
+ /** Sessions holding active work on the named slices (null = rig-wide).
439
+ * Region membership derives from work-on-scope, never rig co-residency.
440
+ * Runtime/idle telemetry is honest-unknown at v1 (queue-derived only). */
441
+ agentsForSlices(sliceNames) {
442
+ if (!this.tableExists("queue_items"))
443
+ return [];
444
+ const summaryCol = this.columnExists("queue_items", "summary") ? "summary" : "NULL AS summary";
445
+ const rows = this.db
446
+ .prepare(`SELECT qitem_id, ts_created, ts_updated, destination_session, state, priority, tier, tags, ${summaryCol},
447
+ blocked_on, closure_required_at
448
+ FROM queue_items
449
+ WHERE state IN (${ACTIVE_STATES.map(() => "?").join(",")})`)
450
+ .all(...ACTIVE_STATES);
451
+ const bySession = new Map();
452
+ for (const r of rows) {
453
+ if (isHumanSeatSession(r.destination_session))
454
+ continue;
455
+ let tags = [];
456
+ try {
457
+ tags = JSON.parse(r.tags ?? "[]") ?? [];
458
+ }
459
+ catch {
460
+ tags = [];
461
+ }
462
+ const rowSlices = tags.filter((t) => t.startsWith("slice:")).map((t) => t.slice("slice:".length));
463
+ if (sliceNames !== null && !rowSlices.some((s) => sliceNames.includes(s)))
464
+ continue;
465
+ const entry = bySession.get(r.destination_session) ?? { rows: [], slices: new Set() };
466
+ entry.rows.push(r);
467
+ for (const s of rowSlices)
468
+ entry.slices.add(s);
469
+ bySession.set(r.destination_session, entry);
470
+ }
471
+ return [...bySession.entries()]
472
+ .sort(([a], [b]) => a.localeCompare(b))
473
+ .map(([session, e]) => {
474
+ const latest = e.rows.reduce((acc, r) => (r.ts_updated > acc.ts_updated ? r : acc), e.rows[0]);
475
+ const parked = e.rows
476
+ .filter((r) => !!r.blocked_on)
477
+ .reduce((acc, r) => (!acc || r.ts_updated > acc.ts_updated ? r : acc), null);
478
+ return {
479
+ agentName: sessionMemberLabel(session), // OPR.0.4.6.MH1 FR-8: shared contract
480
+ sessionName: session,
481
+ runtime: "unknown",
482
+ parkedOn: parked?.blocked_on ?? null,
483
+ idle: null, // honest-unknown: queue rows alone cannot prove liveness
484
+ idleSinceIso: null,
485
+ doing: parked?.summary ?? latest.summary,
486
+ holdsCount: e.rows.length,
487
+ lastTransitionIso: (parked ?? latest).ts_updated,
488
+ slices: [...e.slices].sort(),
489
+ };
490
+ });
491
+ }
492
+ // --- OPR.0.4.4.22 rig-scope helpers (all synchronous SQLite reads) ---
493
+ /** FR-1 roster: agents HOLDING active work on any slice-tagged item, UNION
494
+ * agents RECENTLY holding (their slice-tagged items transitioned today —
495
+ * the ruled display window). Membership derives from work-on-scope,
496
+ * never rig co-residency. */
497
+ rigRoster(todayStartIso) {
498
+ const holders = this.agentsForSlices(null);
499
+ if (!this.tableExists("queue_items"))
500
+ return holders;
501
+ const summaryCol = this.columnExists("queue_items", "summary") ? "summary" : "NULL AS summary";
502
+ // Recently-holding: destination of a slice-tagged qitem whose latest
503
+ // update landed today but is no longer in an active state.
504
+ const rows = this.db
505
+ .prepare(`SELECT qitem_id, ts_created, ts_updated, destination_session, state, priority, tier, tags, ${summaryCol},
506
+ blocked_on, closure_required_at
507
+ FROM queue_items
508
+ WHERE ts_updated >= ?
509
+ AND state NOT IN (${ACTIVE_STATES.map(() => "?").join(",")})
510
+ AND tags LIKE '%"slice:%'`)
511
+ .all(todayStartIso, ...ACTIVE_STATES);
512
+ const known = new Set(holders.map((h) => h.sessionName));
513
+ const recent = new Map();
514
+ for (const r of rows) {
515
+ if (isHumanSeatSession(r.destination_session))
516
+ continue;
517
+ if (known.has(r.destination_session))
518
+ continue;
519
+ let tags = [];
520
+ try {
521
+ tags = JSON.parse(r.tags ?? "[]") ?? [];
522
+ }
523
+ catch {
524
+ tags = [];
525
+ }
526
+ const rowSlices = tags.filter((t) => t.startsWith("slice:")).map((t) => t.slice("slice:".length));
527
+ if (rowSlices.length === 0)
528
+ continue;
529
+ const entry = recent.get(r.destination_session) ?? { latest: r, slices: new Set() };
530
+ if (r.ts_updated > entry.latest.ts_updated)
531
+ entry.latest = r;
532
+ for (const s of rowSlices)
533
+ entry.slices.add(s);
534
+ recent.set(r.destination_session, entry);
535
+ }
536
+ const recentInputs = [...recent.entries()]
537
+ .sort(([a], [b]) => a.localeCompare(b))
538
+ .map(([session, e]) => ({
539
+ agentName: sessionMemberLabel(session), // OPR.0.4.6.MH1 FR-8: shared contract
540
+ sessionName: session,
541
+ runtime: "unknown",
542
+ parkedOn: null,
543
+ idle: null,
544
+ idleSinceIso: null,
545
+ // FR-1: an agent with no tracked ACTIVE item renders the truth —
546
+ // itself a coordination signal; nothing is invented.
547
+ doing: "no tracked work item",
548
+ holdsCount: 0,
549
+ lastTransitionIso: e.latest.ts_updated,
550
+ slices: [...e.slices].sort(),
551
+ }));
552
+ return [...holders, ...recentInputs].sort((a, b) => a.sessionName.localeCompare(b.sessionName));
553
+ }
554
+ /** FR-2 telemetry enrichment: runtime from the sessions/nodes tables, the
555
+ * active/idle light from recorded hook activity (AgentActivityStore).
556
+ * Anything unprovable stays honest-unknown — never guessed. */
557
+ withTelemetry(agents, nowIso) {
558
+ const runtimes = this.sessionRuntimes();
559
+ return agents.map((a) => {
560
+ const runtime = runtimes.get(a.sessionName) ?? "unknown";
561
+ let idle = a.idle;
562
+ let idleSinceIso = a.idleSinceIso;
563
+ if (this.activityStore) {
564
+ try {
565
+ const activity = this.activityStore.getLatestForNode({ sessionName: a.sessionName, now: new Date(nowIso) });
566
+ if (activity?.state === "running") {
567
+ idle = false;
568
+ idleSinceIso = null;
569
+ }
570
+ else if (activity?.state === "idle") {
571
+ idle = true;
572
+ idleSinceIso = activity.eventAt ?? activity.sampledAt ?? null;
573
+ }
574
+ // needs_input / unknown / null → stays honest-unknown.
575
+ }
576
+ catch {
577
+ // Telemetry read failure = unknown, never a guess.
578
+ }
579
+ }
580
+ const normalizedRuntime = runtime === "claude-code" || runtime === "codex" || runtime === "terminal" ? runtime : "unknown";
581
+ return { ...a, runtime: normalizedRuntime, idle, idleSinceIso };
582
+ });
583
+ }
584
+ sessionRuntimes() {
585
+ const out = new Map();
586
+ if (!this.tableExists("sessions") || !this.tableExists("nodes"))
587
+ return out;
588
+ try {
589
+ const rows = this.db
590
+ .prepare(`SELECT s.session_name AS session_name, n.runtime AS runtime
591
+ FROM sessions s JOIN nodes n ON n.id = s.node_id
592
+ WHERE s.session_name IS NOT NULL`)
593
+ .all();
594
+ for (const r of rows)
595
+ if (r.runtime)
596
+ out.set(r.session_name, r.runtime);
597
+ }
598
+ catch {
599
+ /* degrade to unknown runtimes */
600
+ }
601
+ return out;
602
+ }
603
+ /** Rig-scope NEEDS YOU: ALL human-routed active items (no tag filter). */
604
+ attentionAll() {
605
+ if (!this.tableExists("queue_items"))
606
+ return [];
607
+ const hasEvidenceRef = this.columnExists("queue_items", "evidence_ref");
608
+ const summaryCol = this.columnExists("queue_items", "summary") ? "summary" : "NULL AS summary";
609
+ const rows = this.db
610
+ .prepare(`SELECT qitem_id, ts_created, ts_updated, destination_session, state, priority, tier, tags, ${summaryCol},
611
+ blocked_on, closure_required_at${hasEvidenceRef ? ", evidence_ref" : ""}
612
+ FROM queue_items
613
+ WHERE state IN (${ACTIVE_STATES.map(() => "?").join(",")})
614
+ AND (tier = 'human-gate'
615
+ OR destination_session LIKE 'human%'
616
+ OR (state = 'blocked' AND blocked_on LIKE 'human%'))`)
617
+ .all(...ACTIVE_STATES);
618
+ return rows.map((r) => {
619
+ // OPR.0.4.6.WF4 Q6 — stamp the ● workflow pointer from the item's own
620
+ // tags; OMITTED for non-workflow rows (byte-identity-by-omission).
621
+ const workflow = workflowRefFromTags(r.tags);
622
+ return {
623
+ qitemId: r.qitem_id,
624
+ summary: r.summary,
625
+ leg: r.state === "blocked" ? "park-on-human" : "human-routed",
626
+ where: r.destination_session,
627
+ createdAtIso: r.ts_created,
628
+ priority: r.priority,
629
+ tier: r.tier,
630
+ evidenceRef: r.evidence_ref ?? null,
631
+ unblocks: r.state === "blocked" ? r.qitem_id : null,
632
+ destinationSession: r.destination_session,
633
+ closureRequiredAtIso: r.closure_required_at,
634
+ ...(workflow ? { workflow } : {}),
635
+ };
636
+ });
637
+ }
638
+ /** FR-4: today's closed handoffs from the transitions log — the SETTLED
639
+ * band and the health line's handoff count come from the SAME query
640
+ * (two renders, one computation). */
641
+ settledToday(todayStartIso) {
642
+ if (!this.tableExists("queue_transitions"))
643
+ return { settled: [], handoffsToday: 0 };
644
+ const summaryJoin = this.tableExists("queue_items") && this.columnExists("queue_items", "summary")
645
+ ? "LEFT JOIN queue_items q ON q.qitem_id = t.qitem_id"
646
+ : null;
647
+ try {
648
+ const rows = this.db
649
+ .prepare(`SELECT t.qitem_id AS qitem_id, t.ts AS ts, t.actor_session AS actor_session,
650
+ t.closure_target AS closure_target${summaryJoin ? ", q.summary AS summary" : ", NULL AS summary"}
651
+ FROM queue_transitions t
652
+ ${summaryJoin ?? ""}
653
+ WHERE t.closure_reason = 'handed_off_to' AND t.ts >= ?
654
+ ORDER BY t.ts DESC`)
655
+ .all(todayStartIso);
656
+ const settled = rows.map((r) => ({
657
+ fromSession: r.actor_session,
658
+ toSession: r.closure_target ?? "unknown",
659
+ summary: r.summary,
660
+ closedAtIso: r.ts,
661
+ qitemId: r.qitem_id,
662
+ }));
663
+ return { settled, handoffsToday: settled.length };
664
+ }
665
+ catch {
666
+ return { settled: [], handoffsToday: 0 };
667
+ }
668
+ }
669
+ /** FR-3/FR-4: in-progress slice work past closure_required_at, rig-wide.
670
+ * Feeds both the derived NEEDS YOU exception and the health count. */
671
+ overdueWork(nowIso) {
672
+ if (!this.tableExists("queue_items"))
673
+ return [];
674
+ try {
675
+ const summaryCol = this.columnExists("queue_items", "summary") ? "summary" : "NULL AS summary";
676
+ const rows = this.db
677
+ .prepare(`SELECT qitem_id, ts_created, ts_updated, destination_session, state, priority, tier, tags, ${summaryCol},
678
+ blocked_on, closure_required_at
679
+ FROM queue_items
680
+ WHERE state = 'in-progress'
681
+ AND closure_required_at IS NOT NULL
682
+ AND closure_required_at < ?
683
+ AND tags LIKE '%"slice:%'`)
684
+ .all(nowIso);
685
+ return rows.map((r) => {
686
+ // OPR.0.4.6.WF4 Q6 — stamp the ● workflow pointer from the item's own
687
+ // tags; OMITTED for non-workflow rows (byte-identity-by-omission).
688
+ const workflow = workflowRefFromTags(r.tags);
689
+ return {
690
+ qitemId: r.qitem_id,
691
+ summary: r.summary,
692
+ leg: "overdue",
693
+ where: r.destination_session,
694
+ createdAtIso: r.ts_created,
695
+ priority: r.priority,
696
+ tier: r.tier,
697
+ evidenceRef: null,
698
+ unblocks: null,
699
+ destinationSession: r.destination_session,
700
+ closureRequiredAtIso: r.closure_required_at,
701
+ ...(workflow ? { workflow } : {}),
702
+ };
703
+ });
704
+ }
705
+ catch {
706
+ return [];
707
+ }
708
+ }
709
+ hasActiveQitem(name, slice) {
710
+ if (!this.tableExists("queue_items"))
711
+ return false;
712
+ const row = this.db
713
+ .prepare(`SELECT 1 FROM queue_items WHERE state IN (${ACTIVE_STATES.map(() => "?").join(",")}) AND tags LIKE ? LIMIT 1`)
714
+ .get(...ACTIVE_STATES, `%"slice:${name}"%`);
715
+ if (row)
716
+ return true;
717
+ if (slice.qitemIds.length === 0)
718
+ return false;
719
+ const placeholders = slice.qitemIds.map(() => "?").join(",");
720
+ try {
721
+ return this.db
722
+ .prepare(`SELECT 1 FROM queue_items
723
+ WHERE qitem_id IN (${placeholders})
724
+ AND state IN (${ACTIVE_STATES.map(() => "?").join(",")})
725
+ LIMIT 1`)
726
+ .get(...slice.qitemIds, ...ACTIVE_STATES) !== undefined;
727
+ }
728
+ catch {
729
+ return false;
730
+ }
731
+ }
732
+ /** §4 — the two staged-approval stamps (arch F-A: the SHIPPED verb's
733
+ * frontmatter fields), each cross-checked against the pinned
734
+ * scope-approval audit shape (`approval_scope` inside audit_notes_json).
735
+ * A stamp with no matching row -> auditVerified false (UNVERIFIED stamp,
736
+ * rendered loudly — never a block). */
737
+ gatherApproval(slice, fm) {
738
+ const str = (k) => {
739
+ const v = fm[k];
740
+ if (typeof v === "string" && v.trim())
741
+ return v.trim();
742
+ if (v instanceof Date)
743
+ return v.toISOString();
744
+ return null;
745
+ };
746
+ const sliceId = str("id");
747
+ const auditRowPresent = (approvalScope) => {
748
+ if (!this.tableExists("mission_control_actions"))
749
+ return false;
750
+ try {
751
+ return (this.db
752
+ .prepare(`SELECT 1 FROM mission_control_actions
753
+ WHERE action_verb='approve'
754
+ AND audit_notes_json LIKE ?
755
+ AND (audit_notes_json LIKE ? OR audit_notes_json LIKE ?)
756
+ LIMIT 1`)
757
+ .get(`%"approval_scope":"${approvalScope}"%`,
758
+ // A null slice id must never match an empty scope_id row.
759
+ sliceId ? `%"scope_id":"${sliceId}"%` : `%"scope_id":"${slice.name}"%`, `%${slice.name}%`) !== undefined);
760
+ }
761
+ catch {
762
+ return false;
763
+ }
764
+ };
765
+ const stamp = (byKey, atKey, approvalScope) => {
766
+ const by = str(byKey);
767
+ const at = str(atKey);
768
+ if (!by || !at)
769
+ return null;
770
+ return { by, at, auditRowPresent: auditRowPresent(approvalScope) };
771
+ };
772
+ return {
773
+ spec: stamp("approved-spec-by", "approved-spec-at", "spec"),
774
+ delivery: stamp("approved-by", "approved-at", "delivery"),
775
+ };
776
+ }
777
+ git(args) {
778
+ if (!this.gitRepoPath)
779
+ return null;
780
+ try {
781
+ return execFileSync("git", args, { cwd: this.gitRepoPath, timeout: 4000, encoding: "utf8" }).trim();
782
+ }
783
+ catch {
784
+ return null;
785
+ }
786
+ }
787
+ gatherGitFacts(fm, candidateSha) {
788
+ const mainTip = this.git(["rev-parse", "--short", "HEAD"]) ?? "unknown";
789
+ const sliceId = typeof fm["id"] === "string" ? fm["id"] : null;
790
+ let mergeSha = null;
791
+ if (sliceId) {
792
+ const found = this.git(["log", "--fixed-strings", `--grep=Merge ${sliceId}`, "--format=%h", "-1"]);
793
+ mergeSha = found && found.length > 0 ? found : null;
794
+ }
795
+ let mergeIsAncestorOfTip = null;
796
+ if (mergeSha) {
797
+ const out = this.git(["merge-base", "--is-ancestor", mergeSha, "HEAD"]);
798
+ // exec throws (returns null) on non-ancestor exit 1; success returns "".
799
+ mergeIsAncestorOfTip = out !== null;
800
+ }
801
+ let candidateBehindTip = null;
802
+ if (!mergeSha && candidateSha) {
803
+ const base = this.git(["merge-base", candidateSha, "HEAD"]);
804
+ if (base) {
805
+ const count = this.git(["rev-list", "--count", `${base}..HEAD`]);
806
+ candidateBehindTip = count !== null && /^\d+$/.test(count) ? Number(count) : null;
807
+ }
808
+ }
809
+ return { mainTip, mergeSha, mergeIsAncestorOfTip, candidateBehindTip };
810
+ }
811
+ }
812
+ //# sourceMappingURL=gather.js.map