@openrig/cli 0.3.1 → 0.3.3-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. package/daemon/assets/plugins/openrig-core/skills/forming-an-openrig-mental-model/SKILL.md +1 -1
  2. package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +8 -8
  3. package/daemon/dist/adapters/cmux-transport.d.ts.map +1 -1
  4. package/daemon/dist/adapters/cmux-transport.js +51 -9
  5. package/daemon/dist/adapters/cmux-transport.js.map +1 -1
  6. package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
  7. package/daemon/dist/adapters/codex-runtime-adapter.js +34 -5
  8. package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
  9. package/daemon/dist/adapters/tmux.d.ts +68 -1
  10. package/daemon/dist/adapters/tmux.d.ts.map +1 -1
  11. package/daemon/dist/adapters/tmux.js +141 -2
  12. package/daemon/dist/adapters/tmux.js.map +1 -1
  13. package/daemon/dist/db/migrations/037_mission_control_actions.d.ts +5 -1
  14. package/daemon/dist/db/migrations/037_mission_control_actions.d.ts.map +1 -1
  15. package/daemon/dist/db/migrations/037_mission_control_actions.js +5 -1
  16. package/daemon/dist/db/migrations/037_mission_control_actions.js.map +1 -1
  17. package/daemon/dist/db/migrations/041_rig_policy.d.ts +32 -0
  18. package/daemon/dist/db/migrations/041_rig_policy.d.ts.map +1 -0
  19. package/daemon/dist/db/migrations/041_rig_policy.js +47 -0
  20. package/daemon/dist/db/migrations/041_rig_policy.js.map +1 -0
  21. package/daemon/dist/db/migrations/042_rig_archive.d.ts +16 -0
  22. package/daemon/dist/db/migrations/042_rig_archive.d.ts.map +1 -0
  23. package/daemon/dist/db/migrations/042_rig_archive.js +21 -0
  24. package/daemon/dist/db/migrations/042_rig_archive.js.map +1 -0
  25. package/daemon/dist/domain/agent-images/resume-token-discovery.js +1 -1
  26. package/daemon/dist/domain/agent-images/resume-token-discovery.js.map +1 -1
  27. package/daemon/dist/domain/agent-images/snapshot-capturer.d.ts.map +1 -1
  28. package/daemon/dist/domain/agent-images/snapshot-capturer.js +2 -1
  29. package/daemon/dist/domain/agent-images/snapshot-capturer.js.map +1 -1
  30. package/daemon/dist/domain/agent-manifest.js +27 -0
  31. package/daemon/dist/domain/agent-manifest.js.map +1 -1
  32. package/daemon/dist/domain/bootstrap-orchestrator.d.ts.map +1 -1
  33. package/daemon/dist/domain/bootstrap-orchestrator.js +86 -6
  34. package/daemon/dist/domain/bootstrap-orchestrator.js.map +1 -1
  35. package/daemon/dist/domain/bundle-agent-images-router.d.ts +95 -0
  36. package/daemon/dist/domain/bundle-agent-images-router.d.ts.map +1 -0
  37. package/daemon/dist/domain/bundle-agent-images-router.js +140 -0
  38. package/daemon/dist/domain/bundle-agent-images-router.js.map +1 -0
  39. package/daemon/dist/domain/bundle-assembler.d.ts +18 -1
  40. package/daemon/dist/domain/bundle-assembler.d.ts.map +1 -1
  41. package/daemon/dist/domain/bundle-assembler.js +11 -1
  42. package/daemon/dist/domain/bundle-assembler.js.map +1 -1
  43. package/daemon/dist/domain/bundle-audit.d.ts +89 -0
  44. package/daemon/dist/domain/bundle-audit.d.ts.map +1 -0
  45. package/daemon/dist/domain/bundle-audit.js +87 -0
  46. package/daemon/dist/domain/bundle-audit.js.map +1 -0
  47. package/daemon/dist/domain/bundle-conflict-detector.d.ts +57 -0
  48. package/daemon/dist/domain/bundle-conflict-detector.d.ts.map +1 -0
  49. package/daemon/dist/domain/bundle-conflict-detector.js +49 -0
  50. package/daemon/dist/domain/bundle-conflict-detector.js.map +1 -0
  51. package/daemon/dist/domain/bundle-context-packs-router.d.ts +100 -0
  52. package/daemon/dist/domain/bundle-context-packs-router.d.ts.map +1 -0
  53. package/daemon/dist/domain/bundle-context-packs-router.js +158 -0
  54. package/daemon/dist/domain/bundle-context-packs-router.js.map +1 -0
  55. package/daemon/dist/domain/bundle-plugins-router.d.ts +69 -0
  56. package/daemon/dist/domain/bundle-plugins-router.d.ts.map +1 -0
  57. package/daemon/dist/domain/bundle-plugins-router.js +87 -0
  58. package/daemon/dist/domain/bundle-plugins-router.js.map +1 -0
  59. package/daemon/dist/domain/bundle-skills-router.d.ts +62 -0
  60. package/daemon/dist/domain/bundle-skills-router.d.ts.map +1 -0
  61. package/daemon/dist/domain/bundle-skills-router.js +90 -0
  62. package/daemon/dist/domain/bundle-skills-router.js.map +1 -0
  63. package/daemon/dist/domain/bundle-types.d.ts +106 -0
  64. package/daemon/dist/domain/bundle-types.d.ts.map +1 -1
  65. package/daemon/dist/domain/bundle-types.js +375 -0
  66. package/daemon/dist/domain/bundle-types.js.map +1 -1
  67. package/daemon/dist/domain/bundle-workflow-specs-router.d.ts +94 -0
  68. package/daemon/dist/domain/bundle-workflow-specs-router.d.ts.map +1 -0
  69. package/daemon/dist/domain/bundle-workflow-specs-router.js +144 -0
  70. package/daemon/dist/domain/bundle-workflow-specs-router.js.map +1 -0
  71. package/daemon/dist/domain/context-monitor.d.ts +5 -1
  72. package/daemon/dist/domain/context-monitor.d.ts.map +1 -1
  73. package/daemon/dist/domain/context-monitor.js +28 -15
  74. package/daemon/dist/domain/context-monitor.js.map +1 -1
  75. package/daemon/dist/domain/graph-projection.d.ts +6 -0
  76. package/daemon/dist/domain/graph-projection.d.ts.map +1 -1
  77. package/daemon/dist/domain/graph-projection.js +6 -0
  78. package/daemon/dist/domain/graph-projection.js.map +1 -1
  79. package/daemon/dist/domain/native-resume-probe.js +7 -7
  80. package/daemon/dist/domain/native-resume-probe.js.map +1 -1
  81. package/daemon/dist/domain/node-inventory.d.ts +18 -0
  82. package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
  83. package/daemon/dist/domain/node-inventory.js +98 -0
  84. package/daemon/dist/domain/node-inventory.js.map +1 -1
  85. package/daemon/dist/domain/node-launcher.d.ts +12 -0
  86. package/daemon/dist/domain/node-launcher.d.ts.map +1 -1
  87. package/daemon/dist/domain/node-launcher.js +25 -1
  88. package/daemon/dist/domain/node-launcher.js.map +1 -1
  89. package/daemon/dist/domain/pod-bundle-assembler.d.ts +16 -1
  90. package/daemon/dist/domain/pod-bundle-assembler.d.ts.map +1 -1
  91. package/daemon/dist/domain/pod-bundle-assembler.js +11 -1
  92. package/daemon/dist/domain/pod-bundle-assembler.js.map +1 -1
  93. package/daemon/dist/domain/profile-resolver.d.ts +10 -0
  94. package/daemon/dist/domain/profile-resolver.d.ts.map +1 -1
  95. package/daemon/dist/domain/profile-resolver.js +4 -0
  96. package/daemon/dist/domain/profile-resolver.js.map +1 -1
  97. package/daemon/dist/domain/ps-projection.d.ts +28 -1
  98. package/daemon/dist/domain/ps-projection.d.ts.map +1 -1
  99. package/daemon/dist/domain/ps-projection.js +67 -1
  100. package/daemon/dist/domain/ps-projection.js.map +1 -1
  101. package/daemon/dist/domain/queue-repository.d.ts +37 -1
  102. package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  103. package/daemon/dist/domain/queue-repository.js +99 -2
  104. package/daemon/dist/domain/queue-repository.js.map +1 -1
  105. package/daemon/dist/domain/restore-check-service.d.ts +4 -0
  106. package/daemon/dist/domain/restore-check-service.d.ts.map +1 -1
  107. package/daemon/dist/domain/restore-check-service.js +16 -7
  108. package/daemon/dist/domain/restore-check-service.js.map +1 -1
  109. package/daemon/dist/domain/rig-expansion-service.d.ts +1 -1
  110. package/daemon/dist/domain/rig-expansion-service.d.ts.map +1 -1
  111. package/daemon/dist/domain/rig-expansion-service.js +12 -10
  112. package/daemon/dist/domain/rig-expansion-service.js.map +1 -1
  113. package/daemon/dist/domain/rig-policy/rig-policy-defaults.d.ts +48 -0
  114. package/daemon/dist/domain/rig-policy/rig-policy-defaults.d.ts.map +1 -0
  115. package/daemon/dist/domain/rig-policy/rig-policy-defaults.js +96 -0
  116. package/daemon/dist/domain/rig-policy/rig-policy-defaults.js.map +1 -0
  117. package/daemon/dist/domain/rig-policy/rig-policy-store.d.ts +46 -0
  118. package/daemon/dist/domain/rig-policy/rig-policy-store.d.ts.map +1 -0
  119. package/daemon/dist/domain/rig-policy/rig-policy-store.js +171 -0
  120. package/daemon/dist/domain/rig-policy/rig-policy-store.js.map +1 -0
  121. package/daemon/dist/domain/rig-policy/rig-policy-types.d.ts +145 -0
  122. package/daemon/dist/domain/rig-policy/rig-policy-types.d.ts.map +1 -0
  123. package/daemon/dist/domain/rig-policy/rig-policy-types.js +52 -0
  124. package/daemon/dist/domain/rig-policy/rig-policy-types.js.map +1 -0
  125. package/daemon/dist/domain/rig-policy/rig-policy-validator.d.ts +58 -0
  126. package/daemon/dist/domain/rig-policy/rig-policy-validator.d.ts.map +1 -0
  127. package/daemon/dist/domain/rig-policy/rig-policy-validator.js +211 -0
  128. package/daemon/dist/domain/rig-policy/rig-policy-validator.js.map +1 -0
  129. package/daemon/dist/domain/rig-repository.d.ts +28 -2
  130. package/daemon/dist/domain/rig-repository.d.ts.map +1 -1
  131. package/daemon/dist/domain/rig-repository.js +40 -3
  132. package/daemon/dist/domain/rig-repository.js.map +1 -1
  133. package/daemon/dist/domain/rigspec-instantiator.d.ts +177 -1
  134. package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
  135. package/daemon/dist/domain/rigspec-instantiator.js +414 -55
  136. package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
  137. package/daemon/dist/domain/rigspec-preflight.d.ts +19 -1
  138. package/daemon/dist/domain/rigspec-preflight.d.ts.map +1 -1
  139. package/daemon/dist/domain/rigspec-preflight.js +30 -12
  140. package/daemon/dist/domain/rigspec-preflight.js.map +1 -1
  141. package/daemon/dist/domain/rigspec-schema.d.ts +1 -0
  142. package/daemon/dist/domain/rigspec-schema.d.ts.map +1 -1
  143. package/daemon/dist/domain/rigspec-schema.js +4 -1
  144. package/daemon/dist/domain/rigspec-schema.js.map +1 -1
  145. package/daemon/dist/domain/seat-activity-service.d.ts +79 -0
  146. package/daemon/dist/domain/seat-activity-service.d.ts.map +1 -0
  147. package/daemon/dist/domain/seat-activity-service.js +123 -0
  148. package/daemon/dist/domain/seat-activity-service.js.map +1 -0
  149. package/daemon/dist/domain/session-transport.d.ts +15 -0
  150. package/daemon/dist/domain/session-transport.d.ts.map +1 -1
  151. package/daemon/dist/domain/session-transport.js +8 -3
  152. package/daemon/dist/domain/session-transport.js.map +1 -1
  153. package/daemon/dist/domain/slices/slice-indexer.d.ts +12 -0
  154. package/daemon/dist/domain/slices/slice-indexer.d.ts.map +1 -1
  155. package/daemon/dist/domain/slices/slice-indexer.js +23 -0
  156. package/daemon/dist/domain/slices/slice-indexer.js.map +1 -1
  157. package/daemon/dist/domain/spec-library-service.d.ts.map +1 -1
  158. package/daemon/dist/domain/spec-library-service.js +19 -0
  159. package/daemon/dist/domain/spec-library-service.js.map +1 -1
  160. package/daemon/dist/domain/topology-converge.d.ts +97 -0
  161. package/daemon/dist/domain/topology-converge.d.ts.map +1 -0
  162. package/daemon/dist/domain/topology-converge.js +70 -0
  163. package/daemon/dist/domain/topology-converge.js.map +1 -0
  164. package/daemon/dist/domain/types.d.ts +85 -3
  165. package/daemon/dist/domain/types.d.ts.map +1 -1
  166. package/daemon/dist/domain/types.js.map +1 -1
  167. package/daemon/dist/domain/whoami-service.d.ts +8 -0
  168. package/daemon/dist/domain/whoami-service.d.ts.map +1 -1
  169. package/daemon/dist/domain/whoami-service.js +1 -0
  170. package/daemon/dist/domain/whoami-service.js.map +1 -1
  171. package/daemon/dist/domain/workflow-runtime.d.ts.map +1 -1
  172. package/daemon/dist/domain/workflow-runtime.js +9 -1
  173. package/daemon/dist/domain/workflow-runtime.js.map +1 -1
  174. package/daemon/dist/domain/workflow-spec-cache.d.ts +41 -0
  175. package/daemon/dist/domain/workflow-spec-cache.d.ts.map +1 -1
  176. package/daemon/dist/domain/workflow-spec-cache.js +63 -0
  177. package/daemon/dist/domain/workflow-spec-cache.js.map +1 -1
  178. package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts +7 -0
  179. package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts.map +1 -1
  180. package/daemon/dist/domain/workspace/default-workspace-scaffold.js +156 -3
  181. package/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
  182. package/daemon/dist/domain/workspace/workspace-doctor.d.ts +197 -0
  183. package/daemon/dist/domain/workspace/workspace-doctor.d.ts.map +1 -0
  184. package/daemon/dist/domain/workspace/workspace-doctor.js +448 -0
  185. package/daemon/dist/domain/workspace/workspace-doctor.js.map +1 -0
  186. package/daemon/dist/index.d.ts.map +1 -1
  187. package/daemon/dist/index.js +11 -0
  188. package/daemon/dist/index.js.map +1 -1
  189. package/daemon/dist/routes/bundles.d.ts.map +1 -1
  190. package/daemon/dist/routes/bundles.js +966 -7
  191. package/daemon/dist/routes/bundles.js.map +1 -1
  192. package/daemon/dist/routes/config.d.ts.map +1 -1
  193. package/daemon/dist/routes/config.js +19 -2
  194. package/daemon/dist/routes/config.js.map +1 -1
  195. package/daemon/dist/routes/info.d.ts +3 -0
  196. package/daemon/dist/routes/info.d.ts.map +1 -0
  197. package/daemon/dist/routes/info.js +20 -0
  198. package/daemon/dist/routes/info.js.map +1 -0
  199. package/daemon/dist/routes/ps.js +4 -1
  200. package/daemon/dist/routes/ps.js.map +1 -1
  201. package/daemon/dist/routes/queue.d.ts +18 -0
  202. package/daemon/dist/routes/queue.d.ts.map +1 -1
  203. package/daemon/dist/routes/queue.js +97 -5
  204. package/daemon/dist/routes/queue.js.map +1 -1
  205. package/daemon/dist/routes/rig-policy.d.ts +9 -0
  206. package/daemon/dist/routes/rig-policy.d.ts.map +1 -0
  207. package/daemon/dist/routes/rig-policy.js +174 -0
  208. package/daemon/dist/routes/rig-policy.js.map +1 -0
  209. package/daemon/dist/routes/rigs.d.ts.map +1 -1
  210. package/daemon/dist/routes/rigs.js +134 -4
  211. package/daemon/dist/routes/rigs.js.map +1 -1
  212. package/daemon/dist/routes/sessions.d.ts.map +1 -1
  213. package/daemon/dist/routes/sessions.js +26 -3
  214. package/daemon/dist/routes/sessions.js.map +1 -1
  215. package/daemon/dist/routes/up.d.ts +25 -0
  216. package/daemon/dist/routes/up.d.ts.map +1 -1
  217. package/daemon/dist/routes/up.js +70 -3
  218. package/daemon/dist/routes/up.js.map +1 -1
  219. package/daemon/dist/routes/workspace.d.ts.map +1 -1
  220. package/daemon/dist/routes/workspace.js +80 -1
  221. package/daemon/dist/routes/workspace.js.map +1 -1
  222. package/daemon/dist/server.d.ts +10 -0
  223. package/daemon/dist/server.d.ts.map +1 -1
  224. package/daemon/dist/server.js +11 -0
  225. package/daemon/dist/server.js.map +1 -1
  226. package/daemon/dist/startup.d.ts.map +1 -1
  227. package/daemon/dist/startup.js +46 -4
  228. package/daemon/dist/startup.js.map +1 -1
  229. package/daemon/docs/reference/getting-started.md +69 -0
  230. package/daemon/specs/agents/orchestration/orchestrator/guidance/role.md +28 -4
  231. package/daemon/specs/agents/shared/skills/core/openrig-user/SKILL.md +361 -15
  232. package/daemon/specs/agents/shared/skills/core/rig-lifecycle/SKILL.md +2 -2
  233. package/daemon/specs/rigs/launch/conveyor/rig.yaml +1 -1
  234. package/dist/client.d.ts +3 -0
  235. package/dist/client.d.ts.map +1 -1
  236. package/dist/client.js +13 -1
  237. package/dist/client.js.map +1 -1
  238. package/dist/commands/add.d.ts +4 -0
  239. package/dist/commands/add.d.ts.map +1 -0
  240. package/dist/commands/add.js +115 -0
  241. package/dist/commands/add.js.map +1 -0
  242. package/dist/commands/archive.d.ts +10 -0
  243. package/dist/commands/archive.d.ts.map +1 -0
  244. package/dist/commands/archive.js +68 -0
  245. package/dist/commands/archive.js.map +1 -0
  246. package/dist/commands/bootstrap.js +2 -2
  247. package/dist/commands/bootstrap.js.map +1 -1
  248. package/dist/commands/bundle.d.ts.map +1 -1
  249. package/dist/commands/bundle.js +123 -2
  250. package/dist/commands/bundle.js.map +1 -1
  251. package/dist/commands/config-init-workspace.d.ts.map +1 -1
  252. package/dist/commands/config-init-workspace.js +40 -5
  253. package/dist/commands/config-init-workspace.js.map +1 -1
  254. package/dist/commands/discover.js +2 -2
  255. package/dist/commands/discover.js.map +1 -1
  256. package/dist/commands/down.d.ts +1 -1
  257. package/dist/commands/down.d.ts.map +1 -1
  258. package/dist/commands/down.js +91 -3
  259. package/dist/commands/down.js.map +1 -1
  260. package/dist/commands/ps.d.ts.map +1 -1
  261. package/dist/commands/ps.js +72 -10
  262. package/dist/commands/ps.js.map +1 -1
  263. package/dist/commands/queue.d.ts +6 -0
  264. package/dist/commands/queue.d.ts.map +1 -1
  265. package/dist/commands/queue.js +103 -5
  266. package/dist/commands/queue.js.map +1 -1
  267. package/dist/commands/rig-policy.d.ts +48 -0
  268. package/dist/commands/rig-policy.d.ts.map +1 -0
  269. package/dist/commands/rig-policy.js +429 -0
  270. package/dist/commands/rig-policy.js.map +1 -0
  271. package/dist/commands/scope.d.ts +6 -0
  272. package/dist/commands/scope.d.ts.map +1 -0
  273. package/dist/commands/scope.js +659 -0
  274. package/dist/commands/scope.js.map +1 -0
  275. package/dist/commands/send.d.ts.map +1 -1
  276. package/dist/commands/send.js +11 -0
  277. package/dist/commands/send.js.map +1 -1
  278. package/dist/commands/setup.d.ts +7 -0
  279. package/dist/commands/setup.d.ts.map +1 -1
  280. package/dist/commands/setup.js +28 -1
  281. package/dist/commands/setup.js.map +1 -1
  282. package/dist/commands/status.d.ts.map +1 -1
  283. package/dist/commands/status.js +35 -2
  284. package/dist/commands/status.js.map +1 -1
  285. package/dist/commands/unarchive.d.ts +10 -0
  286. package/dist/commands/unarchive.d.ts.map +1 -0
  287. package/dist/commands/unarchive.js +53 -0
  288. package/dist/commands/unarchive.js.map +1 -0
  289. package/dist/commands/up.d.ts.map +1 -1
  290. package/dist/commands/up.js +97 -0
  291. package/dist/commands/up.js.map +1 -1
  292. package/dist/commands/whoami.d.ts.map +1 -1
  293. package/dist/commands/whoami.js +4 -1
  294. package/dist/commands/whoami.js.map +1 -1
  295. package/dist/commands/workflow.d.ts +9 -0
  296. package/dist/commands/workflow.d.ts.map +1 -1
  297. package/dist/commands/workflow.js +141 -4
  298. package/dist/commands/workflow.js.map +1 -1
  299. package/dist/commands/workspace.d.ts +20 -0
  300. package/dist/commands/workspace.d.ts.map +1 -1
  301. package/dist/commands/workspace.js +140 -10
  302. package/dist/commands/workspace.js.map +1 -1
  303. package/dist/daemon-lifecycle.d.ts +48 -1
  304. package/dist/daemon-lifecycle.d.ts.map +1 -1
  305. package/dist/daemon-lifecycle.js +57 -2
  306. package/dist/daemon-lifecycle.js.map +1 -1
  307. package/dist/index.d.ts +5 -0
  308. package/dist/index.d.ts.map +1 -1
  309. package/dist/index.js +12 -0
  310. package/dist/index.js.map +1 -1
  311. package/dist/lib/scope/dot-id.d.ts +43 -0
  312. package/dist/lib/scope/dot-id.d.ts.map +1 -0
  313. package/dist/lib/scope/dot-id.js +165 -0
  314. package/dist/lib/scope/dot-id.js.map +1 -0
  315. package/dist/lib/scope/scope-fs.d.ts +79 -0
  316. package/dist/lib/scope/scope-fs.d.ts.map +1 -0
  317. package/dist/lib/scope/scope-fs.js +468 -0
  318. package/dist/lib/scope/scope-fs.js.map +1 -0
  319. package/dist/lib/scope/templates.d.ts +38 -0
  320. package/dist/lib/scope/templates.d.ts.map +1 -0
  321. package/dist/lib/scope/templates.js +109 -0
  322. package/dist/lib/scope/templates.js.map +1 -0
  323. package/dist/lib/scope/types.d.ts +61 -0
  324. package/dist/lib/scope/types.d.ts.map +1 -0
  325. package/dist/lib/scope/types.js +38 -0
  326. package/dist/lib/scope/types.js.map +1 -0
  327. package/dist/lib/scope-templates/backlog-deprecation.md +26 -0
  328. package/dist/lib/scope-templates/backlog-tech-debt.md +22 -0
  329. package/dist/lib/scope-templates/bug-fix.md +30 -0
  330. package/dist/lib/scope-templates/mission-notes.md +97 -0
  331. package/dist/lib/scope-templates/mission-placeholder.md +20 -0
  332. package/dist/lib/scope-templates/mission-release.md +25 -0
  333. package/dist/lib/scope-templates/placeholder.md +30 -0
  334. package/dist/lib/scope-templates/release-feature.md +26 -0
  335. package/dist/lib/scope-templates/research.md +22 -0
  336. package/dist/mcp-server.d.ts.map +1 -1
  337. package/dist/mcp-server.js +29 -0
  338. package/dist/mcp-server.js.map +1 -1
  339. package/dist/release-surface/affected-skills.d.ts +49 -0
  340. package/dist/release-surface/affected-skills.d.ts.map +1 -0
  341. package/dist/release-surface/affected-skills.js +153 -0
  342. package/dist/release-surface/affected-skills.js.map +1 -0
  343. package/dist/release-surface/extract-surface.d.ts +23 -0
  344. package/dist/release-surface/extract-surface.d.ts.map +1 -0
  345. package/dist/release-surface/extract-surface.js +193 -0
  346. package/dist/release-surface/extract-surface.js.map +1 -0
  347. package/dist/release-surface/generate.d.ts +2 -0
  348. package/dist/release-surface/generate.d.ts.map +1 -0
  349. package/dist/release-surface/generate.js +51 -0
  350. package/dist/release-surface/generate.js.map +1 -0
  351. package/dist/release-surface/surface-diff.d.ts +40 -0
  352. package/dist/release-surface/surface-diff.d.ts.map +1 -0
  353. package/dist/release-surface/surface-diff.js +212 -0
  354. package/dist/release-surface/surface-diff.js.map +1 -0
  355. package/package.json +2 -2
  356. package/ui/dist/assets/index-CrJgCmkX.js +552 -0
  357. package/ui/dist/index.html +1 -1
  358. package/ui/dist/assets/index-Rl3ZBrUg.js +0 -547
