@openrig/cli 0.6.9 → 0.6.10

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 (391) 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-user/SKILL.md +7 -1
  7. package/daemon/assets/skills/rigs/SKILL.md +6 -4
  8. package/daemon/context-packs/help/manifest.yaml +1 -1
  9. package/daemon/context-packs/onboarding-width/manifest.yaml +1 -1
  10. package/daemon/context-packs/onboarding-width/public-what-you-can-do.md +35 -10
  11. package/daemon/context-packs/reference/getting-started.md +10 -6
  12. package/daemon/context-packs/reference/manifest.yaml +1 -1
  13. package/daemon/context-packs/reference/whats-new.md +146 -70
  14. package/daemon/context-packs/skills/agent-operated-software/manifest.yaml +1 -1
  15. package/daemon/context-packs/skills/agent-operated-workflows/manifest.yaml +1 -1
  16. package/daemon/context-packs/skills/applying-a-permission-policy/manifest.yaml +1 -1
  17. package/daemon/context-packs/skills/claude-compaction-restore/manifest.yaml +1 -1
  18. package/daemon/context-packs/skills/core/agent-starters/manifest.yaml +1 -1
  19. package/daemon/context-packs/skills/core/agent-startup-and-context-ingestion/manifest.yaml +1 -1
  20. package/daemon/context-packs/skills/core/cross-host-rig-commands/manifest.yaml +1 -1
  21. package/daemon/context-packs/skills/core/human-in-the-loop/manifest.yaml +1 -1
  22. package/daemon/context-packs/skills/core/messaging-the-human/manifest.yaml +1 -1
  23. package/daemon/context-packs/skills/core/openrig-architect/manifest.yaml +1 -1
  24. package/daemon/context-packs/skills/core/openrig-cmux/manifest.yaml +1 -1
  25. package/daemon/context-packs/skills/core/openrig-herdr/manifest.yaml +1 -1
  26. package/daemon/context-packs/skills/core/openrig-skills/manifest.yaml +1 -1
  27. package/daemon/context-packs/skills/core/openrig-software-factory/manifest.yaml +1 -1
  28. package/daemon/context-packs/skills/core/openrig-upgrade/manifest.yaml +1 -1
  29. package/daemon/context-packs/skills/core/rig-bundles-and-shareable-artifacts/manifest.yaml +1 -1
  30. package/daemon/context-packs/skills/core/rig-lifecycle/manifest.yaml +1 -1
  31. package/daemon/context-packs/skills/core/session-source-fork/manifest.yaml +1 -1
  32. package/daemon/context-packs/skills/core/specification-system/manifest.yaml +1 -1
  33. package/daemon/context-packs/skills/core/topology-mutation-and-seat-management/SKILL.md +2 -2
  34. package/daemon/context-packs/skills/core/topology-mutation-and-seat-management/manifest.yaml +1 -1
  35. package/daemon/context-packs/skills/core/watchdog/manifest.yaml +1 -1
  36. package/daemon/context-packs/skills/delegating-work/manifest.yaml +1 -1
  37. package/daemon/context-packs/skills/forming-an-openrig-mental-model/manifest.yaml +1 -1
  38. package/daemon/context-packs/skills/loading-addressable-markdown/manifest.yaml +1 -1
  39. package/daemon/context-packs/skills/mission-slice-sop/manifest.yaml +1 -1
  40. package/daemon/context-packs/skills/openrig-operating-model/manifest.yaml +1 -1
  41. package/daemon/context-packs/skills/openrig-user/SKILL.md +7 -1
  42. package/daemon/context-packs/skills/openrig-user/manifest.yaml +1 -1
  43. package/daemon/context-packs/skills/orienting-to-an-inherited-seat/manifest.yaml +1 -1
  44. package/daemon/context-packs/skills/pm/backlog-capture/manifest.yaml +1 -1
  45. package/daemon/context-packs/skills/pm/context-builder/manifest.yaml +1 -1
  46. package/daemon/context-packs/skills/pm/exec-summary/manifest.yaml +1 -1
  47. package/daemon/context-packs/skills/pm/office-hours/manifest.yaml +1 -1
  48. package/daemon/context-packs/skills/pm/plan-review/manifest.yaml +1 -1
  49. package/daemon/context-packs/skills/pm/requirements-writer/manifest.yaml +1 -1
  50. package/daemon/context-packs/skills/pm/ui-mockup/manifest.yaml +1 -1
  51. package/daemon/context-packs/skills/pods/development-team/manifest.yaml +1 -1
  52. package/daemon/context-packs/skills/pods/orchestration-team/manifest.yaml +1 -1
  53. package/daemon/context-packs/skills/pods/oversight-team/manifest.yaml +1 -1
  54. package/daemon/context-packs/skills/pods/review-team/manifest.yaml +1 -1
  55. package/daemon/context-packs/skills/process/agent-browser/manifest.yaml +1 -1
  56. package/daemon/context-packs/skills/process/context-engineering/manifest.yaml +1 -1
  57. package/daemon/context-packs/skills/process/dogfood/manifest.yaml +1 -1
  58. package/daemon/context-packs/skills/process/frontend-design/manifest.yaml +1 -1
  59. package/daemon/context-packs/skills/process/systematic-debugging/manifest.yaml +1 -1
  60. package/daemon/context-packs/skills/process/test-driven-development/manifest.yaml +1 -1
  61. package/daemon/context-packs/skills/process/verification-before-completion/manifest.yaml +1 -1
  62. package/daemon/context-packs/skills/queue-handoff/manifest.yaml +1 -1
  63. package/daemon/context-packs/skills/refocusing/manifest.yaml +1 -1
  64. package/daemon/context-packs/skills/retiring-and-inheriting-a-seat/manifest.yaml +1 -1
  65. package/daemon/context-packs/skills/seat-continuity-and-handover/manifest.yaml +1 -1
  66. package/daemon/context-packs/skills/session-compaction-and-restore/manifest.yaml +1 -1
  67. package/daemon/context-packs/skills/software-for-agents/manifest.yaml +1 -1
  68. package/daemon/context-packs/world-example/manifest.yaml +1 -1
  69. package/daemon/context-packs/world-public/manifest.yaml +1 -1
  70. package/daemon/dist/adapters/claude-code-adapter.d.ts.map +1 -1
  71. package/daemon/dist/adapters/claude-code-adapter.js +16 -7
  72. package/daemon/dist/adapters/claude-code-adapter.js.map +1 -1
  73. package/daemon/dist/adapters/claude-resume-launch.d.ts +4 -0
  74. package/daemon/dist/adapters/claude-resume-launch.d.ts.map +1 -0
  75. package/daemon/dist/adapters/claude-resume-launch.js +13 -0
  76. package/daemon/dist/adapters/claude-resume-launch.js.map +1 -0
  77. package/daemon/dist/adapters/claude-resume.d.ts +2 -1
  78. package/daemon/dist/adapters/claude-resume.d.ts.map +1 -1
  79. package/daemon/dist/adapters/claude-resume.js +9 -4
  80. package/daemon/dist/adapters/claude-resume.js.map +1 -1
  81. package/daemon/dist/adapters/tmux-server.d.ts +15 -0
  82. package/daemon/dist/adapters/tmux-server.d.ts.map +1 -0
  83. package/daemon/dist/adapters/tmux-server.js +58 -0
  84. package/daemon/dist/adapters/tmux-server.js.map +1 -0
  85. package/daemon/dist/adapters/tmux.d.ts +3 -1
  86. package/daemon/dist/adapters/tmux.d.ts.map +1 -1
  87. package/daemon/dist/adapters/tmux.js +4 -2
  88. package/daemon/dist/adapters/tmux.js.map +1 -1
  89. package/daemon/dist/build-info.js +3 -3
  90. package/daemon/dist/db/all-migrations.d.ts.map +1 -1
  91. package/daemon/dist/db/all-migrations.js +4 -0
  92. package/daemon/dist/db/all-migrations.js.map +1 -1
  93. package/daemon/dist/db/migrations/099_queue_items_recovery_tags.d.ts +3 -0
  94. package/daemon/dist/db/migrations/099_queue_items_recovery_tags.d.ts.map +1 -0
  95. package/daemon/dist/db/migrations/099_queue_items_recovery_tags.js +19 -0
  96. package/daemon/dist/db/migrations/099_queue_items_recovery_tags.js.map +1 -0
  97. package/daemon/dist/db/migrations/101_claude_resume_rotation.d.ts +3 -0
  98. package/daemon/dist/db/migrations/101_claude_resume_rotation.d.ts.map +1 -0
  99. package/daemon/dist/db/migrations/101_claude_resume_rotation.js +19 -0
  100. package/daemon/dist/db/migrations/101_claude_resume_rotation.js.map +1 -0
  101. package/daemon/dist/domain/agent-activity-store.js +3 -0
  102. package/daemon/dist/domain/agent-activity-store.js.map +1 -1
  103. package/daemon/dist/domain/bootstrap-repository.js +1 -1
  104. package/daemon/dist/domain/bootstrap-repository.js.map +1 -1
  105. package/daemon/dist/domain/chat-repository.d.ts +3 -0
  106. package/daemon/dist/domain/chat-repository.d.ts.map +1 -1
  107. package/daemon/dist/domain/chat-repository.js +15 -4
  108. package/daemon/dist/domain/chat-repository.js.map +1 -1
  109. package/daemon/dist/domain/claude-managed-launch.d.ts +1 -1
  110. package/daemon/dist/domain/claude-managed-launch.d.ts.map +1 -1
  111. package/daemon/dist/domain/claude-managed-launch.js +3 -2
  112. package/daemon/dist/domain/claude-managed-launch.js.map +1 -1
  113. package/daemon/dist/domain/cmux-layout-service.d.ts.map +1 -1
  114. package/daemon/dist/domain/cmux-layout-service.js +2 -1
  115. package/daemon/dist/domain/cmux-layout-service.js.map +1 -1
  116. package/daemon/dist/domain/codex-git-add-dirs.js +1 -1
  117. package/daemon/dist/domain/codex-git-add-dirs.js.map +1 -1
  118. package/daemon/dist/domain/context-usage-store.d.ts.map +1 -1
  119. package/daemon/dist/domain/context-usage-store.js +6 -1
  120. package/daemon/dist/domain/context-usage-store.js.map +1 -1
  121. package/daemon/dist/domain/crash-cart-conductor.d.ts.map +1 -1
  122. package/daemon/dist/domain/crash-cart-conductor.js +3 -1
  123. package/daemon/dist/domain/crash-cart-conductor.js.map +1 -1
  124. package/daemon/dist/domain/files/file-read.d.ts.map +1 -1
  125. package/daemon/dist/domain/files/file-read.js +11 -3
  126. package/daemon/dist/domain/files/file-read.js.map +1 -1
  127. package/daemon/dist/domain/gateway/connections-projection.d.ts +1 -1
  128. package/daemon/dist/domain/gateway/slack/inbound.d.ts +21 -2
  129. package/daemon/dist/domain/gateway/slack/inbound.d.ts.map +1 -1
  130. package/daemon/dist/domain/gateway/slack/inbound.js +70 -11
  131. package/daemon/dist/domain/gateway/slack/inbound.js.map +1 -1
  132. package/daemon/dist/domain/gateway/slack/slack-delivery.d.ts +4 -0
  133. package/daemon/dist/domain/gateway/slack/slack-delivery.d.ts.map +1 -1
  134. package/daemon/dist/domain/gateway/slack/slack-delivery.js +1 -1
  135. package/daemon/dist/domain/gateway/slack/slack-delivery.js.map +1 -1
  136. package/daemon/dist/domain/gateway/slack/slack-subsystem.d.ts.map +1 -1
  137. package/daemon/dist/domain/gateway/slack/slack-subsystem.js +7 -4
  138. package/daemon/dist/domain/gateway/slack/slack-subsystem.js.map +1 -1
  139. package/daemon/dist/domain/history-query.d.ts.map +1 -1
  140. package/daemon/dist/domain/history-query.js +8 -6
  141. package/daemon/dist/domain/history-query.js.map +1 -1
  142. package/daemon/dist/domain/human-questions.d.ts +4 -1
  143. package/daemon/dist/domain/human-questions.d.ts.map +1 -1
  144. package/daemon/dist/domain/human-questions.js.map +1 -1
  145. package/daemon/dist/domain/install-engine.js +2 -2
  146. package/daemon/dist/domain/install-engine.js.map +1 -1
  147. package/daemon/dist/domain/native-process-lineage.d.ts +52 -4
  148. package/daemon/dist/domain/native-process-lineage.d.ts.map +1 -1
  149. package/daemon/dist/domain/native-process-lineage.js +224 -27
  150. package/daemon/dist/domain/native-process-lineage.js.map +1 -1
  151. package/daemon/dist/domain/node-cmux-service.d.ts.map +1 -1
  152. package/daemon/dist/domain/node-cmux-service.js +2 -1
  153. package/daemon/dist/domain/node-cmux-service.js.map +1 -1
  154. package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
  155. package/daemon/dist/domain/node-inventory.js +58 -13
  156. package/daemon/dist/domain/node-inventory.js.map +1 -1
  157. package/daemon/dist/domain/progress/progress-indexer.d.ts.map +1 -1
  158. package/daemon/dist/domain/progress/progress-indexer.js +19 -0
  159. package/daemon/dist/domain/progress/progress-indexer.js.map +1 -1
  160. package/daemon/dist/domain/provider/codex-limit-banner.d.ts +40 -0
  161. package/daemon/dist/domain/provider/codex-limit-banner.d.ts.map +1 -0
  162. package/daemon/dist/domain/provider/codex-limit-banner.js +121 -0
  163. package/daemon/dist/domain/provider/codex-limit-banner.js.map +1 -0
  164. package/daemon/dist/domain/ps-projection.d.ts.map +1 -1
  165. package/daemon/dist/domain/ps-projection.js +3 -2
  166. package/daemon/dist/domain/ps-projection.js.map +1 -1
  167. package/daemon/dist/domain/queue-recovery.d.ts.map +1 -1
  168. package/daemon/dist/domain/queue-recovery.js +10 -3
  169. package/daemon/dist/domain/queue-recovery.js.map +1 -1
  170. package/daemon/dist/domain/queue-repository.d.ts +66 -13
  171. package/daemon/dist/domain/queue-repository.d.ts.map +1 -1
  172. package/daemon/dist/domain/queue-repository.js +56 -40
  173. package/daemon/dist/domain/queue-repository.js.map +1 -1
  174. package/daemon/dist/domain/queue-stuck-sweep.d.ts.map +1 -1
  175. package/daemon/dist/domain/queue-stuck-sweep.js +5 -2
  176. package/daemon/dist/domain/queue-stuck-sweep.js.map +1 -1
  177. package/daemon/dist/domain/queue-wake-ladder.d.ts +17 -0
  178. package/daemon/dist/domain/queue-wake-ladder.d.ts.map +1 -1
  179. package/daemon/dist/domain/queue-wake-ladder.js +49 -3
  180. package/daemon/dist/domain/queue-wake-ladder.js.map +1 -1
  181. package/daemon/dist/domain/restore-guidance.d.ts +39 -0
  182. package/daemon/dist/domain/restore-guidance.d.ts.map +1 -0
  183. package/daemon/dist/domain/restore-guidance.js +163 -0
  184. package/daemon/dist/domain/restore-guidance.js.map +1 -0
  185. package/daemon/dist/domain/restore-orchestrator.d.ts +6 -1
  186. package/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
  187. package/daemon/dist/domain/restore-orchestrator.js +160 -6
  188. package/daemon/dist/domain/restore-orchestrator.js.map +1 -1
  189. package/daemon/dist/domain/runtime-adapter.d.ts +2 -0
  190. package/daemon/dist/domain/runtime-adapter.d.ts.map +1 -1
  191. package/daemon/dist/domain/runtime-adapter.js.map +1 -1
  192. package/daemon/dist/domain/scope/scope-view-projection.d.ts.map +1 -1
  193. package/daemon/dist/domain/scope/scope-view-projection.js +5 -7
  194. package/daemon/dist/domain/scope/scope-view-projection.js.map +1 -1
  195. package/daemon/dist/domain/seat-attention-reconciler.d.ts +5 -2
  196. package/daemon/dist/domain/seat-attention-reconciler.d.ts.map +1 -1
  197. package/daemon/dist/domain/seat-attention-reconciler.js +18 -4
  198. package/daemon/dist/domain/seat-attention-reconciler.js.map +1 -1
  199. package/daemon/dist/domain/seat-identity-reconciler.d.ts.map +1 -1
  200. package/daemon/dist/domain/seat-identity-reconciler.js +7 -2
  201. package/daemon/dist/domain/seat-identity-reconciler.js.map +1 -1
  202. package/daemon/dist/domain/seat-lifecycle-service.d.ts.map +1 -1
  203. package/daemon/dist/domain/seat-status-service.d.ts +2 -1
  204. package/daemon/dist/domain/seat-status-service.d.ts.map +1 -1
  205. package/daemon/dist/domain/seat-status-service.js +1 -0
  206. package/daemon/dist/domain/seat-status-service.js.map +1 -1
  207. package/daemon/dist/domain/seat-structural-activity-service.d.ts +9 -1
  208. package/daemon/dist/domain/seat-structural-activity-service.d.ts.map +1 -1
  209. package/daemon/dist/domain/seat-structural-activity-service.js +28 -4
  210. package/daemon/dist/domain/seat-structural-activity-service.js.map +1 -1
  211. package/daemon/dist/domain/seat-switch-client-service.d.ts.map +1 -1
  212. package/daemon/dist/domain/seat-switch-client-service.js +2 -1
  213. package/daemon/dist/domain/seat-switch-client-service.js.map +1 -1
  214. package/daemon/dist/domain/session-registry.d.ts +46 -0
  215. package/daemon/dist/domain/session-registry.d.ts.map +1 -1
  216. package/daemon/dist/domain/session-registry.js +86 -4
  217. package/daemon/dist/domain/session-registry.js.map +1 -1
  218. package/daemon/dist/domain/session-transport.d.ts +13 -1
  219. package/daemon/dist/domain/session-transport.d.ts.map +1 -1
  220. package/daemon/dist/domain/session-transport.js +101 -5
  221. package/daemon/dist/domain/session-transport.js.map +1 -1
  222. package/daemon/dist/domain/startup-orchestrator.d.ts +8 -0
  223. package/daemon/dist/domain/startup-orchestrator.d.ts.map +1 -1
  224. package/daemon/dist/domain/startup-orchestrator.js +37 -1
  225. package/daemon/dist/domain/startup-orchestrator.js.map +1 -1
  226. package/daemon/dist/domain/terminal/terminal-service.d.ts +5 -1
  227. package/daemon/dist/domain/terminal/terminal-service.d.ts.map +1 -1
  228. package/daemon/dist/domain/terminal/terminal-service.js +30 -4
  229. package/daemon/dist/domain/terminal/terminal-service.js.map +1 -1
  230. package/daemon/dist/domain/terminal/view-composer.d.ts +6 -0
  231. package/daemon/dist/domain/terminal/view-composer.d.ts.map +1 -1
  232. package/daemon/dist/domain/terminal/view-composer.js +2 -1
  233. package/daemon/dist/domain/terminal/view-composer.js.map +1 -1
  234. package/daemon/dist/domain/transcript-store.js +1 -1
  235. package/daemon/dist/domain/transcript-store.js.map +1 -1
  236. package/daemon/dist/domain/types.d.ts +9 -0
  237. package/daemon/dist/domain/types.d.ts.map +1 -1
  238. package/daemon/dist/domain/types.js +5 -0
  239. package/daemon/dist/domain/types.js.map +1 -1
  240. package/daemon/dist/domain/usage-series.d.ts.map +1 -1
  241. package/daemon/dist/domain/usage-series.js +9 -4
  242. package/daemon/dist/domain/usage-series.js.map +1 -1
  243. package/daemon/dist/domain/user-settings/settings-store.d.ts +1 -1
  244. package/daemon/dist/domain/user-settings/settings-store.d.ts.map +1 -1
  245. package/daemon/dist/domain/user-settings/settings-store.js +13 -0
  246. package/daemon/dist/domain/user-settings/settings-store.js.map +1 -1
  247. package/daemon/dist/domain/view-projector.d.ts +4 -0
  248. package/daemon/dist/domain/view-projector.d.ts.map +1 -1
  249. package/daemon/dist/domain/view-projector.js +19 -4
  250. package/daemon/dist/domain/view-projector.js.map +1 -1
  251. package/daemon/dist/domain/workflow-runtime.d.ts +1 -1
  252. package/daemon/dist/routes/activity.d.ts.map +1 -1
  253. package/daemon/dist/routes/activity.js +33 -1
  254. package/daemon/dist/routes/activity.js.map +1 -1
  255. package/daemon/dist/routes/chat.d.ts.map +1 -1
  256. package/daemon/dist/routes/chat.js +6 -2
  257. package/daemon/dist/routes/chat.js.map +1 -1
  258. package/daemon/dist/routes/projects.d.ts.map +1 -1
  259. package/daemon/dist/routes/projects.js +5 -1
  260. package/daemon/dist/routes/projects.js.map +1 -1
  261. package/daemon/dist/routes/query-limit.d.ts +19 -0
  262. package/daemon/dist/routes/query-limit.d.ts.map +1 -0
  263. package/daemon/dist/routes/query-limit.js +24 -0
  264. package/daemon/dist/routes/query-limit.js.map +1 -0
  265. package/daemon/dist/routes/queue.d.ts.map +1 -1
  266. package/daemon/dist/routes/queue.js +18 -7
  267. package/daemon/dist/routes/queue.js.map +1 -1
  268. package/daemon/dist/routes/rig-cmux.js +8 -10
  269. package/daemon/dist/routes/rig-cmux.js.map +1 -1
  270. package/daemon/dist/routes/rigs.d.ts.map +1 -1
  271. package/daemon/dist/routes/rigs.js +6 -4
  272. package/daemon/dist/routes/rigs.js.map +1 -1
  273. package/daemon/dist/routes/stream.d.ts.map +1 -1
  274. package/daemon/dist/routes/stream.js +5 -1
  275. package/daemon/dist/routes/stream.js.map +1 -1
  276. package/daemon/dist/routes/up.d.ts.map +1 -1
  277. package/daemon/dist/routes/up.js +2 -1
  278. package/daemon/dist/routes/up.js.map +1 -1
  279. package/daemon/dist/routes/views.d.ts.map +1 -1
  280. package/daemon/dist/routes/views.js +7 -1
  281. package/daemon/dist/routes/views.js.map +1 -1
  282. package/daemon/dist/startup.d.ts.map +1 -1
  283. package/daemon/dist/startup.js +19 -0
  284. package/daemon/dist/startup.js.map +1 -1
  285. package/daemon/docs/reference/getting-started.md +10 -6
  286. package/daemon/docs/reference/slack-app-setup.md +6 -0
  287. package/daemon/docs/reference/whats-new.md +146 -70
  288. package/daemon/specs/agents/development/qa/guidance/role.md +9 -0
  289. package/daemon/specs/agents/shared/skills/core/topology-mutation-and-seat-management/SKILL.md +2 -2
  290. package/daemon/specs/rigs/launch/factory/CULTURE.md +13 -0
  291. package/daemon/specs/rigs/launch/factory/guidance/lead-first-move.md +18 -5
  292. package/daemon/specs/rigs/launch/kernel/agents/operator/agent/guidance/role.md +20 -1
  293. package/daemon/specs/rigs/launch/starter/CULTURE.md +13 -0
  294. package/daemon/specs/rigs/launch/starter/guidance/lead-first-move.md +18 -5
  295. package/dist/build-info.js +3 -3
  296. package/dist/cli-error.d.ts.map +1 -1
  297. package/dist/cli-error.js +2 -0
  298. package/dist/cli-error.js.map +1 -1
  299. package/dist/commands/add.d.ts.map +1 -1
  300. package/dist/commands/add.js +55 -4
  301. package/dist/commands/add.js.map +1 -1
  302. package/dist/commands/capture.d.ts +9 -0
  303. package/dist/commands/capture.d.ts.map +1 -1
  304. package/dist/commands/capture.js +93 -41
  305. package/dist/commands/capture.js.map +1 -1
  306. package/dist/commands/config.d.ts.map +1 -1
  307. package/dist/commands/config.js +4 -1
  308. package/dist/commands/config.js.map +1 -1
  309. package/dist/commands/daemon.d.ts.map +1 -1
  310. package/dist/commands/daemon.js +37 -3
  311. package/dist/commands/daemon.js.map +1 -1
  312. package/dist/commands/down.d.ts.map +1 -1
  313. package/dist/commands/down.js +1 -50
  314. package/dist/commands/down.js.map +1 -1
  315. package/dist/commands/env.d.ts.map +1 -1
  316. package/dist/commands/env.js +6 -0
  317. package/dist/commands/env.js.map +1 -1
  318. package/dist/commands/heartbeat.js +2 -2
  319. package/dist/commands/heartbeat.js.map +1 -1
  320. package/dist/commands/ps.d.ts +3 -0
  321. package/dist/commands/ps.d.ts.map +1 -1
  322. package/dist/commands/ps.js +8 -3
  323. package/dist/commands/ps.js.map +1 -1
  324. package/dist/commands/queue.d.ts +39 -6
  325. package/dist/commands/queue.d.ts.map +1 -1
  326. package/dist/commands/queue.js +127 -33
  327. package/dist/commands/queue.js.map +1 -1
  328. package/dist/commands/seat.d.ts.map +1 -1
  329. package/dist/commands/seat.js +6 -0
  330. package/dist/commands/seat.js.map +1 -1
  331. package/dist/commands/setup.d.ts +6 -0
  332. package/dist/commands/setup.d.ts.map +1 -1
  333. package/dist/commands/setup.js +100 -44
  334. package/dist/commands/setup.js.map +1 -1
  335. package/dist/commands/start.d.ts.map +1 -1
  336. package/dist/commands/start.js +5 -1
  337. package/dist/commands/start.js.map +1 -1
  338. package/dist/commands/usage.d.ts.map +1 -1
  339. package/dist/commands/usage.js +10 -5
  340. package/dist/commands/usage.js.map +1 -1
  341. package/dist/commands/workflow.d.ts.map +1 -1
  342. package/dist/commands/workflow.js +8 -8
  343. package/dist/commands/workflow.js.map +1 -1
  344. package/dist/config-store.d.ts +2 -1
  345. package/dist/config-store.d.ts.map +1 -1
  346. package/dist/config-store.js +14 -0
  347. package/dist/config-store.js.map +1 -1
  348. package/dist/daemon-lifecycle.d.ts +4 -0
  349. package/dist/daemon-lifecycle.d.ts.map +1 -1
  350. package/dist/daemon-lifecycle.js +16 -4
  351. package/dist/daemon-lifecycle.js.map +1 -1
  352. package/dist/lib/scope/capability-delta.d.ts.map +1 -1
  353. package/dist/lib/scope/capability-delta.js +8 -0
  354. package/dist/lib/scope/capability-delta.js.map +1 -1
  355. package/dist/lib/scope/progress-edit.js +1 -1
  356. package/dist/lib/scope/progress-edit.js.map +1 -1
  357. package/dist/lib/scope/scope-fs.js +3 -3
  358. package/dist/lib/scope/scope-fs.js.map +1 -1
  359. package/dist/rig-handle.d.ts +45 -0
  360. package/dist/rig-handle.d.ts.map +1 -0
  361. package/dist/rig-handle.js +51 -0
  362. package/dist/rig-handle.js.map +1 -0
  363. package/dist/system-preflight.d.ts +5 -0
  364. package/dist/system-preflight.d.ts.map +1 -1
  365. package/dist/system-preflight.js +8 -0
  366. package/dist/system-preflight.js.map +1 -1
  367. package/dist/terminal-window.d.ts.map +1 -1
  368. package/dist/terminal-window.js +3 -1
  369. package/dist/terminal-window.js.map +1 -1
  370. package/package.json +1 -1
  371. package/tui/dist/config/config-model.d.ts.map +1 -1
  372. package/tui/dist/config/config-model.js +1 -0
  373. package/tui/dist/config/config-model.js.map +1 -1
  374. package/tui/dist/daemon-client.d.ts +3 -0
  375. package/tui/dist/daemon-client.d.ts.map +1 -1
  376. package/tui/dist/daemon-client.js +4 -1
  377. package/tui/dist/daemon-client.js.map +1 -1
  378. package/tui/dist/detail.d.ts.map +1 -1
  379. package/tui/dist/detail.js +6 -1
  380. package/tui/dist/detail.js.map +1 -1
  381. package/tui/dist/hydrate.d.ts.map +1 -1
  382. package/tui/dist/hydrate.js +19 -17
  383. package/tui/dist/hydrate.js.map +1 -1
  384. package/tui/dist/input.d.ts.map +1 -1
  385. package/tui/dist/input.js +15 -4
  386. package/tui/dist/input.js.map +1 -1
  387. package/tui/dist/local-reading.js +2 -2
  388. package/tui/dist/local-reading.js.map +1 -1
  389. package/tui/dist/reading.d.ts.map +1 -1
  390. package/tui/dist/reading.js +14 -3
  391. package/tui/dist/reading.js.map +1 -1
