oh-my-codex 0.20.3 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1126) hide show
  1. package/Cargo.lock +35 -18
  2. package/Cargo.toml +1 -1
  3. package/README.md +22 -19
  4. package/crates/omx-runtime/Cargo.toml +3 -0
  5. package/crates/omx-runtime/src/main.rs +390 -0
  6. package/crates/omx-runtime/tests/execution.rs +264 -0
  7. package/dist/adapt/__tests__/herdr-target.test.d.ts +2 -0
  8. package/dist/adapt/__tests__/herdr-target.test.d.ts.map +1 -0
  9. package/dist/adapt/__tests__/herdr-target.test.js +72 -0
  10. package/dist/adapt/__tests__/herdr-target.test.js.map +1 -0
  11. package/dist/adapt/contracts.d.ts +1 -1
  12. package/dist/adapt/contracts.d.ts.map +1 -1
  13. package/dist/adapt/contracts.js +1 -1
  14. package/dist/adapt/contracts.js.map +1 -1
  15. package/dist/adapt/herdr/__tests__/authority.test.d.ts +2 -0
  16. package/dist/adapt/herdr/__tests__/authority.test.d.ts.map +1 -0
  17. package/dist/adapt/herdr/__tests__/authority.test.js +49 -0
  18. package/dist/adapt/herdr/__tests__/authority.test.js.map +1 -0
  19. package/dist/adapt/herdr/__tests__/bridge.test.d.ts +2 -0
  20. package/dist/adapt/herdr/__tests__/bridge.test.d.ts.map +1 -0
  21. package/dist/adapt/herdr/__tests__/bridge.test.js +176 -0
  22. package/dist/adapt/herdr/__tests__/bridge.test.js.map +1 -0
  23. package/dist/adapt/herdr/__tests__/sanitize.test.d.ts +2 -0
  24. package/dist/adapt/herdr/__tests__/sanitize.test.d.ts.map +1 -0
  25. package/dist/adapt/herdr/__tests__/sanitize.test.js +45 -0
  26. package/dist/adapt/herdr/__tests__/sanitize.test.js.map +1 -0
  27. package/dist/adapt/herdr/__tests__/semantic.test.d.ts +2 -0
  28. package/dist/adapt/herdr/__tests__/semantic.test.d.ts.map +1 -0
  29. package/dist/adapt/herdr/__tests__/semantic.test.js +130 -0
  30. package/dist/adapt/herdr/__tests__/semantic.test.js.map +1 -0
  31. package/dist/adapt/herdr/__tests__/seq-store.test.d.ts +2 -0
  32. package/dist/adapt/herdr/__tests__/seq-store.test.d.ts.map +1 -0
  33. package/dist/adapt/herdr/__tests__/seq-store.test.js +54 -0
  34. package/dist/adapt/herdr/__tests__/seq-store.test.js.map +1 -0
  35. package/dist/adapt/herdr/__tests__/socket-live.test.d.ts +2 -0
  36. package/dist/adapt/herdr/__tests__/socket-live.test.d.ts.map +1 -0
  37. package/dist/adapt/herdr/__tests__/socket-live.test.js +104 -0
  38. package/dist/adapt/herdr/__tests__/socket-live.test.js.map +1 -0
  39. package/dist/adapt/herdr/__tests__/team-map.test.d.ts +2 -0
  40. package/dist/adapt/herdr/__tests__/team-map.test.d.ts.map +1 -0
  41. package/dist/adapt/herdr/__tests__/team-map.test.js +46 -0
  42. package/dist/adapt/herdr/__tests__/team-map.test.js.map +1 -0
  43. package/dist/adapt/herdr/__tests__/transport.test.d.ts +2 -0
  44. package/dist/adapt/herdr/__tests__/transport.test.d.ts.map +1 -0
  45. package/dist/adapt/herdr/__tests__/transport.test.js +160 -0
  46. package/dist/adapt/herdr/__tests__/transport.test.js.map +1 -0
  47. package/dist/adapt/herdr/__tests__/wiring.test.d.ts +2 -0
  48. package/dist/adapt/herdr/__tests__/wiring.test.d.ts.map +1 -0
  49. package/dist/adapt/herdr/__tests__/wiring.test.js +118 -0
  50. package/dist/adapt/herdr/__tests__/wiring.test.js.map +1 -0
  51. package/dist/adapt/herdr/authority.d.ts +34 -0
  52. package/dist/adapt/herdr/authority.d.ts.map +1 -0
  53. package/dist/adapt/herdr/authority.js +71 -0
  54. package/dist/adapt/herdr/authority.js.map +1 -0
  55. package/dist/adapt/herdr/bridge.d.ts +84 -0
  56. package/dist/adapt/herdr/bridge.d.ts.map +1 -0
  57. package/dist/adapt/herdr/bridge.js +222 -0
  58. package/dist/adapt/herdr/bridge.js.map +1 -0
  59. package/dist/adapt/herdr/sanitize.d.ts +20 -0
  60. package/dist/adapt/herdr/sanitize.d.ts.map +1 -0
  61. package/dist/adapt/herdr/sanitize.js +70 -0
  62. package/dist/adapt/herdr/sanitize.js.map +1 -0
  63. package/dist/adapt/herdr/semantic.d.ts +67 -0
  64. package/dist/adapt/herdr/semantic.d.ts.map +1 -0
  65. package/dist/adapt/herdr/semantic.js +170 -0
  66. package/dist/adapt/herdr/semantic.js.map +1 -0
  67. package/dist/adapt/herdr/seq-store.d.ts +32 -0
  68. package/dist/adapt/herdr/seq-store.d.ts.map +1 -0
  69. package/dist/adapt/herdr/seq-store.js +126 -0
  70. package/dist/adapt/herdr/seq-store.js.map +1 -0
  71. package/dist/adapt/herdr/team-map.d.ts +30 -0
  72. package/dist/adapt/herdr/team-map.d.ts.map +1 -0
  73. package/dist/adapt/herdr/team-map.js +37 -0
  74. package/dist/adapt/herdr/team-map.js.map +1 -0
  75. package/dist/adapt/herdr/transport.d.ts +115 -0
  76. package/dist/adapt/herdr/transport.d.ts.map +1 -0
  77. package/dist/adapt/herdr/transport.js +260 -0
  78. package/dist/adapt/herdr/transport.js.map +1 -0
  79. package/dist/adapt/herdr/wiring.d.ts +24 -0
  80. package/dist/adapt/herdr/wiring.d.ts.map +1 -0
  81. package/dist/adapt/herdr/wiring.js +62 -0
  82. package/dist/adapt/herdr/wiring.js.map +1 -0
  83. package/dist/adapt/herdr.d.ts +19 -0
  84. package/dist/adapt/herdr.d.ts.map +1 -0
  85. package/dist/adapt/herdr.js +115 -0
  86. package/dist/adapt/herdr.js.map +1 -0
  87. package/dist/adapt/index.d.ts +4 -0
  88. package/dist/adapt/index.d.ts.map +1 -1
  89. package/dist/adapt/index.js +48 -0
  90. package/dist/adapt/index.js.map +1 -1
  91. package/dist/adapt/registry.d.ts.map +1 -1
  92. package/dist/adapt/registry.js +11 -0
  93. package/dist/adapt/registry.js.map +1 -1
  94. package/dist/agents/__tests__/definitions.test.js +0 -27
  95. package/dist/agents/__tests__/definitions.test.js.map +1 -1
  96. package/dist/agents/__tests__/native-config.test.js +3 -8
  97. package/dist/agents/__tests__/native-config.test.js.map +1 -1
  98. package/dist/agents/definitions.d.ts.map +1 -1
  99. package/dist/agents/definitions.js +0 -41
  100. package/dist/agents/definitions.js.map +1 -1
  101. package/dist/agents/policy.d.ts.map +1 -1
  102. package/dist/agents/policy.js +0 -1
  103. package/dist/agents/policy.js.map +1 -1
  104. package/dist/auth/__tests__/hotswap.test.js +60 -1
  105. package/dist/auth/__tests__/hotswap.test.js.map +1 -1
  106. package/dist/auth/__tests__/storage.test.js +33 -1
  107. package/dist/auth/__tests__/storage.test.js.map +1 -1
  108. package/dist/auth/hotswap.d.ts +16 -2
  109. package/dist/auth/hotswap.d.ts.map +1 -1
  110. package/dist/auth/hotswap.js +22 -7
  111. package/dist/auth/hotswap.js.map +1 -1
  112. package/dist/auth/storage.js +1 -1
  113. package/dist/auth/storage.js.map +1 -1
  114. package/dist/autopilot/__tests__/completion-gate-advisory.test.d.ts +2 -0
  115. package/dist/autopilot/__tests__/completion-gate-advisory.test.d.ts.map +1 -0
  116. package/dist/autopilot/__tests__/completion-gate-advisory.test.js +383 -0
  117. package/dist/autopilot/__tests__/completion-gate-advisory.test.js.map +1 -0
  118. package/dist/autopilot/completion-gate.d.ts +6 -1
  119. package/dist/autopilot/completion-gate.d.ts.map +1 -1
  120. package/dist/autopilot/completion-gate.js +247 -7
  121. package/dist/autopilot/completion-gate.js.map +1 -1
  122. package/dist/catalog/__tests__/generator.test.js +15 -10
  123. package/dist/catalog/__tests__/generator.test.js.map +1 -1
  124. package/dist/catalog/__tests__/plugin-bundle-ssot.test.js +13 -7
  125. package/dist/catalog/__tests__/plugin-bundle-ssot.test.js.map +1 -1
  126. package/dist/catalog/__tests__/schema.test.js +3 -5
  127. package/dist/catalog/__tests__/schema.test.js.map +1 -1
  128. package/dist/catalog/schema.js +1 -1
  129. package/dist/catalog/schema.js.map +1 -1
  130. package/dist/cli/__tests__/agents-init.test.js +4 -23
  131. package/dist/cli/__tests__/agents-init.test.js.map +1 -1
  132. package/dist/cli/__tests__/api.test.js +61 -24
  133. package/dist/cli/__tests__/api.test.js.map +1 -1
  134. package/dist/cli/__tests__/auth.test.js +3 -1
  135. package/dist/cli/__tests__/auth.test.js.map +1 -1
  136. package/dist/cli/__tests__/autopilot.test.d.ts +2 -0
  137. package/dist/cli/__tests__/autopilot.test.d.ts.map +1 -0
  138. package/dist/cli/__tests__/autopilot.test.js +143 -0
  139. package/dist/cli/__tests__/autopilot.test.js.map +1 -0
  140. package/dist/cli/__tests__/codex-feature-probe.test.js +66 -1
  141. package/dist/cli/__tests__/codex-feature-probe.test.js.map +1 -1
  142. package/dist/cli/__tests__/codex-plugin-layout.test.js +76 -4
  143. package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
  144. package/dist/cli/__tests__/detached-leader-teardown.test.d.ts +2 -0
  145. package/dist/cli/__tests__/detached-leader-teardown.test.d.ts.map +1 -0
  146. package/dist/cli/__tests__/detached-leader-teardown.test.js +473 -0
  147. package/dist/cli/__tests__/detached-leader-teardown.test.js.map +1 -0
  148. package/dist/cli/__tests__/doctor-process-identity-readiness.test.d.ts +2 -0
  149. package/dist/cli/__tests__/doctor-process-identity-readiness.test.d.ts.map +1 -0
  150. package/dist/cli/__tests__/doctor-process-identity-readiness.test.js +103 -0
  151. package/dist/cli/__tests__/doctor-process-identity-readiness.test.js.map +1 -0
  152. package/dist/cli/__tests__/doctor-state-root-binding.test.d.ts +2 -0
  153. package/dist/cli/__tests__/doctor-state-root-binding.test.d.ts.map +1 -0
  154. package/dist/cli/__tests__/doctor-state-root-binding.test.js +206 -0
  155. package/dist/cli/__tests__/doctor-state-root-binding.test.js.map +1 -0
  156. package/dist/cli/__tests__/doctor-team.test.js +85 -0
  157. package/dist/cli/__tests__/doctor-team.test.js.map +1 -1
  158. package/dist/cli/__tests__/doctor-warning-copy.test.js +38 -6
  159. package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
  160. package/dist/cli/__tests__/exec.test.js +75 -0
  161. package/dist/cli/__tests__/exec.test.js.map +1 -1
  162. package/dist/cli/__tests__/index.test.js +621 -460
  163. package/dist/cli/__tests__/index.test.js.map +1 -1
  164. package/dist/cli/__tests__/launch-fallback.test.js +1125 -143
  165. package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
  166. package/dist/cli/__tests__/mcp-parity.test.js +4 -3
  167. package/dist/cli/__tests__/mcp-parity.test.js.map +1 -1
  168. package/dist/cli/__tests__/native-assets.test.js +398 -16
  169. package/dist/cli/__tests__/native-assets.test.js.map +1 -1
  170. package/dist/cli/__tests__/native-hook-claim-journal.test.js +53 -5
  171. package/dist/cli/__tests__/native-hook-claim-journal.test.js.map +1 -1
  172. package/dist/cli/__tests__/package-bin-contract.test.js +5 -8
  173. package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
  174. package/dist/cli/__tests__/ralph-deslop-contract.test.js +4 -18
  175. package/dist/cli/__tests__/ralph-deslop-contract.test.js.map +1 -1
  176. package/dist/cli/__tests__/ralph-goal-mode-contract.test.js +4 -30
  177. package/dist/cli/__tests__/ralph-goal-mode-contract.test.js.map +1 -1
  178. package/dist/cli/__tests__/ralph-prd-deep-interview.test.js +4 -15
  179. package/dist/cli/__tests__/ralph-prd-deep-interview.test.js.map +1 -1
  180. package/dist/cli/__tests__/ralph.test.js +2 -2
  181. package/dist/cli/__tests__/ralph.test.js.map +1 -1
  182. package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js +57 -57
  183. package/dist/cli/__tests__/ralplan-bootstrap-3181.test.js.map +1 -1
  184. package/dist/cli/__tests__/ralplan-child-binding-3212.test.d.ts +2 -0
  185. package/dist/cli/__tests__/ralplan-child-binding-3212.test.d.ts.map +1 -0
  186. package/dist/cli/__tests__/ralplan-child-binding-3212.test.js +56 -0
  187. package/dist/cli/__tests__/ralplan-child-binding-3212.test.js.map +1 -0
  188. package/dist/cli/__tests__/ralplan.test.js +131 -14
  189. package/dist/cli/__tests__/ralplan.test.js.map +1 -1
  190. package/dist/cli/__tests__/session-scoped-runtime.test.js +1153 -43
  191. package/dist/cli/__tests__/session-scoped-runtime.test.js.map +1 -1
  192. package/dist/cli/__tests__/session-search-help.test.js +65 -3
  193. package/dist/cli/__tests__/session-search-help.test.js.map +1 -1
  194. package/dist/cli/__tests__/setup-agents-overwrite.test.js +57 -55
  195. package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
  196. package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js +34 -0
  197. package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js.map +1 -1
  198. package/dist/cli/__tests__/setup-hooks-trust-e2e.test.js +1 -1
  199. package/dist/cli/__tests__/setup-hooks-trust-e2e.test.js.map +1 -1
  200. package/dist/cli/__tests__/setup-install-mode.test.js +258 -26
  201. package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
  202. package/dist/cli/__tests__/setup-prompts-overwrite.test.js +1 -1
  203. package/dist/cli/__tests__/setup-prompts-overwrite.test.js.map +1 -1
  204. package/dist/cli/__tests__/setup-refresh.test.js +3 -6
  205. package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
  206. package/dist/cli/__tests__/setup-skills-overwrite.test.js +180 -21
  207. package/dist/cli/__tests__/setup-skills-overwrite.test.js.map +1 -1
  208. package/dist/cli/__tests__/sparkshell-cli.test.js +93 -41
  209. package/dist/cli/__tests__/sparkshell-cli.test.js.map +1 -1
  210. package/dist/cli/__tests__/team.test.js +45 -1
  211. package/dist/cli/__tests__/team.test.js.map +1 -1
  212. package/dist/cli/__tests__/ultragoal.test.js +161 -2
  213. package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
  214. package/dist/cli/__tests__/uninstall.test.js +73 -28
  215. package/dist/cli/__tests__/uninstall.test.js.map +1 -1
  216. package/dist/cli/__tests__/update.test.js +749 -177
  217. package/dist/cli/__tests__/update.test.js.map +1 -1
  218. package/dist/cli/__tests__/windows-popup-loop-contract.test.js +32 -2
  219. package/dist/cli/__tests__/windows-popup-loop-contract.test.js.map +1 -1
  220. package/dist/cli/api.d.ts.map +1 -1
  221. package/dist/cli/api.js +9 -10
  222. package/dist/cli/api.js.map +1 -1
  223. package/dist/cli/autopilot.d.ts +8 -0
  224. package/dist/cli/autopilot.d.ts.map +1 -0
  225. package/dist/cli/autopilot.js +160 -0
  226. package/dist/cli/autopilot.js.map +1 -0
  227. package/dist/cli/codex-feature-probe.d.ts +16 -0
  228. package/dist/cli/codex-feature-probe.d.ts.map +1 -1
  229. package/dist/cli/codex-feature-probe.js +44 -0
  230. package/dist/cli/codex-feature-probe.js.map +1 -1
  231. package/dist/cli/codex-home.d.ts.map +1 -1
  232. package/dist/cli/codex-home.js +7 -4
  233. package/dist/cli/codex-home.js.map +1 -1
  234. package/dist/cli/doctor.d.ts +29 -0
  235. package/dist/cli/doctor.d.ts.map +1 -1
  236. package/dist/cli/doctor.js +433 -19
  237. package/dist/cli/doctor.js.map +1 -1
  238. package/dist/cli/index.d.ts +231 -12
  239. package/dist/cli/index.d.ts.map +1 -1
  240. package/dist/cli/index.js +2354 -724
  241. package/dist/cli/index.js.map +1 -1
  242. package/dist/cli/mcp-parity.d.ts.map +1 -1
  243. package/dist/cli/mcp-parity.js +7 -3
  244. package/dist/cli/mcp-parity.js.map +1 -1
  245. package/dist/cli/native-assets.d.ts +26 -1
  246. package/dist/cli/native-assets.d.ts.map +1 -1
  247. package/dist/cli/native-assets.js +448 -51
  248. package/dist/cli/native-assets.js.map +1 -1
  249. package/dist/cli/native-hook-claim-journal.d.ts +8 -4
  250. package/dist/cli/native-hook-claim-journal.d.ts.map +1 -1
  251. package/dist/cli/native-hook-claim-journal.js +30 -8
  252. package/dist/cli/native-hook-claim-journal.js.map +1 -1
  253. package/dist/cli/package-manager-ownership.d.ts +69 -0
  254. package/dist/cli/package-manager-ownership.d.ts.map +1 -0
  255. package/dist/cli/package-manager-ownership.js +338 -0
  256. package/dist/cli/package-manager-ownership.js.map +1 -0
  257. package/dist/cli/plugin-marketplace.d.ts +1 -0
  258. package/dist/cli/plugin-marketplace.d.ts.map +1 -1
  259. package/dist/cli/plugin-marketplace.js +123 -55
  260. package/dist/cli/plugin-marketplace.js.map +1 -1
  261. package/dist/cli/ralph.js +2 -2
  262. package/dist/cli/ralph.js.map +1 -1
  263. package/dist/cli/ralplan.d.ts +6 -2
  264. package/dist/cli/ralplan.d.ts.map +1 -1
  265. package/dist/cli/ralplan.js +134 -34
  266. package/dist/cli/ralplan.js.map +1 -1
  267. package/dist/cli/session-search.d.ts.map +1 -1
  268. package/dist/cli/session-search.js +38 -1
  269. package/dist/cli/session-search.js.map +1 -1
  270. package/dist/cli/setup-preferences.d.ts +15 -0
  271. package/dist/cli/setup-preferences.d.ts.map +1 -1
  272. package/dist/cli/setup-preferences.js +27 -1
  273. package/dist/cli/setup-preferences.js.map +1 -1
  274. package/dist/cli/setup.d.ts +6 -0
  275. package/dist/cli/setup.d.ts.map +1 -1
  276. package/dist/cli/setup.js +425 -215
  277. package/dist/cli/setup.js.map +1 -1
  278. package/dist/cli/sparkshell.d.ts.map +1 -1
  279. package/dist/cli/sparkshell.js +52 -9
  280. package/dist/cli/sparkshell.js.map +1 -1
  281. package/dist/cli/ultragoal.d.ts +1 -1
  282. package/dist/cli/ultragoal.d.ts.map +1 -1
  283. package/dist/cli/ultragoal.js +10 -7
  284. package/dist/cli/ultragoal.js.map +1 -1
  285. package/dist/cli/uninstall.d.ts.map +1 -1
  286. package/dist/cli/uninstall.js +27 -28
  287. package/dist/cli/uninstall.js.map +1 -1
  288. package/dist/cli/update-worker.d.ts +2 -0
  289. package/dist/cli/update-worker.d.ts.map +1 -0
  290. package/dist/cli/update-worker.js +142 -0
  291. package/dist/cli/update-worker.js.map +1 -0
  292. package/dist/cli/update.d.ts +16 -23
  293. package/dist/cli/update.d.ts.map +1 -1
  294. package/dist/cli/update.js +212 -241
  295. package/dist/cli/update.js.map +1 -1
  296. package/dist/compat/__tests__/upgrade-from-0-20.test.d.ts +2 -0
  297. package/dist/compat/__tests__/upgrade-from-0-20.test.d.ts.map +1 -0
  298. package/dist/compat/__tests__/upgrade-from-0-20.test.js +109 -0
  299. package/dist/compat/__tests__/upgrade-from-0-20.test.js.map +1 -0
  300. package/dist/compat/upgrade-from-0-20.d.ts +64 -0
  301. package/dist/compat/upgrade-from-0-20.d.ts.map +1 -0
  302. package/dist/compat/upgrade-from-0-20.js +276 -0
  303. package/dist/compat/upgrade-from-0-20.js.map +1 -0
  304. package/dist/config/__tests__/generator-idempotent.test.js +173 -29
  305. package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
  306. package/dist/config/__tests__/generator-notify.test.js +3 -1
  307. package/dist/config/__tests__/generator-notify.test.js.map +1 -1
  308. package/dist/config/generator.d.ts +25 -3
  309. package/dist/config/generator.d.ts.map +1 -1
  310. package/dist/config/generator.js +113 -35
  311. package/dist/config/generator.js.map +1 -1
  312. package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js +25 -0
  313. package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js.map +1 -1
  314. package/dist/goal-workflows/codex-goal-snapshot.d.ts +1 -1
  315. package/dist/goal-workflows/codex-goal-snapshot.d.ts.map +1 -1
  316. package/dist/goal-workflows/codex-goal-snapshot.js +2 -0
  317. package/dist/goal-workflows/codex-goal-snapshot.js.map +1 -1
  318. package/dist/hooks/__tests__/agents-overlay.test.js +3 -1
  319. package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
  320. package/dist/hooks/__tests__/analyze-skill-contract.test.js +24 -31
  321. package/dist/hooks/__tests__/analyze-skill-contract.test.js.map +1 -1
  322. package/dist/hooks/__tests__/anti-slop-workflow.test.js +66 -135
  323. package/dist/hooks/__tests__/anti-slop-workflow.test.js.map +1 -1
  324. package/dist/hooks/__tests__/autopilot-skill-contract.test.js +47 -106
  325. package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -1
  326. package/dist/hooks/__tests__/code-review-skill-contract.test.js +16 -18
  327. package/dist/hooks/__tests__/code-review-skill-contract.test.js.map +1 -1
  328. package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts +2 -14
  329. package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts.map +1 -1
  330. package/dist/hooks/__tests__/consensus-execution-handoff.test.js +56 -234
  331. package/dist/hooks/__tests__/consensus-execution-handoff.test.js.map +1 -1
  332. package/dist/hooks/__tests__/deep-interview-contract.test.js +1 -3
  333. package/dist/hooks/__tests__/deep-interview-contract.test.js.map +1 -1
  334. package/dist/hooks/__tests__/design-skill.test.js +18 -16
  335. package/dist/hooks/__tests__/design-skill.test.js.map +1 -1
  336. package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.js +24 -20
  337. package/dist/hooks/__tests__/explore-sparkshell-guidance-contract.test.js.map +1 -1
  338. package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.d.ts +2 -0
  339. package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.d.ts.map +1 -0
  340. package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.js +164 -0
  341. package/dist/hooks/__tests__/issue-3293-autopilot-handoff.test.js.map +1 -0
  342. package/dist/hooks/__tests__/issue-3497-hook-simplification.test.d.ts +2 -0
  343. package/dist/hooks/__tests__/issue-3497-hook-simplification.test.d.ts.map +1 -0
  344. package/dist/hooks/__tests__/issue-3497-hook-simplification.test.js +169 -0
  345. package/dist/hooks/__tests__/issue-3497-hook-simplification.test.js.map +1 -0
  346. package/dist/hooks/__tests__/keyword-detector.test.js +226 -858
  347. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  348. package/dist/hooks/__tests__/notify-fallback-watcher.test.js +176 -14
  349. package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
  350. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +1 -0
  351. package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
  352. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +33 -21
  353. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
  354. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +27 -0
  355. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js.map +1 -1
  356. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js +10 -118
  357. package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +1 -1
  358. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +14 -904
  359. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +1 -1
  360. package/dist/hooks/__tests__/notify-hook-regression-205.test.js +7 -0
  361. package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
  362. package/dist/hooks/__tests__/notify-hook-session-scope.test.js +5 -5
  363. package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
  364. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +7 -7
  365. package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
  366. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +11 -8
  367. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
  368. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js +7 -6
  369. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js.map +1 -1
  370. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js +2 -1
  371. package/dist/hooks/__tests__/notify-hook-team-worker-fail-closed.test.js.map +1 -1
  372. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +1 -0
  373. package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
  374. package/dist/hooks/__tests__/pre-context-gate-skills.test.js +19 -21
  375. package/dist/hooks/__tests__/pre-context-gate-skills.test.js.map +1 -1
  376. package/dist/hooks/__tests__/prompt-guidance-contract.test.js +23 -3
  377. package/dist/hooks/__tests__/prompt-guidance-contract.test.js.map +1 -1
  378. package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js +23 -28
  379. package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js.map +1 -1
  380. package/dist/hooks/__tests__/research-workflow-boundaries.test.js +9 -8
  381. package/dist/hooks/__tests__/research-workflow-boundaries.test.js.map +1 -1
  382. package/dist/hooks/__tests__/session.test.js +3656 -656
  383. package/dist/hooks/__tests__/session.test.js.map +1 -1
  384. package/dist/hooks/__tests__/skill-catalog-hygiene.test.js +13 -22
  385. package/dist/hooks/__tests__/skill-catalog-hygiene.test.js.map +1 -1
  386. package/dist/hooks/__tests__/skill-guidance-contract.test.js +3 -13
  387. package/dist/hooks/__tests__/skill-guidance-contract.test.js.map +1 -1
  388. package/dist/hooks/__tests__/sunset-routing-contract.test.d.ts +2 -0
  389. package/dist/hooks/__tests__/sunset-routing-contract.test.d.ts.map +1 -0
  390. package/dist/hooks/__tests__/sunset-routing-contract.test.js +172 -0
  391. package/dist/hooks/__tests__/sunset-routing-contract.test.js.map +1 -0
  392. package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js +2 -2
  393. package/dist/hooks/__tests__/team-runtime-gating-docs-contract.test.js.map +1 -1
  394. package/dist/hooks/__tests__/tmux-hook-engine.test.js +18 -3
  395. package/dist/hooks/__tests__/tmux-hook-engine.test.js.map +1 -1
  396. package/dist/hooks/__tests__/visual-ralph-skill.test.js +20 -17
  397. package/dist/hooks/__tests__/visual-ralph-skill.test.js.map +1 -1
  398. package/dist/hooks/__tests__/visual-verdict-loop.test.js +17 -18
  399. package/dist/hooks/__tests__/visual-verdict-loop.test.js.map +1 -1
  400. package/dist/hooks/agents-overlay.js +1 -1
  401. package/dist/hooks/agents-overlay.js.map +1 -1
  402. package/dist/hooks/extensibility/__tests__/dispatcher.test.js +108 -2
  403. package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +1 -1
  404. package/dist/hooks/extensibility/__tests__/sdk.test.js +151 -1
  405. package/dist/hooks/extensibility/__tests__/sdk.test.js.map +1 -1
  406. package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -1
  407. package/dist/hooks/extensibility/dispatcher.js +20 -3
  408. package/dist/hooks/extensibility/dispatcher.js.map +1 -1
  409. package/dist/hooks/extensibility/plugin-runner.js +1 -0
  410. package/dist/hooks/extensibility/plugin-runner.js.map +1 -1
  411. package/dist/hooks/extensibility/runtime.d.ts.map +1 -1
  412. package/dist/hooks/extensibility/runtime.js.map +1 -1
  413. package/dist/hooks/extensibility/sdk/paths.d.ts +1 -1
  414. package/dist/hooks/extensibility/sdk/paths.d.ts.map +1 -1
  415. package/dist/hooks/extensibility/sdk/paths.js +2 -2
  416. package/dist/hooks/extensibility/sdk/paths.js.map +1 -1
  417. package/dist/hooks/extensibility/sdk/runtime-state.d.ts +1 -1
  418. package/dist/hooks/extensibility/sdk/runtime-state.d.ts.map +1 -1
  419. package/dist/hooks/extensibility/sdk/runtime-state.js +55 -15
  420. package/dist/hooks/extensibility/sdk/runtime-state.js.map +1 -1
  421. package/dist/hooks/extensibility/sdk.d.ts +1 -0
  422. package/dist/hooks/extensibility/sdk.d.ts.map +1 -1
  423. package/dist/hooks/extensibility/sdk.js +1 -1
  424. package/dist/hooks/extensibility/sdk.js.map +1 -1
  425. package/dist/hooks/extensibility/types.d.ts +7 -0
  426. package/dist/hooks/extensibility/types.d.ts.map +1 -1
  427. package/dist/hooks/keyword-detector.d.ts +6 -47
  428. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  429. package/dist/hooks/keyword-detector.js +156 -268
  430. package/dist/hooks/keyword-detector.js.map +1 -1
  431. package/dist/hooks/keyword-registry.d.ts.map +1 -1
  432. package/dist/hooks/keyword-registry.js +14 -26
  433. package/dist/hooks/keyword-registry.js.map +1 -1
  434. package/dist/hooks/native/capability-warnings.d.ts +16 -0
  435. package/dist/hooks/native/capability-warnings.d.ts.map +1 -0
  436. package/dist/hooks/native/capability-warnings.js +40 -0
  437. package/dist/hooks/native/capability-warnings.js.map +1 -0
  438. package/dist/hooks/native/index.d.ts +17 -0
  439. package/dist/hooks/native/index.d.ts.map +1 -0
  440. package/dist/hooks/native/index.js +17 -0
  441. package/dist/hooks/native/index.js.map +1 -0
  442. package/dist/hooks/native/pre-tool-use-advisory.d.ts +17 -0
  443. package/dist/hooks/native/pre-tool-use-advisory.d.ts.map +1 -0
  444. package/dist/hooks/native/pre-tool-use-advisory.js +112 -0
  445. package/dist/hooks/native/pre-tool-use-advisory.js.map +1 -0
  446. package/dist/hooks/native/types.d.ts +30 -0
  447. package/dist/hooks/native/types.d.ts.map +1 -0
  448. package/dist/hooks/native/types.js +22 -0
  449. package/dist/hooks/native/types.js.map +1 -0
  450. package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
  451. package/dist/hooks/prompt-guidance-contract.js +46 -93
  452. package/dist/hooks/prompt-guidance-contract.js.map +1 -1
  453. package/dist/hooks/session.d.ts +197 -18
  454. package/dist/hooks/session.d.ts.map +1 -1
  455. package/dist/hooks/session.js +1939 -271
  456. package/dist/hooks/session.js.map +1 -1
  457. package/dist/hooks/sunset-stub.d.ts +17 -0
  458. package/dist/hooks/sunset-stub.d.ts.map +1 -0
  459. package/dist/hooks/sunset-stub.js +125 -0
  460. package/dist/hooks/sunset-stub.js.map +1 -0
  461. package/dist/hud/__tests__/hud-tmux-injection.test.js +6 -6
  462. package/dist/hud/__tests__/hud-tmux-injection.test.js.map +1 -1
  463. package/dist/hud/__tests__/index.test.js +26 -16
  464. package/dist/hud/__tests__/index.test.js.map +1 -1
  465. package/dist/hud/__tests__/reconcile.test.js +83 -78
  466. package/dist/hud/__tests__/reconcile.test.js.map +1 -1
  467. package/dist/hud/__tests__/state.test.js +36 -31
  468. package/dist/hud/__tests__/state.test.js.map +1 -1
  469. package/dist/hud/__tests__/tmux-split-realtmux.test.d.ts +2 -0
  470. package/dist/hud/__tests__/tmux-split-realtmux.test.d.ts.map +1 -0
  471. package/dist/hud/__tests__/tmux-split-realtmux.test.js +112 -0
  472. package/dist/hud/__tests__/tmux-split-realtmux.test.js.map +1 -0
  473. package/dist/hud/__tests__/tmux.test.js +217 -198
  474. package/dist/hud/__tests__/tmux.test.js.map +1 -1
  475. package/dist/hud/tmux.d.ts +43 -4
  476. package/dist/hud/tmux.d.ts.map +1 -1
  477. package/dist/hud/tmux.js +1025 -139
  478. package/dist/hud/tmux.js.map +1 -1
  479. package/dist/leader/__tests__/contract.test.js +71 -34
  480. package/dist/leader/__tests__/contract.test.js.map +1 -1
  481. package/dist/leader/contract.d.ts +1 -6
  482. package/dist/leader/contract.d.ts.map +1 -1
  483. package/dist/leader/contract.js +25 -24
  484. package/dist/leader/contract.js.map +1 -1
  485. package/dist/mcp/__tests__/hermes-bridge.test.js +17 -0
  486. package/dist/mcp/__tests__/hermes-bridge.test.js.map +1 -1
  487. package/dist/mcp/__tests__/server-lifecycle.test.js +4 -4
  488. package/dist/mcp/__tests__/state-paths.test.js +735 -4
  489. package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
  490. package/dist/mcp/__tests__/state-server-ralph-phase.test.js +29 -4
  491. package/dist/mcp/__tests__/state-server-ralph-phase.test.js.map +1 -1
  492. package/dist/mcp/__tests__/state-server-schema.test.js +13 -3
  493. package/dist/mcp/__tests__/state-server-schema.test.js.map +1 -1
  494. package/dist/mcp/__tests__/state-server.test.js +11 -1033
  495. package/dist/mcp/__tests__/state-server.test.js.map +1 -1
  496. package/dist/mcp/__tests__/trace-server.test.js +2 -2
  497. package/dist/mcp/__tests__/trace-server.test.js.map +1 -1
  498. package/dist/mcp/hermes-bridge.d.ts.map +1 -1
  499. package/dist/mcp/hermes-bridge.js +2 -2
  500. package/dist/mcp/hermes-bridge.js.map +1 -1
  501. package/dist/mcp/state-paths.d.ts +78 -4
  502. package/dist/mcp/state-paths.d.ts.map +1 -1
  503. package/dist/mcp/state-paths.js +543 -40
  504. package/dist/mcp/state-paths.js.map +1 -1
  505. package/dist/mcp/state-server.d.ts +68 -97
  506. package/dist/mcp/state-server.d.ts.map +1 -1
  507. package/dist/mcp/state-server.js +116 -67
  508. package/dist/mcp/state-server.js.map +1 -1
  509. package/dist/modes/__tests__/base-autopilot-gates.test.js +1 -168
  510. package/dist/modes/__tests__/base-autopilot-gates.test.js.map +1 -1
  511. package/dist/modes/__tests__/base-autoresearch-contract.test.js +1 -85
  512. package/dist/modes/__tests__/base-autoresearch-contract.test.js.map +1 -1
  513. package/dist/modes/__tests__/base-multi-state-compat.test.js +1 -35
  514. package/dist/modes/__tests__/base-multi-state-compat.test.js.map +1 -1
  515. package/dist/modes/__tests__/base-session-scope.test.js +10 -158
  516. package/dist/modes/__tests__/base-session-scope.test.js.map +1 -1
  517. package/dist/modes/base.d.ts +6 -6
  518. package/dist/modes/base.d.ts.map +1 -1
  519. package/dist/modes/base.js +116 -90
  520. package/dist/modes/base.js.map +1 -1
  521. package/dist/native-assets/archive.d.ts +17 -0
  522. package/dist/native-assets/archive.d.ts.map +1 -0
  523. package/dist/native-assets/archive.js +238 -0
  524. package/dist/native-assets/archive.js.map +1 -0
  525. package/dist/native-assets/policy.d.ts +42 -0
  526. package/dist/native-assets/policy.d.ts.map +1 -0
  527. package/dist/native-assets/policy.js +155 -0
  528. package/dist/native-assets/policy.js.map +1 -0
  529. package/dist/notifications/__tests__/formatter.test.js +8 -0
  530. package/dist/notifications/__tests__/formatter.test.js.map +1 -1
  531. package/dist/notifications/__tests__/template-engine.test.js +8 -0
  532. package/dist/notifications/__tests__/template-engine.test.js.map +1 -1
  533. package/dist/notifications/formatter.js +1 -1
  534. package/dist/notifications/formatter.js.map +1 -1
  535. package/dist/notifications/template-engine.js +1 -1
  536. package/dist/notifications/template-engine.js.map +1 -1
  537. package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.js +0 -21
  538. package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.js.map +1 -1
  539. package/dist/question/autopilot-wait.d.ts.map +1 -1
  540. package/dist/question/autopilot-wait.js +2 -2
  541. package/dist/question/autopilot-wait.js.map +1 -1
  542. package/dist/question/deep-interview.d.ts +1 -2
  543. package/dist/question/deep-interview.d.ts.map +1 -1
  544. package/dist/question/deep-interview.js +4 -4
  545. package/dist/question/deep-interview.js.map +1 -1
  546. package/dist/ralplan/__tests__/documented-leader-preflight.test.js +328 -39
  547. package/dist/ralplan/__tests__/documented-leader-preflight.test.js.map +1 -1
  548. package/dist/ralplan/__tests__/runtime.test.js +56 -821
  549. package/dist/ralplan/__tests__/runtime.test.js.map +1 -1
  550. package/dist/ralplan/documented-leader-preflight.d.ts +15 -8
  551. package/dist/ralplan/documented-leader-preflight.d.ts.map +1 -1
  552. package/dist/ralplan/documented-leader-preflight.js +356 -54
  553. package/dist/ralplan/documented-leader-preflight.js.map +1 -1
  554. package/dist/ralplan/runtime.d.ts +2 -2
  555. package/dist/ralplan/runtime.d.ts.map +1 -1
  556. package/dist/ralplan/runtime.js +145 -163
  557. package/dist/ralplan/runtime.js.map +1 -1
  558. package/dist/runtime/bridge.d.ts.map +1 -1
  559. package/dist/runtime/bridge.js +45 -0
  560. package/dist/runtime/bridge.js.map +1 -1
  561. package/dist/runtime/run-state.d.ts +5 -1
  562. package/dist/runtime/run-state.d.ts.map +1 -1
  563. package/dist/runtime/run-state.js +15 -8
  564. package/dist/runtime/run-state.js.map +1 -1
  565. package/dist/scripts/__tests__/codex-native-hook.test.js +12490 -19414
  566. package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
  567. package/dist/scripts/__tests__/docs-site-contract.test.js +2 -2
  568. package/dist/scripts/__tests__/docs-site-contract.test.js.map +1 -1
  569. package/dist/scripts/__tests__/generated-artifact-drift.test.d.ts +2 -0
  570. package/dist/scripts/__tests__/generated-artifact-drift.test.d.ts.map +1 -0
  571. package/dist/scripts/__tests__/generated-artifact-drift.test.js +84 -0
  572. package/dist/scripts/__tests__/generated-artifact-drift.test.js.map +1 -0
  573. package/dist/scripts/__tests__/issue-3293-callsite-parity.test.d.ts +2 -0
  574. package/dist/scripts/__tests__/issue-3293-callsite-parity.test.d.ts.map +1 -0
  575. package/dist/scripts/__tests__/issue-3293-callsite-parity.test.js +235 -0
  576. package/dist/scripts/__tests__/issue-3293-callsite-parity.test.js.map +1 -0
  577. package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.d.ts +2 -0
  578. package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.d.ts.map +1 -0
  579. package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.js +188 -0
  580. package/dist/scripts/__tests__/issue-3293-cancel-transaction.test.js.map +1 -0
  581. package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.d.ts +2 -0
  582. package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.d.ts.map +1 -0
  583. package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.js +207 -0
  584. package/dist/scripts/__tests__/issue-3293-hook-owned-cancel.test.js.map +1 -0
  585. package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.d.ts +2 -0
  586. package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.d.ts.map +1 -0
  587. package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.js +156 -0
  588. package/dist/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.js.map +1 -0
  589. package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.d.ts +2 -0
  590. package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.d.ts.map +1 -0
  591. package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.js +191 -0
  592. package/dist/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.js.map +1 -0
  593. package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.d.ts +2 -0
  594. package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.d.ts.map +1 -0
  595. package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.js +40 -0
  596. package/dist/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.js.map +1 -0
  597. package/dist/scripts/__tests__/issue-3481-conductor-deadlock.test.d.ts +2 -0
  598. package/dist/scripts/__tests__/issue-3481-conductor-deadlock.test.d.ts.map +1 -0
  599. package/dist/scripts/__tests__/issue-3481-conductor-deadlock.test.js +63 -0
  600. package/dist/scripts/__tests__/issue-3481-conductor-deadlock.test.js.map +1 -0
  601. package/dist/scripts/__tests__/issue-3486-pretooluse-lock-regression.test.d.ts +2 -0
  602. package/dist/scripts/__tests__/issue-3486-pretooluse-lock-regression.test.d.ts.map +1 -0
  603. package/dist/scripts/__tests__/issue-3486-pretooluse-lock-regression.test.js +65 -0
  604. package/dist/scripts/__tests__/issue-3486-pretooluse-lock-regression.test.js.map +1 -0
  605. package/dist/scripts/__tests__/issue-3536-external-team-state-root.test.d.ts +2 -0
  606. package/dist/scripts/__tests__/issue-3536-external-team-state-root.test.d.ts.map +1 -0
  607. package/dist/scripts/__tests__/issue-3536-external-team-state-root.test.js +189 -0
  608. package/dist/scripts/__tests__/issue-3536-external-team-state-root.test.js.map +1 -0
  609. package/dist/scripts/__tests__/notify-state-io.test.js +26 -0
  610. package/dist/scripts/__tests__/notify-state-io.test.js.map +1 -1
  611. package/dist/scripts/__tests__/notify-tmux-injection.test.js +23 -1
  612. package/dist/scripts/__tests__/notify-tmux-injection.test.js.map +1 -1
  613. package/dist/scripts/__tests__/postinstall.test.js +19 -1
  614. package/dist/scripts/__tests__/postinstall.test.js.map +1 -1
  615. package/dist/scripts/__tests__/prompt-inventory.test.js +54 -1
  616. package/dist/scripts/__tests__/prompt-inventory.test.js.map +1 -1
  617. package/dist/scripts/__tests__/reasoning-artifact-contract.test.js +2 -2
  618. package/dist/scripts/__tests__/reasoning-artifact-contract.test.js.map +1 -1
  619. package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js +46 -60
  620. package/dist/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.js.map +1 -1
  621. package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js +60 -25
  622. package/dist/scripts/__tests__/role-intent-durable-recovery-3181.test.js.map +1 -1
  623. package/dist/scripts/__tests__/smoke-packed-install.test.js +168 -20
  624. package/dist/scripts/__tests__/smoke-packed-install.test.js.map +1 -1
  625. package/dist/scripts/__tests__/verify-native-release-assets.test.d.ts +2 -0
  626. package/dist/scripts/__tests__/verify-native-release-assets.test.d.ts.map +1 -0
  627. package/dist/scripts/__tests__/verify-native-release-assets.test.js +235 -0
  628. package/dist/scripts/__tests__/verify-native-release-assets.test.js.map +1 -0
  629. package/dist/scripts/codex-native-hook.d.ts +51 -2
  630. package/dist/scripts/codex-native-hook.d.ts.map +1 -1
  631. package/dist/scripts/codex-native-hook.js +3648 -1332
  632. package/dist/scripts/codex-native-hook.js.map +1 -1
  633. package/dist/scripts/codex-native-pre-post.d.ts +9 -0
  634. package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
  635. package/dist/scripts/codex-native-pre-post.js +33 -22
  636. package/dist/scripts/codex-native-pre-post.js.map +1 -1
  637. package/dist/scripts/generate-native-release-manifest.js +80 -51
  638. package/dist/scripts/generate-native-release-manifest.js.map +1 -1
  639. package/dist/scripts/notify-fallback-watcher.js +28 -39
  640. package/dist/scripts/notify-fallback-watcher.js.map +1 -1
  641. package/dist/scripts/notify-hook/auto-nudge.d.ts +2 -48
  642. package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
  643. package/dist/scripts/notify-hook/auto-nudge.js +1 -0
  644. package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
  645. package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
  646. package/dist/scripts/notify-hook/state-io.js +5 -0
  647. package/dist/scripts/notify-hook/state-io.js.map +1 -1
  648. package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
  649. package/dist/scripts/notify-hook/team-dispatch.js +8 -5
  650. package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
  651. package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
  652. package/dist/scripts/notify-hook/team-leader-nudge.js +32 -3
  653. package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
  654. package/dist/scripts/notify-hook/team-tmux-guard.d.ts +1 -1
  655. package/dist/scripts/notify-hook/team-tmux-guard.d.ts.map +1 -1
  656. package/dist/scripts/notify-hook/team-tmux-guard.js +3 -2
  657. package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
  658. package/dist/scripts/notify-hook/team-worker-stop.d.ts.map +1 -1
  659. package/dist/scripts/notify-hook/team-worker-stop.js +23 -3
  660. package/dist/scripts/notify-hook/team-worker-stop.js.map +1 -1
  661. package/dist/scripts/notify-hook/team-worker.d.ts.map +1 -1
  662. package/dist/scripts/notify-hook/team-worker.js +45 -5
  663. package/dist/scripts/notify-hook/team-worker.js.map +1 -1
  664. package/dist/scripts/notify-hook/tmux-injection.d.ts +1 -0
  665. package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
  666. package/dist/scripts/notify-hook/tmux-injection.js +4 -1
  667. package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
  668. package/dist/scripts/notify-hook.d.ts.map +1 -1
  669. package/dist/scripts/notify-hook.js +71 -124
  670. package/dist/scripts/notify-hook.js.map +1 -1
  671. package/dist/scripts/postinstall-advisory.d.ts +14 -0
  672. package/dist/scripts/postinstall-advisory.d.ts.map +1 -0
  673. package/dist/scripts/postinstall-advisory.js +49 -0
  674. package/dist/scripts/postinstall-advisory.js.map +1 -0
  675. package/dist/scripts/postinstall.d.ts +1 -1
  676. package/dist/scripts/postinstall.d.ts.map +1 -1
  677. package/dist/scripts/postinstall.js +1 -1
  678. package/dist/scripts/postinstall.js.map +1 -1
  679. package/dist/scripts/prompt-inventory.d.ts +39 -0
  680. package/dist/scripts/prompt-inventory.d.ts.map +1 -1
  681. package/dist/scripts/prompt-inventory.js +108 -3
  682. package/dist/scripts/prompt-inventory.js.map +1 -1
  683. package/dist/scripts/run-compiled-ci.js +2 -0
  684. package/dist/scripts/run-compiled-ci.js.map +1 -1
  685. package/dist/scripts/run-test-files.js +1 -0
  686. package/dist/scripts/run-test-files.js.map +1 -1
  687. package/dist/scripts/smoke-packed-install.d.ts +32 -1
  688. package/dist/scripts/smoke-packed-install.d.ts.map +1 -1
  689. package/dist/scripts/smoke-packed-install.js +407 -60
  690. package/dist/scripts/smoke-packed-install.js.map +1 -1
  691. package/dist/scripts/sync-plugin-mirror.d.ts.map +1 -1
  692. package/dist/scripts/sync-plugin-mirror.js +16 -1
  693. package/dist/scripts/sync-plugin-mirror.js.map +1 -1
  694. package/dist/scripts/sync-prompt-guidance-fragments.js +62 -20
  695. package/dist/scripts/sync-prompt-guidance-fragments.js.map +1 -1
  696. package/dist/scripts/tmux-hook-engine.d.ts +1 -1
  697. package/dist/scripts/tmux-hook-engine.d.ts.map +1 -1
  698. package/dist/scripts/tmux-hook-engine.js +3 -3
  699. package/dist/scripts/tmux-hook-engine.js.map +1 -1
  700. package/dist/scripts/verify-capabilities-lock.d.ts +3 -0
  701. package/dist/scripts/verify-capabilities-lock.d.ts.map +1 -0
  702. package/dist/scripts/verify-capabilities-lock.js +22 -0
  703. package/dist/scripts/verify-capabilities-lock.js.map +1 -0
  704. package/dist/scripts/verify-native-release-assets.js +37 -23
  705. package/dist/scripts/verify-native-release-assets.js.map +1 -1
  706. package/dist/state/__tests__/authority-decreasing.test.d.ts +2 -0
  707. package/dist/state/__tests__/authority-decreasing.test.d.ts.map +1 -0
  708. package/dist/state/__tests__/authority-decreasing.test.js +78 -0
  709. package/dist/state/__tests__/authority-decreasing.test.js.map +1 -0
  710. package/dist/state/__tests__/handoff-carrier.test.d.ts +2 -0
  711. package/dist/state/__tests__/handoff-carrier.test.d.ts.map +1 -0
  712. package/dist/state/__tests__/handoff-carrier.test.js +96 -0
  713. package/dist/state/__tests__/handoff-carrier.test.js.map +1 -0
  714. package/dist/state/__tests__/mode-state-context.test.js +12 -5
  715. package/dist/state/__tests__/mode-state-context.test.js.map +1 -1
  716. package/dist/state/__tests__/operations.test.js +870 -2517
  717. package/dist/state/__tests__/operations.test.js.map +1 -1
  718. package/dist/state/__tests__/single-writer-invariant.test.d.ts +2 -0
  719. package/dist/state/__tests__/single-writer-invariant.test.d.ts.map +1 -0
  720. package/dist/state/__tests__/single-writer-invariant.test.js +342 -0
  721. package/dist/state/__tests__/single-writer-invariant.test.js.map +1 -0
  722. package/dist/state/__tests__/skill-active.test.js +400 -2
  723. package/dist/state/__tests__/skill-active.test.js.map +1 -1
  724. package/dist/state/__tests__/stale-state-neutralization.test.d.ts +2 -0
  725. package/dist/state/__tests__/stale-state-neutralization.test.d.ts.map +1 -0
  726. package/dist/state/__tests__/stale-state-neutralization.test.js +84 -0
  727. package/dist/state/__tests__/stale-state-neutralization.test.js.map +1 -0
  728. package/dist/state/__tests__/workflow-transition.test.js +20 -33
  729. package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
  730. package/dist/state/handoff-carrier.d.ts +46 -0
  731. package/dist/state/handoff-carrier.d.ts.map +1 -0
  732. package/dist/state/handoff-carrier.js +85 -0
  733. package/dist/state/handoff-carrier.js.map +1 -0
  734. package/dist/state/mode-state-context.d.ts +3 -0
  735. package/dist/state/mode-state-context.d.ts.map +1 -1
  736. package/dist/state/mode-state-context.js +27 -13
  737. package/dist/state/mode-state-context.js.map +1 -1
  738. package/dist/state/namespace-owners.d.ts +34 -0
  739. package/dist/state/namespace-owners.d.ts.map +1 -0
  740. package/dist/state/namespace-owners.js +127 -0
  741. package/dist/state/namespace-owners.js.map +1 -0
  742. package/dist/state/operations.d.ts +9 -4
  743. package/dist/state/operations.d.ts.map +1 -1
  744. package/dist/state/operations.js +194 -235
  745. package/dist/state/operations.js.map +1 -1
  746. package/dist/state/skill-active.d.ts +18 -1
  747. package/dist/state/skill-active.d.ts.map +1 -1
  748. package/dist/state/skill-active.js +421 -31
  749. package/dist/state/skill-active.js.map +1 -1
  750. package/dist/state/workflow-transition-reconcile.d.ts +3 -0
  751. package/dist/state/workflow-transition-reconcile.d.ts.map +1 -1
  752. package/dist/state/workflow-transition-reconcile.js +11 -31
  753. package/dist/state/workflow-transition-reconcile.js.map +1 -1
  754. package/dist/state/workflow-transition.d.ts +1 -27
  755. package/dist/state/workflow-transition.d.ts.map +1 -1
  756. package/dist/state/workflow-transition.js +9 -790
  757. package/dist/state/workflow-transition.js.map +1 -1
  758. package/dist/subagents/__tests__/leader-bootstrap-3181.test.js +27 -0
  759. package/dist/subagents/__tests__/leader-bootstrap-3181.test.js.map +1 -1
  760. package/dist/subagents/__tests__/tracker.test.js +837 -1048
  761. package/dist/subagents/__tests__/tracker.test.js.map +1 -1
  762. package/dist/subagents/tracker.d.ts +64 -60
  763. package/dist/subagents/tracker.d.ts.map +1 -1
  764. package/dist/subagents/tracker.js +809 -358
  765. package/dist/subagents/tracker.js.map +1 -1
  766. package/dist/team/__tests__/api-interop.test.js +1 -0
  767. package/dist/team/__tests__/api-interop.test.js.map +1 -1
  768. package/dist/team/__tests__/delivery-e2e-smoke.test.js +6 -7
  769. package/dist/team/__tests__/delivery-e2e-smoke.test.js.map +1 -1
  770. package/dist/team/__tests__/mcp-comm.test.js +104 -3
  771. package/dist/team/__tests__/mcp-comm.test.js.map +1 -1
  772. package/dist/team/__tests__/notice-ledger.test.d.ts +2 -0
  773. package/dist/team/__tests__/notice-ledger.test.d.ts.map +1 -0
  774. package/dist/team/__tests__/notice-ledger.test.js +131 -0
  775. package/dist/team/__tests__/notice-ledger.test.js.map +1 -0
  776. package/dist/team/__tests__/pane-teardown-residue-e2e.test.d.ts +2 -0
  777. package/dist/team/__tests__/pane-teardown-residue-e2e.test.d.ts.map +1 -0
  778. package/dist/team/__tests__/pane-teardown-residue-e2e.test.js +410 -0
  779. package/dist/team/__tests__/pane-teardown-residue-e2e.test.js.map +1 -0
  780. package/dist/team/__tests__/phase-controller.test.js +20 -0
  781. package/dist/team/__tests__/phase-controller.test.js.map +1 -1
  782. package/dist/team/__tests__/runtime.test.js +725 -59
  783. package/dist/team/__tests__/runtime.test.js.map +1 -1
  784. package/dist/team/__tests__/scaling.test.js +269 -245
  785. package/dist/team/__tests__/scaling.test.js.map +1 -1
  786. package/dist/team/__tests__/state-root.test.js +117 -2
  787. package/dist/team/__tests__/state-root.test.js.map +1 -1
  788. package/dist/team/__tests__/team-ops-contract.test.js +1 -0
  789. package/dist/team/__tests__/team-ops-contract.test.js.map +1 -1
  790. package/dist/team/__tests__/tmux-session.test.js +1093 -101
  791. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  792. package/dist/team/__tests__/tmux-source-authority-realtmux.test.d.ts +2 -0
  793. package/dist/team/__tests__/tmux-source-authority-realtmux.test.d.ts.map +1 -0
  794. package/dist/team/__tests__/tmux-source-authority-realtmux.test.js +159 -0
  795. package/dist/team/__tests__/tmux-source-authority-realtmux.test.js.map +1 -0
  796. package/dist/team/__tests__/tmux-test-fixture.d.ts +69 -0
  797. package/dist/team/__tests__/tmux-test-fixture.d.ts.map +1 -1
  798. package/dist/team/__tests__/tmux-test-fixture.js +242 -15
  799. package/dist/team/__tests__/tmux-test-fixture.js.map +1 -1
  800. package/dist/team/__tests__/tmux-test-fixture.test.js +177 -1
  801. package/dist/team/__tests__/tmux-test-fixture.test.js.map +1 -1
  802. package/dist/team/__tests__/worker-bootstrap.test.js +11 -13
  803. package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
  804. package/dist/team/__tests__/worker-provenance.test.d.ts +2 -0
  805. package/dist/team/__tests__/worker-provenance.test.d.ts.map +1 -0
  806. package/dist/team/__tests__/worker-provenance.test.js +251 -0
  807. package/dist/team/__tests__/worker-provenance.test.js.map +1 -0
  808. package/dist/team/__tests__/worker-runtime-identity.test.js +45 -72
  809. package/dist/team/__tests__/worker-runtime-identity.test.js.map +1 -1
  810. package/dist/team/api-interop.d.ts.map +1 -1
  811. package/dist/team/api-interop.js +14 -8
  812. package/dist/team/api-interop.js.map +1 -1
  813. package/dist/team/mcp-comm.d.ts.map +1 -1
  814. package/dist/team/mcp-comm.js +3 -8
  815. package/dist/team/mcp-comm.js.map +1 -1
  816. package/dist/team/notice-ledger.d.ts +54 -0
  817. package/dist/team/notice-ledger.d.ts.map +1 -0
  818. package/dist/team/notice-ledger.js +259 -0
  819. package/dist/team/notice-ledger.js.map +1 -0
  820. package/dist/team/phase-controller.d.ts.map +1 -1
  821. package/dist/team/phase-controller.js +2 -0
  822. package/dist/team/phase-controller.js.map +1 -1
  823. package/dist/team/runtime.d.ts +3 -1
  824. package/dist/team/runtime.d.ts.map +1 -1
  825. package/dist/team/runtime.js +314 -142
  826. package/dist/team/runtime.js.map +1 -1
  827. package/dist/team/scaling.d.ts.map +1 -1
  828. package/dist/team/scaling.js +161 -91
  829. package/dist/team/scaling.js.map +1 -1
  830. package/dist/team/state/monitor.d.ts +10 -0
  831. package/dist/team/state/monitor.d.ts.map +1 -1
  832. package/dist/team/state/monitor.js +13 -0
  833. package/dist/team/state/monitor.js.map +1 -1
  834. package/dist/team/state/types.d.ts +15 -0
  835. package/dist/team/state/types.d.ts.map +1 -1
  836. package/dist/team/state/types.js.map +1 -1
  837. package/dist/team/state-root.d.ts +12 -0
  838. package/dist/team/state-root.d.ts.map +1 -1
  839. package/dist/team/state-root.js +177 -0
  840. package/dist/team/state-root.js.map +1 -1
  841. package/dist/team/state.d.ts +19 -0
  842. package/dist/team/state.d.ts.map +1 -1
  843. package/dist/team/state.js +47 -1
  844. package/dist/team/state.js.map +1 -1
  845. package/dist/team/team-ops.d.ts +1 -0
  846. package/dist/team/team-ops.d.ts.map +1 -1
  847. package/dist/team/team-ops.js +1 -0
  848. package/dist/team/team-ops.js.map +1 -1
  849. package/dist/team/tmux-session.d.ts +42 -4
  850. package/dist/team/tmux-session.d.ts.map +1 -1
  851. package/dist/team/tmux-session.js +572 -196
  852. package/dist/team/tmux-session.js.map +1 -1
  853. package/dist/team/ultragoal-context.d.ts +1 -0
  854. package/dist/team/ultragoal-context.d.ts.map +1 -1
  855. package/dist/team/ultragoal-context.js +2 -0
  856. package/dist/team/ultragoal-context.js.map +1 -1
  857. package/dist/team/worker-provenance.d.ts +35 -0
  858. package/dist/team/worker-provenance.d.ts.map +1 -0
  859. package/dist/team/worker-provenance.js +213 -0
  860. package/dist/team/worker-provenance.js.map +1 -0
  861. package/dist/ultragoal/__tests__/artifacts.test.js +1053 -2
  862. package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
  863. package/dist/ultragoal/__tests__/docs-contract.test.js +89 -59
  864. package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -1
  865. package/dist/ultragoal/artifacts.d.ts +36 -1
  866. package/dist/ultragoal/artifacts.d.ts.map +1 -1
  867. package/dist/ultragoal/artifacts.js +267 -51
  868. package/dist/ultragoal/artifacts.js.map +1 -1
  869. package/dist/url-reader/__tests__/url-reader.test.js +14 -0
  870. package/dist/url-reader/__tests__/url-reader.test.js.map +1 -1
  871. package/dist/url-reader/index.js +5 -3
  872. package/dist/url-reader/index.js.map +1 -1
  873. package/dist/utils/__tests__/file-durability.test.js +58 -1
  874. package/dist/utils/__tests__/file-durability.test.js.map +1 -1
  875. package/dist/utils/__tests__/paths.test.js +21 -1
  876. package/dist/utils/__tests__/paths.test.js.map +1 -1
  877. package/dist/utils/__tests__/version.test.js +17 -0
  878. package/dist/utils/__tests__/version.test.js.map +1 -1
  879. package/dist/utils/file-durability.d.ts +10 -0
  880. package/dist/utils/file-durability.d.ts.map +1 -1
  881. package/dist/utils/file-durability.js +34 -4
  882. package/dist/utils/file-durability.js.map +1 -1
  883. package/dist/utils/paths.d.ts.map +1 -1
  884. package/dist/utils/paths.js +14 -6
  885. package/dist/utils/paths.js.map +1 -1
  886. package/dist/utils/version.d.ts.map +1 -1
  887. package/dist/utils/version.js +2 -1
  888. package/dist/utils/version.js.map +1 -1
  889. package/dist/verification/__tests__/ci-rust-gates.test.js +49 -4
  890. package/dist/verification/__tests__/ci-rust-gates.test.js.map +1 -1
  891. package/dist/verification/__tests__/explore-harness-release-workflow.test.js +60 -0
  892. package/dist/verification/__tests__/explore-harness-release-workflow.test.js.map +1 -1
  893. package/dist/verification/__tests__/native-release-manifest.test.js +157 -4
  894. package/dist/verification/__tests__/native-release-manifest.test.js.map +1 -1
  895. package/package.json +17 -6
  896. package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
  897. package/plugins/oh-my-codex/hooks/codex-native-hook.mjs +81 -17
  898. package/plugins/oh-my-codex/skills/ai-slop-cleaner/SKILL.md +60 -135
  899. package/plugins/oh-my-codex/skills/analyze/SKILL.md +35 -111
  900. package/plugins/oh-my-codex/skills/autopilot/SKILL.md +72 -163
  901. package/plugins/oh-my-codex/skills/cancel/SKILL.md +33 -392
  902. package/plugins/oh-my-codex/skills/code-review/SKILL.md +66 -256
  903. package/plugins/oh-my-codex/skills/configure-notifications/SKILL.md +30 -216
  904. package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +11 -10
  905. package/plugins/oh-my-codex/skills/design/SKILL.md +32 -132
  906. package/plugins/oh-my-codex/skills/doctor/SKILL.md +56 -177
  907. package/plugins/oh-my-codex/skills/omx-setup/SKILL.md +35 -116
  908. package/plugins/oh-my-codex/skills/plan/SKILL.md +45 -228
  909. package/plugins/oh-my-codex/skills/ralplan/SKILL.md +20 -22
  910. package/plugins/oh-my-codex/skills/skill/SKILL.md +82 -807
  911. package/plugins/oh-my-codex/skills/team/SKILL.md +32 -520
  912. package/plugins/oh-my-codex/skills/ultragoal/SKILL.md +47 -150
  913. package/plugins/oh-my-codex/skills/ultraqa/SKILL.md +75 -252
  914. package/plugins/oh-my-codex/skills/visual-ralph/SKILL.md +33 -111
  915. package/plugins/oh-my-codex/skills/worker/SKILL.md +40 -113
  916. package/prompts/analyst.md +27 -107
  917. package/prompts/api-reviewer.md +17 -84
  918. package/prompts/architect.md +31 -70
  919. package/prompts/code-reviewer.md +18 -107
  920. package/prompts/code-simplifier.md +32 -110
  921. package/prompts/critic.md +32 -54
  922. package/prompts/dependency-expert.md +37 -107
  923. package/prompts/designer.md +40 -107
  924. package/prompts/executor.md +26 -75
  925. package/prompts/information-architect.md +51 -200
  926. package/prompts/performance-reviewer.md +17 -81
  927. package/prompts/planner.md +33 -76
  928. package/prompts/product-analyst.md +65 -280
  929. package/prompts/product-manager.md +48 -216
  930. package/prompts/qa-tester.md +33 -104
  931. package/prompts/quality-reviewer.md +17 -93
  932. package/prompts/quality-strategist.md +31 -255
  933. package/prompts/researcher.md +32 -89
  934. package/prompts/security-reviewer.md +12 -98
  935. package/prompts/test-engineer.md +29 -110
  936. package/prompts/ux-researcher.md +46 -300
  937. package/prompts/verifier.md +23 -51
  938. package/skills/ai-slop-cleaner/SKILL.md +60 -135
  939. package/skills/analyze/SKILL.md +35 -111
  940. package/skills/autopilot/SKILL.md +72 -163
  941. package/skills/autoresearch-goal/SKILL.md +6 -31
  942. package/skills/cancel/SKILL.md +33 -392
  943. package/skills/code-review/SKILL.md +66 -256
  944. package/skills/configure-notifications/SKILL.md +30 -216
  945. package/skills/deep-interview/SKILL.md +11 -10
  946. package/skills/design/SKILL.md +32 -132
  947. package/skills/doctor/SKILL.md +56 -177
  948. package/skills/omx-setup/SKILL.md +35 -116
  949. package/skills/pipeline/SKILL.md +6 -89
  950. package/skills/plan/SKILL.md +45 -228
  951. package/skills/ralph/SKILL.md +6 -290
  952. package/skills/ralplan/SKILL.md +20 -22
  953. package/skills/skill/SKILL.md +82 -807
  954. package/skills/team/SKILL.md +32 -520
  955. package/skills/ultragoal/SKILL.md +47 -150
  956. package/skills/ultraqa/SKILL.md +75 -252
  957. package/skills/ultrawork/SKILL.md +6 -182
  958. package/skills/visual-ralph/SKILL.md +33 -111
  959. package/skills/worker/SKILL.md +40 -113
  960. package/src/scripts/__tests__/codex-native-hook.test.ts +18888 -28799
  961. package/src/scripts/__tests__/docs-site-contract.test.ts +2 -2
  962. package/src/scripts/__tests__/generated-artifact-drift.test.ts +97 -0
  963. package/src/scripts/__tests__/issue-3293-callsite-parity.test.ts +197 -0
  964. package/src/scripts/__tests__/issue-3293-cancel-transaction.test.ts +189 -0
  965. package/src/scripts/__tests__/issue-3293-hook-owned-cancel.test.ts +186 -0
  966. package/src/scripts/__tests__/issue-3311-ultragoal-native-outside-tmux.test.ts +177 -0
  967. package/src/scripts/__tests__/issue-3358-ultragoal-cancel-lifecycle.test.ts +201 -0
  968. package/src/scripts/__tests__/issue-3369-autopilot-ralplan-state-machine.test.ts +43 -0
  969. package/src/scripts/__tests__/issue-3481-conductor-deadlock.test.ts +77 -0
  970. package/src/scripts/__tests__/issue-3486-pretooluse-lock-regression.test.ts +95 -0
  971. package/src/scripts/__tests__/issue-3536-external-team-state-root.test.ts +216 -0
  972. package/src/scripts/__tests__/notify-state-io.test.ts +29 -0
  973. package/src/scripts/__tests__/notify-tmux-injection.test.ts +26 -1
  974. package/src/scripts/__tests__/postinstall.test.ts +23 -1
  975. package/src/scripts/__tests__/prompt-inventory.test.ts +62 -1
  976. package/src/scripts/__tests__/reasoning-artifact-contract.test.ts +1 -2
  977. package/src/scripts/__tests__/role-intent-bootstrap-e2e-3181.test.ts +49 -59
  978. package/src/scripts/__tests__/role-intent-durable-recovery-3181.test.ts +61 -27
  979. package/src/scripts/__tests__/smoke-packed-install.test.ts +223 -23
  980. package/src/scripts/__tests__/verify-native-release-assets.test.ts +240 -0
  981. package/src/scripts/codex-native-hook.ts +3618 -1383
  982. package/src/scripts/codex-native-pre-post.ts +50 -24
  983. package/src/scripts/generate-native-release-manifest.ts +83 -79
  984. package/src/scripts/notify-fallback-watcher.ts +38 -38
  985. package/src/scripts/notify-hook/auto-nudge.ts +1 -0
  986. package/src/scripts/notify-hook/state-io.ts +11 -0
  987. package/src/scripts/notify-hook/team-dispatch.ts +8 -5
  988. package/src/scripts/notify-hook/team-leader-nudge.ts +32 -4
  989. package/src/scripts/notify-hook/team-tmux-guard.ts +3 -1
  990. package/src/scripts/notify-hook/team-worker-stop.ts +23 -4
  991. package/src/scripts/notify-hook/team-worker.ts +43 -5
  992. package/src/scripts/notify-hook/tmux-injection.ts +5 -1
  993. package/src/scripts/notify-hook.ts +76 -124
  994. package/src/scripts/postinstall-advisory.ts +67 -0
  995. package/src/scripts/postinstall.ts +1 -1
  996. package/src/scripts/prompt-inventory.ts +142 -3
  997. package/src/scripts/run-compiled-ci.ts +2 -0
  998. package/src/scripts/run-test-files.ts +1 -0
  999. package/src/scripts/smoke-packed-install.ts +440 -59
  1000. package/src/scripts/sync-plugin-mirror.ts +17 -1
  1001. package/src/scripts/sync-prompt-guidance-fragments.ts +59 -22
  1002. package/src/scripts/tmux-hook-engine.ts +3 -3
  1003. package/src/scripts/verify-capabilities-lock.ts +23 -0
  1004. package/src/scripts/verify-native-release-assets.ts +39 -31
  1005. package/templates/AGENTS.md +45 -9
  1006. package/templates/catalog-manifest.json +6 -146
  1007. package/dist/autopilot/__tests__/deep-interview-gate.test.d.ts +0 -2
  1008. package/dist/autopilot/__tests__/deep-interview-gate.test.d.ts.map +0 -1
  1009. package/dist/autopilot/__tests__/deep-interview-gate.test.js +0 -215
  1010. package/dist/autopilot/__tests__/deep-interview-gate.test.js.map +0 -1
  1011. package/dist/autopilot/__tests__/ralplan-gate.test.d.ts +0 -2
  1012. package/dist/autopilot/__tests__/ralplan-gate.test.d.ts.map +0 -1
  1013. package/dist/autopilot/__tests__/ralplan-gate.test.js +0 -1361
  1014. package/dist/autopilot/__tests__/ralplan-gate.test.js.map +0 -1
  1015. package/dist/autopilot/deep-interview-gate.d.ts +0 -18
  1016. package/dist/autopilot/deep-interview-gate.d.ts.map +0 -1
  1017. package/dist/autopilot/deep-interview-gate.js +0 -396
  1018. package/dist/autopilot/deep-interview-gate.js.map +0 -1
  1019. package/dist/autopilot/ralplan-gate.d.ts +0 -18
  1020. package/dist/autopilot/ralplan-gate.d.ts.map +0 -1
  1021. package/dist/autopilot/ralplan-gate.js +0 -148
  1022. package/dist/autopilot/ralplan-gate.js.map +0 -1
  1023. package/dist/hooks/__tests__/prometheus-strict-contract.test.d.ts +0 -2
  1024. package/dist/hooks/__tests__/prometheus-strict-contract.test.d.ts.map +0 -1
  1025. package/dist/hooks/__tests__/prometheus-strict-contract.test.js +0 -320
  1026. package/dist/hooks/__tests__/prometheus-strict-contract.test.js.map +0 -1
  1027. package/dist/pipeline/__tests__/orchestrator.test.d.ts +0 -2
  1028. package/dist/pipeline/__tests__/orchestrator.test.d.ts.map +0 -1
  1029. package/dist/pipeline/__tests__/orchestrator.test.js +0 -770
  1030. package/dist/pipeline/__tests__/orchestrator.test.js.map +0 -1
  1031. package/dist/pipeline/__tests__/stages.test.d.ts +0 -2
  1032. package/dist/pipeline/__tests__/stages.test.d.ts.map +0 -1
  1033. package/dist/pipeline/__tests__/stages.test.js +0 -1778
  1034. package/dist/pipeline/__tests__/stages.test.js.map +0 -1
  1035. package/dist/pipeline/index.d.ts +0 -25
  1036. package/dist/pipeline/index.d.ts.map +0 -1
  1037. package/dist/pipeline/index.js +0 -17
  1038. package/dist/pipeline/index.js.map +0 -1
  1039. package/dist/pipeline/orchestrator.d.ts +0 -52
  1040. package/dist/pipeline/orchestrator.d.ts.map +0 -1
  1041. package/dist/pipeline/orchestrator.js +0 -399
  1042. package/dist/pipeline/orchestrator.js.map +0 -1
  1043. package/dist/pipeline/review-verdict.d.ts +0 -3
  1044. package/dist/pipeline/review-verdict.d.ts.map +0 -1
  1045. package/dist/pipeline/review-verdict.js +0 -14
  1046. package/dist/pipeline/review-verdict.js.map +0 -1
  1047. package/dist/pipeline/stages/code-review.d.ts +0 -35
  1048. package/dist/pipeline/stages/code-review.d.ts.map +0 -1
  1049. package/dist/pipeline/stages/code-review.js +0 -55
  1050. package/dist/pipeline/stages/code-review.js.map +0 -1
  1051. package/dist/pipeline/stages/deep-interview.d.ts +0 -15
  1052. package/dist/pipeline/stages/deep-interview.d.ts.map +0 -1
  1053. package/dist/pipeline/stages/deep-interview.js +0 -32
  1054. package/dist/pipeline/stages/deep-interview.js.map +0 -1
  1055. package/dist/pipeline/stages/ralph-verify.d.ts +0 -53
  1056. package/dist/pipeline/stages/ralph-verify.d.ts.map +0 -1
  1057. package/dist/pipeline/stages/ralph-verify.js +0 -89
  1058. package/dist/pipeline/stages/ralph-verify.js.map +0 -1
  1059. package/dist/pipeline/stages/ralplan.d.ts +0 -27
  1060. package/dist/pipeline/stages/ralplan.d.ts.map +0 -1
  1061. package/dist/pipeline/stages/ralplan.js +0 -152
  1062. package/dist/pipeline/stages/ralplan.js.map +0 -1
  1063. package/dist/pipeline/stages/team-exec.d.ts +0 -52
  1064. package/dist/pipeline/stages/team-exec.d.ts.map +0 -1
  1065. package/dist/pipeline/stages/team-exec.js +0 -266
  1066. package/dist/pipeline/stages/team-exec.js.map +0 -1
  1067. package/dist/pipeline/stages/ultragoal.d.ts +0 -23
  1068. package/dist/pipeline/stages/ultragoal.d.ts.map +0 -1
  1069. package/dist/pipeline/stages/ultragoal.js +0 -53
  1070. package/dist/pipeline/stages/ultragoal.js.map +0 -1
  1071. package/dist/pipeline/stages/ultraqa.d.ts +0 -33
  1072. package/dist/pipeline/stages/ultraqa.d.ts.map +0 -1
  1073. package/dist/pipeline/stages/ultraqa.js +0 -49
  1074. package/dist/pipeline/stages/ultraqa.js.map +0 -1
  1075. package/dist/pipeline/types.d.ts +0 -124
  1076. package/dist/pipeline/types.d.ts.map +0 -1
  1077. package/dist/pipeline/types.js +0 -8
  1078. package/dist/pipeline/types.js.map +0 -1
  1079. package/dist/ralplan/__tests__/consensus-gate.test.d.ts +0 -2
  1080. package/dist/ralplan/__tests__/consensus-gate.test.d.ts.map +0 -1
  1081. package/dist/ralplan/__tests__/consensus-gate.test.js +0 -1455
  1082. package/dist/ralplan/__tests__/consensus-gate.test.js.map +0 -1
  1083. package/dist/ralplan/consensus-gate.d.ts +0 -62
  1084. package/dist/ralplan/consensus-gate.d.ts.map +0 -1
  1085. package/dist/ralplan/consensus-gate.js +0 -760
  1086. package/dist/ralplan/consensus-gate.js.map +0 -1
  1087. package/dist/scripts/notify-hook/ralph-session-resume.d.ts +0 -25
  1088. package/dist/scripts/notify-hook/ralph-session-resume.d.ts.map +0 -1
  1089. package/dist/scripts/notify-hook/ralph-session-resume.js +0 -377
  1090. package/dist/scripts/notify-hook/ralph-session-resume.js.map +0 -1
  1091. package/dist/state/__tests__/planning-gate.test.d.ts +0 -2
  1092. package/dist/state/__tests__/planning-gate.test.d.ts.map +0 -1
  1093. package/dist/state/__tests__/planning-gate.test.js +0 -629
  1094. package/dist/state/__tests__/planning-gate.test.js.map +0 -1
  1095. package/plugins/oh-my-codex/skills/autoresearch-goal/SKILL.md +0 -39
  1096. package/plugins/oh-my-codex/skills/pipeline/SKILL.md +0 -97
  1097. package/plugins/oh-my-codex/skills/prometheus-strict/README.md +0 -35
  1098. package/plugins/oh-my-codex/skills/prometheus-strict/SKILL.md +0 -219
  1099. package/plugins/oh-my-codex/skills/ralph/SKILL.md +0 -298
  1100. package/plugins/oh-my-codex/skills/ultrawork/SKILL.md +0 -190
  1101. package/plugins/oh-my-codex/skills/ultrawork/references/agent-tiers.md +0 -62
  1102. package/prompts/prometheus-strict-metis.md +0 -274
  1103. package/prompts/prometheus-strict-momus.md +0 -82
  1104. package/prompts/prometheus-strict-oracle.md +0 -107
  1105. package/prompts/scholastic.md +0 -11
  1106. package/prompts/sisyphus-lite.md +0 -111
  1107. package/skills/ask-claude/SKILL.md +0 -12
  1108. package/skills/ask-gemini/SKILL.md +0 -12
  1109. package/skills/build-fix/SKILL.md +0 -10
  1110. package/skills/deepsearch/SKILL.md +0 -10
  1111. package/skills/ecomode/SKILL.md +0 -114
  1112. package/skills/ecomode/references/agent-tiers.md +0 -61
  1113. package/skills/frontend-ui-ux/SKILL.md +0 -16
  1114. package/skills/help/SKILL.md +0 -10
  1115. package/skills/note/SKILL.md +0 -10
  1116. package/skills/prometheus-strict/README.md +0 -35
  1117. package/skills/prometheus-strict/SKILL.md +0 -219
  1118. package/skills/ralph-init/SKILL.md +0 -10
  1119. package/skills/review/SKILL.md +0 -10
  1120. package/skills/security-review/SKILL.md +0 -10
  1121. package/skills/swarm/SKILL.md +0 -12
  1122. package/skills/tdd/SKILL.md +0 -104
  1123. package/skills/trace/SKILL.md +0 -10
  1124. package/skills/visual-verdict/SKILL.md +0 -10
  1125. package/skills/web-clone/SKILL.md +0 -357
  1126. package/src/scripts/notify-hook/ralph-session-resume.ts +0 -466
