oh-my-codex 0.18.0 → 0.18.2

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 (410) hide show
  1. package/Cargo.lock +6 -6
  2. package/Cargo.toml +1 -1
  3. package/README.md +45 -19
  4. package/crates/omx-api/src/lib.rs +66 -9
  5. package/crates/omx-sparkshell/src/exec.rs +125 -3
  6. package/crates/omx-sparkshell/src/main.rs +126 -36
  7. package/crates/omx-sparkshell/tests/execution.rs +225 -1
  8. package/dist/agents/__tests__/definitions.test.js +14 -0
  9. package/dist/agents/__tests__/definitions.test.js.map +1 -1
  10. package/dist/agents/__tests__/native-config.test.js +19 -0
  11. package/dist/agents/__tests__/native-config.test.js.map +1 -1
  12. package/dist/agents/definitions.d.ts.map +1 -1
  13. package/dist/agents/definitions.js +30 -0
  14. package/dist/agents/definitions.js.map +1 -1
  15. package/dist/agents/native-config.d.ts +1 -0
  16. package/dist/agents/native-config.d.ts.map +1 -1
  17. package/dist/agents/native-config.js +4 -0
  18. package/dist/agents/native-config.js.map +1 -1
  19. package/dist/catalog/__tests__/generator.test.js +4 -0
  20. package/dist/catalog/__tests__/generator.test.js.map +1 -1
  21. package/dist/cli/__tests__/codex-plugin-layout.test.js +15 -7
  22. package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
  23. package/dist/cli/__tests__/doctor-warning-copy.test.js +137 -8
  24. package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
  25. package/dist/cli/__tests__/index.test.js +203 -15
  26. package/dist/cli/__tests__/index.test.js.map +1 -1
  27. package/dist/cli/__tests__/install-docs-contract.test.d.ts +2 -0
  28. package/dist/cli/__tests__/install-docs-contract.test.d.ts.map +1 -0
  29. package/dist/cli/__tests__/install-docs-contract.test.js +55 -0
  30. package/dist/cli/__tests__/install-docs-contract.test.js.map +1 -0
  31. package/dist/cli/__tests__/launch-fallback.test.js +163 -0
  32. package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
  33. package/dist/cli/__tests__/question.test.js +29 -43
  34. package/dist/cli/__tests__/question.test.js.map +1 -1
  35. package/dist/cli/__tests__/setup-install-mode.test.js +94 -35
  36. package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
  37. package/dist/cli/__tests__/sparkshell-cli.test.js +20 -1
  38. package/dist/cli/__tests__/sparkshell-cli.test.js.map +1 -1
  39. package/dist/cli/__tests__/sparkshell-packaging.test.js +1 -0
  40. package/dist/cli/__tests__/sparkshell-packaging.test.js.map +1 -1
  41. package/dist/cli/__tests__/ultragoal.test.js +227 -4
  42. package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
  43. package/dist/cli/__tests__/update.test.js +72 -1
  44. package/dist/cli/__tests__/update.test.js.map +1 -1
  45. package/dist/cli/codex-feature-probe.d.ts +5 -0
  46. package/dist/cli/codex-feature-probe.d.ts.map +1 -1
  47. package/dist/cli/codex-feature-probe.js +13 -7
  48. package/dist/cli/codex-feature-probe.js.map +1 -1
  49. package/dist/cli/doctor.d.ts +7 -0
  50. package/dist/cli/doctor.d.ts.map +1 -1
  51. package/dist/cli/doctor.js +297 -17
  52. package/dist/cli/doctor.js.map +1 -1
  53. package/dist/cli/index.d.ts +9 -1
  54. package/dist/cli/index.d.ts.map +1 -1
  55. package/dist/cli/index.js +465 -110
  56. package/dist/cli/index.js.map +1 -1
  57. package/dist/cli/plugin-marketplace.d.ts +2 -0
  58. package/dist/cli/plugin-marketplace.d.ts.map +1 -1
  59. package/dist/cli/plugin-marketplace.js +15 -1
  60. package/dist/cli/plugin-marketplace.js.map +1 -1
  61. package/dist/cli/setup.d.ts.map +1 -1
  62. package/dist/cli/setup.js +71 -11
  63. package/dist/cli/setup.js.map +1 -1
  64. package/dist/cli/sparkshell.d.ts +7 -1
  65. package/dist/cli/sparkshell.d.ts.map +1 -1
  66. package/dist/cli/sparkshell.js +13 -3
  67. package/dist/cli/sparkshell.js.map +1 -1
  68. package/dist/cli/ultragoal.d.ts +1 -1
  69. package/dist/cli/ultragoal.d.ts.map +1 -1
  70. package/dist/cli/ultragoal.js +184 -10
  71. package/dist/cli/ultragoal.js.map +1 -1
  72. package/dist/cli/update.d.ts +2 -0
  73. package/dist/cli/update.d.ts.map +1 -1
  74. package/dist/cli/update.js +14 -3
  75. package/dist/cli/update.js.map +1 -1
  76. package/dist/compat/__tests__/doctor-contract.test.js +3 -0
  77. package/dist/compat/__tests__/doctor-contract.test.js.map +1 -1
  78. package/dist/config/__tests__/codex-feature-flags.test.js +11 -1
  79. package/dist/config/__tests__/codex-feature-flags.test.js.map +1 -1
  80. package/dist/config/__tests__/codex-hooks.test.js +22 -11
  81. package/dist/config/__tests__/codex-hooks.test.js.map +1 -1
  82. package/dist/config/__tests__/commit-lore-guard.test.d.ts +2 -0
  83. package/dist/config/__tests__/commit-lore-guard.test.d.ts.map +1 -0
  84. package/dist/config/__tests__/commit-lore-guard.test.js +20 -0
  85. package/dist/config/__tests__/commit-lore-guard.test.js.map +1 -0
  86. package/dist/config/codex-feature-flags.d.ts +4 -0
  87. package/dist/config/codex-feature-flags.d.ts.map +1 -1
  88. package/dist/config/codex-feature-flags.js +4 -0
  89. package/dist/config/codex-feature-flags.js.map +1 -1
  90. package/dist/config/codex-hooks.d.ts +1 -0
  91. package/dist/config/codex-hooks.d.ts.map +1 -1
  92. package/dist/config/codex-hooks.js +8 -10
  93. package/dist/config/codex-hooks.js.map +1 -1
  94. package/dist/config/commit-lore-guard.d.ts +1 -0
  95. package/dist/config/commit-lore-guard.d.ts.map +1 -1
  96. package/dist/config/commit-lore-guard.js +29 -3
  97. package/dist/config/commit-lore-guard.js.map +1 -1
  98. package/dist/config/generator.d.ts +17 -1
  99. package/dist/config/generator.d.ts.map +1 -1
  100. package/dist/config/generator.js +124 -11
  101. package/dist/config/generator.js.map +1 -1
  102. package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js +21 -0
  103. package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js.map +1 -1
  104. package/dist/goal-workflows/codex-goal-snapshot.d.ts +4 -0
  105. package/dist/goal-workflows/codex-goal-snapshot.d.ts.map +1 -1
  106. package/dist/goal-workflows/codex-goal-snapshot.js +50 -3
  107. package/dist/goal-workflows/codex-goal-snapshot.js.map +1 -1
  108. package/dist/hooks/__tests__/autopilot-skill-contract.test.js +27 -6
  109. package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -1
  110. package/dist/hooks/__tests__/consensus-execution-handoff.test.d.ts +1 -1
  111. package/dist/hooks/__tests__/consensus-execution-handoff.test.js +13 -11
  112. package/dist/hooks/__tests__/consensus-execution-handoff.test.js.map +1 -1
  113. package/dist/hooks/__tests__/deep-interview-contract.test.js +4 -3
  114. package/dist/hooks/__tests__/deep-interview-contract.test.js.map +1 -1
  115. package/dist/hooks/__tests__/keyword-detector.test.js +173 -17
  116. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  117. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js +33 -0
  118. package/dist/hooks/__tests__/notify-hook-team-tmux-guard.test.js.map +1 -1
  119. package/dist/hooks/__tests__/prometheus-strict-contract.test.d.ts +2 -0
  120. package/dist/hooks/__tests__/prometheus-strict-contract.test.d.ts.map +1 -0
  121. package/dist/hooks/__tests__/prometheus-strict-contract.test.js +320 -0
  122. package/dist/hooks/__tests__/prometheus-strict-contract.test.js.map +1 -0
  123. package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js +12 -0
  124. package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js.map +1 -1
  125. package/dist/hooks/__tests__/research-workflow-boundaries.test.d.ts +2 -0
  126. package/dist/hooks/__tests__/research-workflow-boundaries.test.d.ts.map +1 -0
  127. package/dist/hooks/__tests__/research-workflow-boundaries.test.js +35 -0
  128. package/dist/hooks/__tests__/research-workflow-boundaries.test.js.map +1 -0
  129. package/dist/hooks/extensibility/__tests__/dispatcher.test.js +26 -3
  130. package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +1 -1
  131. package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -1
  132. package/dist/hooks/extensibility/dispatcher.js +29 -14
  133. package/dist/hooks/extensibility/dispatcher.js.map +1 -1
  134. package/dist/hooks/keyword-detector.d.ts +1 -1
  135. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  136. package/dist/hooks/keyword-detector.js +36 -9
  137. package/dist/hooks/keyword-detector.js.map +1 -1
  138. package/dist/hooks/keyword-registry.d.ts.map +1 -1
  139. package/dist/hooks/keyword-registry.js +1 -0
  140. package/dist/hooks/keyword-registry.js.map +1 -1
  141. package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
  142. package/dist/hooks/prompt-guidance-contract.js +14 -2
  143. package/dist/hooks/prompt-guidance-contract.js.map +1 -1
  144. package/dist/hud/__tests__/hud-tmux-injection.test.js +36 -8
  145. package/dist/hud/__tests__/hud-tmux-injection.test.js.map +1 -1
  146. package/dist/hud/__tests__/reconcile.test.js +122 -11
  147. package/dist/hud/__tests__/reconcile.test.js.map +1 -1
  148. package/dist/hud/__tests__/render.test.js +84 -0
  149. package/dist/hud/__tests__/render.test.js.map +1 -1
  150. package/dist/hud/__tests__/resource-leak-watch.test.d.ts +2 -0
  151. package/dist/hud/__tests__/resource-leak-watch.test.d.ts.map +1 -0
  152. package/dist/hud/__tests__/resource-leak-watch.test.js +28 -0
  153. package/dist/hud/__tests__/resource-leak-watch.test.js.map +1 -0
  154. package/dist/hud/__tests__/state.test.js +51 -1
  155. package/dist/hud/__tests__/state.test.js.map +1 -1
  156. package/dist/hud/__tests__/tmux.test.js +69 -23
  157. package/dist/hud/__tests__/tmux.test.js.map +1 -1
  158. package/dist/hud/index.d.ts +2 -2
  159. package/dist/hud/index.d.ts.map +1 -1
  160. package/dist/hud/index.js +17 -6
  161. package/dist/hud/index.js.map +1 -1
  162. package/dist/hud/reconcile.d.ts.map +1 -1
  163. package/dist/hud/reconcile.js +6 -3
  164. package/dist/hud/reconcile.js.map +1 -1
  165. package/dist/hud/render.d.ts.map +1 -1
  166. package/dist/hud/render.js +26 -0
  167. package/dist/hud/render.js.map +1 -1
  168. package/dist/hud/state.d.ts +2 -1
  169. package/dist/hud/state.d.ts.map +1 -1
  170. package/dist/hud/state.js +62 -1
  171. package/dist/hud/state.js.map +1 -1
  172. package/dist/hud/tmux.d.ts +10 -3
  173. package/dist/hud/tmux.d.ts.map +1 -1
  174. package/dist/hud/tmux.js +60 -11
  175. package/dist/hud/tmux.js.map +1 -1
  176. package/dist/hud/types.d.ts +22 -0
  177. package/dist/hud/types.d.ts.map +1 -1
  178. package/dist/hud/types.js.map +1 -1
  179. package/dist/notifications/__tests__/http-client-resource.test.d.ts +2 -0
  180. package/dist/notifications/__tests__/http-client-resource.test.d.ts.map +1 -0
  181. package/dist/notifications/__tests__/http-client-resource.test.js +41 -0
  182. package/dist/notifications/__tests__/http-client-resource.test.js.map +1 -0
  183. package/dist/notifications/__tests__/verbosity.test.js +20 -0
  184. package/dist/notifications/__tests__/verbosity.test.js.map +1 -1
  185. package/dist/notifications/config.d.ts.map +1 -1
  186. package/dist/notifications/config.js +6 -3
  187. package/dist/notifications/config.js.map +1 -1
  188. package/dist/notifications/http-client.d.ts.map +1 -1
  189. package/dist/notifications/http-client.js +78 -27
  190. package/dist/notifications/http-client.js.map +1 -1
  191. package/dist/notifications/types.d.ts +2 -0
  192. package/dist/notifications/types.d.ts.map +1 -1
  193. package/dist/openclaw/__tests__/dispatcher.test.js +49 -1
  194. package/dist/openclaw/__tests__/dispatcher.test.js.map +1 -1
  195. package/dist/openclaw/dispatcher.d.ts +7 -4
  196. package/dist/openclaw/dispatcher.d.ts.map +1 -1
  197. package/dist/openclaw/dispatcher.js +32 -69
  198. package/dist/openclaw/dispatcher.js.map +1 -1
  199. package/dist/pipeline/__tests__/orchestrator.test.js +128 -4
  200. package/dist/pipeline/__tests__/orchestrator.test.js.map +1 -1
  201. package/dist/pipeline/__tests__/stages.test.js +460 -9
  202. package/dist/pipeline/__tests__/stages.test.js.map +1 -1
  203. package/dist/pipeline/index.d.ts +8 -2
  204. package/dist/pipeline/index.d.ts.map +1 -1
  205. package/dist/pipeline/index.js +5 -2
  206. package/dist/pipeline/index.js.map +1 -1
  207. package/dist/pipeline/orchestrator.d.ts +5 -4
  208. package/dist/pipeline/orchestrator.d.ts.map +1 -1
  209. package/dist/pipeline/orchestrator.js +85 -17
  210. package/dist/pipeline/orchestrator.js.map +1 -1
  211. package/dist/pipeline/stages/code-review.d.ts +2 -2
  212. package/dist/pipeline/stages/code-review.d.ts.map +1 -1
  213. package/dist/pipeline/stages/code-review.js +5 -3
  214. package/dist/pipeline/stages/code-review.js.map +1 -1
  215. package/dist/pipeline/stages/deep-interview.d.ts +15 -0
  216. package/dist/pipeline/stages/deep-interview.d.ts.map +1 -0
  217. package/dist/pipeline/stages/deep-interview.js +32 -0
  218. package/dist/pipeline/stages/deep-interview.js.map +1 -0
  219. package/dist/pipeline/stages/ralph-verify.d.ts +5 -5
  220. package/dist/pipeline/stages/ralph-verify.d.ts.map +1 -1
  221. package/dist/pipeline/stages/ralph-verify.js +2 -2
  222. package/dist/pipeline/stages/ralph-verify.js.map +1 -1
  223. package/dist/pipeline/stages/ralplan.d.ts.map +1 -1
  224. package/dist/pipeline/stages/ralplan.js +41 -6
  225. package/dist/pipeline/stages/ralplan.js.map +1 -1
  226. package/dist/pipeline/stages/ultragoal.d.ts +19 -0
  227. package/dist/pipeline/stages/ultragoal.d.ts.map +1 -0
  228. package/dist/pipeline/stages/ultragoal.js +38 -0
  229. package/dist/pipeline/stages/ultragoal.js.map +1 -0
  230. package/dist/pipeline/stages/ultraqa.d.ts +30 -0
  231. package/dist/pipeline/stages/ultraqa.d.ts.map +1 -0
  232. package/dist/pipeline/stages/ultraqa.js +46 -0
  233. package/dist/pipeline/stages/ultraqa.js.map +1 -0
  234. package/dist/pipeline/types.d.ts +8 -6
  235. package/dist/pipeline/types.d.ts.map +1 -1
  236. package/dist/pipeline/types.js +2 -2
  237. package/dist/question/__tests__/ui.test.js +43 -10
  238. package/dist/question/__tests__/ui.test.js.map +1 -1
  239. package/dist/question/ui.d.ts +12 -0
  240. package/dist/question/ui.d.ts.map +1 -1
  241. package/dist/question/ui.js +83 -46
  242. package/dist/question/ui.js.map +1 -1
  243. package/dist/ralplan/__tests__/runtime.test.js +200 -10
  244. package/dist/ralplan/__tests__/runtime.test.js.map +1 -1
  245. package/dist/ralplan/consensus-gate.d.ts +23 -0
  246. package/dist/ralplan/consensus-gate.d.ts.map +1 -0
  247. package/dist/ralplan/consensus-gate.js +212 -0
  248. package/dist/ralplan/consensus-gate.js.map +1 -0
  249. package/dist/ralplan/runtime.d.ts +25 -0
  250. package/dist/ralplan/runtime.d.ts.map +1 -1
  251. package/dist/ralplan/runtime.js +144 -8
  252. package/dist/ralplan/runtime.js.map +1 -1
  253. package/dist/scripts/__tests__/codex-native-hook.test.js +1358 -79
  254. package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
  255. package/dist/scripts/__tests__/docs-site-contract.test.d.ts +2 -0
  256. package/dist/scripts/__tests__/docs-site-contract.test.d.ts.map +1 -0
  257. package/dist/scripts/__tests__/docs-site-contract.test.js +42 -0
  258. package/dist/scripts/__tests__/docs-site-contract.test.js.map +1 -0
  259. package/dist/scripts/__tests__/notify-dispatcher.test.js +115 -2
  260. package/dist/scripts/__tests__/notify-dispatcher.test.js.map +1 -1
  261. package/dist/scripts/__tests__/run-test-files.test.js +57 -0
  262. package/dist/scripts/__tests__/run-test-files.test.js.map +1 -1
  263. package/dist/scripts/__tests__/smoke-packed-install.test.js +23 -1
  264. package/dist/scripts/__tests__/smoke-packed-install.test.js.map +1 -1
  265. package/dist/scripts/__tests__/verify-native-agents.test.js +18 -3
  266. package/dist/scripts/__tests__/verify-native-agents.test.js.map +1 -1
  267. package/dist/scripts/cleanup-explore-harness.js +1 -0
  268. package/dist/scripts/cleanup-explore-harness.js.map +1 -1
  269. package/dist/scripts/codex-native-hook.d.ts.map +1 -1
  270. package/dist/scripts/codex-native-hook.js +372 -44
  271. package/dist/scripts/codex-native-hook.js.map +1 -1
  272. package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
  273. package/dist/scripts/codex-native-pre-post.js +9 -1
  274. package/dist/scripts/codex-native-pre-post.js.map +1 -1
  275. package/dist/scripts/notify-dispatcher.js +188 -4
  276. package/dist/scripts/notify-dispatcher.js.map +1 -1
  277. package/dist/scripts/notify-hook/process-runner.d.ts.map +1 -1
  278. package/dist/scripts/notify-hook/process-runner.js +39 -17
  279. package/dist/scripts/notify-hook/process-runner.js.map +1 -1
  280. package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
  281. package/dist/scripts/notify-hook/team-dispatch.js +9 -5
  282. package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
  283. package/dist/scripts/notify-hook/team-tmux-guard.d.ts +1 -1
  284. package/dist/scripts/notify-hook/team-tmux-guard.d.ts.map +1 -1
  285. package/dist/scripts/notify-hook/team-tmux-guard.js +7 -1
  286. package/dist/scripts/notify-hook/team-tmux-guard.js.map +1 -1
  287. package/dist/scripts/run-test-files.js +13 -0
  288. package/dist/scripts/run-test-files.js.map +1 -1
  289. package/dist/scripts/smoke-packed-install.d.ts +3 -0
  290. package/dist/scripts/smoke-packed-install.d.ts.map +1 -1
  291. package/dist/scripts/smoke-packed-install.js +99 -1
  292. package/dist/scripts/smoke-packed-install.js.map +1 -1
  293. package/dist/scripts/sync-plugin-mirror.js +2 -2
  294. package/dist/scripts/sync-plugin-mirror.js.map +1 -1
  295. package/dist/scripts/verify-native-agents.js +2 -2
  296. package/dist/scripts/verify-native-agents.js.map +1 -1
  297. package/dist/sidecar/__tests__/resource-leak-watch.test.d.ts +2 -0
  298. package/dist/sidecar/__tests__/resource-leak-watch.test.d.ts.map +1 -0
  299. package/dist/sidecar/__tests__/resource-leak-watch.test.js +38 -0
  300. package/dist/sidecar/__tests__/resource-leak-watch.test.js.map +1 -0
  301. package/dist/sidecar/index.d.ts +1 -1
  302. package/dist/sidecar/index.d.ts.map +1 -1
  303. package/dist/sidecar/index.js +29 -12
  304. package/dist/sidecar/index.js.map +1 -1
  305. package/dist/state/__tests__/operations-ralph-phase.test.js +88 -1
  306. package/dist/state/__tests__/operations-ralph-phase.test.js.map +1 -1
  307. package/dist/state/__tests__/workflow-transition.test.js +6 -0
  308. package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
  309. package/dist/state/operations.d.ts.map +1 -1
  310. package/dist/state/operations.js +11 -0
  311. package/dist/state/operations.js.map +1 -1
  312. package/dist/state/workflow-transition.d.ts +1 -1
  313. package/dist/state/workflow-transition.d.ts.map +1 -1
  314. package/dist/state/workflow-transition.js +7 -0
  315. package/dist/state/workflow-transition.js.map +1 -1
  316. package/dist/subagents/tracker.d.ts.map +1 -1
  317. package/dist/subagents/tracker.js +4 -3
  318. package/dist/subagents/tracker.js.map +1 -1
  319. package/dist/team/__tests__/runtime.test.js +36 -44
  320. package/dist/team/__tests__/runtime.test.js.map +1 -1
  321. package/dist/team/__tests__/tmux-session.test.js +163 -15
  322. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  323. package/dist/team/runtime.d.ts.map +1 -1
  324. package/dist/team/runtime.js +10 -20
  325. package/dist/team/runtime.js.map +1 -1
  326. package/dist/team/tmux-session.d.ts.map +1 -1
  327. package/dist/team/tmux-session.js +51 -21
  328. package/dist/team/tmux-session.js.map +1 -1
  329. package/dist/ultragoal/__tests__/artifacts.test.js +764 -10
  330. package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
  331. package/dist/ultragoal/__tests__/docs-contract.test.js +57 -1
  332. package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -1
  333. package/dist/ultragoal/__tests__/steering-fixtures.d.ts +68 -0
  334. package/dist/ultragoal/__tests__/steering-fixtures.d.ts.map +1 -0
  335. package/dist/ultragoal/__tests__/steering-fixtures.js +259 -0
  336. package/dist/ultragoal/__tests__/steering-fixtures.js.map +1 -0
  337. package/dist/ultragoal/__tests__/steering-fixtures.test.d.ts +2 -0
  338. package/dist/ultragoal/__tests__/steering-fixtures.test.d.ts.map +1 -0
  339. package/dist/ultragoal/__tests__/steering-fixtures.test.js +65 -0
  340. package/dist/ultragoal/__tests__/steering-fixtures.test.js.map +1 -0
  341. package/dist/ultragoal/artifacts.d.ts +97 -2
  342. package/dist/ultragoal/artifacts.d.ts.map +1 -1
  343. package/dist/ultragoal/artifacts.js +837 -256
  344. package/dist/ultragoal/artifacts.js.map +1 -1
  345. package/dist/utils/__tests__/sleep-resource.test.d.ts +2 -0
  346. package/dist/utils/__tests__/sleep-resource.test.d.ts.map +1 -0
  347. package/dist/utils/__tests__/sleep-resource.test.js +39 -0
  348. package/dist/utils/__tests__/sleep-resource.test.js.map +1 -0
  349. package/dist/utils/sleep.d.ts.map +1 -1
  350. package/dist/utils/sleep.js +17 -6
  351. package/dist/utils/sleep.js.map +1 -1
  352. package/package.json +2 -1
  353. package/plugins/oh-my-codex/.codex-plugin/plugin.json +4 -3
  354. package/plugins/oh-my-codex/hooks/codex-native-hook.mjs +56 -0
  355. package/plugins/oh-my-codex/hooks/hooks.json +77 -0
  356. package/plugins/oh-my-codex/skills/autopilot/SKILL.md +92 -50
  357. package/plugins/oh-my-codex/skills/autoresearch/SKILL.md +4 -0
  358. package/plugins/oh-my-codex/skills/autoresearch-goal/SKILL.md +1 -1
  359. package/plugins/oh-my-codex/skills/best-practice-research/SKILL.md +1 -1
  360. package/plugins/oh-my-codex/skills/cancel/SKILL.md +2 -2
  361. package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +8 -8
  362. package/plugins/oh-my-codex/skills/omx-setup/SKILL.md +1 -1
  363. package/plugins/oh-my-codex/skills/pipeline/SKILL.md +23 -12
  364. package/plugins/oh-my-codex/skills/plan/SKILL.md +8 -8
  365. package/plugins/oh-my-codex/skills/prometheus-strict/README.md +35 -0
  366. package/plugins/oh-my-codex/skills/prometheus-strict/SKILL.md +219 -0
  367. package/plugins/oh-my-codex/skills/ralph/SKILL.md +7 -0
  368. package/plugins/oh-my-codex/skills/ralplan/SKILL.md +22 -7
  369. package/plugins/oh-my-codex/skills/team/SKILL.md +1 -1
  370. package/plugins/oh-my-codex/skills/ultragoal/SKILL.md +38 -4
  371. package/plugins/oh-my-codex/skills/ultrawork/SKILL.md +1 -1
  372. package/prompts/planner.md +1 -1
  373. package/prompts/prometheus-strict-metis.md +274 -0
  374. package/prompts/prometheus-strict-momus.md +82 -0
  375. package/prompts/prometheus-strict-oracle.md +107 -0
  376. package/prompts/researcher.md +22 -3
  377. package/skills/autopilot/SKILL.md +92 -50
  378. package/skills/autoresearch/SKILL.md +4 -0
  379. package/skills/autoresearch-goal/SKILL.md +1 -1
  380. package/skills/best-practice-research/SKILL.md +1 -1
  381. package/skills/cancel/SKILL.md +2 -2
  382. package/skills/deep-interview/SKILL.md +8 -8
  383. package/skills/omx-setup/SKILL.md +1 -1
  384. package/skills/pipeline/SKILL.md +23 -12
  385. package/skills/plan/SKILL.md +8 -8
  386. package/skills/prometheus-strict/README.md +35 -0
  387. package/skills/prometheus-strict/SKILL.md +219 -0
  388. package/skills/ralph/SKILL.md +7 -0
  389. package/skills/ralplan/SKILL.md +22 -7
  390. package/skills/team/SKILL.md +1 -1
  391. package/skills/ultragoal/SKILL.md +38 -4
  392. package/skills/ultrawork/SKILL.md +1 -1
  393. package/src/scripts/__tests__/codex-native-hook.test.ts +1757 -210
  394. package/src/scripts/__tests__/docs-site-contract.test.ts +47 -0
  395. package/src/scripts/__tests__/notify-dispatcher.test.ts +132 -3
  396. package/src/scripts/__tests__/run-test-files.test.ts +67 -0
  397. package/src/scripts/__tests__/smoke-packed-install.test.ts +31 -0
  398. package/src/scripts/__tests__/verify-native-agents.test.ts +23 -3
  399. package/src/scripts/cleanup-explore-harness.ts +1 -0
  400. package/src/scripts/codex-native-hook.ts +393 -40
  401. package/src/scripts/codex-native-pre-post.ts +16 -1
  402. package/src/scripts/notify-dispatcher.ts +202 -4
  403. package/src/scripts/notify-hook/process-runner.ts +40 -16
  404. package/src/scripts/notify-hook/team-dispatch.ts +9 -5
  405. package/src/scripts/notify-hook/team-tmux-guard.ts +7 -0
  406. package/src/scripts/run-test-files.ts +13 -0
  407. package/src/scripts/smoke-packed-install.ts +105 -0
  408. package/src/scripts/sync-plugin-mirror.ts +3 -3
  409. package/src/scripts/verify-native-agents.ts +2 -2
  410. package/templates/catalog-manifest.json +22 -0
