@openrig/cli 0.6.9 → 0.6.11

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 (570) hide show
  1. package/README.md +2 -2
  2. package/daemon/assets/onboarding/02-self-and-competent-action.md +4 -3
  3. package/daemon/assets/plugins/openrig-core/.claude-plugin/plugin.json +1 -1
  4. package/daemon/assets/plugins/openrig-core/.codex-plugin/plugin.json +1 -1
  5. package/daemon/assets/plugins/openrig-core/hooks/scripts/activity-relay.cjs +42 -2
  6. package/daemon/assets/plugins/openrig-core/skills/openrig-skills/SKILL.md +1 -1
  7. package/daemon/assets/plugins/openrig-core/skills/openrig-user/SKILL.md +7 -1
  8. package/daemon/assets/plugins/openrig-core/skills/refocusing/scripts/trace-to-root.py +6 -1
  9. package/daemon/assets/skills/rigs/SKILL.md +7 -5
  10. package/daemon/context-packs/help/manifest.yaml +1 -1
  11. package/daemon/context-packs/onboarding-width/manifest.yaml +1 -1
  12. package/daemon/context-packs/onboarding-width/public-what-you-can-do.md +64 -14
  13. package/daemon/context-packs/reference/getting-started.md +10 -6
  14. package/daemon/context-packs/reference/manifest.yaml +1 -1
  15. package/daemon/context-packs/reference/rig-spec.md +2 -2
  16. package/daemon/context-packs/reference/whats-new.md +151 -74
  17. package/daemon/context-packs/skills/agent-operated-software/manifest.yaml +1 -1
  18. package/daemon/context-packs/skills/agent-operated-workflows/manifest.yaml +1 -1
  19. package/daemon/context-packs/skills/applying-a-permission-policy/manifest.yaml +1 -1
  20. package/daemon/context-packs/skills/claude-compaction-restore/manifest.yaml +1 -1
  21. package/daemon/context-packs/skills/core/agent-starters/manifest.yaml +1 -1
  22. package/daemon/context-packs/skills/core/agent-startup-and-context-ingestion/manifest.yaml +1 -1
  23. package/daemon/context-packs/skills/core/cross-host-rig-commands/manifest.yaml +1 -1
  24. package/daemon/context-packs/skills/core/human-in-the-loop/manifest.yaml +1 -1
  25. package/daemon/context-packs/skills/core/messaging-the-human/manifest.yaml +1 -1
  26. package/daemon/context-packs/skills/core/openrig-architect/manifest.yaml +1 -1
  27. package/daemon/context-packs/skills/core/openrig-cmux/manifest.yaml +1 -1
  28. package/daemon/context-packs/skills/core/openrig-herdr/manifest.yaml +1 -1
  29. package/daemon/context-packs/skills/core/openrig-skills/SKILL.md +1 -1
  30. package/daemon/context-packs/skills/core/openrig-skills/manifest.yaml +3 -3
  31. package/daemon/context-packs/skills/core/openrig-software-factory/manifest.yaml +1 -1
  32. package/daemon/context-packs/skills/core/openrig-upgrade/manifest.yaml +1 -1
  33. package/daemon/context-packs/skills/core/rig-bundles-and-shareable-artifacts/manifest.yaml +1 -1
  34. package/daemon/context-packs/skills/core/rig-lifecycle/manifest.yaml +1 -1
  35. package/daemon/context-packs/skills/core/session-source-fork/manifest.yaml +1 -1
  36. package/daemon/context-packs/skills/core/specification-system/manifest.yaml +1 -1
  37. package/daemon/context-packs/skills/core/topology-mutation-and-seat-management/SKILL.md +2 -2
  38. package/daemon/context-packs/skills/core/topology-mutation-and-seat-management/manifest.yaml +1 -1
  39. package/daemon/context-packs/skills/core/watchdog/manifest.yaml +1 -1
  40. package/daemon/context-packs/skills/delegating-work/manifest.yaml +1 -1
  41. package/daemon/context-packs/skills/forming-an-openrig-mental-model/manifest.yaml +1 -1
  42. package/daemon/context-packs/skills/loading-addressable-markdown/manifest.yaml +1 -1
  43. package/daemon/context-packs/skills/mission-slice-sop/manifest.yaml +1 -1
  44. package/daemon/context-packs/skills/openrig-operating-model/manifest.yaml +1 -1
  45. package/daemon/context-packs/skills/openrig-user/SKILL.md +7 -1
  46. package/daemon/context-packs/skills/openrig-user/manifest.yaml +1 -1
  47. package/daemon/context-packs/skills/orienting-to-an-inherited-seat/manifest.yaml +1 -1
  48. package/daemon/context-packs/skills/pm/backlog-capture/manifest.yaml +1 -1
  49. package/daemon/context-packs/skills/pm/context-builder/manifest.yaml +1 -1
  50. package/daemon/context-packs/skills/pm/exec-summary/manifest.yaml +1 -1
  51. package/daemon/context-packs/skills/pm/office-hours/manifest.yaml +1 -1
  52. package/daemon/context-packs/skills/pm/plan-review/manifest.yaml +1 -1
  53. package/daemon/context-packs/skills/pm/requirements-writer/manifest.yaml +1 -1
  54. package/daemon/context-packs/skills/pm/ui-mockup/manifest.yaml +1 -1
  55. package/daemon/context-packs/skills/pods/development-team/manifest.yaml +1 -1
  56. package/daemon/context-packs/skills/pods/orchestration-team/manifest.yaml +1 -1
  57. package/daemon/context-packs/skills/pods/oversight-team/manifest.yaml +1 -1
  58. package/daemon/context-packs/skills/pods/review-team/manifest.yaml +1 -1
  59. package/daemon/context-packs/skills/process/agent-browser/manifest.yaml +1 -1
  60. package/daemon/context-packs/skills/process/context-engineering/manifest.yaml +1 -1
  61. package/daemon/context-packs/skills/process/dogfood/manifest.yaml +1 -1
  62. package/daemon/context-packs/skills/process/frontend-design/manifest.yaml +1 -1
  63. package/daemon/context-packs/skills/process/systematic-debugging/manifest.yaml +1 -1
  64. package/daemon/context-packs/skills/process/test-driven-development/manifest.yaml +1 -1
  65. package/daemon/context-packs/skills/process/verification-before-completion/manifest.yaml +1 -1
  66. package/daemon/context-packs/skills/queue-handoff/manifest.yaml +1 -1
  67. package/daemon/context-packs/skills/refocusing/manifest.yaml +1 -1
  68. package/daemon/context-packs/skills/refocusing/scripts/trace-to-root.py +6 -1
  69. package/daemon/context-packs/skills/retiring-and-inheriting-a-seat/manifest.yaml +1 -1
  70. package/daemon/context-packs/skills/seat-continuity-and-handover/manifest.yaml +1 -1
  71. package/daemon/context-packs/skills/session-compaction-and-restore/manifest.yaml +1 -1
  72. package/daemon/context-packs/skills/software-for-agents/manifest.yaml +1 -1
  73. package/daemon/context-packs/world-example/manifest.yaml +1 -1
  74. package/daemon/context-packs/world-public/manifest.yaml +1 -1
  75. package/daemon/dist/adapters/claude-code-adapter.d.ts +0 -14
  76. package/daemon/dist/adapters/claude-code-adapter.d.ts.map +1 -1
  77. package/daemon/dist/adapters/claude-code-adapter.js +43 -80
  78. package/daemon/dist/adapters/claude-code-adapter.js.map +1 -1
  79. package/daemon/dist/adapters/claude-resume-launch.d.ts +4 -0
  80. package/daemon/dist/adapters/claude-resume-launch.d.ts.map +1 -0
  81. package/daemon/dist/adapters/claude-resume-launch.js +13 -0
  82. package/daemon/dist/adapters/claude-resume-launch.js.map +1 -0
  83. package/daemon/dist/adapters/claude-resume.d.ts +2 -1
  84. package/daemon/dist/adapters/claude-resume.d.ts.map +1 -1
  85. package/daemon/dist/adapters/claude-resume.js +9 -4
  86. package/daemon/dist/adapters/claude-resume.js.map +1 -1
  87. package/daemon/dist/adapters/codex-runtime-adapter.d.ts +35 -0
  88. package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
  89. package/daemon/dist/adapters/codex-runtime-adapter.js +94 -44
  90. package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
  91. package/daemon/dist/adapters/pi-runner.d.ts.map +1 -1
  92. package/daemon/dist/adapters/pi-runner.js +6 -3
  93. package/daemon/dist/adapters/pi-runner.js.map +1 -1
  94. package/daemon/dist/adapters/pi-runtime-adapter.js +1 -1
  95. package/daemon/dist/adapters/pi-runtime-adapter.js.map +1 -1
  96. package/daemon/dist/adapters/tmux-server.d.ts +15 -0
  97. package/daemon/dist/adapters/tmux-server.d.ts.map +1 -0
  98. package/daemon/dist/adapters/tmux-server.js +58 -0
  99. package/daemon/dist/adapters/tmux-server.js.map +1 -0
  100. package/daemon/dist/adapters/tmux.d.ts +26 -1
  101. package/daemon/dist/adapters/tmux.d.ts.map +1 -1
  102. package/daemon/dist/adapters/tmux.js +130 -7
  103. package/daemon/dist/adapters/tmux.js.map +1 -1
  104. package/daemon/dist/build-info.js +3 -3
  105. package/daemon/dist/db/all-migrations.d.ts.map +1 -1
  106. package/daemon/dist/db/all-migrations.js +6 -0
  107. package/daemon/dist/db/all-migrations.js.map +1 -1
  108. package/daemon/dist/db/migrations/099_queue_items_recovery_tags.d.ts +3 -0
  109. package/daemon/dist/db/migrations/099_queue_items_recovery_tags.d.ts.map +1 -0
  110. package/daemon/dist/db/migrations/099_queue_items_recovery_tags.js +19 -0
  111. package/daemon/dist/db/migrations/099_queue_items_recovery_tags.js.map +1 -0
  112. package/daemon/dist/db/migrations/101_claude_resume_rotation.d.ts +3 -0
  113. package/daemon/dist/db/migrations/101_claude_resume_rotation.d.ts.map +1 -0
  114. package/daemon/dist/db/migrations/101_claude_resume_rotation.js +19 -0
  115. package/daemon/dist/db/migrations/101_claude_resume_rotation.js.map +1 -0
  116. package/daemon/dist/db/migrations/103_session_stop_intent.d.ts +4 -0
  117. package/daemon/dist/db/migrations/103_session_stop_intent.d.ts.map +1 -0
  118. package/daemon/dist/db/migrations/103_session_stop_intent.js +9 -0
  119. package/daemon/dist/db/migrations/103_session_stop_intent.js.map +1 -0
  120. package/daemon/dist/domain/active-occupant.d.ts +14 -0
  121. package/daemon/dist/domain/active-occupant.d.ts.map +1 -1
  122. package/daemon/dist/domain/active-occupant.js +17 -0
  123. package/daemon/dist/domain/active-occupant.js.map +1 -1
  124. package/daemon/dist/domain/agent-activity-store.js +3 -0
  125. package/daemon/dist/domain/agent-activity-store.js.map +1 -1
  126. package/daemon/dist/domain/bootstrap-repository.js +1 -1
  127. package/daemon/dist/domain/bootstrap-repository.js.map +1 -1
  128. package/daemon/dist/domain/chat-repository.d.ts +3 -0
  129. package/daemon/dist/domain/chat-repository.d.ts.map +1 -1
  130. package/daemon/dist/domain/chat-repository.js +15 -4
  131. package/daemon/dist/domain/chat-repository.js.map +1 -1
  132. package/daemon/dist/domain/claude-managed-launch.d.ts +1 -1
  133. package/daemon/dist/domain/claude-managed-launch.d.ts.map +1 -1
  134. package/daemon/dist/domain/claude-managed-launch.js +3 -2
  135. package/daemon/dist/domain/claude-managed-launch.js.map +1 -1
  136. package/daemon/dist/domain/cmux-layout-service.d.ts.map +1 -1
  137. package/daemon/dist/domain/cmux-layout-service.js +2 -1
  138. package/daemon/dist/domain/cmux-layout-service.js.map +1 -1
  139. package/daemon/dist/domain/codex-git-add-dirs.js +1 -1
  140. package/daemon/dist/domain/codex-git-add-dirs.js.map +1 -1
  141. package/daemon/dist/domain/codex-network-default.d.ts +3 -0
  142. package/daemon/dist/domain/codex-network-default.d.ts.map +1 -1
  143. package/daemon/dist/domain/codex-network-default.js +1 -1
  144. package/daemon/dist/domain/codex-network-default.js.map +1 -1
  145. package/daemon/dist/domain/codex-pane-patterns.d.ts +2 -0
  146. package/daemon/dist/domain/codex-pane-patterns.d.ts.map +1 -0
  147. package/daemon/dist/domain/codex-pane-patterns.js +5 -0
  148. package/daemon/dist/domain/codex-pane-patterns.js.map +1 -0
  149. package/daemon/dist/domain/context-monitor.d.ts.map +1 -1
  150. package/daemon/dist/domain/context-monitor.js +46 -22
  151. package/daemon/dist/domain/context-monitor.js.map +1 -1
  152. package/daemon/dist/domain/context-usage-store.d.ts.map +1 -1
  153. package/daemon/dist/domain/context-usage-store.js +6 -1
  154. package/daemon/dist/domain/context-usage-store.js.map +1 -1
  155. package/daemon/dist/domain/crash-cart-conductor.d.ts.map +1 -1
  156. package/daemon/dist/domain/crash-cart-conductor.js +3 -1
  157. package/daemon/dist/domain/crash-cart-conductor.js.map +1 -1
  158. package/daemon/dist/domain/cwd-resolution.d.ts +8 -0
  159. package/daemon/dist/domain/cwd-resolution.d.ts.map +1 -1
  160. package/daemon/dist/domain/cwd-resolution.js +24 -3
  161. package/daemon/dist/domain/cwd-resolution.js.map +1 -1
  162. package/daemon/dist/domain/files/file-read.d.ts.map +1 -1
  163. package/daemon/dist/domain/files/file-read.js +11 -3
  164. package/daemon/dist/domain/files/file-read.js.map +1 -1
  165. package/daemon/dist/domain/gateway/connections-projection.d.ts +1 -1
  166. package/daemon/dist/domain/gateway/slack/channel-recovery.d.ts.map +1 -1
  167. package/daemon/dist/domain/gateway/slack/channel-recovery.js +4 -3
  168. package/daemon/dist/domain/gateway/slack/channel-recovery.js.map +1 -1
  169. package/daemon/dist/domain/gateway/slack/inbound.d.ts +21 -2
  170. package/daemon/dist/domain/gateway/slack/inbound.d.ts.map +1 -1
  171. package/daemon/dist/domain/gateway/slack/inbound.js +70 -11
  172. package/daemon/dist/domain/gateway/slack/inbound.js.map +1 -1
  173. package/daemon/dist/domain/gateway/slack/slack-delivery.d.ts +4 -0
  174. package/daemon/dist/domain/gateway/slack/slack-delivery.d.ts.map +1 -1
  175. package/daemon/dist/domain/gateway/slack/slack-delivery.js +1 -1
  176. package/daemon/dist/domain/gateway/slack/slack-delivery.js.map +1 -1
  177. package/daemon/dist/domain/gateway/slack/slack-subsystem.d.ts.map +1 -1
  178. package/daemon/dist/domain/gateway/slack/slack-subsystem.js +7 -4
  179. package/daemon/dist/domain/gateway/slack/slack-subsystem.js.map +1 -1
  180. package/daemon/dist/domain/history-query.d.ts.map +1 -1
  181. package/daemon/dist/domain/history-query.js +8 -6
  182. package/daemon/dist/domain/history-query.js.map +1 -1
  183. package/daemon/dist/domain/human-questions.d.ts +4 -1
  184. package/daemon/dist/domain/human-questions.d.ts.map +1 -1
  185. package/daemon/dist/domain/human-questions.js.map +1 -1
  186. package/daemon/dist/domain/install-engine.js +2 -2
  187. package/daemon/dist/domain/install-engine.js.map +1 -1
  188. package/daemon/dist/domain/native-process-lineage.d.ts +57 -4
  189. package/daemon/dist/domain/native-process-lineage.d.ts.map +1 -1
  190. package/daemon/dist/domain/native-process-lineage.js +277 -42
  191. package/daemon/dist/domain/native-process-lineage.js.map +1 -1
  192. package/daemon/dist/domain/node-cmux-service.d.ts.map +1 -1
  193. package/daemon/dist/domain/node-cmux-service.js +2 -1
  194. package/daemon/dist/domain/node-cmux-service.js.map +1 -1
  195. package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
  196. package/daemon/dist/domain/node-inventory.js +71 -18
  197. package/daemon/dist/domain/node-inventory.js.map +1 -1
  198. package/daemon/dist/domain/node-launcher.d.ts.map +1 -1
  199. package/daemon/dist/domain/node-launcher.js +2 -1
  200. package/daemon/dist/domain/node-launcher.js.map +1 -1
  201. package/daemon/dist/domain/pane-cutover.d.ts +27 -0
  202. package/daemon/dist/domain/pane-cutover.d.ts.map +1 -0
  203. package/daemon/dist/domain/pane-cutover.js +37 -0
  204. package/daemon/dist/domain/pane-cutover.js.map +1 -0
  205. package/daemon/dist/domain/parent-session-env.d.ts +8 -0
  206. package/daemon/dist/domain/parent-session-env.d.ts.map +1 -0
  207. package/daemon/dist/domain/parent-session-env.js +37 -0
  208. package/daemon/dist/domain/parent-session-env.js.map +1 -0
  209. package/daemon/dist/domain/policies/parked-owner-consumer.d.ts +11 -0
  210. package/daemon/dist/domain/policies/parked-owner-consumer.d.ts.map +1 -1
  211. package/daemon/dist/domain/policies/parked-owner-consumer.js +81 -11
  212. package/daemon/dist/domain/policies/parked-owner-consumer.js.map +1 -1
  213. package/daemon/dist/domain/profile-resolver.d.ts.map +1 -1
  214. package/daemon/dist/domain/profile-resolver.js +2 -3
  215. package/daemon/dist/domain/profile-resolver.js.map +1 -1
  216. package/daemon/dist/domain/progress/progress-indexer.d.ts.map +1 -1
  217. package/daemon/dist/domain/progress/progress-indexer.js +19 -0
  218. package/daemon/dist/domain/progress/progress-indexer.js.map +1 -1
  219. package/daemon/dist/domain/proof/judgments.d.ts +10 -5
  220. package/daemon/dist/domain/proof/judgments.d.ts.map +1 -1
  221. package/daemon/dist/domain/proof/judgments.js +27 -19
  222. package/daemon/dist/domain/proof/judgments.js.map +1 -1
  223. package/daemon/dist/domain/provider/codex-limit-banner.d.ts +40 -0
  224. package/daemon/dist/domain/provider/codex-limit-banner.d.ts.map +1 -0
  225. package/daemon/dist/domain/provider/codex-limit-banner.js +168 -0
  226. package/daemon/dist/domain/provider/codex-limit-banner.js.map +1 -0
  227. package/daemon/dist/domain/provider/codex-usage-reader.d.ts +31 -0
  228. package/daemon/dist/domain/provider/codex-usage-reader.d.ts.map +1 -0
  229. package/daemon/dist/domain/provider/codex-usage-reader.js +115 -0
  230. package/daemon/dist/domain/provider/codex-usage-reader.js.map +1 -0
  231. package/daemon/dist/domain/provider/codex-usage-windows.d.ts +78 -0
  232. package/daemon/dist/domain/provider/codex-usage-windows.d.ts.map +1 -0
  233. package/daemon/dist/domain/provider/codex-usage-windows.js +259 -0
  234. package/daemon/dist/domain/provider/codex-usage-windows.js.map +1 -0
  235. package/daemon/dist/domain/provider/provider-service-impl.d.ts +10 -0
  236. package/daemon/dist/domain/provider/provider-service-impl.d.ts.map +1 -1
  237. package/daemon/dist/domain/provider/provider-service-impl.js +27 -1
  238. package/daemon/dist/domain/provider/provider-service-impl.js.map +1 -1
  239. package/daemon/dist/domain/provider/provider-service.d.ts +5 -0
  240. package/daemon/dist/domain/provider/provider-service.d.ts.map +1 -1
  241. package/daemon/dist/domain/provider/provider-types.d.ts +65 -0
  242. package/daemon/dist/domain/provider/provider-types.d.ts.map +1 -1
  243. package/daemon/dist/domain/ps-projection.d.ts +5 -2
  244. package/daemon/dist/domain/ps-projection.d.ts.map +1 -1
  245. package/daemon/dist/domain/ps-projection.js +29 -26
  246. package/daemon/dist/domain/ps-projection.js.map +1 -1
  247. package/daemon/dist/domain/queue-recovery.d.ts.map +1 -1
  248. package/daemon/dist/domain/queue-recovery.js +10 -3
  249. package/daemon/dist/domain/queue-recovery.js.map +1 -1
  250. package/daemon/dist/domain/queue-repository.d.ts +68 -13
  251. package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  252. package/daemon/dist/domain/queue-repository.js +72 -43
  253. package/daemon/dist/domain/queue-repository.js.map +1 -1
  254. package/daemon/dist/domain/queue-stuck-sweep.d.ts.map +1 -1
  255. package/daemon/dist/domain/queue-stuck-sweep.js +26 -9
  256. package/daemon/dist/domain/queue-stuck-sweep.js.map +1 -1
  257. package/daemon/dist/domain/queue-wake-ladder.d.ts +17 -0
  258. package/daemon/dist/domain/queue-wake-ladder.d.ts.map +1 -1
  259. package/daemon/dist/domain/queue-wake-ladder.js +49 -3
  260. package/daemon/dist/domain/queue-wake-ladder.js.map +1 -1
  261. package/daemon/dist/domain/restore-check-service.d.ts +8 -0
  262. package/daemon/dist/domain/restore-check-service.d.ts.map +1 -1
  263. package/daemon/dist/domain/restore-check-service.js +12 -3
  264. package/daemon/dist/domain/restore-check-service.js.map +1 -1
  265. package/daemon/dist/domain/restore-guidance.d.ts +39 -0
  266. package/daemon/dist/domain/restore-guidance.d.ts.map +1 -0
  267. package/daemon/dist/domain/restore-guidance.js +163 -0
  268. package/daemon/dist/domain/restore-guidance.js.map +1 -0
  269. package/daemon/dist/domain/restore-orchestrator.d.ts +10 -1
  270. package/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
  271. package/daemon/dist/domain/restore-orchestrator.js +192 -9
  272. package/daemon/dist/domain/restore-orchestrator.js.map +1 -1
  273. package/daemon/dist/domain/restore-plan-preview.d.ts +4 -0
  274. package/daemon/dist/domain/restore-plan-preview.d.ts.map +1 -1
  275. package/daemon/dist/domain/restore-plan-preview.js +14 -3
  276. package/daemon/dist/domain/restore-plan-preview.js.map +1 -1
  277. package/daemon/dist/domain/rigspec-preflight.d.ts.map +1 -1
  278. package/daemon/dist/domain/rigspec-preflight.js +7 -6
  279. package/daemon/dist/domain/rigspec-preflight.js.map +1 -1
  280. package/daemon/dist/domain/runtime-adapter.d.ts +3 -0
  281. package/daemon/dist/domain/runtime-adapter.d.ts.map +1 -1
  282. package/daemon/dist/domain/runtime-adapter.js.map +1 -1
  283. package/daemon/dist/domain/scope/scope-view-projection.d.ts +4 -2
  284. package/daemon/dist/domain/scope/scope-view-projection.d.ts.map +1 -1
  285. package/daemon/dist/domain/scope/scope-view-projection.js +11 -11
  286. package/daemon/dist/domain/scope/scope-view-projection.js.map +1 -1
  287. package/daemon/dist/domain/seat-attention-reconciler.d.ts +5 -2
  288. package/daemon/dist/domain/seat-attention-reconciler.d.ts.map +1 -1
  289. package/daemon/dist/domain/seat-attention-reconciler.js +18 -4
  290. package/daemon/dist/domain/seat-attention-reconciler.js.map +1 -1
  291. package/daemon/dist/domain/seat-identity-reconciler.d.ts.map +1 -1
  292. package/daemon/dist/domain/seat-identity-reconciler.js +7 -2
  293. package/daemon/dist/domain/seat-identity-reconciler.js.map +1 -1
  294. package/daemon/dist/domain/seat-lifecycle-service.d.ts +117 -2
  295. package/daemon/dist/domain/seat-lifecycle-service.d.ts.map +1 -1
  296. package/daemon/dist/domain/seat-lifecycle-service.js +335 -74
  297. package/daemon/dist/domain/seat-lifecycle-service.js.map +1 -1
  298. package/daemon/dist/domain/seat-restart-in-place.d.ts +292 -0
  299. package/daemon/dist/domain/seat-restart-in-place.d.ts.map +1 -0
  300. package/daemon/dist/domain/seat-restart-in-place.js +895 -0
  301. package/daemon/dist/domain/seat-restart-in-place.js.map +1 -0
  302. package/daemon/dist/domain/seat-status-service.d.ts +2 -1
  303. package/daemon/dist/domain/seat-status-service.d.ts.map +1 -1
  304. package/daemon/dist/domain/seat-status-service.js +1 -0
  305. package/daemon/dist/domain/seat-status-service.js.map +1 -1
  306. package/daemon/dist/domain/seat-structural-activity-service.d.ts +9 -1
  307. package/daemon/dist/domain/seat-structural-activity-service.d.ts.map +1 -1
  308. package/daemon/dist/domain/seat-structural-activity-service.js +27 -4
  309. package/daemon/dist/domain/seat-structural-activity-service.js.map +1 -1
  310. package/daemon/dist/domain/seat-switch-client-service.d.ts.map +1 -1
  311. package/daemon/dist/domain/seat-switch-client-service.js +2 -1
  312. package/daemon/dist/domain/seat-switch-client-service.js.map +1 -1
  313. package/daemon/dist/domain/session-fingerprinter.d.ts.map +1 -1
  314. package/daemon/dist/domain/session-fingerprinter.js +9 -5
  315. package/daemon/dist/domain/session-fingerprinter.js.map +1 -1
  316. package/daemon/dist/domain/session-registry.d.ts +49 -0
  317. package/daemon/dist/domain/session-registry.d.ts.map +1 -1
  318. package/daemon/dist/domain/session-registry.js +92 -5
  319. package/daemon/dist/domain/session-registry.js.map +1 -1
  320. package/daemon/dist/domain/session-transport.d.ts +46 -4
  321. package/daemon/dist/domain/session-transport.d.ts.map +1 -1
  322. package/daemon/dist/domain/session-transport.js +492 -26
  323. package/daemon/dist/domain/session-transport.js.map +1 -1
  324. package/daemon/dist/domain/startup-orchestrator.d.ts +10 -0
  325. package/daemon/dist/domain/startup-orchestrator.d.ts.map +1 -1
  326. package/daemon/dist/domain/startup-orchestrator.js +41 -4
  327. package/daemon/dist/domain/startup-orchestrator.js.map +1 -1
  328. package/daemon/dist/domain/successor-session-launcher.d.ts +3 -7
  329. package/daemon/dist/domain/successor-session-launcher.d.ts.map +1 -1
  330. package/daemon/dist/domain/successor-session-launcher.js +6 -32
  331. package/daemon/dist/domain/successor-session-launcher.js.map +1 -1
  332. package/daemon/dist/domain/terminal/terminal-service.d.ts +5 -1
  333. package/daemon/dist/domain/terminal/terminal-service.d.ts.map +1 -1
  334. package/daemon/dist/domain/terminal/terminal-service.js +30 -4
  335. package/daemon/dist/domain/terminal/terminal-service.js.map +1 -1
  336. package/daemon/dist/domain/terminal/view-composer.d.ts +6 -0
  337. package/daemon/dist/domain/terminal/view-composer.d.ts.map +1 -1
  338. package/daemon/dist/domain/terminal/view-composer.js +2 -1
  339. package/daemon/dist/domain/terminal/view-composer.js.map +1 -1
  340. package/daemon/dist/domain/transcript-store.js +1 -1
  341. package/daemon/dist/domain/transcript-store.js.map +1 -1
  342. package/daemon/dist/domain/types.d.ts +38 -0
  343. package/daemon/dist/domain/types.d.ts.map +1 -1
  344. package/daemon/dist/domain/types.js +5 -0
  345. package/daemon/dist/domain/types.js.map +1 -1
  346. package/daemon/dist/domain/usage-series.d.ts.map +1 -1
  347. package/daemon/dist/domain/usage-series.js +9 -4
  348. package/daemon/dist/domain/usage-series.js.map +1 -1
  349. package/daemon/dist/domain/user-settings/settings-store.d.ts +1 -1
  350. package/daemon/dist/domain/user-settings/settings-store.d.ts.map +1 -1
  351. package/daemon/dist/domain/user-settings/settings-store.js +44 -0
  352. package/daemon/dist/domain/user-settings/settings-store.js.map +1 -1
  353. package/daemon/dist/domain/view-projector.d.ts +4 -0
  354. package/daemon/dist/domain/view-projector.d.ts.map +1 -1
  355. package/daemon/dist/domain/view-projector.js +19 -4
  356. package/daemon/dist/domain/view-projector.js.map +1 -1
  357. package/daemon/dist/domain/wake-resolver.js +2 -2
  358. package/daemon/dist/domain/wake-resolver.js.map +1 -1
  359. package/daemon/dist/domain/watchdog-jobs-repository.d.ts.map +1 -1
  360. package/daemon/dist/domain/watchdog-jobs-repository.js +19 -3
  361. package/daemon/dist/domain/watchdog-jobs-repository.js.map +1 -1
  362. package/daemon/dist/domain/whoami-service.d.ts +4 -1
  363. package/daemon/dist/domain/whoami-service.d.ts.map +1 -1
  364. package/daemon/dist/domain/whoami-service.js +25 -19
  365. package/daemon/dist/domain/whoami-service.js.map +1 -1
  366. package/daemon/dist/domain/workflow-runtime.d.ts +1 -1
  367. package/daemon/dist/domain/workspace/project-read.d.ts +2 -0
  368. package/daemon/dist/domain/workspace/project-read.d.ts.map +1 -1
  369. package/daemon/dist/domain/workspace/project-read.js +19 -8
  370. package/daemon/dist/domain/workspace/project-read.js.map +1 -1
  371. package/daemon/dist/index.d.ts.map +1 -1
  372. package/daemon/dist/index.js +6 -0
  373. package/daemon/dist/index.js.map +1 -1
  374. package/daemon/dist/routes/activity.d.ts.map +1 -1
  375. package/daemon/dist/routes/activity.js +33 -1
  376. package/daemon/dist/routes/activity.js.map +1 -1
  377. package/daemon/dist/routes/chat.d.ts.map +1 -1
  378. package/daemon/dist/routes/chat.js +29 -4
  379. package/daemon/dist/routes/chat.js.map +1 -1
  380. package/daemon/dist/routes/projects.d.ts.map +1 -1
  381. package/daemon/dist/routes/projects.js +5 -1
  382. package/daemon/dist/routes/projects.js.map +1 -1
  383. package/daemon/dist/routes/proof.d.ts.map +1 -1
  384. package/daemon/dist/routes/proof.js +99 -10
  385. package/daemon/dist/routes/proof.js.map +1 -1
  386. package/daemon/dist/routes/provider.d.ts.map +1 -1
  387. package/daemon/dist/routes/provider.js +31 -0
  388. package/daemon/dist/routes/provider.js.map +1 -1
  389. package/daemon/dist/routes/query-limit.d.ts +19 -0
  390. package/daemon/dist/routes/query-limit.d.ts.map +1 -0
  391. package/daemon/dist/routes/query-limit.js +24 -0
  392. package/daemon/dist/routes/query-limit.js.map +1 -0
  393. package/daemon/dist/routes/queue.d.ts.map +1 -1
  394. package/daemon/dist/routes/queue.js +35 -12
  395. package/daemon/dist/routes/queue.js.map +1 -1
  396. package/daemon/dist/routes/rig-cmux.js +8 -10
  397. package/daemon/dist/routes/rig-cmux.js.map +1 -1
  398. package/daemon/dist/routes/rigs.d.ts.map +1 -1
  399. package/daemon/dist/routes/rigs.js +11 -7
  400. package/daemon/dist/routes/rigs.js.map +1 -1
  401. package/daemon/dist/routes/scopes.d.ts.map +1 -1
  402. package/daemon/dist/routes/scopes.js +5 -3
  403. package/daemon/dist/routes/scopes.js.map +1 -1
  404. package/daemon/dist/routes/seat.d.ts.map +1 -1
  405. package/daemon/dist/routes/seat.js +32 -0
  406. package/daemon/dist/routes/seat.js.map +1 -1
  407. package/daemon/dist/routes/stream.d.ts.map +1 -1
  408. package/daemon/dist/routes/stream.js +5 -1
  409. package/daemon/dist/routes/stream.js.map +1 -1
  410. package/daemon/dist/routes/up.d.ts.map +1 -1
  411. package/daemon/dist/routes/up.js +2 -1
  412. package/daemon/dist/routes/up.js.map +1 -1
  413. package/daemon/dist/routes/views.d.ts.map +1 -1
  414. package/daemon/dist/routes/views.js +7 -1
  415. package/daemon/dist/routes/views.js.map +1 -1
  416. package/daemon/dist/startup.d.ts.map +1 -1
  417. package/daemon/dist/startup.js +30 -1
  418. package/daemon/dist/startup.js.map +1 -1
  419. package/daemon/docs/reference/agent-startup-guide.md +19 -0
  420. package/daemon/docs/reference/getting-started.md +10 -6
  421. package/daemon/docs/reference/keeping-a-watch.md +156 -0
  422. package/daemon/docs/reference/rig-spec.md +2 -2
  423. package/daemon/docs/reference/sdlc-conventions.md +11 -1
  424. package/daemon/docs/reference/slack-app-setup.md +12 -4
  425. package/daemon/docs/reference/whats-new.md +151 -74
  426. package/daemon/specs/agents/development/qa/guidance/role.md +9 -0
  427. package/daemon/specs/agents/shared/skills/core/openrig-skills/SKILL.md +1 -1
  428. package/daemon/specs/agents/shared/skills/core/topology-mutation-and-seat-management/SKILL.md +2 -2
  429. package/daemon/specs/rigs/launch/factory/CULTURE.md +13 -0
  430. package/daemon/specs/rigs/launch/factory/guidance/lead-first-move.md +18 -5
  431. package/daemon/specs/rigs/launch/kernel/agents/operator/agent/guidance/role.md +20 -1
  432. package/daemon/specs/rigs/launch/starter/CULTURE.md +13 -0
  433. package/daemon/specs/rigs/launch/starter/guidance/lead-first-move.md +18 -5
  434. package/dist/build-info.js +3 -3
  435. package/dist/cli-error.d.ts.map +1 -1
  436. package/dist/cli-error.js +2 -0
  437. package/dist/cli-error.js.map +1 -1
  438. package/dist/commands/add.d.ts.map +1 -1
  439. package/dist/commands/add.js +55 -4
  440. package/dist/commands/add.js.map +1 -1
  441. package/dist/commands/capture.d.ts +9 -0
  442. package/dist/commands/capture.d.ts.map +1 -1
  443. package/dist/commands/capture.js +93 -41
  444. package/dist/commands/capture.js.map +1 -1
  445. package/dist/commands/config.d.ts.map +1 -1
  446. package/dist/commands/config.js +6 -1
  447. package/dist/commands/config.js.map +1 -1
  448. package/dist/commands/daemon.d.ts.map +1 -1
  449. package/dist/commands/daemon.js +44 -3
  450. package/dist/commands/daemon.js.map +1 -1
  451. package/dist/commands/down.d.ts.map +1 -1
  452. package/dist/commands/down.js +1 -50
  453. package/dist/commands/down.js.map +1 -1
  454. package/dist/commands/env.d.ts.map +1 -1
  455. package/dist/commands/env.js +6 -0
  456. package/dist/commands/env.js.map +1 -1
  457. package/dist/commands/heartbeat.js +2 -2
  458. package/dist/commands/heartbeat.js.map +1 -1
  459. package/dist/commands/proof.d.ts.map +1 -1
  460. package/dist/commands/proof.js +11 -5
  461. package/dist/commands/proof.js.map +1 -1
  462. package/dist/commands/provider.d.ts.map +1 -1
  463. package/dist/commands/provider.js +72 -0
  464. package/dist/commands/provider.js.map +1 -1
  465. package/dist/commands/ps.d.ts +7 -0
  466. package/dist/commands/ps.d.ts.map +1 -1
  467. package/dist/commands/ps.js +20 -6
  468. package/dist/commands/ps.js.map +1 -1
  469. package/dist/commands/queue.d.ts +48 -5
  470. package/dist/commands/queue.d.ts.map +1 -1
  471. package/dist/commands/queue.js +215 -45
  472. package/dist/commands/queue.js.map +1 -1
  473. package/dist/commands/scope.d.ts.map +1 -1
  474. package/dist/commands/scope.js +57 -36
  475. package/dist/commands/scope.js.map +1 -1
  476. package/dist/commands/seat.d.ts.map +1 -1
  477. package/dist/commands/seat.js +167 -10
  478. package/dist/commands/seat.js.map +1 -1
  479. package/dist/commands/setup.d.ts +6 -0
  480. package/dist/commands/setup.d.ts.map +1 -1
  481. package/dist/commands/setup.js +100 -44
  482. package/dist/commands/setup.js.map +1 -1
  483. package/dist/commands/start.d.ts.map +1 -1
  484. package/dist/commands/start.js +9 -4
  485. package/dist/commands/start.js.map +1 -1
  486. package/dist/commands/up.d.ts.map +1 -1
  487. package/dist/commands/up.js +10 -0
  488. package/dist/commands/up.js.map +1 -1
  489. package/dist/commands/usage.d.ts.map +1 -1
  490. package/dist/commands/usage.js +10 -5
  491. package/dist/commands/usage.js.map +1 -1
  492. package/dist/commands/workflow.d.ts.map +1 -1
  493. package/dist/commands/workflow.js +8 -8
  494. package/dist/commands/workflow.js.map +1 -1
  495. package/dist/config-store.d.ts +8 -1
  496. package/dist/config-store.d.ts.map +1 -1
  497. package/dist/config-store.js +57 -0
  498. package/dist/config-store.js.map +1 -1
  499. package/dist/daemon-lifecycle.d.ts +4 -0
  500. package/dist/daemon-lifecycle.d.ts.map +1 -1
  501. package/dist/daemon-lifecycle.js +16 -4
  502. package/dist/daemon-lifecycle.js.map +1 -1
  503. package/dist/lib/scope/capability-delta.d.ts.map +1 -1
  504. package/dist/lib/scope/capability-delta.js +8 -0
  505. package/dist/lib/scope/capability-delta.js.map +1 -1
  506. package/dist/lib/scope/mission-composition.d.ts +5 -1
  507. package/dist/lib/scope/mission-composition.d.ts.map +1 -1
  508. package/dist/lib/scope/mission-composition.js +61 -1
  509. package/dist/lib/scope/mission-composition.js.map +1 -1
  510. package/dist/lib/scope/progress-edit.js +1 -1
  511. package/dist/lib/scope/progress-edit.js.map +1 -1
  512. package/dist/lib/scope/scope-fs.d.ts +2 -1
  513. package/dist/lib/scope/scope-fs.d.ts.map +1 -1
  514. package/dist/lib/scope/scope-fs.js +7 -7
  515. package/dist/lib/scope/scope-fs.js.map +1 -1
  516. package/dist/lib/scope/slice-claims.d.ts +8 -0
  517. package/dist/lib/scope/slice-claims.d.ts.map +1 -0
  518. package/dist/lib/scope/slice-claims.js +88 -0
  519. package/dist/lib/scope/slice-claims.js.map +1 -0
  520. package/dist/queue-receipt.d.ts +41 -0
  521. package/dist/queue-receipt.d.ts.map +1 -0
  522. package/dist/queue-receipt.js +272 -0
  523. package/dist/queue-receipt.js.map +1 -0
  524. package/dist/rig-handle.d.ts +45 -0
  525. package/dist/rig-handle.d.ts.map +1 -0
  526. package/dist/rig-handle.js +51 -0
  527. package/dist/rig-handle.js.map +1 -0
  528. package/dist/system-preflight.d.ts +5 -0
  529. package/dist/system-preflight.d.ts.map +1 -1
  530. package/dist/system-preflight.js +8 -0
  531. package/dist/system-preflight.js.map +1 -1
  532. package/dist/terminal-window.d.ts.map +1 -1
  533. package/dist/terminal-window.js +3 -1
  534. package/dist/terminal-window.js.map +1 -1
  535. package/package.json +1 -1
  536. package/tui/dist/config/config-model.d.ts.map +1 -1
  537. package/tui/dist/config/config-model.js +3 -0
  538. package/tui/dist/config/config-model.js.map +1 -1
  539. package/tui/dist/daemon-client.d.ts +3 -0
  540. package/tui/dist/daemon-client.d.ts.map +1 -1
  541. package/tui/dist/daemon-client.js +4 -1
  542. package/tui/dist/daemon-client.js.map +1 -1
  543. package/tui/dist/detail.d.ts.map +1 -1
  544. package/tui/dist/detail.js +6 -1
  545. package/tui/dist/detail.js.map +1 -1
  546. package/tui/dist/hydrate.d.ts.map +1 -1
  547. package/tui/dist/hydrate.js +30 -21
  548. package/tui/dist/hydrate.js.map +1 -1
  549. package/tui/dist/input.d.ts.map +1 -1
  550. package/tui/dist/input.js +15 -4
  551. package/tui/dist/input.js.map +1 -1
  552. package/tui/dist/local-reading.js +2 -2
  553. package/tui/dist/local-reading.js.map +1 -1
  554. package/tui/dist/pulse/pulse-model.d.ts +1 -0
  555. package/tui/dist/pulse/pulse-model.d.ts.map +1 -1
  556. package/tui/dist/pulse/pulse-model.js +7 -3
  557. package/tui/dist/pulse/pulse-model.js.map +1 -1
  558. package/tui/dist/pulse/render-pulse.d.ts.map +1 -1
  559. package/tui/dist/pulse/render-pulse.js +3 -1
  560. package/tui/dist/pulse/render-pulse.js.map +1 -1
  561. package/tui/dist/reading.d.ts.map +1 -1
  562. package/tui/dist/reading.js +14 -3
  563. package/tui/dist/reading.js.map +1 -1
  564. package/tui/dist/render.d.ts.map +1 -1
  565. package/tui/dist/render.js +26 -11
  566. package/tui/dist/render.js.map +1 -1
  567. package/tui/dist/types.d.ts +3 -0
  568. package/tui/dist/types.d.ts.map +1 -1
  569. package/ui/dist/assets/{index-D5n8EwkG.js → index-DhmxKuZf.js} +159 -159
  570. package/ui/dist/index.html +1 -1