@@ -0,0 +1,163 @@
1
+ // A resumed seat's working guidance.
2
+ //
3
+ // An exact resume replays no startup content (the replay containment in restore-orchestrator.ts),
4
+ // because managed CLAUDE.md blocks were once rewritten during a resume. Ordinary `rig down` still
5
+ // strips OpenRig's managed blocks from each seat's guidance file, so an exact resume came back with
6
+ // no role, culture or SOP guidance (and the rig reported fully_restored). The exception is narrow:
7
+ // before the native harness starts, put back only the managed guidance blocks that are MISSING,
8
+ // from the saved startup selection (guidance projections and guidance_merge startup files). An
9
+ // existing block is never refreshed or overwritten; nothing is sent to the conversation; no
10
+ // startup action, skill or plugin runs; no profile is resolved again. The blocks are rebuilt from
11
+ // the saved source paths' current bytes, not from a byte snapshot of the old file.
12
+ //
13
+ // Guidance problems never block the exact resume. What can't be put back is reported.
14
+ import nodePath from "node:path";
15
+ import { MANAGED_BLOCK_START, MANAGED_BLOCK_END, DEFAULT_CLAUDE_MANAGED_BLOCK_FILE, mergeManagedBlock, stripManagedBlocks, } from "./managed-blocks.js";
16
+ import { resolveConcreteHint } from "./runtime-adapter.js";
17
+ import { reanchorBuiltinStartupFile, reanchorShippedProjectionEntry } from "./builtin-startup-files.js";
18
+ const LEGACY_BLOCK_START = (id) => `<!-- BEGIN RIGGED MANAGED BLOCK: ${id} -->`;
19
+ const LEGACY_BLOCK_END = (id) => `<!-- END RIGGED MANAGED BLOCK: ${id} -->`;
20
+ /** The per-seat role block is delivered through send_text, never merged into a shared file
21
+ * (ADR-0006); the adapters skip it, and so does this. */
22
+ const NEVER_MERGED = new Set(["rig-role"]);
23
+ /** The guidance file a seat's managed blocks live in, and the blocks it should hold on restore. */
24
+ export function seatGuidance(startupCtx, cwd, claudeManagedBlockFile, exists, readFile) {
25
+ if (!startupCtx || !cwd)
26
+ return null;
27
+ const fileName = startupCtx.runtime === "claude-code"
28
+ ? (claudeManagedBlockFile ?? DEFAULT_CLAUDE_MANAGED_BLOCK_FILE)
29
+ : startupCtx.runtime === "codex" ? "AGENTS.md" : null;
30
+ if (!fileName)
31
+ return null;
32
+ const items = new Map();
33
+ for (const saved of startupCtx.projectionEntries) {
34
+ if (saved.category !== "guidance" || saved.mergeStrategy !== "managed_block")
35
+ continue;
36
+ const e = reanchorShippedProjectionEntry(saved, undefined, exists);
37
+ items.set(e.effectiveId, { blockId: e.effectiveId, sourcePath: e.absolutePath });
38
+ }
39
+ // Every guidance startup file the last launch merged, whatever its appliesOn: a fresh-start-only
40
+ // file (onboarding, an agent starter) was merged at that launch and stayed in the file until
41
+ // `rig down` stripped it, so it is part of what the resumed conversation had.
42
+ for (const saved of startupCtx.resolvedStartupFiles) {
43
+ const f = reanchorBuiltinStartupFile(saved, undefined, undefined, exists);
44
+ // An "auto" file is classified from its content, as at launch (a `# SKILL` file is a skill,
45
+ // not guidance). If the source can't be read it can't be classified: it is reported, not dropped.
46
+ let hint = f.deliveryHint;
47
+ if (hint === "auto") {
48
+ try {
49
+ hint = resolveConcreteHint(f.path, readFile(f.absolutePath));
50
+ }
51
+ catch {
52
+ if (f.path.endsWith(".md") && !f.path.endsWith("SKILL.md")) {
53
+ items.set(f.path, { blockId: f.path, sourcePath: f.absolutePath, unresolved: true });
54
+ }
55
+ continue;
56
+ }
57
+ }
58
+ if (hint !== "guidance_merge")
59
+ continue;
60
+ items.set(f.path, { blockId: f.path, sourcePath: f.absolutePath });
61
+ }
62
+ for (const id of NEVER_MERGED)
63
+ items.delete(id);
64
+ return { targetPath: nodePath.join(cwd, fileName), items: [...items.values()] };
65
+ }
66
+ /** A block counts only with both its markers (current or legacy form). A lone marker is incomplete:
67
+ * writing next to it is unsafe, because cleanup strips from a BEGIN to the next END. */
68
+ function blockState(content, blockId) {
69
+ const current = [content.includes(MANAGED_BLOCK_START(blockId)), content.includes(MANAGED_BLOCK_END(blockId))];
70
+ const legacy = [content.includes(LEGACY_BLOCK_START(blockId)), content.includes(LEGACY_BLOCK_END(blockId))];
71
+ if ((current[0] && current[1]) || (legacy[0] && legacy[1]))
72
+ return "complete";
73
+ if (current[0] || current[1] || legacy[0] || legacy[1])
74
+ return "incomplete";
75
+ return "absent";
76
+ }
77
+ function blockStates(guidance, fs) {
78
+ const content = fs.exists(guidance.targetPath) ? fs.readFile(guidance.targetPath) : "";
79
+ return new Map(guidance.items.map((item) => [item.blockId, blockState(content, item.blockId)]));
80
+ }
81
+ /** The block ids the seat's guidance file lacks right now (absent, or only partly there). */
82
+ export function missingGuidanceBlocks(guidance, fs) {
83
+ return [...blockStates(guidance, fs)].filter(([, state]) => state !== "complete").map(([id]) => id);
84
+ }
85
+ /** Put back only the missing managed guidance blocks. Existing blocks and any other text in the
86
+ * file are left exactly as they are. Never throws: a failure becomes a reported gap. */
87
+ /** Would appending these blocks to `content` be safe for the next `rig down`? Decided by effect,
88
+ * with cleanup itself: safe only when stripping the new file gives exactly what stripping the
89
+ * current one gives, so the added blocks strip away cleanly and take nothing else with them. A
90
+ * stray, truncated or misplaced marker (cleanup strips from any BEGIN to the next END that ends a
91
+ * line) makes the two differ. No second marker grammar to keep in step with cleanup. */
92
+ export function appendIsCleanupSafe(content, blocks) {
93
+ let candidate = content;
94
+ const memory = {
95
+ exists: () => true,
96
+ readFile: () => candidate,
97
+ writeFile: (_path, next) => { candidate = next; },
98
+ };
99
+ for (const block of blocks)
100
+ mergeManagedBlock(memory, "(in memory)", block.blockId, block.content);
101
+ return stripManagedBlocks(candidate) === stripManagedBlocks(content);
102
+ }
103
+ /** Put back only the missing managed guidance blocks. Existing blocks and any other text in the
104
+ * file are left exactly as they are, and nothing is written unless cleanup would later remove
105
+ * exactly what was added. Never throws: a failure becomes a reported gap. */
106
+ export function restoreMissingGuidance(guidance, fs) {
107
+ const repair = { restored: [], gaps: [] };
108
+ let states;
109
+ let existing;
110
+ try {
111
+ states = blockStates(guidance, fs);
112
+ existing = fs.exists(guidance.targetPath) ? fs.readFile(guidance.targetPath) : null;
113
+ }
114
+ catch (err) {
115
+ repair.gaps.push(`could not read ${guidance.targetPath}: ${err.message}`);
116
+ return repair;
117
+ }
118
+ const toWrite = [];
119
+ for (const item of guidance.items) {
120
+ const state = states.get(item.blockId);
121
+ if (state === "complete")
122
+ continue;
123
+ if (state === "incomplete") {
124
+ repair.gaps.push(`${item.blockId}: ${guidance.targetPath} holds only part of this block (one marker); left as it is`);
125
+ continue;
126
+ }
127
+ if (item.unresolved) {
128
+ repair.gaps.push(`${item.blockId}: its source ${item.sourcePath} can't be read, so this older startup file can't be classified or put back`);
129
+ continue;
130
+ }
131
+ try {
132
+ if (!fs.exists(item.sourcePath)) {
133
+ repair.gaps.push(`${item.blockId}: its source ${item.sourcePath} no longer exists`);
134
+ continue;
135
+ }
136
+ toWrite.push({ blockId: item.blockId, content: fs.readFile(item.sourcePath) });
137
+ }
138
+ catch (err) {
139
+ repair.gaps.push(`${item.blockId}: ${err.message}`);
140
+ }
141
+ }
142
+ if (toWrite.length === 0)
143
+ return repair;
144
+ // A file that doesn't exist yet holds no text to lose. An existing one is written only if the
145
+ // next rig down would remove exactly what is added.
146
+ if (existing !== null && !appendIsCleanupSafe(existing, toWrite)) {
147
+ for (const block of toWrite) {
148
+ repair.gaps.push(`${block.blockId}: not written, because ${guidance.targetPath} has a managed-block marker that the next rig down would strip together with other text, so adding blocks there could cost that text`);
149
+ }
150
+ return repair;
151
+ }
152
+ for (const block of toWrite) {
153
+ try {
154
+ mergeManagedBlock(fs, guidance.targetPath, block.blockId, block.content);
155
+ repair.restored.push(block.blockId);
156
+ }
157
+ catch (err) {
158
+ repair.gaps.push(`${block.blockId}: ${err.message}`);
159
+ }
160
+ }
161
+ return repair;
162
+ }
163
+ //# sourceMappingURL=restore-guidance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restore-guidance.js","sourceRoot":"","sources":["../../src/domain/restore-guidance.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type Database from "better-sqlite3";
2
2
  import type { RigRepository } from "./rig-repository.js";