@@ -240,8 +240,8 @@ export class RigInstantiator {
240
240
  }
241
241
  // -- Pod-aware instantiator (AgentSpec reboot) --
242
242
  import { RigSpecCodec as PodRigSpecCodec } from "./rigspec-codec.js";
243
- import { RigSpecSchema as PodRigSpecSchema } from "./rigspec-schema.js";
244
- import { rigPreflight } from "./rigspec-preflight.js";
243
+ import { RigSpecSchema as PodRigSpecSchema, VALID_EDGE_KINDS } from "./rigspec-schema.js";
244
+ import { rigPreflight, preflightValidatedSpec } from "./rigspec-preflight.js";
245
245
  import { resolveAgentRef } from "./agent-resolver.js";
246
246
  import { resolveNodeConfig } from "./profile-resolver.js";
247
247
  import { resolveStartup } from "./startup-resolver.js";
@@ -296,6 +296,57 @@ export class PodRigInstantiator {
296
296
  if (!preflight.ready) {
297
297
  return { ok: false, code: "preflight_failed", errors: preflight.errors, warnings: preflight.warnings };
298
298
  }
299
+ // OPR.0.3.3.24: parse/validate/preflight is the separable FRONT-END; the
300
+ // persistence CORE (createPod + create-node + edges + events, in one tx)
301
+ // takes the already-parsed+validated spec so `expand` and the `add_member`
302
+ // converge op compose it WITHOUT fabricating a synthetic rig spec.
303
+ return this.materializeValidatedSpec(rigSpec, rigRoot, opts);
304
+ }
305
+ /**
306
+ * materialize with a STRUCTURED front (OPR.0.3.3.24): the YAML-free sibling of
307
+ * materialize(). Runs the SAME front-end (validate + preflight, via the
308
+ * preflight CORE using this adapter's fsOps) on an already-built raw spec
309
+ * OBJECT, then the persistence core - so `expand` (and the add_member op) drop
310
+ * the synthetic-spec YAML round-trip. Byte-identical to materialize(yaml): same
311
+ * validate(externalQualifiedIds), same preflight checks, same MaterializeOutcome
312
+ * error codes (validation_failed / preflight_failed / target_rig_not_found /
313
+ * materialize_conflict). fsOps stays encapsulated here (the expansion service
314
+ * has none) - this wrapper is mechanics only, no behaviour/layering change.
315
+ */
316
+ async materializeStructured(raw, rigRoot, opts) {
317
+ const targetRig = opts?.targetRigId ? this.deps.rigRepo.getRig(opts.targetRigId) : null;
318
+ if (opts?.targetRigId && !targetRig) {
319
+ return { ok: false, code: "target_rig_not_found", message: `Rig "${opts.targetRigId}" not found` };
320
+ }
321
+ const validation = PodRigSpecSchema.validate(raw, {
322
+ externalQualifiedIds: targetRig?.nodes.map((node) => node.logicalId),
323
+ });
324
+ if (!validation.valid) {
325
+ return { ok: false, code: "validation_failed", errors: validation.errors };
326
+ }
327
+ const rigSpec = PodRigSpecSchema.normalize(raw);
328
+ const preflight = preflightValidatedSpec(rigSpec, {
329
+ rigRoot,
330
+ cwdOverride: opts?.cwdOverride,
331
+ fsOps: this.deps.fsOps,
332
+ rigNameOverride: targetRig?.rig.name,
333
+ });
334
+ if (!preflight.ready) {
335
+ return { ok: false, code: "preflight_failed", errors: preflight.errors, warnings: preflight.warnings };
336
+ }
337
+ return this.materializeValidatedSpec(rigSpec, rigRoot, opts);
338
+ }
339
+ /**
340
+ * materialize CORE (OPR.0.3.3.24): the persistence body of materialize, taking
341
+ * an already-parsed + validated + preflighted PodRigSpec. Creates pods +
342
+ * member nodes (via the create-node primitive) + edges + events in one
343
+ * transaction. Parse/validate/preflight is the caller's separable front-end
344
+ * (materialize() for YAML; expand/add_member build + validate a structured
345
+ * spec). This is the cut that lets `expand` drop its synthetic-spec hack and
346
+ * `add_member` reuse the exact create path — create+launch only, no identity
347
+ * migration.
348
+ */
349
+ async materializeValidatedSpec(rigSpec, rigRoot, opts) {
299
350
  const persistedEvents = [];
300
351
  const nodeResults = [];
301
352
  try {
@@ -342,26 +393,17 @@ export class PodRigInstantiator {
342
393
  }));