@@ -5,10 +5,13 @@ import { mkdtemp, rm, mkdir, readFile, writeFile } from 'fs/promises';
5
5
  import { basename, dirname, join, relative } from 'path';
6
6
  import { tmpdir } from 'os';
7
7
  import { existsSync } from 'fs';
8
+ import { createDeepInterviewStage, buildDeepInterviewInstruction } from '../stages/deep-interview.js';
8
9
  import { createRalplanStage } from '../stages/ralplan.js';
9
10
  import { createTeamExecStage, buildTeamInstruction } from '../stages/team-exec.js';
10
11
  import { createRalphVerifyStage, createRalphStage, buildRalphInstruction } from '../stages/ralph-verify.js';
11
12
  import { createCodeReviewStage, buildCodeReviewInstruction } from '../stages/code-review.js';
13
+ import { createUltragoalStage, buildUltragoalInstruction } from '../stages/ultragoal.js';
14
+ import { createUltraqaStage, buildUltraqaInstruction } from '../stages/ultraqa.js';
12
15
  import { buildFollowupStaffingPlan } from '../../team/followup-planner.js';
13
16
  import { packageRoot } from '../../utils/paths.js';
14
17
  // ---------------------------------------------------------------------------
@@ -94,12 +97,13 @@ describe('RALPLAN Stage', () => {
94
97
  const stage = createRalplanStage();
95
98
  assert.equal(stage.name, 'ralplan');
96
99
  });