@@ -1,14 +1,14 @@
1
1
  import { afterEach, beforeEach, describe, it } from 'node:test';
2
2
  import assert from 'node:assert/strict';
3
3
  import { createHash } from 'node:crypto';
4
- import { execFileSync, spawn } from 'child_process';
4
+ import { execFileSync, spawn, spawnSync } from 'child_process';
5
5
  import { mkdtemp, rm, writeFile, readFile, mkdir, chmod, readdir } from 'fs/promises';
6
6
  import { join, relative, dirname } from 'path';
7
7
  import { tmpdir } from 'os';
8
8
  import { existsSync } from 'fs';
9
9
  import { HUD_TMUX_TEAM_HEIGHT_LINES } from '../../hud/constants.js';
10
- import { DEFAULT_MAX_WORKERS, initTeamState, createTask, writeWorkerInbox, readTeamConfig, saveTeamConfig, listMailboxMessages, listDispatchRequests, transitionDispatchRequest, updateWorkerHeartbeat, writeAtomic, readTask, readMonitorSnapshot, claimTask, transitionTaskStatus, readWorkerStatus, writeWorkerStatus, } from '../state.js';
11
- import { monitorTeam, shutdownTeam, resumeTeam, startTeam, assignTask, sendWorkerMessage, applyCreatedInteractiveSessionToConfig, resolveWorkerLaunchArgsFromEnv, resolveTeamWorkerCliForResolvedLaunchArgs, shouldPrekillInteractiveShutdownProcessTrees, waitForWorkerStartupEvidence, waitForClaudeStartupEvidence, cleanupTeamWorkerLaunchOrphanedMcpProcesses, settleStartupAttemptResults, setDetachedSessionDestroyAfterJournalHookForTest, } from '../runtime.js';
10
+ import { DEFAULT_MAX_WORKERS, initTeamState, createTask, writeWorkerInbox, readTeamConfig, saveTeamConfig, listMailboxMessages, sendDirectMessage, listDispatchRequests, transitionDispatchRequest, updateWorkerHeartbeat, writeAtomic, readTask, readMonitorSnapshot, claimTask, transitionTaskStatus, readWorkerStatus, writeWorkerStatus, readTeamPhase, writeTeamPhase, } from '../state.js';
11
+ import { monitorTeam, shutdownTeam, resumeTeam, startTeam, assignTask, sendWorkerMessage, applyCreatedInteractiveSessionToConfig, reconcileStartupCleanupPanes, resolveWorkerLaunchArgsFromEnv, resolveTeamWorkerCliForResolvedLaunchArgs, shouldPrekillInteractiveShutdownProcessTrees, waitForWorkerStartupEvidence, waitForClaudeStartupEvidence, cleanupTeamWorkerLaunchOrphanedMcpProcesses, settleStartupAttemptResults, setDetachedSessionDestroyAfterJournalHookForTest, setTerminalEpochStartedHookForTest, } from '../runtime.js';
12
12
  import { resolveAgentReasoningEffort, resolveTeamLowComplexityDefaultModel, TEAM_WORKER_INHERITED_MODEL_ENV, } from '../model-contract.js';