343
394
  for (const member of pod.members) {
344
395
  const qualifiedId = `${pod.id}.${member.id}`;
345
- const effectiveCwd = resolveLaunchCwd(member.cwd, rigRoot, opts?.cwdOverride);
346
- const node = this.deps.rigRepo.addNode(materializedRigId, qualifiedId, {
347
- runtime: member.runtime,
348
- model: member.model,
349
- codexConfigProfile: member.codexConfigProfile,
350
- cwd: effectiveCwd,
351
- restorePolicy: member.restorePolicy,
396
+ const { node, event } = this.createMemberNode({
397
+ rigId: materializedRigId,
398
+ qualifiedId,
399
+ member,
352
400
  podId: podRecord.id,
353
- agentRef: member.agentRef,
354
- profile: member.profile,
355
- label: member.label,
401
+ rigRoot,
402
+ cwdOverride: opts?.cwdOverride,
356
403
  });
357
404
  logicalIdToNodeId.set(qualifiedId, node.id);
358
405
  nodeResults.push({ logicalId: qualifiedId, status: "materialized" });
359
- persistedEvents.push(this.deps.eventBus.persistWithinTransaction({
360
- type: "node.added",
361
- rigId: materializedRigId,
362
- nodeId: node.id,
363
- logicalId: qualifiedId,
364
- }));
406
+ persistedEvents.push(event);
365
407
  }
366
408
  }
367
409
  for (const pod of rigSpec.pods) {
@@ -434,6 +476,17 @@ export class PodRigInstantiator {
434
476
  return { ok: false, code: "validation_failed", errors: validation.errors };
435
477
  }
436
478
  const rigSpec = PodRigSpecSchema.normalize(raw);
479
+ return this.launchValidatedSpec(rigSpec, rigRoot, targetRigId);
480
+ }
481
+ /**
482
+ * launch CORE (OPR.0.3.3.24): given an already-parsed+validated spec whose
483
+ * nodes are already materialized, compute launch order and bring each node
484
+ * live via the launch-binding primitive. Extracted from launchMaterialized so
485
+ * `expand` (and the add_member op) launch a structured spec WITHOUT a YAML
486
+ * round-trip; launchMaterialized(yaml) is the parse/validate/normalize front
487
+ * over it. Behaviour identical (loop body relocated verbatim).
488
+ */
489
+ async launchValidatedSpec(rigSpec, rigRoot, targetRigId) {
437
490
  const launchOrder = this.computePodLaunchOrder(rigSpec);
438
491
  const podWarnings = [];
439
492
  const nodeResults = [];
@@ -458,25 +511,15 @@ export class PodRigInstantiator {
458
511
  });
459
512
  continue;
460
513
  }