3
- import type { SessionRegistry } from "./session-registry.js";
3
+ import { type SessionRegistry } from "./session-registry.js";
4
4
  import type { EventBus } from "./event-bus.js";
5
5
  import type { SnapshotRepository } from "./snapshot-repository.js";
6
6
  import type { SnapshotCapture } from "./snapshot-capture.js";
@@ -180,6 +180,11 @@ export declare class RestoreOrchestrator {
180
180
  private restoreNodeState;
181
181
  private computeRestorePlan;
182
182
  private restoreNodeWithCompensation;
183
+ /** A seat that came back running should also have its role, culture and SOP guidance. If its
184
+ * guidance file still lacks a managed block it should hold, the seat keeps its true status (a
185
+ * live resumed session is still running) and the gap is disclosed on the node and in the
186
+ * warnings, so the rig is reported partially_restored, not fully_restored. */
187
+ private checkRestoredGuidance;
183
188
  /** OPR.0.3.4.2 (B) — roll a just-launched session back to ZERO sessions for
184
189
  * the awaiting-decision outcome: kill the live blank session, mark its row
185
190
  * superseded, and restore the prior binding/session state (the existing
@@ -1 +1 @@
1
- {"version":3,"file":"restore-orchestrator.d.ts","sourceRoot":"","sources":["../../src/domain/restore-orchestrator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"restore-orchestrator.d.ts","sourceRoot":"","sources":["../../src/domain/restore-orchestrator.ts"],"names":[],"mappings":"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"}
@@ -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";
@@ -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,25 @@ 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
+ return { kind: "fresh", why: "saves no session for this seat" };
66
+ const policy = session.restorePolicy ?? "resume_if_possible";
67
+ if (policy !== "resume_if_possible")
68
+ return { kind: "fresh", why: `saves this seat with restore policy '${policy}'` };
69
+ if (!session.resumeToken)
70
+ return { kind: "decision", why: "has no resume token for this seat" };
71
+ if (!session.resumeType || session.resumeType === "none")
72
+ return { kind: "fresh", why: "records no resume source for this seat" };
73
+ return { kind: "resume" };
74
+ }
51
75
  export class RestoreOrchestrator {
52
76
  db;
53
77
  activeRestores = new Set();
@@ -334,11 +358,28 @@ export class RestoreOrchestrator {
334
358
  .filter((s) => s.nodeId === node.id && s.status === "running");
335
359
  let isLive = false;
336
360
  let isUnknown = false;
361
+ let idleSession;
337
362
  for (const session of sessions) {
338
363
  try {
339
364
  const alive = await this.tmuxAdapter.hasSession(session.sessionName);
340
365
  if (alive) {
366
+ // A preserved shell is not a running agent. Reuse the process-lineage
367
+ // check's positive idle-shell evidence; opaque wrappers stay untouched.
341
368
  isLive = true;
369
+ const binding = this.sessionRegistry.getBindingForNode(node.id);
370
+ const pane = binding?.tmuxSession === session.sessionName ? binding.tmuxPane : null;
371
+ const runtime = allNodes.find(current => current.id === node.id)?.runtime ?? node.runtime;
372
+ // Launch needs consistent positive evidence: both samples idle with the same fingerprint, and the
373
+ // bound pane still in this session (a recycled pane id could name another session's shell).
374
+ if (pane && ["claude-code", "codex", "pi", "omp"].includes(runtime ?? "")
375
+ && isShellForeground(await this.tmuxAdapter.getPaneCommand(pane) ?? "")
376
+ && (await this.tmuxAdapter.listPanes(session.sessionName)).some(candidate => candidate.id === pane)
377
+ && (await observeClaudeDelivery({ target: pane, tmux: this.tmuxAdapter, listProcesses: this.listProcesses }, { unknownKeepsIdle: false })).state === "idle_shell"
378
+ && isShellForeground(await this.tmuxAdapter.getPaneCommand(pane) ?? "")) {
379
+ idleSession = session.sessionName;
380
+ isLive = false;
381
+ continue;
382
+ }
342
383
  break;
343
384
  }
344
385
  }
@@ -350,6 +391,26 @@ export class RestoreOrchestrator {
350
391
  alreadyRunning.push({ nodeId: node.id, logicalId: node.logicalId });
351
392
  continue;
352
393
  }
394
+ if (idleSession) {
395
+ // Keep the pane/history and the existing per-target failure contract.
396
+ // Choosing a fresh versus resumed conversation belongs to the person. Stopping closes the pane, so
397
+ // stop-then-launch is offered as a resume only when this snapshot can resume the seat; otherwise the
398
+ // message says what that launch would do instead. The command pins the snapshot that was checked.
399
+ const outcome = snapshotLaunchOutcome(snapshot.data, node.id);
400
+ const launchCommand = `rig launch ${rigId} ${node.logicalId} --snapshot-id ${snapshot.id}`;
401
+ const relaunch = outcome.kind === "resume"
402
+ ? `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). `
403
+ : `Stopping it and launching from snapshot ${snapshot.id} won't resume this conversation: that snapshot ${outcome.why}, so launch would `
404
+ + `${outcome.kind === "fresh" ? "start a fresh conversation" : outcome.kind === "decision" ? "start nothing and ask for a decision" : "fail"}. `;
405
+ launched.push({
406
+ nodeId: node.id, logicalId: node.logicalId, status: "attention_required",
407
+ error: `Session alive, agent not running for '${node.logicalId}': tmux session '${idleSession}' holds an idle shell, and its pane and history are preserved. `
408
+ + `The person chooses how to bring the agent back. ${relaunch}`
409
+ + `To start a blank occupant: rig seat launch ${idleSession} --fresh --stop --reason "<why>". `
410
+ + `To keep the pane: attach to tmux session '${idleSession}' and restart the agent there by hand.`,
411
+ });
412
+ continue;
413
+ }
353
414
  if (isUnknown) {
354
415
  // OPR.0.4.3.28 correction — INVERT the fail-closed-on-unknown launch default. A failed tmux
355
416
  // liveness probe is NOT positive evidence of a live seat (only isLive, above, is). Deny-by-
@@ -724,7 +785,39 @@ export class RestoreOrchestrator {
724
785
  if (launchResult.warnings?.length) {
725
786
  warnings?.push(...launchResult.warnings);
726
787
  }
727
- return this.postLaunchRestore(entry, rigId, data, launchResult.sessionName, launchResult, opts, warnings, priorState);
788
+ const restored = await this.postLaunchRestore(entry, rigId, data, launchResult.sessionName, launchResult, opts, warnings, priorState);
789
+ return this.checkRestoredGuidance(restored, entry.node, rigId, data, warnings);
790
+ }
791
+ /** A seat that came back running should also have its role, culture and SOP guidance. If its
792
+ * guidance file still lacks a managed block it should hold, the seat keeps its true status (a
793
+ * live resumed session is still running) and the gap is disclosed on the node and in the
794
+ * warnings, so the rig is reported partially_restored, not fully_restored. */
795
+ checkRestoredGuidance(result, node, rigId, data, warnings) {
796
+ // Every status with a live session; attention_required keeps its status and gains the disclosure.
797
+ if (!["resumed", "fresh-primed", "fresh", "rebuilt", "attention_required"].includes(result.status))
798
+ return result;
799
+ let guidance;
800
+ try {
801
+ guidance = seatGuidance(data.nodeStartupContext?.[node.id] ?? null, node.cwd, this.rigRepo.getRigClaudeManagedBlockFile(rigId), existsSync, (path) => readFileSync(path, "utf-8"));
802
+ }
803
+ catch (err) {
804
+ warnings?.push(`Restore: ${node.logicalId}: could not check its guidance: ${err.message}`);
805
+ return { ...result, guidanceGaps: ["(guidance check failed)"] };
806
+ }
807
+ if (!guidance || guidance.items.length === 0)
808
+ return result;
809
+ let missing;
810
+ try {
811
+ missing = missingGuidanceBlocks(guidance, { exists: existsSync, readFile: (path) => readFileSync(path, "utf-8") });
812
+ }
813
+ catch (err) {
814
+ missing = [`(could not read ${guidance.targetPath}: ${err.message})`];
815
+ }
816
+ if (missing.length === 0)
817
+ return result;
818
+ const gap = `${node.logicalId} is running without part of its guidance: ${guidance.targetPath} lacks the OpenRig blocks ${missing.join(", ")}.`;
819
+ warnings?.push(`Restore: ${gap}`);
820
+ return { ...result, guidanceGaps: missing };
728
821
  }
729
822
  /** OPR.0.3.4.2 (B) — roll a just-launched session back to ZERO sessions for
730
823
  * the awaiting-decision outcome: kill the live blank session, mark its row
@@ -804,6 +897,34 @@ export class RestoreOrchestrator {
804
897
  warnings?.push(`Restore activity hooks: ${error.message}`);
805
898
  }
806
899
  }
900
+ // A narrow exception to the replay containment below: before either native resume path
901
+ // starts the harness, put back only the MISSING managed guidance blocks from the saved
902
+ // startup selection. Ordinary `rig down` strips them; without this the resumed
903
+ // seat came back with no role, culture or SOP. Existing blocks are never refreshed; nothing
904
+ // reaches the conversation; no action, skill or plugin runs. Never blocks the resume.
905
+ if (resumeRequested && resumeToken && launchResult) {
906
+ let guidance = null;
907
+ try {
908
+ guidance = seatGuidance(startupCtx, node.cwd, this.rigRepo.getRigClaudeManagedBlockFile(rigId), existsSync, (path) => readFileSync(path, "utf-8"));
909
+ }
910
+ catch (err) {
911
+ // Guidance never blocks the exact resume; the post-launch check discloses the gap.
912
+ warnings?.push(`Restore guidance: ${node.logicalId}: could not read its saved guidance selection: ${err.message}`);
913
+ }
914
+ if (guidance && guidance.items.length > 0) {
915
+ const repair = restoreMissingGuidance(guidance, {
916
+ exists: existsSync,
917
+ readFile: (path) => readFileSync(path, "utf-8"),
918
+ writeFile: (path, content) => writeFileSync(path, content, "utf-8"),
919
+ mkdirp: (path) => mkdirSync(path, { recursive: true }),
920
+ });
921
+ if (repair.restored.length > 0) {
922
+ warnings?.push(`Restore guidance: ${node.logicalId}: put back missing blocks ${repair.restored.join(", ")} in ${guidance.targetPath} from their current source files.`);
923
+ }
924
+ for (const gap of repair.gaps)
925
+ warnings?.push(`Restore guidance: ${node.logicalId}: ${gap}`);
926
+ }
927
+ }
807
928
  if (resumeRequested && !isPodAware) {
808
929
  // Legacy resume path
809
930
  if (!resumeToken) {
@@ -815,9 +936,28 @@ export class RestoreOrchestrator {
815
936
  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
937
  }
817
938
  else {
939
+ const launchedSessionId = launchResult?.session.id;
940
+ if (launchedSessionId && this.claudeResume.canResume(resumeType, resumeToken)) {
941
+ // Before the resume: Claude's SessionStart hook can land before attemptResume returns.
942
+ try {
943
+ this.sessionRegistry.recordResumeLaunch(launchedSessionId, resumeToken);
944
+ }
945
+ catch { /* best-effort: without it a rotation stays unproved, as before */ }
946
+ }
818
947
  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