@@ -1,11 +1,13 @@
1
1
  import { nonInterruptiveNotice, nonInterruptiveSummary } from "../adapters/non-interruptive.js";
2
- import { readFileSync, writeFileSync } from "node:fs";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
3
  import { join } from "node:path";
4
4
  import { NativePermissionStore } from "./native-permission-store.js";
5
5
  import { resolvePermissionPolicyAttachment } from "./permission-policy/policy-ref.js";
6
+ import { claudeResumeRotation } from "./session-registry.js";
6
7
  import { assessNativeResumeProbe } from "./native-resume-probe.js";
7
- import { verifyClaudePaneProcess } from "./native-process-lineage.js";
8
+ import { observeClaudeDelivery, observeClaudeResumeLaunch, verifyClaudePaneProcess } from "./native-process-lineage.js";
8
9
  import { reanchorBuiltinStartupFile, reanchorShippedProjectionEntry } from "./builtin-startup-files.js";
10
+ import { seatGuidance, restoreMissingGuidance, missingGuidanceBlocks } from "./restore-guidance.js";
9
11
  import { AppliedLaunchObservationStore } from "./applied-launch-observation-store.js";
10
12
  import { classifyPaneRuntimeMatch } from "./seat-identity-reconciler.js";
11
13
  import { isShellForeground } from "./shell-classifier.js";