13
13
  import { readTeamEvents } from '../state/events.js';
14
14
  import { sanitizeTeamName } from '../tmux-session.js';
@@ -433,10 +433,94 @@ if (process.argv.includes('--version') || process.argv.includes('-V')) {
433
433
  }
434
434
  ${body}`;
435
435
  }
436
+ function codexMdmTmuxScript(marker) {
437
+ return (tmuxLogPath) => `#!/bin/sh
438
+ set -eu
439
+ ${tmuxOwnerProofShim}
440
+ printf '%s\n' "$*" >> "${tmuxLogPath}"
441
+ case "$1" in
442
+ -V) echo 'tmux 3.4' ;;
443
+ display-message)
444
+ case "$*" in *'#{window_width}'*) echo 120 ;; *) echo 'leader:0 %1' ;; esac
445
+ ;;
446
+ list-panes)
447
+ case "$*" in
448
+ *'-a -F #{pane_id}'*)
449
+ printf '%%1\t0\t2000001111\n'
450
+ if [ -f "${tmuxLogPath}.worker-created" ]; then
451
+ worker_pid=$(cat "${tmuxLogPath}.worker-pid")
452
+ printf '%%2\t0\t%s\n' "$worker_pid"
453
+ fi
454
+ if [ -f "${tmuxLogPath}.hud-created" ]; then printf '%%3\t0\t2000003333\n'; fi
455
+ ;;
456
+ *'pane_current_command'*)
457
+ printf "%%1\tnode\t'codex'\n"
458
+ if [ -f "${tmuxLogPath}.worker-created" ]; then printf '%%2\tcodex\tcodex\n'; fi
459
+ if [ -f "${tmuxLogPath}.hud-created" ]; then printf '%%3\tnode\thud --watch\n'; fi
460
+ ;;
461
+ *'#{pane_dead} #{pane_pid}'*)
462
+ case "$*" in
463
+ *'%1'*) echo '0 2000001111' ;;
464
+ *'%2'*) if [ -f "${tmuxLogPath}.worker-pid" ]; then echo "0 $(cat "${tmuxLogPath}.worker-pid")"; fi ;;
465
+ *'%3'*) echo '0 2000003333' ;;
466
+ esac
467
+ ;;
468
+ *'#{pane_dead}'*) echo 0 ;;
469
+ *'#{pane_pid}'*)
470
+ case "$*" in
471
+ *'%1'*) echo 2000001111 ;;
472
+ *'%2'*) if [ -f "${tmuxLogPath}.worker-pid" ]; then cat "${tmuxLogPath}.worker-pid"; fi ;;
473
+ *'%3'*) echo 2000003333 ;;
474
+ esac
475
+ ;;
476
+ esac
477
+ ;;
478
+ capture-pane)
479
+ count=0
480
+ [ -f "${tmuxLogPath}.capture-count" ] && count=$(cat "${tmuxLogPath}.capture-count")
481
+ count=$((count + 1))
482
+ printf '%s' "$count" > "${tmuxLogPath}.capture-count"
483
+ if [ "${'$'}{OMX_MDM_CAPTURE_MODE:-direct}" = detailed ] && [ "$count" -lt 5 ]; then
484
+ printf 'OpenAI Codex\\nmodel: test\\ndirectory: /tmp/demo\\n'
485
+ else
486
+ printf '%s\\n' '${marker}'
487
+ fi
488
+ ;;
489
+ split-window)
490
+ case "$*" in
491
+ *' -h '*)
492
+ : > "${tmuxLogPath}.worker-created"
493
+ last=''
494
+ for arg in "$@"; do last="$arg"; done
495
+ sh -c "$last" >/dev/null 2>&1 &
496
+ printf '%s' "$!" > "${tmuxLogPath}.worker-pid"
497
+ echo '%2'
498
+ ;;
499
+ *) : > "${tmuxLogPath}.hud-created"; echo '%3' ;;
500
+ esac
501
+ ;;
502
+ kill-pane)
503
+ case "$*" in
504
+ *'%2'*)
505
+ if [ -f "${tmuxLogPath}.worker-pid" ]; then kill "$(cat "${tmuxLogPath}.worker-pid")" 2>/dev/null || true; fi
506
+ rm -f "${tmuxLogPath}.worker-created" "${tmuxLogPath}.worker-pid"
507
+ ;;
508
+ *'%3'*) rm -f "${tmuxLogPath}.hud-created" ;;
509
+ esac
510
+ ;;
511
+ set-hook|run-shell|select-layout|set-window-option|select-pane|send-keys|kill-session|resize-pane) ;;
512
+ esac
513
+ `;
514
+ }
436
515
  function teamStateTestPath(cwd, ...parts) {
437
516
  const stateRoot = process.env.OMX_TEAM_STATE_ROOT ?? join(cwd, '.omx', 'state');
438
517
  return join(stateRoot, ...parts);
439
518
  }
519
+ async function settleReceiptInterval(timer, pending) {
520
+ if (timer)
521
+ clearInterval(timer);
522
+ await pending;
523
+ }
440
524
  async function withMockTmuxFixture(options, run) {
441
525
  const fakeBinDir = await mkdtemp(join(tmpdir(), options.dirPrefix));
442
526
  const tmuxLogPath = join(fakeBinDir, 'tmux.log');
@@ -449,10 +533,165 @@ async function withMockTmuxFixture(options, run) {
449
533
  };
450
534
  try {
451
535
  const tmuxFixture = options.tmuxScript(tmuxLogPath);
536
+ const originalFixturePath = `${tmuxStubPath}.fixture`;
537
+ await writeFile(originalFixturePath, tmuxFixture);
538
+ const originalSyntaxCheck = spawnSync('sh', ['-n', originalFixturePath], { encoding: 'utf-8' });
539
+ if (originalSyntaxCheck.status !== 0 || originalSyntaxCheck.error) {
540
+ throw new Error(`invalid original mock tmux shell fixture: ${originalSyntaxCheck.error?.message ?? originalSyntaxCheck.stderr ?? 'sh -n failed'}`);
541
+ }
452
542
  const fixtureDefinesGlobalExactPaneSnapshot = tmuxFixture.includes('-a -F #{pane_id}');
543
+ const sourceAuthorityTmuxFixture = tmuxFixture.replace('#!/bin/sh\n', `#!/bin/sh
544
+ # Every current-dev start fixture must provide the complete source-pane incarnation
545
+ # captured by createTeamSession. Keep this narrow so command-specific fixture
546
+ # behavior remains authoritative.
547
+ log_command() {
548
+ printf '%s\n' "$*" >> "${tmuxLogPath}"
549
+ }
550
+ canonical_pane_pid() {
551
+ if [ -f "$0.actual-pid-$1" ]; then cat "$0.actual-pid-$1"; else printf '%s' "$((2000000000 + $1 * 1111))"; fi
552
+ }
553
+ actual_pane_pid() {
554
+ pane_number="$1"
555
+ if [ -f "$0.actual-pid-$pane_number" ]; then
556
+ IFS= read -r pane_pid < "$0.actual-pid-$pane_number" || true
557
+ case "$pane_pid" in *[!0-9]*|'') ;; *) printf '%s' "$pane_pid"; return ;; esac
558
+ fi
559
+ canonical_pane_pid "$pane_number"
560
+ }
561
+ owner_target() {
562
+ previous=''
563
+ for argument in "$@"; do
564
+ if [ "$previous" = '-t' ]; then
565
+ printf '%s' "$argument"
566
+ return
567
+ fi
568
+ previous="$argument"
569
+ done
570
+ }
571
+ # Capture the exact session/window/pane incarnation the production code binds
572
+ # every source-authorized operation to. The generic fixture owns only this
573
+ # canonical query; test scripts retain their command-specific topology.
574
+ if [ "\${1:-}" = "display-message" ] && [ "\${2:-}" = "-p" ] && [ "\${3:-}" = "-t" ] \
575
+ && [ "\${5:-}" = "#{session_name}\t#{session_id}\t#{session_created}\t#{window_index}\t#{window_id}\t#{pane_id}\t#{pane_pid}" ]; then
576
+ case "\${4:-}" in
577
+ %*)
578
+ pane_number="\${4#%}"
579
+ case "$pane_number" in *[!0-9]*|'') exit 1 ;; esac
580
+ if [ ! -f "$0.actual-pid-$pane_number" ]; then
581
+ observed_pid="$("$0" list-panes -a -F '#{pane_id}\\t#{pane_dead}\\t#{pane_pid}' 2>/dev/null | awk -F '\\t' -v pane="\${4}" '$1 == pane && $2 == "0" && $3 ~ /^[1-9][0-9]*$/ { print $3; exit }')"
582
+ [ -z "$observed_pid" ] || printf '%s' "$observed_pid" > "$0.actual-pid-$pane_number"
583
+ fi
584
+ pane_pid="$(actual_pane_pid "$pane_number")"
585
+ : > "$0.source-proof-$pane_number"
586
+ log_command "$@"
587
+ printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\n' 'leader' '$1' '1700000000' '0' '@1' "\${4}" "$pane_pid"
588
+ exit 0
589
+ ;;
590
+ esac
591
+ fi
592
+ # Match the immediately following exact-pane liveness proof to the seven-field
593
+ # capture above, without changing later command-specific global snapshots.
594
+ if [ "\${1:-}" = "list-panes" ] && [ "\${2:-}" = "-a" ] && [ "\${3:-}" = "-F" ] && [ "\${4:-}" = "#{pane_id}\t#{pane_dead}\t#{pane_pid}" ]; then
595
+ for source_proof in "$0".source-proof-*; do
596
+ [ -e "$source_proof" ] || continue
597
+ pane_number="\${source_proof##*-}"
598
+ case "$pane_number" in *[!0-9]*|'') continue ;; esac
599
+ log_command "$@"
600
+ printf '%%%s\t0\t%s\n' "$pane_number" "$(actual_pane_pid "$pane_number")"
601
+ rm -f "$source_proof"
602
+ exit 0
603
+ done
604
+ fi
605
+ # A source-authorized tmux operation is one server-side transaction. Emulate
606
+ # the guarded branch rather than letting fixture scripts accidentally treat
607
+ # if-shell as an unconditional success. Tests that model a failed/drifted
608
+ # transaction continue to do so by making their source query/proof invalid.
609
+ if [ "\${1:-}" = "if-shell" ] && [ "\${2:-}" = "-F" ] && [ "\${3:-}" = "-t" ]; then
610
+ source_pane="\${4:-}"
611
+ predicate="\${5:-}"
612
+ effect="\${6:-}"
613
+ pane_number="\${source_pane#%}"
614
+ case "$pane_number" in *[!0-9]*|'') log_command "$@"; exit 0 ;; esac
615
+ quote="'"
616
+ double_quote='"'
617
+ pane_pid="$(actual_pane_pid "$pane_number")"
618
+ case "$predicate" in
619
+ *"#{==:#{pane_id},$source_pane}"*"#{==:#{pane_pid},$pane_pid}"*'#{==:#{session_id},$1}'*'#{==:#{session_created},1700000000}'*'#{==:#{window_id},@1}'*) ;;
620
+ *) source_pane='' ;;
621
+ esac
622
+ if [ -n "$source_pane" ]; then
623
+ log_command "$@"
624
+ if [ "\${effect#*split-window}" != "$effect" ]; then
625
+ receipt="$(printf '%s' "$effect" | sed -n 's/.*\\(omx_source_[A-Za-z0-9_]*\\).*/\\1/p')"
626
+ effect_command="\${effect%% ; display-message*}"
627
+ eval "set -- $effect_command"
628
+ split_output="$("$0" "$@")" || exit 1
629
+ created_pane="$(printf '%s\\n' "$split_output" | awk -F '\\t' 'NR == 1 { print $1 }')"
630
+ case "$created_pane" in %*) ;; *) exit 1 ;; esac
631
+ pane_number="\${created_pane#%}"
632
+ created_pid="$("$0" list-panes -a -F '#{pane_id}\\t#{pane_dead}\\t#{pane_pid}' 2>/dev/null | awk -F '\\t' -v pane="$created_pane" '$1 == pane && $2 == "0" && $3 ~ /^[1-9][0-9]*$/ { print $3; exit }')"
633
+ [ -z "$created_pid" ] || printf '%s' "$created_pid" > "$0.actual-pid-$pane_number"
634
+ printf '%s\\t%s\\n' "$created_pane" "$receipt"
635
+ exit 0
636
+ fi
637
+ # Owner markers are part of the authority contract and must survive the
638
+ # guarded tagging transaction for subsequent source/final-sink proofs.
639
+ case "$effect" in
640
+ *'@omx_team_pane_owner_id '*)
641
+ tag_target="\${effect#* -t }"
642
+ tag_target="\${tag_target%% *}"
643
+ owner_value="\${effect##*@omx_team_pane_owner_id }"
644
+ owner_value="\${owner_value%% *}"
645
+ owner_value="\${owner_value#"$double_quote"}"
646
+ owner_value="\${owner_value%"$double_quote"}"
647
+ owner_value="\${owner_value#"$quote"}"
648
+ owner_value="\${owner_value%"$quote"}"
649
+ printf '%s' "$owner_value" > "$0.owner-\${tag_target#%}"
650
+ ;;
651
+ esac
652
+ receipt="\${effect##*display-message -p }"
653
+ receipt="\${receipt#"$quote"}"
654
+ receipt="\${receipt%"$quote"}"
655
+ printf '%s\n' "$receipt"
656
+ exit 0
657
+ fi
658
+ fi
659
+ # Keep owner-tag reads and writes coherent even in compact fixtures that do not
660
+ # spell out the tmux option commands themselves.
661
+ if [ "\${1:-}" = "set-option" ]; then
662
+ owner_key=''
663
+ for argument in "$@"; do [ "$argument" = '@omx_team_pane_owner_id' ] && owner_key=1; done
664
+ if [ -n "$owner_key" ]; then
665
+ target="$(owner_target "$@")"
666
+ owner_value=''
667
+ previous=''
668
+ for argument in "$@"; do
669
+ if [ "$previous" = '@omx_team_pane_owner_id' ]; then owner_value="$argument"; break; fi
670
+ previous="$argument"
671
+ done
672
+ if [ -n "$target" ] && [ -n "$owner_value" ]; then
673
+ log_command "$@"
674
+ printf '%s' "$owner_value" > "$0.owner-\${target#%}"
675
+ exit 0
676
+ fi
677
+ fi
678
+ fi
679
+ if [ "\${1:-}" = "show-option" ] || [ "\${1:-}" = "show-options" ]; then
680
+ owner_key=''
681
+ for argument in "$@"; do [ "$argument" = '@omx_team_pane_owner_id' ] && owner_key=1; done
682
+ if [ -n "$owner_key" ]; then
683
+ target="$(owner_target "$@")"
684
+ if [ -f "$0.owner-\${target#%}" ]; then
685
+ log_command "$@"
686
+ cat "$0.owner-\${target#%}"
687
+ exit 0
688
+ fi
689
+ fi
690
+ fi
691
+ `);
453
692
  const compatibleTmuxFixture = fixtureDefinesGlobalExactPaneSnapshot
454
- ? tmuxFixture
455
- : tmuxFixture.replace('#!/bin/sh\n', `#!/bin/sh
693
+ ? sourceAuthorityTmuxFixture
694
+ : sourceAuthorityTmuxFixture.replace('#!/bin/sh\n', `#!/bin/sh
456
695
  # Legacy fixtures without a global snapshot get deterministic, valid live panes.
457
696
  if [ "\${1:-}" = "list-panes" ] && [ "\${2:-}" = "-a" ] && [ "\${3:-}" = "-F" ] && [ "\${4:-}" = "#{pane_id}\t#{pane_dead}\t#{pane_pid}" ]; then
458
697
  printf '%s\n' "$*" >> "${tmuxLogPath}"
@@ -465,6 +704,10 @@ if [ "\${1:-}" = "list-panes" ] && [ "\${2:-}" = "-a" ] && [ "\${3:-}" = "-F" ]
465
704
  fi
466
705
  `);