97
- it('runs successfully and produces artifacts', async () => {
100
+ it('fails closed without planning artifacts and consensus evidence', async () => {
98
101
  const stage = createRalplanStage();
99
102
  const result = await stage.run(makeCtx());
100
- assert.equal(result.status, 'completed');
103
+ assert.equal(result.status, 'failed');
101
104
  assert.equal(result.artifacts.stage, 'ralplan');
102
105
  assert.ok(result.artifacts.instruction);
106
+ assert.equal(result.error, 'ralplan_planning_artifacts_missing');
103
107
  });
104
108
  it('canSkip returns false when no plans directory exists', () => {
105
109
  const stage = createRalplanStage();
@@ -118,13 +122,329 @@ describe('RALPLAN Stage', () => {
118
122
  const stage = createRalplanStage();
119
123
  assert.equal(stage.canSkip(makeCtx()), false);
120
124
  });
121
- it('canSkip returns true when both prd and test spec plan files exist', async () => {
125
+ it('canSkip returns false when only prd and test spec plan files exist without consensus evidence', async () => {
126
+ const plansDir = join(tempDir, '.omx', 'plans');
127
+ await mkdir(plansDir, { recursive: true });
128
+ await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
129
+ await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
130
+ const stage = createRalplanStage();
131
+ assert.equal(stage.canSkip(makeCtx()), false);
132
+ });
133
+ it('run fails with consensus-specific artifact error when consensus exists but planning artifacts are missing', async () => {
134
+ const stage = createRalplanStage();
135
+ const result = await stage.run(makeCtx({
136
+ artifacts: {
137
+ ralplan: {
138
+ ralplanConsensusGate: {
139
+ complete: true,
140
+ sequence: ['architect-review', 'critic-review'],
141
+ ralplan_architect_review: { agent_role: 'architect', verdict: 'approve' },
142
+ ralplan_critic_review: { agent_role: 'critic', verdict: 'approve' },
143
+ },
144
+ },
145
+ },
146
+ }));
147
+ assert.equal(result.status, 'failed');
148
+ assert.equal(result.error, 'ralplan_planning_artifacts_missing_after_consensus');
149
+ assert.equal(result.artifacts.planningComplete, false);
150
+ });
151
+ it('canSkip returns true only when planning artifacts have sequential Architect and Critic approval evidence', async () => {
152
+ const plansDir = join(tempDir, '.omx', 'plans');
153
+ await mkdir(plansDir, { recursive: true });
154
+ await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
155
+ await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
156
+ const stage = createRalplanStage();
157
+ assert.equal(stage.canSkip(makeCtx({
158
+ artifacts: {
159
+ ralplan: {
160
+ ralplanConsensusGate: {
161
+ complete: true,
162
+ ralplan_architect_review: { agent_role: 'architect', verdict: 'approve', summary: 'architect approved' },
163
+ ralplan_critic_review: { agent_role: 'critic', verdict: 'approve', summary: 'critic approved after architect' },
164
+ },
165
+ },
166
+ },
167
+ })), true);
168
+ });
169
+ it('canSkip honors explicit session-scoped consensus state before root state', async () => {
170
+ const plansDir = join(tempDir, '.omx', 'plans');
171
+ const stateDir = join(tempDir, '.omx', 'state');
172
+ const sessionDir = join(stateDir, 'sessions', 'sess-explicit');
173
+ await mkdir(plansDir, { recursive: true });
174
+ await mkdir(sessionDir, { recursive: true });
175
+ await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
176
+ await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
177
+ await writeFile(join(stateDir, 'autopilot-state.json'), JSON.stringify({
178
+ state: {
179
+ handoff_artifacts: {
180
+ ralplan_architect_review: { agent_role: 'architect', verdict: 'reject', approved: true },
181
+ ralplan_critic_review: { agent_role: 'critic', verdict: 'approve' },
182
+ },
183
+ },
184
+ }));
185
+ await writeFile(join(sessionDir, 'autopilot-state.json'), JSON.stringify({
186
+ state: {
187
+ handoff_artifacts: {
188
+ ralplan_architect_review: { agent_role: 'architect', verdict: 'approve' },
189
+ ralplan_critic_review: { agent_role: 'critic', verdict: 'approve' },
190
+ },
191
+ },
192
+ }));
193
+ const stage = createRalplanStage();
194
+ assert.equal(stage.canSkip(makeCtx({ sessionId: 'sess-explicit' })), true);
195
+ });
196
+ it('canSkip fails closed when explicit session state is missing despite root consensus', async () => {
197
+ const plansDir = join(tempDir, '.omx', 'plans');
198
+ const stateDir = join(tempDir, '.omx', 'state');
199
+ await mkdir(plansDir, { recursive: true });
200
+ await mkdir(stateDir, { recursive: true });
201
+ await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
202
+ await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
203
+ await writeFile(join(stateDir, 'autopilot-state.json'), JSON.stringify({
204
+ state: {
205
+ handoff_artifacts: {
206
+ ralplan_architect_review: { agent_role: 'architect', verdict: 'approve' },
207
+ ralplan_critic_review: { agent_role: 'critic', verdict: 'approve' },
208
+ },
209
+ },
210
+ }));
211
+ const stage = createRalplanStage();
212
+ assert.equal(stage.canSkip(makeCtx({ sessionId: 'sess-missing' })), false);
213
+ });
214
+ it('canSkip fails closed for malformed explicit session ids instead of falling back to root consensus', async () => {
215
+ const plansDir = join(tempDir, '.omx', 'plans');
216
+ const stateDir = join(tempDir, '.omx', 'state');
217
+ await mkdir(plansDir, { recursive: true });
218
+ await mkdir(stateDir, { recursive: true });
219
+ await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
220
+ await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
221
+ await writeFile(join(stateDir, 'ralplan-state.json'), JSON.stringify({
222
+ ralplanConsensusGate: {
223
+ complete: true,
224
+ sequence: ['architect-review', 'critic-review'],
225
+ ralplan_architect_review: { agent_role: 'architect', verdict: 'approve' },
226
+ ralplan_critic_review: { agent_role: 'critic', verdict: 'approve' },
227
+ },
228
+ }));
229
+ const stage = createRalplanStage();
230
+ for (const sessionId of ['../bad', 'a'.repeat(65), '']) {
231
+ assert.equal(stage.canSkip(makeCtx({ sessionId })), false);
232
+ }
233
+ });
234
+ it('canSkip rejects blocker aliases even with approval-shaped booleans', async () => {
235
+ const plansDir = join(tempDir, '.omx', 'plans');
236
+ await mkdir(plansDir, { recursive: true });
237
+ await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
238
+ await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
239
+ const stage = createRalplanStage();
240
+ for (const blocker of [
241
+ { blocking: true },
242
+ { request_changes: true },
243
+ { requestChanges: true },
244
+ { status: 'request changes' },
245
+ { recommendation: 'changes-requested' },
246
+ ]) {
247
+ assert.equal(stage.canSkip(makeCtx({
248
+ artifacts: {
249
+ ralplan: {
250
+ ralplanConsensusGate: {
251
+ complete: true,
252
+ ralplan_architect_review: { agent_role: 'architect', verdict: 'approve' },
253
+ ralplan_critic_review: { agent_role: 'critic', approved: true, clean: true, ...blocker },
254
+ },
255
+ },
256
+ },
257
+ })), false);
258
+ }
259
+ });
260
+ it('canSkip returns false when Critic evidence is recorded before Architect evidence', async () => {
261
+ const plansDir = join(tempDir, '.omx', 'plans');
262
+ await mkdir(plansDir, { recursive: true });
263
+ await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
264
+ await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
265
+ const stage = createRalplanStage();
266
+ assert.equal(stage.canSkip(makeCtx({
267
+ artifacts: {
268
+ ralplan: {
269
+ ralplanConsensusGate: {
270
+ complete: true,
271
+ sequence: ['critic-review', 'architect-review'],
272
+ ralplan_architect_review: { agent_role: 'architect', verdict: 'approve' },
273
+ ralplan_critic_review: { agent_role: 'critic', verdict: 'approve' },
274
+ },
275
+ },
276
+ },
277
+ })), false);
278
+ });
279
+ it('canSkip returns false when Critic timestamp predates Architect timestamp', async () => {
280
+ const plansDir = join(tempDir, '.omx', 'plans');
281
+ await mkdir(plansDir, { recursive: true });
282
+ await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
283
+ await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
284
+ const stage = createRalplanStage();
285
+ assert.equal(stage.canSkip(makeCtx({
286
+ artifacts: {
287
+ ralplan: {
288
+ ralplanConsensusGate: {
289
+ complete: true,
290
+ sequence: ['architect-review', 'critic-review'],
291
+ ralplan_architect_review: {
292
+ agent_role: 'architect',
293
+ verdict: 'approve',
294
+ completed_at: '2026-05-21T10:05:00.000Z',
295
+ },
296
+ ralplan_critic_review: {
297
+ agent_role: 'critic',
298
+ verdict: 'approve',
299
+ completed_at: '2026-05-21T10:00:00.000Z',
300
+ },
301
+ },
302
+ },
303
+ },
304
+ })), false);
305
+ });
306
+ it('canSkip ignores ambient OMX_ROOT consensus state for local PRD/test-spec-only artifacts', async () => {
307
+ const ambientRoot = await mkdtemp(join(tmpdir(), 'omx-ralplan-ambient-'));
308
+ const previousOmxRoot = process.env.OMX_ROOT;
309
+ try {
310
+ const plansDir = join(tempDir, '.omx', 'plans');
311
+ await mkdir(plansDir, { recursive: true });
312
+ await writeFile(join(plansDir, 'prd-local.md'), '# Plan\n');
313
+ await writeFile(join(plansDir, 'test-spec-local.md'), '# Test Spec\n');
314
+ const ambientStateDir = join(ambientRoot, '.omx', 'state');
315
+ await mkdir(ambientStateDir, { recursive: true });
316
+ await writeFile(join(ambientStateDir, 'ralplan-state.json'), JSON.stringify({
317
+ current_phase: 'complete',
318
+ planning_complete: true,
319
+ ralplan_consensus_gate: {
320
+ complete: true,
321
+ ralplan_architect_review: { agent_role: 'architect', verdict: 'approve', iteration: 1 },
322
+ ralplan_critic_review: { agent_role: 'critic', verdict: 'approve', iteration: 1 },
323
+ },
324
+ }));
325
+ process.env.OMX_ROOT = ambientRoot;
326
+ const stage = createRalplanStage();
327
+ assert.equal(stage.canSkip(makeCtx()), false);
328
+ }
329
+ finally {
330
+ if (previousOmxRoot === undefined)
331
+ delete process.env.OMX_ROOT;
332
+ else
333
+ process.env.OMX_ROOT = previousOmxRoot;
334
+ await rm(ambientRoot, { recursive: true, force: true });
335
+ }
336
+ });
337
+ it('canSkip returns false for rejected consensus objects with approval-shaped booleans', async () => {
122
338
  const plansDir = join(tempDir, '.omx', 'plans');
123
339
  await mkdir(plansDir, { recursive: true });
124
340
  await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
125
341
  await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
126
342
  const stage = createRalplanStage();
127
- assert.equal(stage.canSkip(makeCtx()), true);
343
+ assert.equal(stage.canSkip(makeCtx({
344
+ artifacts: {
345
+ ralplan: {
346
+ ralplanConsensusGate: {
347
+ complete: true,
348
+ ralplan_architect_review: {
349
+ agent_role: 'architect',
350
+ verdict: 'reject',
351
+ approved: true,
352
+ clean: true,
353
+ },
354
+ ralplan_critic_review: {
355
+ agent_role: 'critic',
356
+ verdict: 'approve',
357
+ approved: true,
358
+ clean: true,
359
+ },
360
+ },
361
+ },
362
+ },
363
+ })), false);
364
+ });
365
+ it('canSkip returns false when consensus-shaped reviews do not record agent roles', async () => {
366
+ const plansDir = join(tempDir, '.omx', 'plans');
367
+ await mkdir(plansDir, { recursive: true });
368
+ await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
369
+ await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
370
+ const stage = createRalplanStage();
371
+ assert.equal(stage.canSkip(makeCtx({
372
+ artifacts: {
373
+ ralplan: {
374
+ ralplanConsensusGate: {
375
+ complete: true,
376
+ ralplan_architect_review: { verdict: 'approve', summary: 'role missing' },
377
+ ralplan_critic_review: { verdict: 'approve', summary: 'role missing' },
378
+ },
379
+ },
380
+ },
381
+ })), false);
382
+ });
383
+ it('canSkip returns false when review history entries do not record agent roles', async () => {
384
+ const plansDir = join(tempDir, '.omx', 'plans');
385
+ await mkdir(plansDir, { recursive: true });
386
+ await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
387
+ await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
388
+ const stage = createRalplanStage();
389
+ assert.equal(stage.canSkip(makeCtx({
390
+ artifacts: {
391
+ ralplan: {
392
+ review_history: [{
393
+ architect_review: { verdict: 'approve', summary: 'role missing' },
394
+ critic_review: { verdict: 'approve', summary: 'role missing' },
395
+ }],
396
+ },
397
+ },
398
+ })), false);
399
+ });
400
+ it('canSkip returns false when review arrays do not record agent roles', async () => {
401
+ const plansDir = join(tempDir, '.omx', 'plans');
402
+ await mkdir(plansDir, { recursive: true });
403
+ await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
404
+ await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
405
+ const stage = createRalplanStage();
406
+ assert.equal(stage.canSkip(makeCtx({
407
+ artifacts: {
408
+ ralplan: {
409
+ architectReviews: [{ verdict: 'approve', summary: 'role missing' }],
410
+ criticReviews: [{ verdict: 'approve', summary: 'role missing' }],
411
+ },
412
+ },
413
+ })), false);
414
+ });
415
+ it('canSkip returns false when local state only has latest verdict fields', async () => {
416
+ const plansDir = join(tempDir, '.omx', 'plans');
417
+ const stateDir = join(tempDir, '.omx', 'state');
418
+ await mkdir(plansDir, { recursive: true });
419
+ await mkdir(stateDir, { recursive: true });
420
+ await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
421
+ await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
422
+ await writeFile(join(stateDir, 'ralplan-state.json'), JSON.stringify({
423
+ current_phase: 'complete',
424
+ planning_complete: true,
425
+ latest_architect_verdict: 'approve',
426
+ latest_critic_verdict: 'approve',
427
+ }));
428
+ const stage = createRalplanStage();
429
+ assert.equal(stage.canSkip(makeCtx()), false);
430
+ });
431
+ it('canSkip returns false when Architect and Critic roles are swapped', async () => {
432
+ const plansDir = join(tempDir, '.omx', 'plans');
433
+ await mkdir(plansDir, { recursive: true });
434
+ await writeFile(join(plansDir, 'prd-my-feature.md'), '# Plan\n');
435
+ await writeFile(join(plansDir, 'test-spec-my-feature.md'), '# Test Spec\n');
436
+ const stage = createRalplanStage();
437
+ assert.equal(stage.canSkip(makeCtx({
438
+ artifacts: {
439
+ ralplan: {
440
+ ralplanConsensusGate: {
441
+ complete: true,
442
+ ralplan_architect_review: { agent_role: 'critic', verdict: 'approve' },
443
+ ralplan_critic_review: { agent_role: 'architect', verdict: 'approve' },
444
+ },
445
+ },
446
+ },
447
+ })), false);
128
448
  });
129
449
  it('canSkip returns false after non-clean code-review loopback even when plans exist', async () => {
130
450
  const plansDir = join(tempDir, '.omx', 'plans');
@@ -186,11 +506,100 @@ describe('RALPLAN Stage', () => {
186
506
  const result = await stage.run(makeCtx({ task: 'live ralplan run' }));
187
507
  const artifacts = result.artifacts;
188
508
  assert.equal(result.status, 'completed');
509
+ assert.equal(result.error, undefined);
189
510
  assert.equal(artifacts.runtime, true);
190
511
  assert.equal(artifacts.planningComplete, true);
512
+ assert.deepEqual(artifacts.ralplanConsensusGate, {
513
+ complete: true,
514
+ sequence: ['architect-review', 'critic-review'],
515
+ ralplan_architect_review: { agent_role: 'architect', iteration: 1, verdict: 'approve', summary: 'architect ok' },
516
+ ralplan_critic_review: { agent_role: 'critic', iteration: 1, verdict: 'approve', summary: 'critic ok' },
517
+ source: 'runtime-result',
518
+ blockedReason: null,
519
+ });
191
520
  assert.equal(artifacts.iteration, 1);
192
521
  assert.equal(artifacts.runtimeDrafted, true);
193
522
  });
523
+ it('fails runtime handoff when consensus approves but test spec does not match selected PRD', async () => {
524
+ const stage = createRalplanStage({
525
+ executor: {
526
+ async draft() {
527
+ const plansDir = join(tempDir, '.omx', 'plans');
528
+ await mkdir(plansDir, { recursive: true });
529
+ const prdPath = join(plansDir, 'prd-new.md');
530
+ await writeFile(prdPath, '# New runtime plan\n');
531
+ await writeFile(join(plansDir, 'test-spec-old.md'), '# Stale runtime tests\n');
532
+ return { summary: 'drafted mismatched artifacts', planPath: prdPath };
533
+ },
534
+ async architectReview() {
535
+ return { verdict: 'approve', summary: 'architect ok' };
536
+ },
537
+ async criticReview() {
538
+ return { verdict: 'approve', summary: 'critic ok' };
539
+ },
540
+ },
541
+ });
542
+ const result = await stage.run(makeCtx({ task: 'live ralplan mismatched artifacts' }));
543
+ const artifacts = result.artifacts;
544
+ assert.equal(result.status, 'failed');
545
+ assert.equal(result.error, 'ralplan_planning_artifacts_missing_after_consensus');
546
+ assert.equal(artifacts.planningComplete, false);
547
+ assert.equal(artifacts.ralplanConsensusGate.complete, true);
548
+ });
549
+ it('fails runtime handoff when consensus approves but required planning artifacts are missing', async () => {
550
+ const stage = createRalplanStage({
551
+ executor: {
552
+ async draft() {
553
+ return { summary: 'draft without files' };
554
+ },
555
+ async architectReview() {
556
+ return { verdict: 'approve', summary: 'architect ok' };
557
+ },
558
+ async criticReview() {
559
+ return { verdict: 'approve', summary: 'critic ok' };
560
+ },
561
+ },
562
+ });
563
+ const result = await stage.run(makeCtx({ task: 'live ralplan no artifacts' }));
564
+ const artifacts = result.artifacts;
565
+ assert.equal(result.status, 'failed');
566
+ assert.equal(result.error, 'ralplan_planning_artifacts_missing_after_consensus');
567
+ assert.equal(artifacts.planningComplete, false);
568
+ assert.equal(artifacts.ralplanConsensusGate.complete, true);
569
+ });
570
+ it('fails runtime handoff when Critic has not approved after Architect', async () => {
571
+ const stage = createRalplanStage({
572
+ executor: {
573
+ async draft() {
574
+ const plansDir = join(tempDir, '.omx', 'plans');
575
+ await mkdir(plansDir, { recursive: true });
576
+ const prdPath = join(plansDir, 'prd-runtime.md');
577
+ await writeFile(prdPath, '# Runtime Plan\n');
578
+ await writeFile(join(plansDir, 'test-spec-runtime.md'), '# Runtime Tests\n');
579
+ return { summary: 'drafted', planPath: prdPath };
580
+ },
581
+ async architectReview() {
582
+ return { verdict: 'approve', summary: 'architect ok' };
583
+ },
584
+ async criticReview() {
585
+ return { verdict: 'iterate', summary: 'critic needs changes' };
586
+ },
587
+ },
588
+ maxIterations: 1,
589
+ });
590
+ const result = await stage.run(makeCtx({ task: 'live ralplan run' }));
591
+ const artifacts = result.artifacts;
592
+ assert.equal(result.status, 'failed');
593
+ assert.equal(result.error, 'ralplan_consensus_not_reached_after_1_iterations');
594
+ assert.deepEqual(artifacts.ralplanConsensusGate, {
595
+ complete: false,
596
+ sequence: ['architect-review', 'critic-review'],
597
+ ralplan_architect_review: null,
598
+ ralplan_critic_review: null,
599
+ source: null,
600
+ blockedReason: 'missing_sequential_architect_then_critic_approval',
601
+ });
602
+ });
194
603
  it('canSkip returns false for non-prd plan files', async () => {
195
604
  const plansDir = join(tempDir, '.omx', 'plans');
196
605
  await mkdir(plansDir, { recursive: true });
@@ -1000,13 +1409,13 @@ describe('Ralph Verify Stage', () => {
1000
1409
  // ---------------------------------------------------------------------------
1001
1410
  // Strict Autopilot stage tests
1002
1411
  // ---------------------------------------------------------------------------
1003
- describe('Strict Autopilot Ralph Stage', () => {
1412
+ describe('Explicit Legacy Ralph Stage', () => {
1004
1413
  beforeEach(async () => { await setup(); });
1005
1414
  afterEach(async () => { await cleanup(); });
1006
- it('uses the strict phase name ralph', () => {
1415
+ it('uses the explicit legacy phase name ralph', () => {
1007
1416
  assert.equal(createRalphStage().name, 'ralph');
1008
1417
  });
1009
- it('uses ralplan artifacts as the primary strict ralph execution input', async () => {
1418
+ it('uses ralplan artifacts as the primary explicit legacy Ralph execution input', async () => {
1010
1419
  const result = await createRalphStage().run(makeCtx({
1011
1420
  artifacts: {
1012
1421
  ralplan: { plan: 'approved plan' },
@@ -1017,14 +1426,56 @@ describe('Strict Autopilot Ralph Stage', () => {
1017
1426
  assert.deepEqual(descriptor.executionArtifacts, { plan: 'approved plan' });
1018
1427
  });
1019
1428
  });
1429
+ describe('Default Autopilot Ultragoal Stage Adapters', () => {
1430
+ beforeEach(async () => { await setup(); });
1431
+ afterEach(async () => { await cleanup(); });
1432
+ it('creates a deep-interview descriptor and instruction', async () => {
1433
+ const stage = createDeepInterviewStage();
1434
+ assert.equal(stage.name, 'deep-interview');
1435
+ const result = await stage.run(makeCtx());
1436
+ const artifacts = result.artifacts;
1437
+ assert.equal(artifacts.stage, 'deep-interview');
1438
+ assert.match(artifacts.instruction, /^\$deep-interview /);
1439
+ assert.match(buildDeepInterviewInstruction('clarify me'), /^\$deep-interview /);
1440
+ });
1441
+ it('creates an ultragoal descriptor with explicit team condition', async () => {
1442
+ const stage = createUltragoalStage();
1443
+ assert.equal(stage.name, 'ultragoal');
1444
+ const result = await stage.run(makeCtx({ artifacts: { ralplan: { plan: 'approved' } } }));
1445
+ const artifacts = result.artifacts;
1446
+ const descriptor = artifacts.ultragoalDescriptor;
1447
+ assert.equal(artifacts.stage, 'ultragoal');
1448
+ assert.deepEqual(descriptor.ralplanArtifacts, { plan: 'approved' });
1449
+ assert.match(artifacts.team_condition, /Launch \$team only inside an active Ultragoal story/);
1450
+ assert.match(buildUltragoalInstruction('execute me'), /^\$ultragoal /);
1451
+ });
1452
+ it('creates an ultraqa gate that fails closed without evidence and can record clean skips', async () => {
1453
+ const missingEvidence = await createUltraqaStage().run(makeCtx({
1454
+ artifacts: { ultragoal: { tests: 'passed' }, 'code-review': { review_verdict: { clean: true } } },
1455
+ }));
1456
+ const missingArtifacts = missingEvidence.artifacts;
1457
+ const missingVerdict = missingArtifacts.qa_verdict;
1458
+ assert.equal(missingVerdict.clean, false);
1459
+ assert.equal(missingArtifacts.return_to_ralplan_reason, 'UltraQA evidence missing; fail closed and return to ralplan.');
1460
+ const skipped = await createUltraqaStage({ skipped: true, summary: 'Docs-only change; QA not applicable.' }).run(makeCtx());
1461
+ const skippedArtifacts = skipped.artifacts;
1462
+ const skippedVerdict = skippedArtifacts.qa_verdict;
1463
+ assert.equal(skippedVerdict.clean, true);
1464
+ assert.equal(skippedVerdict.skipped, true);
1465
+ assert.equal(skippedArtifacts.return_to_ralplan_reason, null);
1466
+ assert.match(buildUltraqaInstruction('qa me'), /^\$ultraqa /);
1467
+ });
1468
+ });
1020
1469
  describe('Code Review Stage', () => {
1021
1470
  beforeEach(async () => { await setup(); });
1022
1471
  afterEach(async () => { await cleanup(); });
1023
- it('creates a strict code-review stage that fails closed without review evidence', async () => {
1472
+ it('creates a code-review stage that fails closed without review evidence', async () => {
1024
1473
  const stage = createCodeReviewStage();
1025
1474
  assert.equal(stage.name, 'code-review');
1026
- const result = await stage.run(makeCtx({ artifacts: { ralph: { tests: 'passed' } } }));
1475
+ const result = await stage.run(makeCtx({ artifacts: { ultragoal: { tests: 'passed' } } }));
1027
1476
  const artifacts = result.artifacts;
1477
+ const descriptor = artifacts.codeReviewDescriptor;
1478
+ assert.deepEqual(descriptor.executionArtifacts, { tests: 'passed' });
1028
1479
  const verdict = artifacts.review_verdict;
1029
1480
  assert.equal(result.status, 'completed');
1030
1481
  assert.equal(verdict.clean, false);