461
- const launched = memberContext.member.agentRef === "builtin:terminal"
462
- ? await this.launchExistingTerminalMember({
463
- rigId: targetRigId,
464
- rigSpec,
465
- rigRoot,
466
- pod: memberContext.pod,
467
- member: memberContext.member,
468
- qualifiedId: logicalId,
469
- nodeId: node.id,
470
- })
471
- : await this.launchExistingAgentMember({
472
- rigId: targetRigId,
473
- rigSpec,
474
- rigRoot,
475
- pod: memberContext.pod,
476
- member: memberContext.member,
477
- qualifiedId: logicalId,
478
- nodeId: node.id,
479
- });
514
+ const launched = await this.launchBinding({
515
+ rigId: targetRigId,
516
+ rigSpec,
517
+ rigRoot,
518
+ pod: memberContext.pod,
519
+ member: memberContext.member,
520
+ qualifiedId: logicalId,
521
+ nodeId: node.id,
522
+ });
480
523
  if (launched.warnings?.length) {
481
524
  podWarnings.push(...launched.warnings);
482
525
  }
@@ -496,6 +539,187 @@ export class PodRigInstantiator {
496
539
  },
497
540
  };
498
541
  }
542
+ /**
543
+ * add_member converge op (OPR.0.3.3.24): add a single MEMBER to an EXISTING
544
+ * pod in a live rig, composing the two extracted primitives — createMemberNode
545
+ * (create-node) + launchBinding (launch-binding) — WITHOUT createPod and
546
+ * WITHOUT fabricating a synthetic rig spec.
547
+ *
548
+ * Identity-migration-FREE: the new node mints a fresh node id + fresh logical
549
+ * id + fresh `@rigged_*` at launch; no existing seat's logical id,
550
+ * continuity_state, queue routing, or session is re-keyed. This is the
551
+ * source-visible fault line that lets add_member ship while move/fork wait for
552
+ * the 0.4.0 identity stack.
553
+ *
554
+ * Versus materialize: this does NOT call materializeValidatedSpec (which always
555
+ * createPods and carries the pod-exists conflict guard). It resolves the
556
+ * EXISTING pod's DB id via `podRepo.getPodByNamespace` and creates the one node
557
+ * directly under it. The pod-exists guard is lifted (adding to a live pod is
558
+ * not a conflict); the per-member duplicate-logical-id guard is KEPT (AC-3).
559
+ */
560
+ async addMemberToPod(rigId, podNamespace, memberFragment, rigRoot, opts) {
561
+ // 1. Resolve the rig.
562
+ const rig = this.deps.rigRepo.getRig(rigId);
563
+ if (!rig) {
564
+ return { ok: false, code: "rig_not_found", message: `Rig "${rigId}" not found.` };
565
+ }
566
+ // 2. Resolve the EXISTING pod's DB id via getPodByNamespace (the corrected
567
+ // pod-id source — NOT a pre-computed namespace->podId map). Honest not-found
568
+ // with the available namespaces so the caller can correct the handle.
569
+ const pod = this.deps.podRepo.getPodByNamespace(rigId, podNamespace);
570
+ if (!pod) {
571
+ const available = this.deps.podRepo.getPodsForRig(rigId).map((p) => p.namespace);
572
+ const hint = available.length > 0 ? available.join(", ") : "(none)";
573
+ return {
574
+ ok: false,
575
+ code: "pod_not_found",
576
+ message: `Pod "${podNamespace}" not found in rig "${rig.rig.name}". Existing pods: ${hint}. Check the namespace, or add a new pod with \`rig expand\`.`,
577
+ };
578
+ }
579
+ // 3. Build a minimal one-pod-one-member raw spec around the EXISTING pod so
580
+ // the new member runs the SAME validate + preflight the materialize front
581
+ // does — without a whole-rig spec or a YAML round-trip. The member fragment
582
+ // is embedded raw (spec snake_case shape, as expand's structured path emits);
583
+ // validate/normalize is the type gate.
584
+ const rawSpec = {
585
+ version: "0.2",
586
+ name: rig.rig.name,
587
+ pods: [{ id: podNamespace, label: pod.label, members: [memberFragment], edges: [] }],
588
+ edges: [],
589
+ };
590
+ // 4. Validate + normalize. externalQualifiedIds is the existing rig's node
591
+ // set (matches the materialize front; used for cross-pod edge resolution).
592
+ const validation = PodRigSpecSchema.validate(rawSpec, {
593
+ externalQualifiedIds: rig.nodes.map((node) => node.logicalId),
594
+ });
595
+ if (!validation.valid) {
596
+ return { ok: false, code: "validation_failed", errors: validation.errors };
597
+ }
598
+ const rigSpec = PodRigSpecSchema.normalize(rawSpec);
599
+ const member = rigSpec.pods[0].members[0];
600
+ const qualifiedId = `${podNamespace}.${member.id}`;
601
+ // 5. KEEP the per-member duplicate-logical-id guard (AC-3). The pod-exists
602
+ // guard is lifted (we are adding to a live pod on purpose), but minting a
603
+ // colliding logical id would be a real seat collision — reject it honestly.
604
+ // (validate's externalQualifiedIds only resolves edge targets; it does NOT
605
+ // reject a member colliding with an existing node, so this guard is load-bearing.)
606
+ if (rig.nodes.some((node) => node.logicalId === qualifiedId)) {
607
+ return {
608
+ ok: false,
609
+ code: "member_conflict",
610
+ message: `Member "${qualifiedId}" already exists in rig "${rig.rig.name}". Pick a different member id, or remove the existing seat first.`,
611
+ };
612
+ }
613
+ // 6. Preflight the new member on the normalized spec (same checks the
614
+ // materialize front runs, via the core, using this adapter's fsOps).
615
+ // rigNameOverride suppresses the rig-name-collision check (we are appending
616
+ // to an existing rig, exactly like expand's structured path).
617
+ const preflight = preflightValidatedSpec(rigSpec, {
618
+ rigRoot,
619
+ cwdOverride: opts?.cwdOverride,
620
+ fsOps: this.deps.fsOps,
621
+ rigNameOverride: rig.rig.name,
622
+ });
623
+ if (!preflight.ready) {
624
+ return { ok: false, code: "preflight_failed", errors: preflight.errors, warnings: preflight.warnings };
625
+ }
626
+ // 7. Validate + resolve any declared pod-local edges BEFORE creating the
627
+ // node, so a bad edge fails fast with no orphan seat. Two honest failure
628
+ // classes: (a) DECLARATION validity (non-array / empty fields / a kind
629
+ // outside the canonical VALID_EDGE_KINDS - mirrors the rigspec pod-local
630
+ // edge contract, NOT a second looser path) -> validation_failed; (b) live
631
+ // ENDPOINT resolution against the new member + existing pod-mates ->
632
+ // edge_unresolved. Edges carry NO runtime behavior yet (the edge-runtime
633
+ // fence); we persist the declared graph so it is NOT silently dropped (FM2).
634
+ const rawEdges = opts?.edges;
635
+ if (rawEdges !== undefined && rawEdges !== null && !Array.isArray(rawEdges)) {
636
+ return { ok: false, code: "validation_failed", errors: ["edges: must be an array of { from, to, kind }"] };
637
+ }
638
+ const declaredEdges = Array.isArray(rawEdges) ? rawEdges : [];
639
+ const edgeErrors = [];
640
+ declaredEdges.forEach((edge, i) => {
641
+ if (typeof edge?.from !== "string" || typeof edge?.to !== "string" || typeof edge?.kind !== "string"
642
+ || edge.from.trim() === "" || edge.to.trim() === "" || edge.kind.trim() === "") {
643
+ edgeErrors.push(`edges[${i}]: from, to, and kind are required non-empty strings`);
644
+ return;
645
+ }
646
+ if (!VALID_EDGE_KINDS.has(edge.kind)) {
647
+ edgeErrors.push(`edges[${i}].kind: must be one of ${[...VALID_EDGE_KINDS].join(", ")} (got "${edge.kind}")`);
648
+ }
649
+ });
650
+ if (edgeErrors.length > 0) {
651
+ return { ok: false, code: "validation_failed", errors: edgeErrors };
652
+ }
653
+ const knownLogicalIds = new Set([...rig.nodes.map((node) => node.logicalId), qualifiedId]);
654
+ const resolvedEdges = [];
655
+ for (const edge of declaredEdges) {
656
+ const from = `${podNamespace}.${edge.from}`;
657
+ const to = `${podNamespace}.${edge.to}`;
658
+ if (!knownLogicalIds.has(from) || !knownLogicalIds.has(to)) {
659
+ const missing = !knownLogicalIds.has(from) ? from : to;
660
+ return { ok: false, code: "edge_unresolved", message: `Pod-local edge references "${missing}", which is neither the new member "${qualifiedId}" nor an existing seat in rig "${rig.rig.name}". Use member ids within pod "${podNamespace}".` };
661
+ }
662
+ resolvedEdges.push({ from, to, kind: edge.kind });
663
+ }
664
+ // 8. create-node into the EXISTING pod (pod_id = resolved pod.id) + persist
665
+ // the resolved pod-local edges, all in one tx so the node row, the
666
+ // node.added event, and the edges commit atomically (mirroring the
667
+ // materialize core); subscribers notified after commit.
668
+ let createdNodeId = "";
669
+ let createdEvent;
670
+ const tx = this.db.transaction(() => {
671
+ const { node, event } = this.createMemberNode({
672
+ rigId,
673
+ qualifiedId,
674
+ member,
675
+ podId: pod.id,
676
+ rigRoot,
677
+ cwdOverride: opts?.cwdOverride,
678
+ });
679
+ createdNodeId = node.id;
680
+ createdEvent = event;
681
+ if (resolvedEdges.length > 0) {
682
+ const logicalIdToNodeId = new Map(rig.nodes.map((n) => [n.logicalId, n.id]));
683
+ logicalIdToNodeId.set(qualifiedId, node.id);
684
+ for (const edge of resolvedEdges) {
685
+ this.deps.rigRepo.addEdge(rigId, logicalIdToNodeId.get(edge.from), logicalIdToNodeId.get(edge.to), edge.kind);
686
+ }
687
+ }
688
+ });
689
+ tx();
690
+ if (createdEvent)
691
+ this.deps.eventBus.notifySubscribers(createdEvent);
692
+ // 9. launch-binding for the one new node (startup projection + delivery +
693
+ // readiness + `@rigged_*`). The minimal spec supplies the member/pod/rig
694
+ // context launchBinding needs; the derived session name is
695
+ // `${podNamespace}-${member.id}@${rig.name}` — queue-addressable immediately.
696
+ const launched = await this.launchBinding({
697
+ rigId,
698
+ rigSpec,
699
+ rigRoot,
700
+ pod: rigSpec.pods[0],
701
+ member,
702
+ qualifiedId,
703
+ nodeId: createdNodeId,
704
+ cwdOverride: opts?.cwdOverride,
705
+ });
706
+ return {
707
+ ok: true,
708
+ result: {
709
+ podId: pod.id,
710
+ podNamespace,
711
+ node: {
712
+ logicalId: qualifiedId,
713
+ nodeId: createdNodeId,
714
+ status: launched.status,
715
+ error: launched.error,
716
+ sessionName: launched.sessionName,
717
+ },
718
+ edges: resolvedEdges,
719
+ warnings: launched.warnings,
720
+ },
721
+ };
722
+ }
499
723
  async instantiate(rigSpecYaml, rigRoot, opts) {
500
724
  // 1. Parse + validate
501
725
  let rigSpec;
@@ -515,7 +739,21 @@ export class PodRigInstantiator {
515
739
  if (!preflight.ready) {
516
740
  return { ok: false, code: "preflight_failed", errors: preflight.errors, warnings: preflight.warnings };
517
741
  }
518
- // 3. Create rig
742
+ // 3. Compute launch order from edges (rejects cycles)
743
+ //
744
+ // OPR.0.3.2.22 Bug 2: this MUST run BEFORE createRig. Pre-fix, a
745
+ // cycle in the spec left an orphan stopped-state rig record because
746
+ // createRig had already committed before the cycle check ran. The
747
+ // operator-facing consequence was the "ambiguous library-spec vs
748
+ // restore-target" UX trap on the very next `rig up <builtin>` retry.
749
+ let launchOrder;
750
+ try {
751
+ launchOrder = this.computePodLaunchOrder(rigSpec);
752
+ }
753
+ catch (err) {
754
+ return { ok: false, code: "cycle_error", message: err.message };
755
+ }
756
+ // 4. Create rig (after cycle check passes)
519
757
  let rigId;
520
758
  try {
521
759
  const rig = this.deps.rigRepo.createRig(rigSpec.name);
@@ -529,14 +767,6 @@ export class PodRigInstantiator {
529
767
  catch (err) {
530
768
  return { ok: false, code: "instantiate_error", message: err.message };
531
769
  }
532
- // 4. Compute launch order from edges (rejects cycles)
533
- let launchOrder;
534
- try {
535
- launchOrder = this.computePodLaunchOrder(rigSpec);
536
- }
537
- catch (err) {
538
- return { ok: false, code: "cycle_error", message: err.message };
539
- }
540
770
  // 5. Create pods + nodes + edges, then launch in topological order
541
771
  const nodeResults = [];
542
772
  const nodeIdMap = {}; // "pod.member" -> node DB id
@@ -568,10 +798,15 @@ export class PodRigInstantiator {
568
798
  // Sort members by topological launch order
569
799
  const orderMap = new Map(launchOrder.map((id, i) => [id, i]));
570
800
  memberEntries.sort((a, b) => (orderMap.get(a.qualifiedId) ?? 999) - (orderMap.get(b.qualifiedId) ?? 999));
571
- // Prelaunch hook: service gate runs after topology setup, before any node launch
801
+ // Prelaunch hook: service gate runs after topology setup, before any node launch.
802
+ //
803
+ // OPR.0.3.2.22 Bug 2: if the hook fails, roll back the rig record so
804
+ // the spec name is left free for a clean retry. Pods rely on rigs
805
+ // via ON DELETE CASCADE so deleting the rig is sufficient.
572
806
  if (opts?.prelaunchHook) {
573
807
  const hookResult = await opts.prelaunchHook(rigId);
574
808
  if (!hookResult.ok) {
809
+ this.deps.rigRepo.deleteRig(rigId);
575
810
  return { ok: false, code: "service_boot_failed", message: hookResult.message };
576
811
  }
577
812
  }
@@ -654,6 +889,8 @@ export class PodRigInstantiator {
654
889
  logicalId: qualifiedId,
655
890
  status: launched.status,
656
891
  error: launched.error,
892
+ evidence: launched.evidence,
893
+ sessionName: launched.sessionName,
657
894
  });
658
895
  }
659
896
  // Create pod-local edges (after all members created)
@@ -680,9 +917,23 @@ export class PodRigInstantiator {
680
917
  catch { /* best-effort */ }
681
918
  }
682
919
  }
683
- // Check for total failure — kill orphan tmux sessions and clean up rig
684
- const allFailed = nodeResults.length > 0 && nodeResults.every((n) => n.status === "failed");
685
- if (allFailed) {
920
+ // OPR.0.3.2.CT (conveyor-trust-minimal-fix):
921
+ // Distinguish recoverable attention_required (e.g., workspace trust
922
+ // gate) from terminal failure. ANY attention_required node means
923
+ // the rig is operator-recoverable — do NOT tear down. Only when
924
+ // every node is TERMINALLY failed (status === "failed") does the
925
+ // tear-down run, preserving the existing failure-cleanup behavior.
926
+ //
927
+ // For all-attention_required (no successful launch, no terminal
928
+ // failure), surface an attention_required outcome that carries
929
+ // the actionable per-node detail. The route returns a 3-part
930
+ // error pointing the operator at the approve→resume path. Sessions
931
+ // remain in startup_status='attention_required' so `rig ps` lists
932
+ // them and tmux panes are NOT killed.
933
+ const hasAttention = nodeResults.some((n) => n.status === "attention_required");
934
+ const hasLaunched = nodeResults.some((n) => n.status === "launched");
935
+ const allTerminal = nodeResults.length > 0 && nodeResults.every((n) => n.status === "failed");
936
+ if (allTerminal) {
686
937
  // Kill orphan tmux sessions
687
938
  if (this.deps.tmuxAdapter) {
688
939
  for (const sessionName of launchedSessionNames) {
@@ -699,14 +950,55 @@ export class PodRigInstantiator {
699
950
  const details = nodeResults.map((n) => `${n.logicalId}: ${n.error ?? "unknown"}`).join("; ");
700
951
  return { ok: false, code: "instantiate_error", message: `all node launches/startups failed — ${details}` };
701
952
  }
953
+ if (hasAttention && !hasLaunched) {
954
+ // All-attention_required path — rig + sessions PRESERVED; no
955
+ // tear-down. The operator's path: attach to a session via
956
+ // `tmux attach -t <session>` and answer the runtime prompt. NO
957
+ // new trust primitive
958
+ // introduced (HG-5); reuses the runtime's shipped in-pane
959
+ // trust-grant prompt.
960
+ const attentionNodes = nodeResults
961
+ .filter((n) => n.status === "attention_required")
962
+ .map((n) => ({
963
+ logicalId: n.logicalId,
964
+ sessionName: n.sessionName ?? "",
965
+ evidence: n.evidence,
966
+ reason: n.error ?? "node awaiting attention",
967
+ }));
968
+ // Emit rig.imported so callers see the rig exists; nodes are
969
+ // attention_required, not "launched", so `rig ps` shows the
970
+ // correct lifecycle state.
971
+ try {
972
+ this.deps.eventBus.emit({ type: "rig.imported", rigId, specName: rigSpec.name, specVersion: rigSpec.version });
973
+ }
974
+ catch { /* best-effort */ }
975
+ return {
976
+ ok: false,
977
+ code: "attention_required",
978
+ message: `${attentionNodes.length} node${attentionNodes.length === 1 ? "" : "s"} require attention before becoming interactive (rig parked, NOT failed; approve and resume to proceed).`,
979
+ rigId,
980
+ attentionNodes,
981
+ };
982
+ }
702
983
  // Emit rig.imported
703
984
  try {
704
985
  this.deps.eventBus.emit({ type: "rig.imported", rigId, specName: rigSpec.name, specVersion: rigSpec.version });
705
986
  }
706
987
  catch { /* best-effort */ }
988
+ // Carry sessionName + evidence through to InstantiateResult.nodes
989
+ // so BootstrapOrchestrator can build AttentionNode[] in the mixed
990
+ // launched+attention_required path (guard verdict
991
+ // qitem-20260518082933 BLOCKER 1).
992
+ const resultNodes = nodeResults.map((n) => ({
993
+ logicalId: n.logicalId,
994
+ status: n.status,
995
+ error: n.error,
996
+ sessionName: n.sessionName,
997
+ evidence: n.evidence,
998
+ }));
707
999
  return {
708
1000
  ok: true,
709
- result: { rigId, specName: rigSpec.name, specVersion: rigSpec.version, nodes: nodeResults, warnings: podInstantiateWarnings.length > 0 ? podInstantiateWarnings : undefined },
1001
+ result: { rigId, specName: rigSpec.name, specVersion: rigSpec.version, nodes: resultNodes, warnings: podInstantiateWarnings.length > 0 ? podInstantiateWarnings : undefined },
710
1002
  };
711
1003
  }
712
1004
  computePodLaunchOrder(rigSpec) {
@@ -826,6 +1118,50 @@ export class PodRigInstantiator {
826
1118
  const member = pod?.members.find((entry) => entry.id === memberId);
827
1119
  return pod && member ? { pod, member } : null;
828
1120
  }
1121
+ /**
1122
+ * create-node primitive (OPR.0.3.3.24): mint a fresh node row for one member
1123
+ * (fresh stable id + fresh qualified logical id, `pod_id` = the given pod) plus
1124
+ * the matching `node.added` event. Extracted from materialize's loop so the
1125
+ * `add_member` converge op and a de-YAML'd `expand` create a member node
1126
+ * WITHOUT fabricating a synthetic rig spec. Identity-migration-FREE: addNode
1127
+ * mints a brand-new identity; nothing existing re-keys. The caller pushes the
1128
+ * returned `event` into its transaction's persisted-events list.
1129
+ */
1130
+ createMemberNode(input) {
1131
+ const effectiveCwd = resolveLaunchCwd(input.member.cwd, input.rigRoot, input.cwdOverride);
1132
+ const node = this.deps.rigRepo.addNode(input.rigId, input.qualifiedId, {
1133
+ runtime: input.member.runtime,
1134
+ model: input.member.model,
1135
+ codexConfigProfile: input.member.codexConfigProfile,
1136
+ cwd: effectiveCwd,
1137
+ restorePolicy: input.member.restorePolicy,
1138
+ podId: input.podId,
1139
+ agentRef: input.member.agentRef,
1140
+ profile: input.member.profile,
1141
+ label: input.member.label,
1142
+ });
1143
+ const event = this.deps.eventBus.persistWithinTransaction({
1144
+ type: "node.added",
1145
+ rigId: input.rigId,
1146
+ nodeId: node.id,
1147
+ logicalId: input.qualifiedId,
1148
+ });
1149
+ return { node, event };
1150
+ }
1151
+ /**
1152
+ * launch-binding primitive (OPR.0.3.3.24): given an already-created node and
1153
+ * its member context, bring it fully live — harness launch + startup
1154
+ * projection + delivery + readiness + `@rigged_*` metadata. Dispatches the
1155
+ * terminal vs agent launch path. Extracted as an independently-callable
1156
+ * primitive so launchMaterialized's loop, `expand`, and the `add_member`
1157
+ * converge op all launch a node WITHOUT fabricating a synthetic rig spec.
1158
+ * Behaviour is identical to the prior inline dispatch.
1159
+ */
1160
+ async launchBinding(input) {
1161
+ return input.member.agentRef === "builtin:terminal"
1162
+ ? this.launchExistingTerminalMember(input)
1163
+ : this.launchExistingAgentMember(input);
1164
+ }
829
1165
  async launchExistingAgentMember(input) {
830
1166
  const resolveResult = input.resolveResult ?? resolveAgentRef(input.member.agentRef, input.rigRoot, this.deps.fsOps);
831
1167
  if (!resolveResult.ok) {
@@ -854,7 +1190,16 @@ export class PodRigInstantiator {
854
1190
  return { status: "failed", error: sessionNameErrors.join("; ") };
855
1191
  }
856
1192
  const canonicalSessionName = deriveCanonicalSessionName(input.pod.id, input.member.id, input.rigSpec.name);
857
- const launchResult = await this.deps.nodeLauncher.launchNode(input.rigId, input.qualifiedId, { sessionName: canonicalSessionName });
1193
+ // Slice 15 forward per-seat silenceWindowSeconds from the resolved
1194
+ // profile.activity block. NodeLauncher applies the launcher default
1195
+ // (3s) when this is undefined. The seat's tmux monitor-silence is
1196
+ // configured immediately after createSession; SeatActivityService
1197
+ // then reads window_activity to compute terminalActive against this
1198
+ // threshold per poll.
1199
+ const launchResult = await this.deps.nodeLauncher.launchNode(input.rigId, input.qualifiedId, {
1200
+ sessionName: canonicalSessionName,
1201
+ silenceWindowSeconds: configResult.config.activity?.silenceWindowSeconds,
1202
+ });
858
1203
  if (!launchResult.ok) {
859
1204
  return { status: "failed", error: launchResult.message };
860
1205
  }
@@ -920,7 +1265,8 @@ export class PodRigInstantiator {
920
1265
  else if (input.member.sessionSource?.mode === "agent_image") {
921
1266
  // PL-016 Item 4: agent_image → resolve via library + dispatch
922
1267
  // through the native-fork code path so nativeResumeProbe
923
- // semantics are preserved (architecture.md § Resume honesty).
1268
+ // semantics are preserved
1269
+ // (docs/as-built/architecture/adapters-and-runtimes.md § Resume honesty).
924
1270
  const library = this.deps.agentImageLibrary;
925
1271
  if (!library) {
926
1272
  return {
@@ -1028,9 +1374,22 @@ export class PodRigInstantiator {
1028
1374
  console.warn(`[openrig] agent-image fork_count bump failed for ${consumedAgentImageId}: ${err.message}`);
1029
1375
  }
1030
1376
  }
1377
+ // OPR.0.3.2.CT — preserve the attention_required distinction so
1378
+ // the instantiator can leave a recoverable rig + sessions instead
1379
+ // of zero-collapsing. The session row's startup_status was already
1380
+ // persisted by startupOrchestrator.fail() (see startup-orchestrator.ts
1381
+ // lines 223-225, 241-243).
1382
+ if (startupResult.ok) {
1383
+ return {
1384
+ status: "launched",
1385
+ sessionName: canonicalSessionName,
1386
+ warnings: launchResult.warnings,
1387
+ };
1388
+ }
1031
1389
  return {
1032
- status: startupResult.ok ? "launched" : "failed",
1033
- error: startupResult.ok ? undefined : startupResult.errors.join("; "),
1390
+ status: startupResult.startupStatus === "attention_required" ? "attention_required" : "failed",
1391
+ error: startupResult.errors.join("; "),
1392
+ evidence: startupResult.evidence,
1034
1393
  sessionName: canonicalSessionName,
1035
1394
  warnings: launchResult.warnings,
1036
1395
  };