@@ -19,7 +21,7 @@ const LAUNCH_DEPENDENCY_KINDS = new Set(["delegates_to", "spawned_by"]);
19
21
  // in the pure leaf module active-occupant.ts, shared with preview, snapshot
20
22
  // usability, and lifecycle projection. Imported and re-exported here so the
21
23
  // existing export surface and the execution call sites below are unchanged.
22
- import { resolveActiveSnapshotSession, activeOccupantAmbiguityError } from "./active-occupant.js";
24
+ import { resolveActiveSnapshotSession, activeOccupantAmbiguityError, absentSeatResumeHistory, absentSeatResumeHistoryError } from "./active-occupant.js";
23
25
  export { resolveActiveSnapshotSession } from "./active-occupant.js";
24
26
  export function rollupRestoreRigResult(nodes) {
25
27
  if (nodes.length === 0)
@@ -30,6 +32,9 @@ export function rollupRestoreRigResult(nodes) {
30
32
  const allFailed = nodes.every((node) => node.status === "failed");
31
33
  if (allFailed)
32
34
  return "failed";
35
+ // A seat running without part of its guidance keeps its own status; the rig isn't fully restored.
36
+ if (nodes.some((node) => (node.guidanceGaps?.length ?? 0) > 0))
37
+ return "partially_restored";
33
38
  if (nodes.some((node) => node.status === "fresh" || node.status === "fresh-primed" || node.status === "awaiting-decision" || node.status === "failed" || node.status === "attention_required")) {
34
39
  return "partially_restored";
35
40
  }
@@ -48,6 +53,30 @@ export const NON_RUNNING_LAUNCH_STATUSES = new Set([
48
53
  export function launchStatusIsRunning(status) {
49
54
  return !NON_RUNNING_LAUNCH_STATUSES.has(status);
50
55
  }
56
+ /** What `rig launch` does for this node from this snapshot without --fresh, read as the restore path reads it: the
57
+ * occupant, then the pre-launch stop-and-ask check, then the resume decision (restoreNodeWithCompensation and the
58
+ * resume step after it). An exited agent's message offers stop-then-launch as a resume only when this says so. */
59
+ function snapshotLaunchOutcome(data, nodeId) {
60
+ const occupant = resolveActiveSnapshotSession(data, nodeId);
61
+ if (occupant.kind === "ambiguous")
62
+ return { kind: "unrecoverable", why: "can't tell which saved session is this seat's" };
63
+ const session = occupant.kind === "resolved" ? occupant.session : null;
64
+ if (!session) {
65
+ // The restore's own rule for a seat stopped at capture whose earlier occupant left a token.
66
+ const prior = occupant.kind === "none" ? absentSeatResumeHistory(data.sessions, nodeId) : null;
67
+ return prior
68
+ ? { kind: "decision", why: `had no running occupant for this seat when it was taken, but an earlier occupant left a '${prior.resumeType}' resume token` }
69
+ : { kind: "fresh", why: "saves no session for this seat" };
70
+ }
71
+ const policy = session.restorePolicy ?? "resume_if_possible";
72
+ if (policy !== "resume_if_possible")
73
+ return { kind: "fresh", why: `saves this seat with restore policy '${policy}'` };
74
+ if (!session.resumeToken)
75
+ return { kind: "decision", why: "has no resume token for this seat" };
76
+ if (!session.resumeType || session.resumeType === "none")
77
+ return { kind: "fresh", why: "records no resume source for this seat" };
78
+ return { kind: "resume" };
79
+ }
51
80
  export class RestoreOrchestrator {
52
81
  db;
53
82
  activeRestores = new Set();
@@ -334,11 +363,28 @@ export class RestoreOrchestrator {
334
363
  .filter((s) => s.nodeId === node.id && s.status === "running");
335
364
  let isLive = false;
336
365
  let isUnknown = false;
366
+ let idleSession;
337
367
  for (const session of sessions) {
338
368
  try {
339
369
  const alive = await this.tmuxAdapter.hasSession(session.sessionName);
340
370
  if (alive) {
371
+ // A preserved shell is not a running agent. Reuse the process-lineage
372
+ // check's positive idle-shell evidence; opaque wrappers stay untouched.
341
373
  isLive = true;
374
+ const binding = this.sessionRegistry.getBindingForNode(node.id);
375
+ const pane = binding?.tmuxSession === session.sessionName ? binding.tmuxPane : null;
376
+ const runtime = allNodes.find(current => current.id === node.id)?.runtime ?? node.runtime;
377
+ // Launch needs consistent positive evidence: both samples idle with the same fingerprint, and the
378
+ // bound pane still in this session (a recycled pane id could name another session's shell).
379
+ if (pane && ["claude-code", "codex", "pi", "omp"].includes(runtime ?? "")
380
+ && isShellForeground(await this.tmuxAdapter.getPaneCommand(pane) ?? "")
381
+ && (await this.tmuxAdapter.listPanes(session.sessionName)).some(candidate => candidate.id === pane)
382
+ && (await observeClaudeDelivery({ target: pane, tmux: this.tmuxAdapter, listProcesses: this.listProcesses }, { unknownKeepsIdle: false })).state === "idle_shell"
383
+ && isShellForeground(await this.tmuxAdapter.getPaneCommand(pane) ?? "")) {
384
+ idleSession = session.sessionName;
385
+ isLive = false;
386
+ continue;
387
+ }
342
388
  break;
343
389
  }
344
390
  }
@@ -350,6 +396,26 @@ export class RestoreOrchestrator {
350
396
  alreadyRunning.push({ nodeId: node.id, logicalId: node.logicalId });
351
397
  continue;
352
398
  }
399
+ if (idleSession) {
400
+ // Keep the pane/history and the existing per-target failure contract.
401
+ // Choosing a fresh versus resumed conversation belongs to the person. Stopping closes the pane, so
402
+ // stop-then-launch is offered as a resume only when this snapshot can resume the seat; otherwise the
403
+ // message says what that launch would do instead. The command pins the snapshot that was checked.
404
+ const outcome = snapshotLaunchOutcome(snapshot.data, node.id);
405
+ const launchCommand = `rig launch ${rigId} ${node.logicalId} --snapshot-id ${snapshot.id}`;
406
+ const relaunch = outcome.kind === "resume"
407
+ ? `To resume its conversation: rig seat stop ${idleSession} --reason "<why>", then ${launchCommand} (this closes the pane, and launch resumes from that snapshot's resume token). `
408
+ : `Stopping it and launching from snapshot ${snapshot.id} won't resume this conversation: that snapshot ${outcome.why}, so launch would `
409
+ + `${outcome.kind === "fresh" ? "start a fresh conversation" : outcome.kind === "decision" ? "start nothing and ask for a decision" : "fail"}. `;
410
+ launched.push({
411
+ nodeId: node.id, logicalId: node.logicalId, status: "attention_required",
412
+ error: `Session alive, agent not running for '${node.logicalId}': tmux session '${idleSession}' holds an idle shell, and its pane and history are preserved. `
413
+ + `The person chooses how to bring the agent back. ${relaunch}`
414
+ + `To start a blank occupant: rig seat launch ${idleSession} --fresh --stop --reason "<why>". `
415
+ + `To keep the pane: attach to tmux session '${idleSession}' and restart the agent there by hand.`,
416
+ });
417
+ continue;
418
+ }
353
419
  if (isUnknown) {
354
420
  // OPR.0.4.3.28 correction — INVERT the fail-closed-on-unknown launch default. A failed tmux
355
421
  // liveness probe is NOT positive evidence of a live seat (only isLive, above, is). Deny-by-
@@ -574,6 +640,10 @@ export class RestoreOrchestrator {
574
640
  node: nodeById.get(id),
575
641
  }));
576
642
  }
643
+ /**
644
+ * Restore one planned seat, checking continuity before launching its occupant.
645
+ * Preserve prior state so a failed launch or resume can be compensated.
646
+ */
577
647
  async restoreNodeWithCompensation(entry, rigId, snapshotId, data, opts, warnings) {
578
648
  const node = entry.node;
579
649
  const nodeId = node.id;
@@ -582,7 +652,7 @@ export class RestoreOrchestrator {
582
652
  // a pod node in 'restoring' otherwise returns a silent status "fresh"
583
653
  // (classified running downstream) while the occupant truth is ambiguous,
584
654
  // bypassing A1's loud-failure semantics. Resolved/none/legacy states
585
- // fall through and keep the restoring/degraded behavior unchanged.
655
+ // fall through to absent-history classification and the continuity check.
586
656
  const occupantResolution = resolveActiveSnapshotSession(data, nodeId);
587
657
  if (occupantResolution.kind === "ambiguous") {
588
658
  return {
@@ -592,6 +662,15 @@ export class RestoreOrchestrator {
592
662
  error: activeOccupantAmbiguityError(occupantResolution.candidateIds, occupantResolution.detail),
593
663
  };
594
664
  }
665
+ // Classify absent-seat history before the continuity short-circuit: a
666
+ // restoring seat must not report fresh while its forecast awaits a decision.
667
+ const freshRequested = opts?.freshLogicalIds?.includes(node.logicalId) ?? false;
668
+ const priorWithToken = occupantResolution.kind === "none" && !freshRequested
669
+ ? absentSeatResumeHistory(data.sessions, nodeId)
670
+ : null;
671
+ if (priorWithToken) {
672
+ return { nodeId, logicalId: node.logicalId, status: "awaiting-decision", error: absentSeatResumeHistoryError(node.logicalId, priorWithToken.resumeType, this.rigRepo.getRig(rigId)?.rig.name ?? data.rig.name) };
673
+ }
595
674
  // Consult live continuity state BEFORE clearing stale state
596
675
  if (node.podId) {
597
676
  const continuityRow = this.db.prepare("SELECT status FROM continuity_state WHERE pod_id = ? AND node_id = ?").get(node.podId, nodeId);
@@ -623,7 +702,6 @@ export class RestoreOrchestrator {
623
702
  // returned there, so only resolved/none reach here.
624
703
  const snapSession = occupantResolution.kind === "resolved" ? occupantResolution.session : null;
625
704
  const policy = snapSession?.restorePolicy ?? "resume_if_possible";
626
- const freshRequested = opts?.freshLogicalIds?.includes(node.logicalId) ?? false;
627
705
  const resumeSourceRecorded = !!snapSession?.resumeType && snapSession.resumeType !== "none";
628
706
  if (policy === "resume_if_possible" && snapSession && !snapSession.resumeToken && !freshRequested) {
629
707
  const sourceNote = resumeSourceRecorded
@@ -724,7 +802,39 @@ export class RestoreOrchestrator {
724
802
  if (launchResult.warnings?.length) {
725
803
  warnings?.push(...launchResult.warnings);
726
804
  }
727
- return this.postLaunchRestore(entry, rigId, data, launchResult.sessionName, launchResult, opts, warnings, priorState);
805
+ const restored = await this.postLaunchRestore(entry, rigId, data, launchResult.sessionName, launchResult, opts, warnings, priorState);
806
+ return this.checkRestoredGuidance(restored, entry.node, rigId, data, warnings);
807
+ }
808
+ /** A seat that came back running should also have its role, culture and SOP guidance. If its
809
+ * guidance file still lacks a managed block it should hold, the seat keeps its true status (a
810
+ * live resumed session is still running) and the gap is disclosed on the node and in the
811
+ * warnings, so the rig is reported partially_restored, not fully_restored. */
812
+ checkRestoredGuidance(result, node, rigId, data, warnings) {
813
+ // Every status with a live session; attention_required keeps its status and gains the disclosure.
814
+ if (!["resumed", "fresh-primed", "fresh", "rebuilt", "attention_required"].includes(result.status))
815
+ return result;
816
+ let guidance;
817
+ try {
818
+ guidance = seatGuidance(data.nodeStartupContext?.[node.id] ?? null, node.cwd, this.rigRepo.getRigClaudeManagedBlockFile(rigId), existsSync, (path) => readFileSync(path, "utf-8"));
819
+ }
820
+ catch (err) {
821
+ warnings?.push(`Restore: ${node.logicalId}: could not check its guidance: ${err.message}`);
822
+ return { ...result, guidanceGaps: ["(guidance check failed)"] };
823
+ }
824
+ if (!guidance || guidance.items.length === 0)
825
+ return result;
826
+ let missing;
827
+ try {
828
+ missing = missingGuidanceBlocks(guidance, { exists: existsSync, readFile: (path) => readFileSync(path, "utf-8") });
829
+ }
830
+ catch (err) {
831
+ missing = [`(could not read ${guidance.targetPath}: ${err.message})`];
832
+ }
833
+ if (missing.length === 0)
834
+ return result;
835
+ const gap = `${node.logicalId} is running without part of its guidance: ${guidance.targetPath} lacks the OpenRig blocks ${missing.join(", ")}.`;
836
+ warnings?.push(`Restore: ${gap}`);
837
+ return { ...result, guidanceGaps: missing };
728
838
  }
729
839
  /** OPR.0.3.4.2 (B) — roll a just-launched session back to ZERO sessions for
730
840
  * the awaiting-decision outcome: kill the live blank session, mark its row
@@ -804,6 +914,34 @@ export class RestoreOrchestrator {
804
914
  warnings?.push(`Restore activity hooks: ${error.message}`);
805
915
  }
806
916
  }
917
+ // A narrow exception to the replay containment below: before either native resume path
918
+ // starts the harness, put back only the MISSING managed guidance blocks from the saved
919
+ // startup selection. Ordinary `rig down` strips them; without this the resumed
920
+ // seat came back with no role, culture or SOP. Existing blocks are never refreshed; nothing
921
+ // reaches the conversation; no action, skill or plugin runs. Never blocks the resume.
922
+ if (resumeRequested && resumeToken && launchResult) {
923
+ let guidance = null;
924
+ try {
925
+ guidance = seatGuidance(startupCtx, node.cwd, this.rigRepo.getRigClaudeManagedBlockFile(rigId), existsSync, (path) => readFileSync(path, "utf-8"));
926
+ }
927
+ catch (err) {
928
+ // Guidance never blocks the exact resume; the post-launch check discloses the gap.
929
+ warnings?.push(`Restore guidance: ${node.logicalId}: could not read its saved guidance selection: ${err.message}`);
930
+ }
931
+ if (guidance && guidance.items.length > 0) {
932
+ const repair = restoreMissingGuidance(guidance, {
933
+ exists: existsSync,
934
+ readFile: (path) => readFileSync(path, "utf-8"),
935
+ writeFile: (path, content) => writeFileSync(path, content, "utf-8"),
936
+ mkdirp: (path) => mkdirSync(path, { recursive: true }),
937
+ });
938
+ if (repair.restored.length > 0) {
939
+ warnings?.push(`Restore guidance: ${node.logicalId}: put back missing blocks ${repair.restored.join(", ")} in ${guidance.targetPath} from their current source files.`);
940
+ }
941
+ for (const gap of repair.gaps)
942
+ warnings?.push(`Restore guidance: ${node.logicalId}: ${gap}`);
943
+ }
944
+ }
807
945
  if (resumeRequested && !isPodAware) {
808
946
  // Legacy resume path
809
947
  if (!resumeToken) {
@@ -815,9 +953,28 @@ export class RestoreOrchestrator {
815
953
  return { nodeId: node.id, logicalId: node.logicalId, status: "awaiting-decision", error: `Original session unresumable: resume requested but no token available. No session is running. Re-run with --fresh ${node.logicalId} for a deliberate fresh-primed seat, or restore the original session manually.` };
816
954
  }
817
955
  else {
956
+ const launchedSessionId = launchResult?.session.id;
957
+ if (launchedSessionId && this.claudeResume.canResume(resumeType, resumeToken)) {
958
+ // Before the resume: Claude's SessionStart hook can land before attemptResume returns.
959
+ try {
960
+ this.sessionRegistry.recordResumeLaunch(launchedSessionId, resumeToken);
961
+ }
962
+ catch { /* best-effort: without it a rotation stays unproved, as before */ }
963
+ }
818
964
  const resumeOutcome = await this.attemptResume(node.id, sessionName, resumeType, resumeToken, node.cwd ?? "/", node.codexConfigProfile, node.model, this.resolveRestorePosture(node.id, rigId), node.effort, warnings);
819
965
  if (resumeOutcome.kind === "resumed") {
820
966
  baseStatus = "resumed";
967
+ if (launchedSessionId && this.claudeResume.canResume(resumeType, resumeToken)) {
968
+ // The process this resume started, as the launch itself observes it (#1077): the one its
969
+ // identity check proved, else one observed now.
970
+ try {
971
+ const launched = resumeOutcome.launchedProcess ?? await observeClaudeResumeLaunch({ target: sessionName, tmux: this.tmuxAdapter,
972
+ ...(this.listProcesses ? { listProcesses: this.listProcesses } : {}), token: resumeToken });
973
+ if (launched)
974
+ this.sessionRegistry.recordResumeLaunchProcess(launchedSessionId, resumeToken, launched);
975
+ }
976
+ catch { /* best-effort: without it a rotation stays unproved, as before */ }
977
+ }
821
978
  }
822
979
  else if (resumeOutcome.kind === "attention_required") {
823
980
  // L3 Decision 2: Claude resume-selection prompt -> attention_required.
@@ -896,6 +1053,9 @@ export class RestoreOrchestrator {
896
1053
  // explicit+versioned+durable+idempotent contract in the D4 operation-id
897
1054
  // phase, where its durability primitives live. Deliberate fresh-primed
898
1055
  // launches are new histories and keep their replay.
1056
+ // One narrow exception: MISSING managed guidance blocks are put back before the harness
1057
+ // starts (see restoreMissingGuidance above); existing blocks are still never rewritten, and
1058
+ // nothing else is replayed.
899
1059
  const replayContained = resumeRequested && !!resumeToken;
900
1060
  const startupRuntime = startupCtx?.runtime ?? node.runtime ?? null;
901
1061
  const startupAdapter = startupRuntime ? opts?.adapters?.[startupRuntime] : undefined;
@@ -980,7 +1140,8 @@ export class RestoreOrchestrator {
980
1140
  };
981
1141
  try {
982
1142
  const { StartupOrchestrator } = await import("./startup-orchestrator.js");
983
- const startupOrch = new StartupOrchestrator({ db: this.db, sessionRegistry: this.sessionRegistry, eventBus: this.eventBus, tmuxAdapter: this.tmuxAdapter });
1143
+ const startupOrch = new StartupOrchestrator({ db: this.db, sessionRegistry: this.sessionRegistry, eventBus: this.eventBus, tmuxAdapter: this.tmuxAdapter,
1144
+ ...(this.listProcesses ? { listProcesses: this.listProcesses } : {}) });
984
1145
  const replayAsRestore = baseStatus !== "fresh-primed";
985
1146
  const shouldLaunchHarness = isPodAware;
986
1147
  const startupResult = await startupOrch.startNode({
@@ -1048,6 +1209,18 @@ export class RestoreOrchestrator {
1048
1209
  };
1049
1210
  }
1050
1211
  if (isPodAware && resumeRequested) {
1212
+ // Only the runtime's own report that the conversation doesn't exist rolls the seat back
1213
+ // as unresumable. A pane that went back to its shell for another reason stays failed,
1214
+ // with its pane and binding kept, so its output can still be read.
1215
+ if (startupResult.recovery === "retry_fresh" && startupResult.missingConversation) {
1216
+ await this.rollbackToZeroSession(node.id, sessionName, launchResult?.session.id, priorState);
1217
+ return {
1218
+ nodeId: node.id,
1219
+ logicalId: node.logicalId,
1220
+ status: "awaiting-decision",
1221
+ error: `Original session unresumable: ${startupResult.errors.join("; ")}. The blank session was rolled back; no session is running. Re-run with --fresh ${node.logicalId} to deliberately start a fresh-primed seat, or restore the original session manually.`,
1222
+ };
1223
+ }
1051
1224
  return {
1052
1225
  nodeId: node.id,
1053
1226
  logicalId: node.logicalId,
@@ -1140,7 +1313,10 @@ export class RestoreOrchestrator {
1140
1313
  // join; a hook/operator may have changed it meanwhile. Never backfill here.
1141
1314
  const retained = sameSession && (managedClaudeResume
1142
1315
  ? this.sessionRegistry.resumeTokenMatches(sessionId, "claude_id", resumeToken)
1316
+ // Claude continued the resumed conversation under a new id (its hook said so).
1317
+ || this.sessionRegistry.claudeResumeRotatedFrom(sessionId, resumeToken)
1143
1318
  : current.resume_token === resumeToken
1319
+ || (node.runtime === "claude-code" && this.sessionRegistry.claudeResumeRotatedFrom(sessionId, resumeToken))
1144
1320
  || (!current.resume_token && this.sessionRegistry.updateResumeToken(sessionId, node.runtime === "codex" ? "codex_id" : "claude_id", resumeToken, "scrape")));
1145
1321
  if (!retained) {
1146
1322
  markManagedResumeAttention();
@@ -1272,7 +1448,7 @@ export class RestoreOrchestrator {
1272
1448
  warnings?.push(`${sessionName}: ${notice}`);
1273
1449
  if (result.appliedLaunch && launchGeneration)
1274
1450
  this.appliedLaunchStore.recordGeneration(launchGeneration, result.appliedLaunch);
1275
- return { kind: "resumed" };
1451
+ return { kind: "resumed", ...(result.launchedProcess ? { launchedProcess: result.launchedProcess } : {}) };
1276
1452
  }
1277
1453
  if (result.code === "retry_fresh")
1278
1454
  return { kind: "retry_fresh" };
@@ -1412,11 +1588,15 @@ export class RestoreOrchestrator {
1412
1588
  if (!sessionName) {
1413
1589
  return { ok: false, code: "tmux_session_missing", detail: "No tmux session bound for this node." };
1414
1590
  }
1415
- const sessRow = this.db.prepare("SELECT session_name, resume_token FROM sessions WHERE node_id = ? ORDER BY created_at DESC, id DESC LIMIT 1").get(nodeId);
1591
+ const sessRow = this.db.prepare("SELECT session_name, resume_type, resume_token, resume_provenance, resume_rotated_from, resume_rotated_process, resume_launch_process FROM sessions WHERE node_id = ? ORDER BY created_at DESC, id DESC LIMIT 1").get(nodeId);
1416
1592
  if (!sessRow || sessRow.session_name !== sessionName) {
1417
1593
  return { ok: false, code: "binding_mismatch", detail: `Canonical binding ${sessionName} does not match the latest session row.` };
1418
1594
  }
1419
1595
  const expectedResumeToken = sessRow.resume_token;
1596
+ // The one alternative argv may carry: the token OpenRig launched this row to resume, when the
1597
+ // first hook after that launch recorded Claude continuing it as the stored token (#1077), and
1598
+ // only in the process that sent that hook.
1599
+ const rotation = sessRow.resume_type === "claude_id" ? claudeResumeRotation(sessRow) : null;
1420
1600
  if (!expectedResumeToken) {
1421
1601
  return { ok: false, code: "resume_token_not_used", detail: "No resume token recorded on the latest session row." };
1422
1602
  }
@@ -1437,6 +1617,7 @@ export class RestoreOrchestrator {
1437
1617
  // basename alone is never sufficient for no-input recovery.
1438
1618
  const nodeRow = this.db.prepare("SELECT runtime FROM nodes WHERE id = ?").get(nodeId);
1439
1619
  const runtime = nodeRow?.runtime ?? null;
1620
+ // One exact-lineage check per process, accepting the stored token or the recorded rotation.
1440
1621
  const identity = await rebindAndVerifyPaneIdentity({
1441
1622
  db: this.db,
1442
1623
  sessionRegistry: this.sessionRegistry,
@@ -1446,6 +1627,7 @@ export class RestoreOrchestrator {
1446
1627
  runtime,
1447
1628
  expectedResumeToken,
1448
1629
  requireExactResumeLineage: true,
1630
+ resumeRotation: rotation,
1449
1631
  ...(this.listProcesses ? { listProcesses: this.listProcesses } : {}),
1450
1632
  });
1451
1633
  if (!identity.ok) {
@@ -1457,6 +1639,7 @@ export class RestoreOrchestrator {
1457
1639
  target: identity.pane,
1458
1640
  tmux: this.tmuxAdapter,
1459
1641
  expectedToken: expectedResumeToken,
1642
+ rotation,
1460
1643
  requireResume: true,
1461
1644
  ...(this.listProcesses ? { listProcesses: this.listProcesses } : {}),
1462
1645
  });