948
  if (resumeOutcome.kind === "resumed") {
820
949
  baseStatus = "resumed";
950
+ if (launchedSessionId && this.claudeResume.canResume(resumeType, resumeToken)) {
951
+ // The process this resume started, as the launch itself observes it (#1077): the one its
952
+ // identity check proved, else one observed now.
953
+ try {
954
+ const launched = resumeOutcome.launchedProcess ?? await observeClaudeResumeLaunch({ target: sessionName, tmux: this.tmuxAdapter,
955
+ ...(this.listProcesses ? { listProcesses: this.listProcesses } : {}), token: resumeToken });
956
+ if (launched)
957
+ this.sessionRegistry.recordResumeLaunchProcess(launchedSessionId, resumeToken, launched);
958
+ }
959
+ catch { /* best-effort: without it a rotation stays unproved, as before */ }
960
+ }
821
961
  }
822
962
  else if (resumeOutcome.kind === "attention_required") {
823
963
  // L3 Decision 2: Claude resume-selection prompt -> attention_required.
@@ -896,6 +1036,9 @@ export class RestoreOrchestrator {
896
1036
  // explicit+versioned+durable+idempotent contract in the D4 operation-id
897
1037
  // phase, where its durability primitives live. Deliberate fresh-primed
898
1038
  // launches are new histories and keep their replay.
1039
+ // One narrow exception: MISSING managed guidance blocks are put back before the harness
1040
+ // starts (see restoreMissingGuidance above); existing blocks are still never rewritten, and
1041
+ // nothing else is replayed.
899
1042
  const replayContained = resumeRequested && !!resumeToken;
900
1043
  const startupRuntime = startupCtx?.runtime ?? node.runtime ?? null;
901
1044
  const startupAdapter = startupRuntime ? opts?.adapters?.[startupRuntime] : undefined;
@@ -980,7 +1123,8 @@ export class RestoreOrchestrator {
980
1123
  };
981
1124
  try {
982
1125
  const { StartupOrchestrator } = await import("./startup-orchestrator.js");
983
- const startupOrch = new StartupOrchestrator({ db: this.db, sessionRegistry: this.sessionRegistry, eventBus: this.eventBus, tmuxAdapter: this.tmuxAdapter });
1126
+ const startupOrch = new StartupOrchestrator({ db: this.db, sessionRegistry: this.sessionRegistry, eventBus: this.eventBus, tmuxAdapter: this.tmuxAdapter,
1127
+ ...(this.listProcesses ? { listProcesses: this.listProcesses } : {}) });
984
1128
  const replayAsRestore = baseStatus !== "fresh-primed";
985
1129
  const shouldLaunchHarness = isPodAware;
986
1130
  const startupResult = await startupOrch.startNode({
@@ -1140,7 +1284,10 @@ export class RestoreOrchestrator {
1140
1284
  // join; a hook/operator may have changed it meanwhile. Never backfill here.
1141
1285
  const retained = sameSession && (managedClaudeResume
1142
1286
  ? this.sessionRegistry.resumeTokenMatches(sessionId, "claude_id", resumeToken)
1287
+ // Claude continued the resumed conversation under a new id (its hook said so).
1288
+ || this.sessionRegistry.claudeResumeRotatedFrom(sessionId, resumeToken)
1143
1289
  : current.resume_token === resumeToken
1290
+ || (node.runtime === "claude-code" && this.sessionRegistry.claudeResumeRotatedFrom(sessionId, resumeToken))
1144
1291
  || (!current.resume_token && this.sessionRegistry.updateResumeToken(sessionId, node.runtime === "codex" ? "codex_id" : "claude_id", resumeToken, "scrape")));
1145
1292
  if (!retained) {
1146
1293
  markManagedResumeAttention();
@@ -1272,7 +1419,7 @@ export class RestoreOrchestrator {
1272
1419
  warnings?.push(`${sessionName}: ${notice}`);
1273
1420
  if (result.appliedLaunch && launchGeneration)
1274
1421
  this.appliedLaunchStore.recordGeneration(launchGeneration, result.appliedLaunch);
1275
- return { kind: "resumed" };
1422
+ return { kind: "resumed", ...(result.launchedProcess ? { launchedProcess: result.launchedProcess } : {}) };
1276
1423
  }
1277
1424
  if (result.code === "retry_fresh")
1278
1425
  return { kind: "retry_fresh" };
@@ -1412,11 +1559,15 @@ export class RestoreOrchestrator {
1412
1559
  if (!sessionName) {
1413
1560
  return { ok: false, code: "tmux_session_missing", detail: "No tmux session bound for this node." };
1414
1561
  }
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);
1562
+ 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
1563
  if (!sessRow || sessRow.session_name !== sessionName) {
1417
1564
  return { ok: false, code: "binding_mismatch", detail: `Canonical binding ${sessionName} does not match the latest session row.` };
1418
1565
  }
1419
1566
  const expectedResumeToken = sessRow.resume_token;
1567
+ // The one alternative argv may carry: the token OpenRig launched this row to resume, when the
1568
+ // first hook after that launch recorded Claude continuing it as the stored token (#1077), and
1569
+ // only in the process that sent that hook.
1570
+ const rotation = sessRow.resume_type === "claude_id" ? claudeResumeRotation(sessRow) : null;
1420
1571
  if (!expectedResumeToken) {
1421
1572
  return { ok: false, code: "resume_token_not_used", detail: "No resume token recorded on the latest session row." };
1422
1573
  }
@@ -1437,6 +1588,7 @@ export class RestoreOrchestrator {
1437
1588
  // basename alone is never sufficient for no-input recovery.
1438
1589
  const nodeRow = this.db.prepare("SELECT runtime FROM nodes WHERE id = ?").get(nodeId);
1439
1590
  const runtime = nodeRow?.runtime ?? null;
1591
+ // One exact-lineage check per process, accepting the stored token or the recorded rotation.
1440
1592
  const identity = await rebindAndVerifyPaneIdentity({
1441
1593
  db: this.db,
1442
1594
  sessionRegistry: this.sessionRegistry,
@@ -1446,6 +1598,7 @@ export class RestoreOrchestrator {
1446
1598
  runtime,
1447
1599
  expectedResumeToken,
1448
1600
  requireExactResumeLineage: true,
1601
+ resumeRotation: rotation,
1449
1602
  ...(this.listProcesses ? { listProcesses: this.listProcesses } : {}),
1450
1603
  });
1451
1604
  if (!identity.ok) {
@@ -1457,6 +1610,7 @@ export class RestoreOrchestrator {
1457
1610
  target: identity.pane,
1458
1611
  tmux: this.tmuxAdapter,
1459
1612
  expectedToken: expectedResumeToken,
1613
+ rotation,
1460
1614
  requireResume: true,
1461
1615
  ...(this.listProcesses ? { listProcesses: this.listProcesses } : {}),
1462
1616
  });