467
706
  await writeFile(tmuxStubPath, compatibleTmuxFixture);
707
+ const wrapperSyntaxCheck = spawnSync('sh', ['-n', tmuxStubPath], { encoding: 'utf-8' });
708
+ if (wrapperSyntaxCheck.status !== 0 || wrapperSyntaxCheck.error) {
709
+ throw new Error(`invalid generated mock tmux shell wrapper: ${wrapperSyntaxCheck.error?.message ?? wrapperSyntaxCheck.stderr ?? 'sh -n failed'}`);
710
+ }
468
711
  await chmod(tmuxStubPath, 0o755);
469
712
  for (const binary of options.binaries ?? []) {
470
713
  const binaryPath = join(fakeBinDir, binary.name);
@@ -535,6 +778,7 @@ beforeEach(() => {
535
778
  delete process.env.OMX_TEAM_STATE_ROOT;
536
779
  });
537
780
  afterEach(() => {
781
+ setTerminalEpochStartedHookForTest(null);
538
782
  if (typeof ORIGINAL_OMX_TEAM_STATE_ROOT === 'string')
539
783
  process.env.OMX_TEAM_STATE_ROOT = ORIGINAL_OMX_TEAM_STATE_ROOT;
540
784
  else
@@ -1281,7 +1525,9 @@ require('fs').writeFileSync(process.env.OMX_NON_CODEX_CAPTURE, process.argv.slic
1281
1525
  const prevStartupDispatchRetries = process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES;
1282
1526
  const prevStartupDispatchRetryDelay = process.env.OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS;
1283
1527
  let receiptNotifier = null;
1528
+ let receiptNotifierPending = null;
1284
1529
  let progressWriter = null;
1530
+ let progressWriterPending = null;
1285
1531
  try {
1286
1532
  await withMockTmuxFixture({
1287
1533
  dirPrefix: 'omx-runtime-startup-window-bin-',
@@ -1384,17 +1630,17 @@ esac
1384
1630
  process.env.OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS = '50';
1385
1631
  const expectedTeamName = buildInternalTeamName('team-startup-window', resolveTeamIdentityScope(process.env));
1386
1632
  receiptNotifier = setInterval(() => {
1387
- void markPendingInboxDispatchesNotified(expectedTeamName, cwd, {
1633
+ receiptNotifierPending ??= markPendingInboxDispatchesNotified(expectedTeamName, cwd, {
1388
1634
  toWorker: 'worker-1',
1389
1635
  lastReason: 'test_notified_receipt',
1390
- }).catch(() => { });
1636
+ }).catch(() => { }).finally(() => { receiptNotifierPending = null; });
1391
1637
  }, 20);
1392
1638
  progressWriter = setTimeout(() => {
1393
- void writeWorkerStatus(expectedTeamName, 'worker-1', {
1639
+ progressWriterPending = writeWorkerStatus(expectedTeamName, 'worker-1', {
1394
1640
  state: 'working',
1395
1641
  current_task_id: '1',
1396
1642
  updated_at: new Date().toISOString(),
1397
- }, cwd).catch(() => { });
1643
+ }, cwd).catch(() => { }).finally(() => { progressWriterPending = null; });
1398
1644
  }, 6_000);
1399
1645
  const runtime = await withoutTeamWorkerEnv(() => startTeam('team-startup-window', 'interactive startup should wait for slow Codex evidence', 'executor', 1, [{ subject: 's', description: 'd', owner: 'worker-1' }], cwd));
1400
1646
  assert.equal(runtime.teamName, expectedTeamName);
@@ -1402,10 +1648,10 @@ esac
1402
1648
  });
1403
1649
  }
1404
1650
  finally {
1405
- if (receiptNotifier)
1406
- clearInterval(receiptNotifier);
1651
+ await settleReceiptInterval(receiptNotifier, receiptNotifierPending);
1407
1652
  if (progressWriter)
1408
1653
  clearTimeout(progressWriter);
1654
+ await progressWriterPending;
1409
1655
  if (typeof prevTmux === 'string')
1410
1656
  process.env.TMUX = prevTmux;
1411
1657
  else
@@ -1458,6 +1704,7 @@ esac
1458
1704
  const prevStartupDispatchRetries = process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES;
1459
1705
  const prevStartupDispatchRetryDelay = process.env.OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS;
1460
1706
  let receiptFailer = null;
1707
+ let receiptFailerPending = null;
1461
1708
  try {
1462
1709
  await withMockTmuxFixture({
1463
1710
  dirPrefix: 'omx-runtime-startup-no-evidence-bin-',
@@ -1560,28 +1807,26 @@ esac
1560
1807
  process.env.OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS = '50';
1561
1808
  const expectedTeamName = buildInternalTeamName('team-startup-no-evidence', resolveTeamIdentityScope(process.env));
1562
1809
  receiptFailer = setInterval(() => {
1563
- void (async () => {
1810
+ receiptFailerPending ??= (async () => {
1564
1811
  const requests = await listDispatchRequests(expectedTeamName, cwd, { kind: 'inbox' }).catch(() => []);
1565
1812
  for (const request of requests) {
1566
1813
  if (request.status !== 'pending')
1567
1814
  continue;
1568
1815
  await transitionDispatchRequest(expectedTeamName, request.request_id, 'pending', 'failed', { last_reason: 'test_failed_receipt' }, cwd).catch(() => { });
1569
1816
  }
1570
- })();
1817
+ })().catch(() => { }).finally(() => { receiptFailerPending = null; });
1571
1818
  }, 20);
1572
1819
  await assert.rejects(withoutTeamWorkerEnv(() => startTeam('team-startup-no-evidence', 'interactive startup rejects missing worker evidence without false task evidence', 'executor', 1, [{ subject: 's', description: 'd', owner: 'worker-1' }], cwd)), /(worker_notify_failed:worker-1:codex_startup_no_evidence_after_fallback|startup_rollback_pane_proof_unavailable:%2:pane_proof_lost_during_process_teardown)/);
1573
- if (receiptFailer) {
1574
- clearInterval(receiptFailer);
1575
- receiptFailer = null;
1576
- }
1820
+ await settleReceiptInterval(receiptFailer, receiptFailerPending);
1821
+ receiptFailer = null;
1822
+ receiptFailerPending = null;
1577
1823
  const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1578
1824
  assert.match(tmuxLog, /send-keys -t %2 -l --/);
1579
1825
  await shutdownTeam(expectedTeamName, cwd, { force: true }).catch(() => { });
1580
1826
  });
1581
1827
  }
1582
1828
  finally {
1583
- if (receiptFailer)
1584
- clearInterval(receiptFailer);
1829
+ await settleReceiptInterval(receiptFailer, receiptFailerPending);
1585
1830
  if (typeof prevTmux === 'string')
1586
1831
  process.env.TMUX = prevTmux;
1587
1832
  else
@@ -1961,9 +2206,9 @@ esac
1961
2206
  const manifest = JSON.parse(await readFile(join(cwd, '.omx', 'state', 'team', runtime.teamName, 'manifest.v2.json'), 'utf-8'));
1962
2207
  assert.equal(manifest.leader?.session_id, '%1');
1963
2208
  const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1964
- assert.match(tmuxLog, /set-option -p -t %1 @omx_pane_instance_id %1/);
1965
- assert.match(tmuxLog, /set-option -p -t %2 @omx_pane_instance_id %1/);
1966
- assert.match(tmuxLog, /set-option -p -t %3 @omx_pane_instance_id %1/);
2209
+ assert.match(tmuxLog, /set-option -p -t %1 @omx_pane_instance_id '%1'/);
2210
+ assert.match(tmuxLog, /set-option -p -t %2 @omx_pane_instance_id '%1'/);
2211
+ assert.match(tmuxLog, /set-option -p -t %3 @omx_pane_instance_id '%1'/);
1967
2212
  assert.match(tmuxLog, /exec env OMX_SESSION_ID='%1' OMX_TMUX_HUD_OWNER=1 OMX_TMUX_HUD_LEADER_PANE='%1' .*hud --watch/);
1968
2213
  await shutdownTeam(runtime.teamName, cwd, { force: true }).catch(() => { });
1969
2214
  runtime = null;
@@ -2124,13 +2369,13 @@ esac
2124
2369
  const manifest = JSON.parse(await readFile(join(cwd, '.omx', 'state', 'team', runtime.teamName, 'manifest.v2.json'), 'utf-8'));
2125
2370
  assert.equal(manifest.leader?.session_id, 'logical-session-from-env');
2126
2371
  const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
2127
- assert.match(tmuxLog, /set-option -t leader @omx_instance_id logical-session-from-env/);
2128
- assert.match(tmuxLog, /set-option -p -t %1 @omx_pane_instance_id logical-session-from-env/);
2129
- assert.match(tmuxLog, /set-option -p -t %2 @omx_pane_instance_id logical-session-from-env/);
2130
- assert.match(tmuxLog, /set-option -p -t %3 @omx_pane_instance_id logical-session-from-env/);
2131
- assert.match(tmuxLog, /set-option -p -t %1 @omx_team_pane_owner_id team:pane-owner-env-isolat-[a-f0-9]{8}/);
2132
- assert.match(tmuxLog, /set-option -p -t %2 @omx_team_pane_owner_id team:pane-owner-env-isolat-[a-f0-9]{8}/);
2133
- assert.match(tmuxLog, /set-option -p -t %3 @omx_team_pane_owner_id team:pane-owner-env-isolat-[a-f0-9]{8}/);
2372
+ assert.match(tmuxLog, /set-option -t \$1 @omx_instance_id 'logical-session-from-env'/);
2373
+ assert.match(tmuxLog, /set-option -p -t %1 @omx_pane_instance_id 'logical-session-from-env'/);
2374
+ assert.match(tmuxLog, /set-option -p -t %2 @omx_pane_instance_id 'logical-session-from-env'/);
2375
+ assert.match(tmuxLog, /set-option -p -t %3 @omx_pane_instance_id 'logical-session-from-env'/);
2376
+ assert.match(tmuxLog, /set-option -p -t %1 @omx_team_pane_owner_id 'team:pane-owner-env-isolat-[a-f0-9]{8}'/);
2377
+ assert.match(tmuxLog, /set-option -p -t %2 @omx_team_pane_owner_id 'team:pane-owner-env-isolat-[a-f0-9]{8}'/);
2378
+ assert.match(tmuxLog, /set-option -p -t %3 @omx_team_pane_owner_id 'team:pane-owner-env-isolat-[a-f0-9]{8}'/);
2134
2379
  assert.doesNotMatch(tmuxLog, /set-option -p -t %1 @omx_team_pane_owner_id logical-session-from-env/);
2135
2380
  assert.match(tmuxLog, /exec env OMX_SESSION_ID='logical-session-from-env' OMX_TMUX_HUD_OWNER=1 OMX_TMUX_HUD_LEADER_PANE='%1' .*hud --watch/);
2136
2381
  await shutdownTeam(runtime.teamName, cwd, { force: true }).catch(() => { });
@@ -2394,6 +2639,10 @@ esac
2394
2639
  workerPaneIds: ['%30'],
2395
2640
  workerPaneIdsByIndex: [null, '%30'],
2396
2641
  workerPanePidsByIndex: [null, 2000000030],
2642
+ startupCleanupPanes: [
2643
+ { paneId: '%40', panePid: 2000000040 },
2644
+ { paneId: '%41', panePid: 2000000041 },
2645
+ ],
2397
2646
  leaderPanePid: 2000000001,
2398
2647
  hudPanePid: 2000000004,
2399
2648
  leaderPaneId: '%1',
@@ -2408,6 +2657,79 @@ esac
2408
2657
  assert.equal(config.workers[1]?.pid, 2000000030);
2409
2658
  assert.equal(config.leader_pane_pid, 2000000001);
2410
2659
  assert.equal(config.hud_pane_pid, 2000000004);
2660
+ assert.deepEqual(config.startup_cleanup_panes, [
2661
+ { pane_id: '%40', pid: 2000000040 },
2662
+ { pane_id: '%41', pid: 2000000041 },
2663
+ ]);
2664
+ await saveTeamConfig(config, cwd);
2665
+ const durablePartialConfig = await readTeamConfig('team-pane-persist-race', cwd);
2666
+ assert.ok(durablePartialConfig);
2667
+ assert.deepEqual(durablePartialConfig.startup_cleanup_panes, config.startup_cleanup_panes);
2668
+ }
2669
+ finally {
2670
+ await rm(cwd, { recursive: true, force: true });
2671
+ }
2672
+ });
2673
+ it('replays durable startup cleanup panes by exact PID and Team owner', async () => {
2674
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-startup-cleanup-replay-'));
2675
+ try {
2676
+ const config = await initTeamState('startup-cleanup-replay', 'replay startup pane cleanup debt', 'executor', 1, cwd);
2677
+ applyCreatedInteractiveSessionToConfig(config, {
2678
+ name: 'leader:0',
2679
+ workerCount: 1,
2680
+ cwd,
2681
+ workerPaneIds: [],
2682
+ workerPaneIdsByIndex: [null],
2683
+ workerPanePidsByIndex: [null],
2684
+ startupCleanupPanes: [
2685
+ { paneId: '%40', panePid: 2000044440 },
2686
+ { paneId: '%41', panePid: 2000045551 },
2687
+ ],
2688
+ leaderPaneId: '%1',
2689
+ leaderPanePid: 2000000001,
2690
+ hudPaneId: null,
2691
+ hudPanePid: null,
2692
+ resizeHookName: null,
2693
+ resizeHookTarget: null,
2694
+ teamPaneOwnerId: 'team:startup-cleanup-replay',
2695
+ }, [undefined]);
2696
+ await saveTeamConfig(config, cwd);
2697
+ await withMockTmuxFixture({
2698
+ dirPrefix: 'omx-runtime-startup-cleanup-replay-',
2699
+ tmuxScript: (tmuxLogPath) => `#!/bin/sh
2700
+ set -eu
2701
+ printf '%s\\n' "$*" >> "${tmuxLogPath}"
2702
+ case "\${1:-}" in
2703
+ list-panes)
2704
+ case "$*" in
2705
+ *'-a -F #{pane_id}'*)
2706
+ [ -f "${tmuxLogPath}.killed-40" ] || printf '%%40\\t0\\t2000044440\\n'
2707
+ [ -f "${tmuxLogPath}.killed-41" ] || printf '%%41\\t0\\t2000045551\\n'
2708
+ ;;
2709
+ esac
2710
+ ;;
2711
+ show-option) printf 'team:startup-cleanup-replay\\n' ;;
2712
+ kill-pane)
2713
+ case "$*" in
2714
+ *"%40"*) : > "${tmuxLogPath}.killed-40" ;;
2715
+ *"%41"*) : > "${tmuxLogPath}.killed-41" ;;
2716
+ esac
2717
+ ;;
2718
+ *) ;;
2719
+ esac
2720
+ `,
2721
+ }, async ({ tmuxLogPath }) => {
2722
+ const durable = await readTeamConfig('startup-cleanup-replay', cwd);
2723
+ assert.ok(durable);
2724
+ const reconciled = await reconcileStartupCleanupPanes(durable, cwd);
2725
+ assert.equal(reconciled.startup_cleanup_panes, undefined);
2726
+ const persisted = await readTeamConfig('startup-cleanup-replay', cwd);
2727
+ assert.ok(persisted);
2728
+ assert.equal(persisted.startup_cleanup_panes, undefined);
2729
+ const log = await readFile(tmuxLogPath, 'utf-8');
2730
+ assert.match(log, /kill-pane -t %40/);
2731
+ assert.match(log, /kill-pane -t %41/);
2732
+ });
2411
2733
  }
2412
2734
  finally {
2413
2735
  await rm(cwd, { recursive: true, force: true });
@@ -2921,6 +3243,128 @@ esac
2921
3243
  await rm(cwd, { recursive: true, force: true });
2922
3244
  }
2923
3245
  });
3246
+ it('terminates attached Codex startup on the first exact MDM bypass marker without dispatch or retry', async () => {
3247
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-codex-mdm-direct-'));
3248
+ const teamName = `codex-mdm-${process.pid}-${Date.now().toString(36)}`;
3249
+ const argvCapturePath = join(cwd, 'codex-argv.json');
3250
+ const marker = 'MDM_POLICY_REJECTED: approval_policy=never forbids --dangerously-bypass-approvals-and-sandbox';
3251
+ const previousTmux = process.env.TMUX;
3252
+ const previousPane = process.env.TMUX_PANE;
3253
+ try {
3254
+ await withMockTmuxFixture({
3255
+ dirPrefix: 'omx-runtime-codex-mdm-direct-bin-',
3256
+ tmuxScript: codexMdmTmuxScript(marker),
3257
+ binaries: [{
3258
+ name: 'codex',
3259
+ content: fakeCodexNodeScript(`require('fs').writeFileSync(process.env.OMX_CODEX_ARGV_CAPTURE, JSON.stringify(process.argv.slice(2)));
3260
+ process.stdin.resume();`),
3261
+ }],
3262
+ env: {
3263
+ OMX_TEAM_WORKER_LAUNCH_MODE: 'interactive',
3264
+ OMX_TEAM_WORKER_CLI: 'codex',
3265
+ OMX_TEAM_WORKER_LAUNCH_ARGS: '--dangerously-bypass-approvals-and-sandbox --model gpt-5.6-test',
3266
+ OMX_CODEX_ARGV_CAPTURE: argvCapturePath,
3267
+ OMX_TEAM_READY_TIMEOUT_MS: '50',
3268
+ OMX_TEAM_STARTUP_EVIDENCE_TIMEOUT_MS: '50',
3269
+ OMX_TEAM_STARTUP_DISPATCH_RETRIES: '2',
3270
+ OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS: '1',
3271
+ },
3272
+ }, async ({ tmuxLogPath }) => {
3273
+ delete process.env.TMUX;
3274
+ process.env.TMUX_PANE = '%1';
3275
+ await assert.rejects(() => withoutTeamWorkerEnv(() => startTeam(teamName, 'reject an attached Codex bypass rejected by MDM', 'executor', 1, [{ subject: 'w1', description: 'worker one', owner: 'worker-1' }], cwd)), /(worker_startup_incompatible:worker-1:codex_bypass_mdm_incompatible|startup_rollback_pane_proof_unavailable:%2:pane_proof_lost_during_process_teardown)/);
3276
+ const finalArgv = JSON.parse(await waitForFileText(argvCapturePath, (content) => content.length > 0));
3277
+ assert.deepEqual(finalArgv.slice(0, 5), [
3278
+ '-c', 'model_reasoning_effort="medium"',
3279
+ '--model', 'gpt-5.6-test',
3280
+ '--dangerously-bypass-approvals-and-sandbox',
3281
+ ]);
3282
+ assert.ok(finalArgv.some((arg) => arg.startsWith('model_instructions_file=')));
3283
+ assert.equal(finalArgv.filter((arg) => arg === '--dangerously-bypass-approvals-and-sandbox').length, 1);
3284
+ const tmuxEvents = (await readFile(tmuxLogPath, 'utf-8')).trim().split('\n').filter(Boolean);
3285
+ const captureEvents = tmuxEvents.filter((event) => event.startsWith('capture-pane '));
3286
+ assert.equal(captureEvents.length, 1, 'marker must not enter a second readiness cycle');
3287
+ assert.equal(tmuxEvents.some((event) => event.startsWith('send-keys ') && event.includes(' -l -- ')), false, `marker must stop before any literal dispatch: ${tmuxEvents.join(',')}`);
3288
+ const retainedTeams = await readdir(teamStateTestPath(cwd, 'team'));
3289
+ assert.equal(retainedTeams.length, 1, 'proof-loss rollback must retain one inspectable team root');
3290
+ const retainedTeamName = retainedTeams[0];
3291
+ const retainedTask = await readTask(retainedTeamName, '1', cwd);
3292
+ assert.equal(retainedTask?.status, 'pending');
3293
+ assert.equal(retainedTask?.owner, 'worker-1');
3294
+ assert.equal(retainedTask?.claim, undefined);
3295
+ const retainedWorker = await readWorkerStatus(retainedTeamName, 'worker-1', cwd);
3296
+ assert.equal(retainedWorker.reason, 'codex_bypass_mdm_incompatible');
3297
+ assert.equal(retainedWorker.current_task_id, undefined);
3298
+ });
3299
+ }
3300
+ finally {
3301
+ if (typeof previousTmux === 'string')
3302
+ process.env.TMUX = previousTmux;
3303
+ else
3304
+ delete process.env.TMUX;
3305
+ if (typeof previousPane === 'string')
3306
+ process.env.TMUX_PANE = previousPane;
3307
+ else
3308
+ delete process.env.TMUX_PANE;
3309
+ await rm(cwd, { recursive: true, force: true });
3310
+ }
3311
+ });
3312
+ it('terminates on an MDM marker first observed during detailed readiness before fallback dispatch', async () => {
3313
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-codex-mdm-detailed-'));
3314
+ const teamName = `codex-mdm-detailed-${process.pid}-${Date.now().toString(36)}`;
3315
+ const marker = 'MDM_POLICY_REJECTED: approval_policy=never forbids --dangerously-bypass-approvals-and-sandbox';
3316
+ const previousTmux = process.env.TMUX;
3317
+ const previousPane = process.env.TMUX_PANE;
3318
+ try {
3319
+ await withMockTmuxFixture({
3320
+ dirPrefix: 'omx-runtime-codex-mdm-detailed-bin-',
3321
+ tmuxScript: codexMdmTmuxScript(marker),
3322
+ binaries: [{ name: 'codex', content: fakeCodexNodeScript('process.stdin.resume();') }],
3323
+ env: {
3324
+ OMX_TEAM_WORKER_LAUNCH_MODE: 'interactive',
3325
+ OMX_TEAM_WORKER_CLI: 'codex',
3326
+ OMX_TEAM_WORKER_LAUNCH_ARGS: '--dangerously-bypass-approvals-and-sandbox --model gpt-5.6-test',
3327
+ OMX_MDM_CAPTURE_MODE: 'detailed',
3328
+ OMX_TEAM_READY_TIMEOUT_MS: '50',
3329
+ OMX_TEAM_STARTUP_EVIDENCE_TIMEOUT_MS: '50',
3330
+ OMX_TEAM_STARTUP_DISPATCH_RETRIES: '2',
3331
+ OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS: '1',
3332
+ },
3333
+ }, async ({ tmuxLogPath }) => {
3334
+ delete process.env.TMUX;
3335
+ process.env.TMUX_PANE = '%1';
3336
+ await assert.rejects(() => withoutTeamWorkerEnv(() => startTeam(teamName, 'reject a detailed-readiness Codex MDM bypass marker', 'executor', 1, [{ subject: 'w1', description: 'worker one', owner: 'worker-1' }], cwd)), /(worker_startup_incompatible:worker-1:codex_bypass_mdm_incompatible|startup_rollback_pane_proof_unavailable:%2:pane_proof_lost_during_process_teardown)/);
3337
+ const tmuxEvents = (await readFile(tmuxLogPath, 'utf-8')).trim().split('\n').filter(Boolean);
3338
+ const captureIndexes = tmuxEvents
3339
+ .map((event, index) => event.startsWith('capture-pane ') ? index : -1)
3340
+ .filter((index) => index >= 0);
3341
+ assert.ok(captureIndexes.length >= 5, `expected startup-direct delivery captures followed by detailed readiness marker: ${tmuxEvents.join(',')}`);
3342
+ const markerCaptureIndex = captureIndexes[4];
3343
+ assert.equal(tmuxEvents.slice(markerCaptureIndex + 1).some((event) => event.startsWith('send-keys ') && event.includes(' -l -- ')), false, `marker must stop before fallback dispatch/retry: ${tmuxEvents.join(',')}`);
3344
+ const retainedTeams = await readdir(teamStateTestPath(cwd, 'team'));
3345
+ assert.equal(retainedTeams.length, 1, 'proof-loss rollback must retain one inspectable team root');
3346
+ const retainedTeamName = retainedTeams[0];
3347
+ const retainedTask = await readTask(retainedTeamName, '1', cwd);
3348
+ assert.equal(retainedTask?.status, 'pending');
3349
+ assert.equal(retainedTask?.owner, 'worker-1');
3350
+ assert.equal(retainedTask?.claim, undefined);
3351
+ const retainedWorker = await readWorkerStatus(retainedTeamName, 'worker-1', cwd);
3352
+ assert.equal(retainedWorker.reason, 'codex_bypass_mdm_incompatible');
3353
+ assert.equal(retainedWorker.current_task_id, undefined);
3354
+ });
3355
+ }
3356
+ finally {
3357
+ if (typeof previousTmux === 'string')
3358
+ process.env.TMUX = previousTmux;
3359
+ else
3360
+ delete process.env.TMUX;
3361
+ if (typeof previousPane === 'string')
3362
+ process.env.TMUX_PANE = previousPane;
3363
+ else
3364
+ delete process.env.TMUX_PANE;
3365
+ await rm(cwd, { recursive: true, force: true });
3366
+ }
3367
+ });
2924
3368
  it('startTeam treats a confirmed ready prompt as startup evidence after hook notification', async () => {
2925
3369
  const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-ready-prompt-evidence-'));
2926
3370
  const previousTmux = process.env.TMUX;
@@ -2931,6 +3375,7 @@ esac
2931
3375
  const previousStartupEvidenceTimeout = process.env.OMX_TEAM_STARTUP_EVIDENCE_TIMEOUT_MS;
2932
3376
  const previousStartupDispatchRetries = process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES;
2933
3377
  let receiptNotifier = null;
3378
+ let receiptNotifierPending = null;
2934
3379
  let runtimeTeamName = null;
2935
3380
  try {
2936
3381
  await withMockTmuxFixture({
@@ -3005,7 +3450,7 @@ esac
3005
3450
  process.env.OMX_TEAM_STARTUP_EVIDENCE_TIMEOUT_MS = '100';
3006
3451
  process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES = '1';
3007
3452
  receiptNotifier = setInterval(() => {
3008
- void markPendingInboxDispatchesNotified('team-ready-prompt-evidence', cwd);
3453
+ receiptNotifierPending ??= markPendingInboxDispatchesNotified('team-ready-prompt-evidence', cwd).catch(() => { }).finally(() => { receiptNotifierPending = null; });
3009
3454
  }, 20);
3010
3455
  const runtime = await withoutTeamWorkerEnv(() => startTeam('team-ready-prompt-evidence', 'interactive ready prompt should settle startup evidence after notification', 'executor', 1, [{ subject: 'w1', description: 'worker one', owner: 'worker-1' }], cwd));
3011
3456
  runtimeTeamName = runtime.teamName;
@@ -3026,8 +3471,7 @@ esac
3026
3471
  });
3027
3472
  }
3028
3473
  finally {
3029
- if (receiptNotifier)
3030
- clearInterval(receiptNotifier);
3474
+ await settleReceiptInterval(receiptNotifier, receiptNotifierPending);
3031
3475
  if (runtimeTeamName)
3032
3476
  await shutdownTeam(runtimeTeamName, cwd, { force: true }).catch(() => { });
3033
3477
  if (typeof previousTmux === 'string')
@@ -3077,6 +3521,7 @@ esac
3077
3521
  const previousStartupDispatchRetryDelay = process.env.OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS;
3078
3522
  const teamName = `trt-${process.pid}-${Date.now().toString(36)}`;
3079
3523
  let receiptNotifier = null;
3524
+ let receiptNotifierPending = null;
3080
3525
  let runtimeTeamName = null;
3081
3526
  try {
3082
3527
  await withMockTmuxFixture({
@@ -3143,7 +3588,7 @@ esac
3143
3588
  process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES = '1';
3144
3589
  process.env.OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS = '50';
3145
3590
  receiptNotifier = setInterval(() => {
3146
- void markPendingInboxDispatchesNotified(teamName, cwd);
3591
+ receiptNotifierPending ??= markPendingInboxDispatchesNotified(teamName, cwd).catch(() => { }).finally(() => { receiptNotifierPending = null; });
3147
3592
  }, 20);
3148
3593
  await assert.rejects(withoutTeamWorkerEnv(() => startTeam(teamName, 'ready prompt timeout should not count a draft-only worker as started', 'executor', 1, [{ subject: 'w1', description: 'worker one', owner: 'worker-1' }], cwd)), /(worker_notify_failed:worker-1:codex_startup_no_evidence_after_fallback|startup_rollback_pane_proof_unavailable:%2:pane_proof_lost_during_process_teardown)/);
3149
3594
  const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
@@ -3152,8 +3597,7 @@ esac
3152
3597
  });
3153
3598
  }
3154
3599
  finally {
3155
- if (receiptNotifier)
3156
- clearInterval(receiptNotifier);
3600
+ await settleReceiptInterval(receiptNotifier, receiptNotifierPending);
3157
3601
  if (runtimeTeamName)
3158
3602
  await shutdownTeam(runtimeTeamName, cwd, { force: true }).catch(() => { });
3159
3603
  if (typeof previousTmux === 'string')
@@ -3202,6 +3646,7 @@ esac
3202
3646
  const previousStartupDispatchRetries = process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES;
3203
3647
  const previousStartupDispatchRetryDelay = process.env.OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS;
3204
3648
  let receiptDeliverer = null;
3649
+ let receiptDelivererPending = null;
3205
3650
  let runtimeTeamName = null;
3206
3651
  try {
3207
3652
  await withMockTmuxFixture({
@@ -3295,9 +3740,9 @@ esac
3295
3740
  process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES = '1';
3296
3741
  process.env.OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS = '50';
3297
3742
  receiptDeliverer = setInterval(() => {
3298
- void (async () => {
3743
+ receiptDelivererPending ??= (async () => {
3299
3744
  await markPendingInboxDispatchesDelivered('team-parallel-ready', cwd);
3300
- })();
3745
+ })().catch(() => { }).finally(() => { receiptDelivererPending = null; });
3301
3746
  }, 20);
3302
3747
  const runtime = await withoutTeamWorkerEnv(() => startTeam('team-parallel-ready', 'worker-2 readiness should not wait for worker-1 readiness settle', 'executor', 2, [
3303
3748
  { subject: 'w1', description: 'worker one', owner: 'worker-1' },
@@ -3312,8 +3757,7 @@ esac
3312
3757
  });
3313
3758
  }
3314
3759
  finally {
3315
- if (receiptDeliverer)
3316
- clearInterval(receiptDeliverer);
3760
+ await settleReceiptInterval(receiptDeliverer, receiptDelivererPending);
3317
3761
  if (runtimeTeamName)
3318
3762
  await shutdownTeam(runtimeTeamName, cwd, { force: true }).catch(() => { });
3319
3763
  if (typeof previousTmux === 'string')
@@ -3362,6 +3806,7 @@ esac
3362
3806
  const previousStartupDispatchRetries = process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES;
3363
3807
  const previousStartupDispatchRetryDelay = process.env.OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS;
3364
3808
  let receiptFailer = null;
3809
+ let receiptFailerPending = null;
3365
3810
  let runtime = null;
3366
3811
  const teamName = 'team-no-startup-evidence';
3367
3812
  let observedNoEvidenceRequest = false;
@@ -3459,7 +3904,7 @@ process.on('SIGTERM', () => process.exit(0));
3459
3904
  process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES = '1';
3460
3905
  process.env.OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS = '50';
3461
3906
  receiptFailer = setInterval(() => {
3462
- void (async () => {
3907
+ receiptFailerPending ??= (async () => {
3463
3908
  const runtimeTeamName = await resolveRuntimeTeamName(cwd, teamName);
3464
3909
  const requests = await listDispatchRequests(runtimeTeamName, cwd, { kind: 'inbox' }).catch(() => []);
3465
3910
  for (const request of requests) {
@@ -3468,7 +3913,7 @@ process.on('SIGTERM', () => process.exit(0));
3468
3913
  continue;
3469
3914
  await transitionDispatchRequest(teamName, request.request_id, 'pending', 'failed', { last_reason: 'test_failed_receipt' }, cwd).catch(() => { });
3470
3915
  }
3471
- })();
3916
+ })().catch(() => { }).finally(() => { receiptFailerPending = null; });
3472
3917
  }, 20);
3473
3918
  await assert.rejects(withoutTeamWorkerEnv(() => startTeam(teamName, 'interactive startup should reject no-evidence startup even while panes stay alive', 'executor', 2, [
3474
3919
  { subject: 'worker-1 task', description: 'd', owner: 'worker-1' },
@@ -3478,8 +3923,7 @@ process.on('SIGTERM', () => process.exit(0));
3478
3923
  });
3479
3924
  }
3480
3925
  finally {
3481
- if (receiptFailer)
3482
- clearInterval(receiptFailer);
3926
+ await settleReceiptInterval(receiptFailer, receiptFailerPending);
3483
3927
  if (runtime) {
3484
3928
  await shutdownTeam(teamName, cwd, { force: true }).catch(() => { });
3485
3929
  }
@@ -3535,6 +3979,7 @@ process.on('SIGTERM', () => process.exit(0));
3535
3979
  const previousStartupDispatchRetries = process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES;
3536
3980
  const previousStartupDispatchRetryDelay = process.env.OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS;
3537
3981
  let receiptFailer = null;
3982
+ let receiptFailerPending = null;
3538
3983
  try {
3539
3984
  await withMockTmuxFixture({
3540
3985
  dirPrefix: 'omx-runtime-parallel-dead-pane-bin-',
@@ -3628,14 +4073,14 @@ esac
3628
4073
  process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES = '1';
3629
4074
  process.env.OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS = '50';
3630
4075
  receiptFailer = setInterval(() => {
3631
- void (async () => {
4076
+ receiptFailerPending ??= (async () => {
3632
4077
  const requests = await listDispatchRequests('team-parallel-dead-pane', cwd, { kind: 'inbox' }).catch(() => []);
3633
4078
  for (const request of requests) {
3634
4079
  if (request.status !== 'pending')
3635
4080
  continue;
3636
4081
  await transitionDispatchRequest('team-parallel-dead-pane', request.request_id, 'pending', 'failed', { last_reason: 'test_failed_receipt' }, cwd).catch(() => { });
3637
4082
  }
3638
- })();
4083
+ })().catch(() => { }).finally(() => { receiptFailerPending = null; });
3639
4084
  }, 20);
3640
4085
  await assert.rejects(() => withoutTeamWorkerEnv(() => startTeam('team-parallel-dead-pane', 'worker-2 should be attempted despite worker-1 fatal readiness failure', 'executor', 2, [
3641
4086
  { subject: 'w1', description: 'worker one', owner: 'worker-1' },
@@ -3647,8 +4092,7 @@ esac
3647
4092
  });
3648
4093
  }
3649
4094
  finally {
3650
- if (receiptFailer)
3651
- clearInterval(receiptFailer);
4095
+ await settleReceiptInterval(receiptFailer, receiptFailerPending);
3652
4096
  if (typeof previousTmux === 'string')
3653
4097
  process.env.TMUX = previousTmux;
3654
4098
  else
@@ -3863,6 +4307,101 @@ esac
3863
4307
  await rm(cwd, { recursive: true, force: true });
3864
4308
  }
3865
4309
  });
4310
+ it('startTeam preserves the proof-unavailable contract for an ambiguous worker split whose reconciled pane proof is unavailable', async () => {
4311
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-ambiguous-split-proof-'));
4312
+ const previousTmux = process.env.TMUX;
4313
+ const previousTmuxPane = process.env.TMUX_PANE;
4314
+ const previousLaunchMode = process.env.OMX_TEAM_WORKER_LAUNCH_MODE;
4315
+ const previousWorkerCli = process.env.OMX_TEAM_WORKER_CLI;
4316
+ try {
4317
+ await withMockTmuxFixture({
4318
+ dirPrefix: 'omx-runtime-ambiguous-split-proof-bin-',
4319
+ tmuxScript: () => `#!/bin/sh
4320
+ set -eu
4321
+ ${tmuxOwnerProofShim}
4322
+ case "$1" in
4323
+ -V)
4324
+ echo "tmux 3.4"
4325
+ exit 0
4326
+ ;;
4327
+ display-message)
4328
+ case "$*" in
4329
+ *"#{window_width}"*) echo "120" ;;
4330
+ *) echo "leader:0 %1" ;;
4331
+ esac
4332
+ exit 0
4333
+ ;;
4334
+ list-panes)
4335
+ case "$*" in
4336
+ *"-a -F #{pane_id}"*)
4337
+ if [ -f "${cwd}/ambiguous-w1" ]; then
4338
+ echo "forced exact proof query failure" >&2
4339
+ exit 1
4340
+ fi
4341
+ printf "%%1\t0\t2000000001\n"
4342
+ ;;
4343
+ *"pane_current_command"*)
4344
+ printf "%%1\tnode\t'codex'\n"
4345
+ if [ -f "${cwd}/ambiguous-w1" ]; then printf "%%2\tcodex\tcodex\n"; fi
4346
+ ;;
4347
+ *)
4348
+ printf "%%1\n"
4349
+ if [ -f "${cwd}/ambiguous-w1" ]; then printf "%%2\n"; fi
4350
+ ;;
4351
+ esac
4352
+ exit 0
4353
+ ;;
4354
+ capture-pane)
4355
+ exit 0
4356
+ ;;
4357
+ split-window)
4358
+ case "$*" in
4359
+ *" -h "*) : > "${cwd}/ambiguous-w1"; printf "%%2\\n%%9\\n" ;;
4360
+ *) printf "%%3\\n" ;;
4361
+ esac
4362
+ exit 0
4363
+ ;;
4364
+ set-hook|run-shell|select-layout|set-window-option|select-pane|send-keys|kill-pane|kill-session|resize-pane)
4365
+ exit 0
4366
+ ;;
4367
+ *)
4368
+ exit 0
4369
+ ;;
4370
+ esac
4371
+ `,
4372
+ binaries: [{ name: 'codex', content: fakeCodexNodeScript('process.stdin.resume();\n') }],
4373
+ }, async () => {
4374
+ delete process.env.TMUX;
4375
+ process.env.TMUX_PANE = '%1';
4376
+ process.env.OMX_TEAM_WORKER_LAUNCH_MODE = 'interactive';
4377
+ process.env.OMX_TEAM_WORKER_CLI = 'codex';
4378
+ await assert.rejects(() => withoutTeamWorkerEnv(() => startTeam('team-ambiguous-split-proof', 'ambiguous reconciled worker proof must stay fail-closed', 'executor', 1, [{ subject: 's', description: 'd', owner: 'worker-1' }], cwd)), /startup_rollback_pane_proof_unavailable:%2:query_failed/);
4379
+ const runtimeTeamName = await resolveRuntimeTeamName(cwd, 'team-ambiguous-split-proof');
4380
+ const preservedConfig = await readTeamConfig(runtimeTeamName, cwd);
4381
+ assert.ok(preservedConfig, 'proof-unavailable ambiguous split must preserve retry state');
4382
+ assert.equal(preservedConfig?.workers[0]?.pane_id, '%2');
4383
+ });
4384
+ }
4385
+ finally {
4386
+ if (typeof previousTmux === 'string')
4387
+ process.env.TMUX = previousTmux;
4388
+ else
4389
+ delete process.env.TMUX;
4390
+ if (typeof previousTmuxPane === 'string')
4391
+ process.env.TMUX_PANE = previousTmuxPane;
4392
+ else
4393
+ delete process.env.TMUX_PANE;
4394
+ if (typeof previousLaunchMode === 'string')
4395
+ process.env.OMX_TEAM_WORKER_LAUNCH_MODE = previousLaunchMode;
4396
+ else
4397
+ delete process.env.OMX_TEAM_WORKER_LAUNCH_MODE;
4398
+ if (typeof previousWorkerCli === 'string')
4399
+ process.env.OMX_TEAM_WORKER_CLI = previousWorkerCli;
4400
+ else
4401
+ delete process.env.OMX_TEAM_WORKER_CLI;
4402
+ await rm(cwd, { recursive: true, force: true });
4403
+ }
4404
+ });
3866
4405
  it('startTeam persists partial create-session metadata when rollback proof is unavailable', async () => {
3867
4406
  const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-partial-create-proof-'));
3868
4407
  const previousTmux = process.env.TMUX;
@@ -3936,7 +4475,7 @@ esac
3936
4475
  process.env.TMUX_PANE = '%1';
3937
4476
  process.env.OMX_TEAM_WORKER_LAUNCH_MODE = 'interactive';
3938
4477
  process.env.OMX_TEAM_WORKER_CLI = 'codex';
3939
- await assert.rejects(() => withoutTeamWorkerEnv(() => startTeam('team-partial-create-proof', 'partial tmux session must remain recoverable', 'executor', 1, [{ subject: 's', description: 'd', owner: 'worker-1' }], cwd)), /startup_rollback_pane_proof_unavailable:%2:malformed_snapshot/);
4478
+ await assert.rejects(() => withoutTeamWorkerEnv(() => startTeam('team-partial-create-proof', 'partial tmux session must remain recoverable', 'executor', 1, [{ subject: 's', description: 'd', owner: 'worker-1' }], cwd)), /create_team_session_cleanup_incomplete/);
3940
4479
  const runtimeTeamName = await resolveRuntimeTeamName(cwd, 'team-partial-create-proof');
3941
4480
  const config = await readTeamConfig(runtimeTeamName, cwd);
3942
4481
  assert.ok(config);
@@ -3946,7 +4485,7 @@ esac
3946
4485
  assert.equal(config?.hud_pane_id, null);
3947
4486
  const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
3948
4487
  assert.match(tmuxLog, /list-panes -a -F #\{pane_id\}\t#\{pane_dead\}\t#\{pane_pid\}/);
3949
- assert.doesNotMatch(tmuxLog, /kill-pane -t %2/);
4488
+ assert.equal(tmuxLog.match(/kill-pane -t %2/g)?.length ?? 0, 1);
3950
4489
  });
3951
4490
  }
3952
4491
  finally {
@@ -4031,7 +4570,7 @@ esac
4031
4570
  process.env.OMX_TEAM_WORKER_CLI = 'codex';
4032
4571
  process.env.OMX_ENTRY_PATH = join(cwd, 'omx.js');
4033
4572
  process.argv = [previousArgv[0] || 'node', join(cwd, 'omx.js')];
4034
- await assert.rejects(() => withoutTeamWorkerEnv(() => startTeam('team-no-resource-create-proof', 'target and leader identity alone must not persist startup state', 'executor', 1, [{ subject: 's', description: 'd', owner: 'worker-1' }], cwd)), /exact_pane_proof_unavailable:%1:malformed_snapshot/);
4573
+ await assert.rejects(() => withoutTeamWorkerEnv(() => startTeam('team-no-resource-create-proof', 'target and leader identity alone must not persist startup state', 'executor', 1, [{ subject: 's', description: 'd', owner: 'worker-1' }], cwd)), /exact_pane_proof_unavailable:%2:malformed_snapshot/);
4035
4574
  const runtimeTeamName = await resolveRuntimeTeamName(cwd, 'team-no-resource-create-proof');
4036
4575
  assert.equal(await readTeamConfig(runtimeTeamName, cwd), null);
4037
4576
  const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
@@ -4074,6 +4613,7 @@ esac
4074
4613
  const previousStartupDispatchRetries = process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES;
4075
4614
  const previousStartupDispatchRetryDelay = process.env.OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS;
4076
4615
  let receiptFailer = null;
4616
+ let receiptFailerPending = null;
4077
4617
  try {
4078
4618
  await withMockTmuxFixture({
4079
4619
  dirPrefix: 'omx-runtime-materialize-before-evidence-bin-',
@@ -4170,7 +4710,7 @@ process.on('SIGTERM', () => process.exit(0));
4170
4710
  process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES = '1';
4171
4711
  process.env.OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS = '50';
4172
4712
  receiptFailer = setInterval(() => {
4173
- void (async () => {
4713
+ receiptFailerPending ??= (async () => {
4174
4714
  const activeTeamName = await resolveRuntimeTeamName(cwd, 'team-materialize-before-evidence');
4175
4715
  runtimeTeamName = activeTeamName;
4176
4716
  const requests = await listDispatchRequests(activeTeamName, cwd, { kind: 'inbox' }).catch(() => []);
@@ -4179,7 +4719,7 @@ process.on('SIGTERM', () => process.exit(0));
4179
4719
  continue;
4180
4720
  await transitionDispatchRequest(activeTeamName, request.request_id, 'pending', 'failed', { last_reason: 'test_failed_receipt' }, cwd).catch(() => { });
4181
4721
  }
4182
- })();
4722
+ })().catch(() => { }).finally(() => { receiptFailerPending = null; });
4183
4723
  }, 20);
4184
4724
  const teamPromise = withoutTeamWorkerEnv(() => startTeam('team-materialize-before-evidence', 'later workers should materialize before startup evidence failure', 'executor', 2, [
4185
4725
  { subject: 'w1', description: 'worker one', owner: 'worker-1' },
@@ -4208,8 +4748,7 @@ process.on('SIGTERM', () => process.exit(0));
4208
4748
  });
4209
4749
  }
4210
4750
  finally {
4211
- if (receiptFailer)
4212
- clearInterval(receiptFailer);
4751
+ await settleReceiptInterval(receiptFailer, receiptFailerPending);
4213
4752
  if (typeof previousTmux === 'string')
4214
4753
  process.env.TMUX = previousTmux;
4215
4754
  else
@@ -4903,8 +5442,8 @@ exit 0
4903
5442
  assert.equal(tmuxLog.match(/set-hook -t leader:0 client-resized\[\d+\]/g)?.length ?? 0, 2);
4904
5443
  assert.equal(tmuxLog.match(/set-hook -t leader:0 client-attached\[\d+\]/g)?.length ?? 0, 2);
4905
5444
  assert.match(tmuxLog, /snapshot=\$\(tmux list-panes -a -F/);
4906
- assert.ok((tmuxLog.match(/list-panes -a -F '#\{pane_id\}\\t#\{pane_dead\}\\t#\{pane_pid\}'/g)?.length ?? 0) >= 6);
4907
- assert.ok((tmuxLog.match(/select-layout -t leader:0 main-vertical/g)?.length ?? 0) >= 2);
5445
+ assert.ok((tmuxLog.match(/list-panes -a -F '#\{pane_id\}\t#\{pane_dead\}\t#\{pane_pid\}'/g)?.length ?? 0) >= 6);
5446
+ assert.ok((tmuxLog.match(/select-layout -t @1 main-vertical/g)?.length ?? 0) >= 2);
4908
5447
  assert.equal(tmuxLog.match(/kill-pane -t %3/g)?.length ?? 0, 2);
4909
5448
  });
4910
5449
  }
@@ -6125,6 +6664,118 @@ exec "${realGit}" "$@"
6125
6664
  await rm(cwd, { recursive: true, force: true });
6126
6665
  }
6127
6666
  });
6667
+ it('follow-up created before terminal epoch blocks shutdown without starting the epoch', async () => {
6668
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-terminal-before-'));
6669
+ try {
6670
+ await initTeamState('team-terminal-before', 'terminal boundary before test', 'executor', 1, cwd);
6671
+ await createTask('team-terminal-before', { subject: 'valid follow-up', description: 'must block shutdown', status: 'pending' }, cwd);
6672
+ await assert.rejects(() => shutdownTeam('team-terminal-before', cwd), /shutdown_gate_blocked:pending=1,blocked=0,in_progress=0,failed=0/);
6673
+ const phase = await readTeamPhase('team-terminal-before', cwd);
6674
+ assert.equal(phase?.terminal_epoch, undefined);
6675
+ assert.equal(phase?.terminal_reason, undefined);
6676
+ assert.equal((await readTask('team-terminal-before', '1', cwd))?.status, 'pending');
6677
+ }
6678
+ finally {
6679
+ await rm(cwd, { recursive: true, force: true });
6680
+ }
6681
+ });
6682
+ it('terminal epoch rejects duplicate late assignment and task creation without stale delivery', async () => {
6683
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-terminal-after-'));
6684
+ let releaseEpoch;
6685
+ let observeEpoch;
6686
+ const epochObserved = new Promise((resolve) => { observeEpoch = resolve; });
6687
+ const epochRelease = new Promise((resolve) => { releaseEpoch = resolve; });
6688
+ try {
6689
+ await initTeamState('team-terminal-after', 'terminal boundary after test', 'executor', 1, cwd);
6690
+ const task = await createTask('team-terminal-after', { subject: 'forced follow-up', description: 'must not leak after epoch', status: 'pending' }, cwd);
6691
+ await markDetachedSessionAbsent('team-terminal-after', cwd);
6692
+ let capturedReason;
6693
+ let capturedCounts;
6694
+ setTerminalEpochStartedHookForTest(async (_teamName, _cwd, phase) => {
6695
+ capturedReason = phase.terminal_reason;
6696
+ capturedCounts = phase.final_task_counts;
6697
+ observeEpoch();
6698
+ await epochRelease;
6699
+ });
6700
+ const shutdown = shutdownWithoutTmuxSession('team-terminal-after', cwd, { force: true });
6701
+ await epochObserved;
6702
+ const attempts = await Promise.allSettled([
6703
+ assignTask('team-terminal-after', 'worker-1', task.id, cwd),
6704
+ assignTask('team-terminal-after', 'worker-1', task.id, cwd),
6705
+ createTask('team-terminal-after', { subject: 'too late', description: 'must require continuation', status: 'pending' }, cwd),
6706
+ ]);
6707
+ const diagnostics = attempts.map((attempt) => {
6708
+ assert.equal(attempt.status, 'rejected');
6709
+ return String(attempt.reason?.message ?? attempt.reason);
6710
+ });
6711
+ assert.equal(new Set(diagnostics).size, 1);
6712
+ assert.match(diagnostics[0] ?? '', /^team_continuation_required:terminal_epoch=.*:reason=forced_shutdown:action=reopen_or_start_continuation$/);
6713
+ assert.equal(capturedReason, 'forced_shutdown');
6714
+ assert.deepEqual(capturedCounts, {
6715
+ total: 1,
6716
+ pending: 1,
6717
+ blocked: 0,
6718
+ in_progress: 0,
6719
+ completed: 0,
6720
+ failed: 0,
6721
+ });
6722
+ assert.equal((await readTask('team-terminal-after', task.id, cwd))?.status, 'pending');
6723
+ assert.equal((await listMailboxMessages('team-terminal-after', 'worker-1', cwd)).length, 0);
6724
+ assert.equal((await listDispatchRequests('team-terminal-after', cwd, { kind: 'inbox' })).length, 0);
6725
+ releaseEpoch();
6726
+ await shutdown;
6727
+ }
6728
+ finally {
6729
+ releaseEpoch?.();
6730
+ setTerminalEpochStartedHookForTest(null);
6731
+ await rm(cwd, { recursive: true, force: true });
6732
+ }
6733
+ });
6734
+ it('terminal watcher phase rejects assignment with one continuation diagnostic', async () => {
6735
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-terminal-watcher-'));
6736
+ try {
6737
+ await initTeamState('team-terminal-watcher', 'terminal watcher test', 'executor', 1, cwd);
6738
+ const task = await createTask('team-terminal-watcher', { subject: 'late watcher work', description: 'worker has exited', status: 'pending' }, cwd);
6739
+ const staleMessage = await sendDirectMessage('team-terminal-watcher', 'leader-fixed', 'worker-1', 'stale follow-up assignment', cwd);
6740
+ await updateWorkerHeartbeat('team-terminal-watcher', 'worker-1', {
6741
+ pid: process.pid,
6742
+ alive: true,
6743
+ last_turn_at: new Date().toISOString(),
6744
+ turn_count: 1,
6745
+ }, cwd);
6746
+ const phase = await readTeamPhase('team-terminal-watcher', cwd);
6747
+ assert.ok(phase);
6748
+ await writeTeamPhase('team-terminal-watcher', {
6749
+ ...phase,
6750
+ current_phase: 'complete',
6751
+ updated_at: '2026-07-19T00:00:00.000Z',
6752
+ terminal_epoch: '2026-07-19T00:00:00.000Z',
6753
+ terminal_reason: 'shutdown_gate_passed',
6754
+ final_task_counts: {
6755
+ total: 1,
6756
+ pending: 1,
6757
+ blocked: 0,
6758
+ in_progress: 0,
6759
+ completed: 0,
6760
+ failed: 0,
6761
+ },
6762
+ }, cwd);
6763
+ await assert.rejects(() => assignTask('team-terminal-watcher', 'worker-1', task.id, cwd), (error) => {
6764
+ assert.equal(error.message, 'team_continuation_required:terminal_epoch=2026-07-19T00:00:00.000Z:reason=shutdown_gate_passed:action=reopen_or_start_continuation');
6765
+ return true;
6766
+ });
6767
+ await monitorTeam('team-terminal-watcher', cwd);
6768
+ assert.equal((await readTask('team-terminal-watcher', task.id, cwd))?.status, 'pending');
6769
+ const mailbox = await listMailboxMessages('team-terminal-watcher', 'worker-1', cwd);
6770
+ assert.equal(mailbox.length, 1);
6771
+ assert.equal(mailbox[0]?.message_id, staleMessage.message_id);
6772
+ assert.equal(mailbox[0]?.notified_at, undefined);
6773
+ assert.equal((await listDispatchRequests('team-terminal-watcher', cwd, { kind: 'inbox' })).length, 0);
6774
+ }
6775
+ finally {
6776
+ await rm(cwd, { recursive: true, force: true });
6777
+ }
6778
+ });
6128
6779
  it('shutdownTeam honors governance cleanup override when active tasks remain', async () => {
6129
6780
  const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-shutdown-gate-override-'));
6130
6781
  try {
@@ -6757,7 +7408,12 @@ case "$1" in
6757
7408
  ;;
6758
7409
  show-option|show-options) echo 'team:team-detached-hud-shutdown' ;;
6759
7410
  kill-pane) : > "${tmuxLogPath}.hud-killed" ;;
6760
- if-shell) : > "${tmuxLogPath}.session-killed" ;;
7411
+ if-shell)
7412
+ case "\${5:-}" in
7413
+ *'#{==:#{pane_dead},0}'*'#{==:#{pane_id},%1}'*'#{==:#{pane_pid},4241}'*'#{==:#{@omx_team_pane_owner_id},team:team-detached-hud-shutdown}'*'#{==:#{session_id},$81}'*'#{==:#{session_created},1700000001}'*) : > "${tmuxLogPath}.session-killed" ;;
7414
+ *) exit 1 ;;
7415
+ esac
7416
+ ;;
6761
7417
  list-sessions)
6762
7418
  if [ -f "${tmuxLogPath}.session-killed" ]; then
6763
7419
  printf '%s\n' 'no server running on /tmp/tmux-1000/default' >&2
@@ -6817,7 +7473,12 @@ case "$1" in
6817
7473
  esac
6818
7474
  ;;
6819
7475
  show-option|show-options) echo 'team:team-postkill-query-fail' ;;
6820
- if-shell) : > "${tmuxLogPath}.session-killed" ;;
7476
+ if-shell)
7477
+ case "\${5:-}" in
7478
+ *'#{==:#{pane_dead},0}'*'#{==:#{pane_id},%1}'*'#{==:#{pane_pid},4241}'*'#{==:#{@omx_team_pane_owner_id},team:team-postkill-query-fail}'*'#{==:#{session_id},$1}'*'#{==:#{session_created},1700000000}'*) : > "${tmuxLogPath}.session-killed" ;;
7479
+ *) exit 1 ;;
7480
+ esac
7481
+ ;;
6821
7482
  list-sessions)
6822
7483
  if [ -f "${tmuxLogPath}.session-killed" ]; then
6823
7484
  if [ -f "${tmuxLogPath}.allow-retry" ]; then
@@ -7017,7 +7678,12 @@ case "$1" in
7017
7678
  esac ;;
7018
7679
  show-option|show-options) echo 'team:intent-receipt' ;;
7019
7680
  list-sessions) [ -f "${tmuxLogPath}.killed" ] || printf 'omx-team-intent-receipt\t$71\t1700000010\n' ;;
7020
- if-shell) : > "${tmuxLogPath}.killed" ;;
7681
+ if-shell)
7682
+ case "\${5:-}" in
7683
+ *'#{==:#{pane_dead},0}'*'#{==:#{pane_id},%1}'*'#{==:#{pane_pid},4241}'*'#{==:#{@omx_team_pane_owner_id},team:intent-receipt}'*'#{==:#{session_id},$71}'*'#{==:#{session_created},1700000010}'*) : > "${tmuxLogPath}.killed" ;;
7684
+ *) exit 1 ;;
7685
+ esac
7686
+ ;;
7021
7687
  *) exit 0 ;;
7022
7688
  esac
7023
7689
  `,