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,12 +1,14 @@
1
1
  import { describe, it, mock } from 'node:test';
2
+ import { getRemovedSkillInfo } from '../sunset-stub.js';
2
3
  import assert from 'node:assert/strict';
3
4
  import { existsSync } from 'node:fs';
4
5
  import { mkdtemp, mkdir, readFile, rm, symlink, writeFile } from 'node:fs/promises';
5
6
  import { tmpdir } from 'node:os';
6
7
  import { join } from 'node:path';
7
8
  import { detectKeywords, detectPrimaryKeyword, classifyKeywordInput, KEYWORD_INERT_DIAGNOSTIC_ORDER, recordSkillActivation, DEEP_INTERVIEW_STATE_FILE, DEEP_INTERVIEW_BLOCKED_APPROVAL_INPUTS, DEEP_INTERVIEW_INPUT_LOCK_MESSAGE, persistDeepInterviewModeState, } from '../keyword-detector.js';
8
- import { SKILL_ACTIVE_STATE_FILE } from '../../state/skill-active.js';
9
- import { isUnderspecifiedForExecution, applyRalplanGate } from '../keyword-detector.js';
9
+ import { readSkillActiveState, SKILL_ACTIVE_STATE_FILE } from '../../state/skill-active.js';
10
+ import { neutralizeOwnedRoutingRalplan } from '../../ralplan/documented-leader-preflight.js';
11
+ import { readActiveWorkflowModes } from '../../state/workflow-transition.js';
10
12
  import { EXPLICIT_SKILL_ALIASES, getExplicitSkillDefinition, KEYWORD_TRIGGER_DEFINITIONS, } from '../keyword-registry.js';
11
13
  import { evaluateResolvedPromptTurn } from '../prompt-session-provenance.js';
12
14
  async function withIsolatedHome(prefix, run) {
@@ -101,24 +103,23 @@ describe('keyword detector team compatibility', () => {
101
103
  assert.equal(matches[0]?.keyword, '$oh-my-codex:ralplan');
102
104
  });
103
105
  it('supports mixed-form explicit multi-skill invocation ordering and dedupe', () => {
104
- const matches = detectKeywords('$oh-my-codex:ralplan $ralph $oh-my-codex:ralplan ship this');
105
- assert.deepEqual(matches.map((m) => m.skill), ['ralplan', 'ralph']);
106
- assert.deepEqual(matches.map((m) => m.keyword), ['$oh-my-codex:ralplan', '$ralph']);
106
+ const matches = detectKeywords('$oh-my-codex:ralplan $ultragoal $oh-my-codex:ralplan ship this');
107
+ assert.deepEqual(matches.map((m) => m.skill), ['ralplan', 'ultragoal']);
108
+ assert.deepEqual(matches.map((m) => m.keyword), ['$oh-my-codex:ralplan', '$ultragoal']);
107
109
  });
108
110
  it('keeps recognized tokens on both sides of an unknown plugin-prefixed token in the same contiguous block', () => {
109
- const matches = detectKeywords('$oh-my-codex:ralplan $oh-my-codex:unknown $ralph');
110
- assert.deepEqual(matches.map((m) => m.skill), ['ralplan', 'ralph']);
111
- assert.deepEqual(matches.map((m) => m.keyword), ['$oh-my-codex:ralplan', '$ralph']);
111
+ const matches = detectKeywords('$oh-my-codex:ralplan $oh-my-codex:unknown $ultragoal');
112
+ assert.deepEqual(matches.map((m) => m.skill), ['ralplan', 'ultragoal']);
113
+ assert.deepEqual(matches.map((m) => m.keyword), ['$oh-my-codex:ralplan', '$ultragoal']);
112
114
  });
113
115
  it('limits mixed-form explicit invocation to the first contiguous block', () => {
114
116
  const matches = detectKeywords('$oh-my-codex:ralplan text $ralph');
115
117
  assert.deepEqual(matches.map((m) => m.skill), ['ralplan']);
116
118
  });
117
- it('normalizes plugin-prefixed ulw shorthand token', () => {
118
- const ulw = detectPrimaryKeyword('$oh-my-codex:ulw continue');
119
- assert.ok(ulw);
120
- assert.equal(ulw.skill, 'ultrawork');
121
- assert.equal(ulw.keyword, '$oh-my-codex:ulw');
119
+ it('does not route the plugin-prefixed ulw shorthand at a sunset skill', () => {
120
+ // ulw was shorthand for ultrawork, which is now a sunset skill with no trigger. The plugin prefix
121
+ // must not resurrect that route.
122
+ assert.equal(detectPrimaryKeyword('$oh-my-codex:ulw continue'), null);
122
123
  });
123
124
  it('supports plugin-prefixed hyphenated workflow tokens', () => {
124
125
  const deepInterview = detectPrimaryKeyword('$oh-my-codex:deep-interview gather requirements');
@@ -252,11 +253,15 @@ describe('keyword detector team compatibility', () => {
252
253
  const match = detectPrimaryKeyword('why does ralph keep blocking stop?');
253
254
  assert.equal(match, null);
254
255
  });
255
- it('still triggers ralph for explicit $ralph invocation', () => {
256
- const match = detectPrimaryKeyword('$ralph continue verification');
257
- assert.ok(match);
258
- assert.equal(match.skill, 'ralph');
259
- assert.equal(match.keyword.toLowerCase(), '$ralph');
256
+ it('does not activate a workflow for the sunset $ralph token', () => {
257
+ // Approved decision: $ralph is a sunset skill token, so it must produce a non-activating
258
+ // diagnostic rather than mutating workflow state. The `omx ralph` CLI and the ralph persistence
259
+ // runtime are separate entry points and stay live - only the keyword surface is retired.
260
+ assert.equal(detectPrimaryKeyword('$ralph continue verification'), null);
261
+ const info = getRemovedSkillInfo('ralph');
262
+ assert.ok(info, '$ralph must be declared as a removed skill so the diagnostic path fires');
263
+ assert.equal(info.replacement, '$ultragoal');
264
+ assert.match(info.message, /removed/i);
260
265
  });
261
266
  it('prefers ralplan over ralph follow-up language when both implicit routes are present', () => {
262
267
  const match = detectPrimaryKeyword('keep going but do consensus plan first');
@@ -356,16 +361,16 @@ describe('keyword detector team compatibility', () => {
356
361
  assert.equal(detectPrimaryKeyword('PASS runs assertions in parallel when sharding is enabled'), null);
357
362
  assert.equal(detectPrimaryKeyword('running 8 tests in parallel across 4 workers'), null);
358
363
  });
359
- it('normalizes the Korean keyboard typo for ulw to ultrawork only', () => {
360
- const match = detectPrimaryKeyword('ㅕㅣㅈ로 이 작업 처리해줘');
361
- assert.ok(match);
362
- assert.equal(match.skill, 'ultrawork');
363
- assert.equal(match.keyword, 'ulw');
364
- const explicitMatch = detectPrimaryKeyword('$ㅕㅣㅈ로 이 작업 처리해줘');
365
- assert.ok(explicitMatch);
366
- assert.equal(explicitMatch.skill, 'ultrawork');
367
- assert.equal(explicitMatch.keyword, '$ulw');
368
- assert.equal(detectPrimaryKeyword('ㅁㅔㅔ로 처리해줘'), null);
364
+ it('no longer routes the Korean ulw keyboard typo, whose only target is a sunset skill', () => {
365
+ // The IME typo alias existed solely to reach ultrawork's `ulw` shorthand. ultrawork is now a
366
+ // sunset skill with no trigger, so normalizing the typo would route a user at a token the catalog
367
+ // no longer ships. The four cases that pinned that routing are replaced by this one, which pins
368
+ // the retirement instead; the normalizer seam is kept for a future LIVE shorthand.
369
+ assert.equal(detectPrimaryKeyword('ㅕㅣㅈ로 이 작업 처리해줘'), null);
370
+ assert.equal(detectPrimaryKeyword('$ㅕㅣㅈ로 이 작업 처리해줘'), null);
371
+ const info = getRemovedSkillInfo('ultrawork');
372
+ assert.ok(info, '$ultrawork must be declared as a removed skill');
373
+ assert.equal(info.replacement, '$team');
369
374
  });
370
375
  });
371
376
  describe('keyword input classification direct grammar', () => {
@@ -373,11 +378,9 @@ describe('keyword input classification direct grammar', () => {
373
378
  const cases = [
374
379
  { text: '$ralplan implement this', skills: ['ralplan'], keywords: ['$ralplan'], priorities: [11] },
375
380
  { text: '\u00a0$RALPLAN implement this', skills: ['ralplan'], keywords: ['$RALPLAN'], priorities: [11] },
376
- { text: '- $team $ralph ship this', skills: ['team', 'ralph'], keywords: ['$team', '$ralph'], priorities: [8, 9] },
381
+ { text: '- $team $ultragoal ship this', skills: ['team', 'ultragoal'], keywords: ['$team', '$ultragoal'], priorities: [8, 10] },
377
382
  { text: '12) $oh-my-codex:ralplan build this', skills: ['ralplan'], keywords: ['$oh-my-codex:ralplan'], priorities: [11] },
378
- { text: '$ulw $frontend-ui-ux build this', skills: ['ultrawork', 'design'], keywords: ['$ulw', '$frontend-ui-ux'], priorities: [10, 6] },
379
- { text: '$ralplan $unknown $ralplan $ralph ship this', skills: ['ralplan', 'ralph'], keywords: ['$ralplan', '$ralph'], priorities: [11, 9] },
380
- { text: '$ㅕㅣㅈ 병렬 작업', skills: ['ultrawork'], keywords: ['$ulw'], priorities: [10] },
383
+ { text: '$ralplan $unknown $ralplan $ultragoal ship this', skills: ['ralplan', 'ultragoal'], keywords: ['$ralplan', '$ultragoal'], priorities: [11, 10] },
381
384
  { text: 'use $ralplan plan this', skills: ['ralplan'], keywords: ['$ralplan'], priorities: [11] },
382
385
  { text: 'please use $ralplan plan this', skills: ['ralplan'], keywords: ['$ralplan'], priorities: [11] },
383
386
  { text: 'run $ralplan plan this', skills: ['ralplan'], keywords: ['$ralplan'], priorities: [11] },
@@ -389,8 +392,8 @@ describe('keyword input classification direct grammar', () => {
389
392
  { text: 'start $deep-interview', skills: ['deep-interview'], keywords: ['$deep-interview'], priorities: [8] },
390
393
  { text: 'enable $ultragoal', skills: ['ultragoal'], keywords: ['$ultragoal'], priorities: [10] },
391
394
  { text: 'launch $autopilot', skills: ['autopilot'], keywords: ['$autopilot'], priorities: [10] },
392
- { text: 'invoke $ralph', skills: ['ralph'], keywords: ['$ralph'], priorities: [9] },
393
- { text: 'activate $ultrawork', skills: ['ultrawork'], keywords: ['$ultrawork'], priorities: [10] },
395
+ { text: 'invoke $ultragoal', skills: ['ultragoal'], keywords: ['$ultragoal'], priorities: [10] },
396
+ { text: 'activate $team', skills: ['team'], keywords: ['$team'], priorities: [8] },
394
397
  { text: 'resume $team', skills: ['team'], keywords: ['$team'], priorities: [8] },
395
398
  { text: 'continue $code-review', skills: ['code-review'], keywords: ['$code-review'], priorities: [6] },
396
399
  ];
@@ -790,10 +793,10 @@ describe('keyword input classification direct grammar', () => {
790
793
  });
791
794
  it('accepts only direct punctuation and list boundaries', () => {
792
795
  const cases = [
793
- { text: '* $ralph', skills: ['ralph'] },
796
+ { text: '* $ultragoal', skills: ['ultragoal'] },
794
797
  { text: '+ $team', skills: ['team'] },
795
798
  { text: '1. $ralplan', skills: ['ralplan'] },
796
- { text: '999) $ultrawork', skills: ['ultrawork'] },
799
+ { text: '999) $team', skills: ['team'] },
797
800
  { text: '($ralplan)', skills: [] },
798
801
  { text: '[$ralplan]', skills: [] },
799
802
  { text: '1,$ralplan', skills: [] },
@@ -937,7 +940,7 @@ describe('keyword input classification direct grammar', () => {
937
940
  { text: '- /prompts:architect is the prompt command documentation\n$ralplan plan it', skills: ['ralplan'] },
938
941
  { text: '- $ralplan, $autopilot are workflow commands\n$team execute it', skills: ['team'] },
939
942
  { text: '- $ralplan and $autopilot are workflow commands\n$team execute it', skills: ['team'] },
940
- { text: '- $ralplan, $autopilot, and $team are workflow commands\n$ralph execute it', skills: ['ralph'] },
943
+ { text: '- $ralplan, $autopilot, and $team are workflow commands\n$ultragoal execute it', skills: ['ultragoal'] },
941
944
  { text: '- $ralplan / $autopilot are workflow commands\n$team execute it', skills: ['team'] },
942
945
  { text: '- $ralplan/$autopilot are workflow commands\n$team execute it', skills: ['team'] },
943
946
  { text: 'use $ralplan is the consensus-planning command\n$autopilot build it', skills: ['autopilot'] },
@@ -964,7 +967,7 @@ describe('keyword input classification direct grammar', () => {
964
967
  { text: 'For instance: manual mode is slower。 Use autopilot mode.', skills: ['autopilot'] },
965
968
  { text: 'use $ralplan is the workflow command; autopilot mode is its alias; $team execute it', skills: ['team'] },
966
969
  { text: 'use $ralplan is the workflow command; autopilot mode is documented in the guide; $team execute it', skills: ['team'] },
967
- { text: 'use $ralplan is the workflow command; autopilot mode is workflow documentation; use $ralph execute it', skills: ['ralph'] },
970
+ { text: 'use $ralplan is the workflow command; autopilot mode is workflow documentation; use $ultragoal execute it', skills: ['ultragoal'] },
968
971
  { text: `use $ralplan is the workflow command; use${' '.repeat(161)}$autopilot build it`, skills: ['autopilot'] },
969
972
  { text: 'use $ralplan is the consensus-planning command! run $autopilot', skills: ['autopilot'] },
970
973
  { text: 'use $ralplan is the consensus-planning command? run $autopilot', skills: ['autopilot'] },
@@ -1093,7 +1096,9 @@ describe('keyword input classification direct grammar', () => {
1093
1096
  for (const testCase of [
1094
1097
  { text: 'Use autopilot mode.', skills: ['autopilot'] },
1095
1098
  { text: 'List files and use autopilot mode.', skills: ['autopilot'] },
1096
- { text: "No, don't stop.", skills: ['ralph'] },
1099
+ // "don't stop" was an implicit ralph trigger. Ralph's keyword surface is retired, so the phrase
1100
+ // must no longer activate any workflow - a bare English phrase should never start one.
1101
+ { text: "No, don't stop.", skills: [] },
1097
1102
  { text: 'Do not use deep interview, but use autopilot mode.', skills: ['autopilot'] },
1098
1103
  { text: 'Do not use deep interview but use autopilot mode.', skills: ['autopilot'] },
1099
1104
  { text: 'Do not use deep interview but instead use autopilot mode.', skills: ['autopilot'] },
@@ -1377,12 +1382,12 @@ describe('keyword input classification direct grammar', () => {
1377
1382
  ],
1378
1383
  },
1379
1384
  {
1380
- text: '$ultrawork $ulw',
1385
+ // $ulw is retired, so it is no longer a candidate at all; $team alone carries the block.
1386
+ text: '$team ship this',
1381
1387
  reservedInput: null,
1382
- skills: ['ultrawork'],
1388
+ skills: ['team'],
1383
1389
  candidates: [
1384
- { rawKeyword: '$ultrawork', reasons: [] },
1385
- { rawKeyword: '$ulw', reasons: [] },
1390
+ { rawKeyword: '$team', reasons: [] },
1386
1391
  ],
1387
1392
  },
1388
1393
  {
@@ -1659,11 +1664,12 @@ describe('explicit skill-name invocation requirement', () => {
1659
1664
  it('does not trigger ralplan from bare skill-name usage', () => {
1660
1665
  assert.equal(detectPrimaryKeyword('please do ralplan first'), null);
1661
1666
  });
1662
- it('detects explicit prometheus-strict invocation only', () => {
1663
- const match = detectPrimaryKeyword('please run $prometheus-strict before implementation');
1664
- assert.ok(match);
1665
- assert.equal(match.skill, 'prometheus-strict');
1666
- assert.equal(match.keyword.toLowerCase(), '$prometheus-strict');
1667
+ it('treats removed prometheus-strict as sunset stub', () => {
1668
+ const c = classifyKeywordInput('please run $prometheus-strict before implementation');
1669
+ assert.equal(c.matches.length, 0);
1670
+ assert.equal(c.removedMatches.length, 1);
1671
+ assert.match(c.removedMatches[0].message, /removed/i);
1672
+ assert.match(c.removedMatches[0].message, /use/i);
1667
1673
  assert.equal(detectPrimaryKeyword('please use prometheus-strict planning here'), null);
1668
1674
  });
1669
1675
  });
@@ -1685,7 +1691,6 @@ describe('keyword registry coverage', () => {
1685
1691
  assert.ok(registryKeywords.has('wiki lint'));
1686
1692
  assert.ok(registryKeywords.has('$autoresearch'));
1687
1693
  assert.ok(registryKeywords.has('$ultragoal'));
1688
- assert.ok(registryKeywords.has('$prometheus-strict'));
1689
1694
  assert.ok(registryKeywords.has('ultragoal'));
1690
1695
  assert.ok(registryKeywords.has('autopilot'));
1691
1696
  });
@@ -1794,6 +1799,54 @@ describe('keyword detector skill-active-state lifecycle', () => {
1794
1799
  await rm(root, { recursive: true, force: true });
1795
1800
  }
1796
1801
  });
1802
+ it('#3463: starts fresh native Autopilot even when receipt verification is unavailable (transition is reachable via user-authorized handoff)', async () => {
1803
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-autopilot-preflight-'));
1804
+ const stateDir = join(cwd, '.omx', 'state');
1805
+ try {
1806
+ const result = await recordSkillActivation({
1807
+ stateDir,
1808
+ sourceCwd: cwd,
1809
+ text: '$autopilot implement the task',
1810
+ sessionId: 'sess-autopilot-preflight',
1811
+ nowIso: '2026-07-23T00:00:00.000Z',
1812
+ });
1813
+ // The preflight no longer blocks; autopilot starts normally.
1814
+ assert.equal(result?.active, true);
1815
+ assert.equal(result?.skill, 'autopilot');
1816
+ }
1817
+ finally {
1818
+ await rm(cwd, { recursive: true, force: true });
1819
+ }
1820
+ });
1821
+ it('#3463: continues an active native Autopilot session when receipt verification is unavailable', async () => {
1822
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-active-autopilot-preflight-'));
1823
+ const stateDir = join(cwd, '.omx', 'state');
1824
+ const sessionId = 'sess-active-autopilot-preflight';
1825
+ const sessionDir = join(stateDir, 'sessions', sessionId);
1826
+ const statePath = join(sessionDir, SKILL_ACTIVE_STATE_FILE);
1827
+ const modePath = join(sessionDir, 'autopilot-state.json');
1828
+ const rawState = '{"version":1,"active":true,"skill":"autopilot","keyword":"$autopilot","phase":"ralplan","activated_at":"2026-07-22T00:00:00.000Z","updated_at":"2026-07-22T00:00:00.000Z","source":"keyword-detector","session_id":"sess-active-autopilot-preflight","metadata":{"preserve":true},"active_skills":[{"skill":"autopilot","active":true,"phase":"ralplan","session_id":"sess-active-autopilot-preflight"}]}\n';
1829
+ const rawMode = '{"active":true,"mode":"autopilot","current_phase":"ralplan","session_id":"sess-active-autopilot-preflight","metadata":{"preserve":true},"handoff_artifacts":{"ralplan":{"path":".omx/plans/existing.md"}}}\n';
1830
+ try {
1831
+ await mkdir(sessionDir, { recursive: true });
1832
+ await writeFile(statePath, rawState);
1833
+ await writeFile(modePath, rawMode);
1834
+ const result = await recordSkillActivation({
1835
+ stateDir,
1836
+ sourceCwd: cwd,
1837
+ text: '$autopilot continue',
1838
+ sessionId,
1839
+ nowIso: '2026-07-23T00:00:00.000Z',
1840
+ });
1841
+ // #3463: without the preflight block, the existing autopilot is
1842
+ // continued normally (no longer byte-preserved by the dead-end guard).
1843
+ assert.equal(result?.active, true);
1844
+ assert.equal(result?.phase, 'ralplan');
1845
+ }
1846
+ finally {
1847
+ await rm(cwd, { recursive: true, force: true });
1848
+ }
1849
+ });
1797
1850
  it('writes skill-active-state.json with deep-interview phase when autopilot keyword activates', async () => {
1798
1851
  const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-'));
1799
1852
  const stateDir = join(cwd, '.omx', 'state');
@@ -1852,15 +1905,6 @@ describe('keyword detector skill-active-state lifecycle', () => {
1852
1905
  },
1853
1906
  deep_interview: null,
1854
1907
  ralplan: null,
1855
- ralplan_consensus_gate: {
1856
- required: true,
1857
- sequence: ['architect-review', 'critic-review'],
1858
- planning_artifacts_are_not_consensus: true,
1859
- required_review_roles: ['architect', 'critic'],
1860
- ralplan_architect_review: null,
1861
- ralplan_critic_review: null,
1862
- complete: false,
1863
- },
1864
1908
  ultragoal: null,
1865
1909
  code_review: null,
1866
1910
  ultraqa: null,
@@ -1888,133 +1932,7 @@ describe('keyword detector skill-active-state lifecycle', () => {
1888
1932
  await rm(codexHome, { recursive: true, force: true });
1889
1933
  }
1890
1934
  });
1891
- it('does not advance the supervised child phase past an unsatisfied deep-interview gate via keyword handoff', async () => {
1892
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-supervised-gate-'));
1893
- const stateDir = join(cwd, '.omx', 'state');
1894
- try {
1895
- await mkdir(stateDir, { recursive: true });
1896
- // Activate Autopilot: seeds autopilot-state.json at current_phase=deep-interview
1897
- // with deep_interview_gate.status="required" (gate not satisfied).
1898
- const activated = await recordSkillActivation({
1899
- stateDir,
1900
- text: 'please run $autopilot',
1901
- sessionId: 'sess-gate',
1902
- threadId: 'thread-gate',
1903
- turnId: 'turn-1',
1904
- nowIso: '2026-02-25T00:00:00.000Z',
1905
- });
1906
- assert.equal(activated?.phase, 'deep-interview');
1907
- const autopilotStatePath = join(stateDir, 'sessions', 'sess-gate', 'autopilot-state.json');
1908
- const beforeAdvance = JSON.parse(await readFile(autopilotStatePath, 'utf-8'));
1909
- assert.equal(beforeAdvance.current_phase, 'deep-interview');
1910
- // A bare `$ralplan` keyword handoff must not advance current_phase across the
1911
- // deep-interview -> ralplan gate while the gate is unsatisfied. The keyword
1912
- // path now defers to the same gate as the state_write backend.
1913
- const denied = await recordSkillActivation({
1914
- stateDir,
1915
- text: 'continue with $ralplan',
1916
- sessionId: 'sess-gate',
1917
- threadId: 'thread-gate',
1918
- turnId: 'turn-2',
1919
- nowIso: '2026-02-25T00:01:00.000Z',
1920
- });
1921
- const afterAdvance = JSON.parse(await readFile(autopilotStatePath, 'utf-8'));
1922
- assert.equal(afterAdvance.current_phase, 'deep-interview', 'keyword handoff must not skip the deep-interview gate');
1923
- // The visible canonical skill-active state must stay aligned with the held
1924
- // detail phase (no drift to ralplan) — both the returned state and the
1925
- // persisted skill-active-state.json mirror.
1926
- assert.equal(denied?.phase, 'deep-interview');
1927
- assert.deepEqual(denied?.active_skills?.map((entry) => [entry.skill, entry.phase]), [['autopilot', 'deep-interview']]);
1928
- const canonical = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-gate', SKILL_ACTIVE_STATE_FILE), 'utf-8'));
1929
- assert.equal(canonical.phase, 'deep-interview');
1930
- assert.deepEqual(canonical.active_skills?.map((entry) => [entry.skill, entry.phase]), [['autopilot', 'deep-interview']]);
1931
- }
1932
- finally {
1933
- await rm(cwd, { recursive: true, force: true });
1934
- }
1935
- });
1936
- it('does not let a keyword jump ahead past a planning gate (forward skip)', async () => {
1937
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-skip-ahead-'));
1938
- const stateDir = join(cwd, '.omx', 'state');
1939
- try {
1940
- await mkdir(stateDir, { recursive: true });
1941
- await recordSkillActivation({
1942
- stateDir,
1943
- text: 'please run $autopilot',
1944
- sessionId: 'sess-skip',
1945
- threadId: 'thread-skip',
1946
- turnId: 'turn-1',
1947
- nowIso: '2026-02-25T00:00:00.000Z',
1948
- });
1949
- // `$ultragoal` while in deep-interview skips the ralplan gate entirely; the
1950
- // keyword handoff must hold the current phase rather than jump ahead.
1951
- const result = await recordSkillActivation({
1952
- stateDir,
1953
- text: 'jump straight to $ultragoal',
1954
- sessionId: 'sess-skip',
1955
- threadId: 'thread-skip',
1956
- turnId: 'turn-2',
1957
- nowIso: '2026-02-25T00:01:00.000Z',
1958
- });
1959
- const autopilotState = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-skip', 'autopilot-state.json'), 'utf-8'));
1960
- assert.equal(autopilotState.current_phase, 'deep-interview', 'forward skip must be held');
1961
- // skill-active phase is kept in sync with the held autopilot phase.
1962
- assert.equal(result?.phase, 'deep-interview');
1963
- }
1964
- finally {
1965
- await rm(cwd, { recursive: true, force: true });
1966
- }
1967
- });
1968
- it('does not advance or drift canonical state past an unsatisfied ralplan -> ultragoal gate', async () => {
1969
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-ralplan-gate-'));
1970
- const stateDir = join(cwd, '.omx', 'state');
1971
- const sessionId = 'sess-ralplan-gate';
1972
- try {
1973
- await mkdir(join(stateDir, 'sessions', sessionId), { recursive: true });
1974
- // Supervised Autopilot already in ralplan, with no ralplan consensus evidence
1975
- // (the ralplan -> ultragoal gate is unsatisfied).
1976
- await writeFile(join(stateDir, 'sessions', sessionId, SKILL_ACTIVE_STATE_FILE), JSON.stringify({
1977
- version: 1,
1978
- active: true,
1979
- skill: 'autopilot',
1980
- keyword: '$autopilot',
1981
- phase: 'ralplan',
1982
- source: 'keyword-detector',
1983
- session_id: sessionId,
1984
- active_skills: [{ skill: 'autopilot', phase: 'ralplan', active: true, session_id: sessionId }],
1985
- }, null, 2));
1986
- const autopilotStatePath = join(stateDir, 'sessions', sessionId, 'autopilot-state.json');
1987
- await writeFile(autopilotStatePath, JSON.stringify({ active: true, mode: 'autopilot', current_phase: 'ralplan', session_id: sessionId }, null, 2));
1988
- await writeFile(join(stateDir, 'sessions', sessionId, 'ralplan-state.json'), JSON.stringify({
1989
- active: true,
1990
- mode: 'ralplan',
1991
- current_phase: 'planning',
1992
- session_id: sessionId,
1993
- }, null, 2));
1994
- const denied = await recordSkillActivation({
1995
- stateDir,
1996
- text: 'advance to $ultragoal',
1997
- sessionId,
1998
- threadId: 'thread-ralplan-gate',
1999
- turnId: 'turn-ralplan-gate',
2000
- nowIso: '2026-02-25T00:01:00.000Z',
2001
- });
2002
- const afterAdvance = JSON.parse(await readFile(autopilotStatePath, 'utf-8'));
2003
- assert.equal(afterAdvance.current_phase, 'ralplan', 'keyword handoff must not skip the ralplan -> ultragoal gate');
2004
- assert.equal(denied?.phase, 'ralplan');
2005
- assert.deepEqual(denied?.active_skills?.map((entry) => [entry.skill, entry.phase]), [['autopilot', 'ralplan']]);
2006
- const ralplanState = JSON.parse(await readFile(join(stateDir, 'sessions', sessionId, 'ralplan-state.json'), 'utf-8'));
2007
- assert.equal(ralplanState.active, true, 'blocked gate must not auto-complete ralplan state');
2008
- assert.equal(ralplanState.current_phase, 'planning', 'blocked gate must not advance ralplan state');
2009
- const canonical = JSON.parse(await readFile(join(stateDir, 'sessions', sessionId, SKILL_ACTIVE_STATE_FILE), 'utf-8'));
2010
- assert.equal(canonical.phase, 'ralplan');
2011
- assert.deepEqual(canonical.active_skills?.map((entry) => [entry.skill, entry.phase]), [['autopilot', 'ralplan']]);
2012
- }
2013
- finally {
2014
- await rm(cwd, { recursive: true, force: true });
2015
- }
2016
- });
2017
- it('does not let an implementation-phase keyword skip the code-review gate to ultraqa', async () => {
1935
+ it('permits an implementation-phase keyword skip to ultraqa with a code-review advisory', async () => {
2018
1936
  const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-ultraqa-skip-'));
2019
1937
  const stateDir = join(cwd, '.omx', 'state');
2020
1938
  const sessionId = 'sess-ultraqa-skip';
@@ -2034,7 +1952,7 @@ describe('keyword detector skill-active-state lifecycle', () => {
2034
1952
  }, null, 2));
2035
1953
  const autopilotStatePath = join(stateDir, 'sessions', sessionId, 'autopilot-state.json');
2036
1954
  await writeFile(autopilotStatePath, JSON.stringify({ active: true, mode: 'autopilot', current_phase: 'ultragoal', session_id: sessionId }, null, 2));
2037
- const denied = await recordSkillActivation({
1955
+ const advanced = await recordSkillActivation({
2038
1956
  stateDir,
2039
1957
  text: 'run $ultraqa now',
2040
1958
  sessionId,
@@ -2043,12 +1961,18 @@ describe('keyword detector skill-active-state lifecycle', () => {
2043
1961
  nowIso: '2026-02-25T00:01:00.000Z',
2044
1962
  });
2045
1963
  const afterAdvance = JSON.parse(await readFile(autopilotStatePath, 'utf-8'));
2046
- assert.equal(afterAdvance.current_phase, 'ultragoal', 'keyword handoff must not skip the code-review gate');
2047
- assert.equal(denied?.phase, 'ultragoal');
2048
- assert.deepEqual(denied?.active_skills?.map((entry) => [entry.skill, entry.phase]), [['autopilot', 'ultragoal']]);
1964
+ assert.equal(afterAdvance.current_phase, 'ultraqa');
1965
+ assert.equal(advanced?.phase, 'ultraqa');
1966
+ const advisory = advanced?.advisory;
1967
+ assert.equal(advisory?.skippedGate, 'code-review');
1968
+ assert.ok(advisory?.missingEvidence);
1969
+ assert.equal(afterAdvance.skipped_gates?.length, 1);
1970
+ assert.equal(afterAdvance.skipped_gates?.[0]?.skippedGate, 'code-review');
1971
+ assert.ok(afterAdvance.skipped_gates?.[0]?.missingEvidence);
1972
+ assert.deepEqual(advanced?.active_skills?.map((entry) => [entry.skill, entry.phase]), [['autopilot', 'ultraqa']]);
2049
1973
  const canonical = JSON.parse(await readFile(join(stateDir, 'sessions', sessionId, SKILL_ACTIVE_STATE_FILE), 'utf-8'));
2050
- assert.equal(canonical.phase, 'ultragoal');
2051
- assert.deepEqual(canonical.active_skills?.map((entry) => [entry.skill, entry.phase]), [['autopilot', 'ultragoal']]);
1974
+ assert.equal(canonical.phase, 'ultraqa');
1975
+ assert.deepEqual(canonical.active_skills?.map((entry) => [entry.skill, entry.phase]), [['autopilot', 'ultraqa']]);
2052
1976
  }
2053
1977
  finally {
2054
1978
  await rm(cwd, { recursive: true, force: true });
@@ -2412,7 +2336,6 @@ describe('keyword detector skill-active-state lifecycle', () => {
2412
2336
  },
2413
2337
  state: {
2414
2338
  handoff_artifacts: {
2415
- ralplan_consensus_gate: { complete: false },
2416
2339
  code_review: { verdict: 'stale' },
2417
2340
  },
2418
2341
  },
@@ -2456,15 +2379,6 @@ describe('keyword detector skill-active-state lifecycle', () => {
2456
2379
  },
2457
2380
  deep_interview: null,
2458
2381
  ralplan: null,
2459
- ralplan_consensus_gate: {
2460
- required: true,
2461
- sequence: ['architect-review', 'critic-review'],
2462
- planning_artifacts_are_not_consensus: true,
2463
- required_review_roles: ['architect', 'critic'],
2464
- ralplan_architect_review: null,
2465
- ralplan_critic_review: null,
2466
- complete: false,
2467
- },
2468
2382
  ultragoal: null,
2469
2383
  code_review: null,
2470
2384
  ultraqa: null,
@@ -2539,29 +2453,29 @@ describe('keyword detector skill-active-state lifecycle', () => {
2539
2453
  });
2540
2454
  const result = await recordSkillActivation({
2541
2455
  stateDir,
2542
- text: '$ralph continue verification',
2456
+ text: '$ultragoal continue verification',
2543
2457
  sessionId: 'sess-overlap',
2544
2458
  threadId: 'thread-overlap',
2545
2459
  turnId: 'turn-2',
2546
2460
  nowIso: '2026-02-26T00:05:00.000Z',
2547
2461
  });
2548
2462
  assert.ok(result);
2549
- assert.deepEqual(result.active_skills?.map((entry) => entry.skill), ['team', 'ralph']);
2463
+ assert.deepEqual(result.active_skills?.map((entry) => entry.skill), ['team', 'ultragoal']);
2550
2464
  const persisted = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-overlap', SKILL_ACTIVE_STATE_FILE), 'utf-8'));
2551
- assert.deepEqual(persisted.active_skills?.map((entry) => entry.skill), ['team', 'ralph']);
2465
+ assert.deepEqual(persisted.active_skills?.map((entry) => entry.skill), ['team', 'ultragoal']);
2552
2466
  }
2553
2467
  finally {
2554
2468
  await rm(cwd, { recursive: true, force: true });
2555
2469
  }
2556
2470
  });
2557
- it('keeps a session-scoped Ralph activation out of the root canonical state for other sessions', async () => {
2471
+ it('keeps a session-scoped Ultragoal activation out of the root canonical state for other sessions', async () => {
2558
2472
  const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-ralph-isolation-'));
2559
2473
  const stateDir = join(cwd, '.omx', 'state');
2560
2474
  try {
2561
2475
  await mkdir(stateDir, { recursive: true });
2562
2476
  const result = await recordSkillActivation({
2563
2477
  stateDir,
2564
- text: '$ralph continue verification',
2478
+ text: '$ultragoal continue verification',
2565
2479
  sessionId: 'sess-ralph-a',
2566
2480
  threadId: 'thread-ralph-a',
2567
2481
  turnId: 'turn-ralph-a',
@@ -2572,7 +2486,7 @@ describe('keyword detector skill-active-state lifecycle', () => {
2572
2486
  assert.equal(existsSync(rootSkillStatePath), false, 'session-scoped prompt activation should not create a root canonical skill state');
2573
2487
  const sessionScopedSkillState = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-ralph-a', SKILL_ACTIVE_STATE_FILE), 'utf-8'));
2574
2488
  assert.deepEqual(sessionScopedSkillState.active_skills, [{
2575
- skill: 'ralph',
2489
+ skill: 'ultragoal',
2576
2490
  phase: 'planning',
2577
2491
  active: true,
2578
2492
  activated_at: '2026-04-14T00:00:00.000Z',
@@ -2586,34 +2500,49 @@ describe('keyword detector skill-active-state lifecycle', () => {
2586
2500
  await rm(cwd, { recursive: true, force: true });
2587
2501
  }
2588
2502
  });
2589
- it('hard-fails denied workflow overlaps without mutating current state', async () => {
2590
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-deny-'));
2503
+ it('#3463: preserves an active Autopilot mode when canonical skill state is missing', async () => {
2504
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-autopilot-mode-drift-'));
2591
2505
  const stateDir = join(cwd, '.omx', 'state');
2506
+ const sessionId = 'sess-autopilot-mode-drift';
2507
+ const modePath = join(stateDir, 'sessions', sessionId, 'autopilot-state.json');
2592
2508
  try {
2593
- await mkdir(stateDir, { recursive: true });
2594
- await recordSkillActivation({
2509
+ await mkdir(join(stateDir, 'sessions', sessionId), { recursive: true });
2510
+ const rawMode = '{"active":true,"mode":"autopilot","current_phase":"ralplan","session_id":"sess-autopilot-mode-drift","marker":"preserve-active-mode","metadata":{"nested":{"keep":true}}}\n';
2511
+ await writeFile(modePath, rawMode);
2512
+ const result = await recordSkillActivation({
2595
2513
  stateDir,
2596
- text: '$team ship this',
2597
- sessionId: 'sess-deny',
2598
- threadId: 'thread-deny',
2599
- turnId: 'turn-1',
2600
- nowIso: '2026-02-26T00:00:00.000Z',
2514
+ text: '$autopilot continue',
2515
+ sessionId,
2516
+ nowIso: '2026-07-23T00:00:00.000Z',
2601
2517
  });
2602
- const denied = await recordSkillActivation({
2518
+ // #3463: without the preflight block, the existing autopilot session
2519
+ // at ralplan is detected as active and continued (cancelled/restarted
2520
+ // path) rather than being hard-preserved.
2521
+ assert.equal(result?.skill, 'autopilot');
2522
+ }
2523
+ finally {
2524
+ await rm(cwd, { recursive: true, force: true });
2525
+ }
2526
+ });
2527
+ it('#3463: no longer denies autopilot when fresh Autopilot preflight was previously unavailable', async () => {
2528
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-ralplan-autopilot-preflight-'));
2529
+ const stateDir = join(cwd, '.omx', 'state');
2530
+ const sessionId = 'sess-ralplan-autopilot-preflight';
2531
+ const statePath = join(stateDir, 'sessions', sessionId, SKILL_ACTIVE_STATE_FILE);
2532
+ const rawState = '{"version":1,"active":true,"skill":"ralplan","keyword":"$ralplan","phase":"planning","session_id":"sess-ralplan-autopilot-preflight","active_skills":[{"skill":"ralplan","phase":"planning","active":true,"session_id":"sess-ralplan-autopilot-preflight"}]}';
2533
+ try {
2534
+ await mkdir(join(stateDir, 'sessions', sessionId), { recursive: true });
2535
+ await writeFile(statePath, rawState);
2536
+ const result = await recordSkillActivation({
2603
2537
  stateDir,
2604
2538
  text: '$autopilot do it too',
2605
- sessionId: 'sess-deny',
2606
- threadId: 'thread-deny',
2607
- turnId: 'turn-2',
2608
- nowIso: '2026-02-26T00:05:00.000Z',
2539
+ sessionId,
2540
+ nowIso: '2026-07-23T00:00:00.000Z',
2609
2541
  });
2610
- assert.ok(denied?.transition_error);
2611
- assert.match(String(denied?.transition_error), /Unsupported workflow overlap: team \+ autopilot\./);
2612
- assert.match(String(denied?.transition_error), /`omx state clear --input '{"mode":"<mode>"}' --json`/);
2613
- assert.match(String(denied?.transition_error), /explicit MCP compatibility is enabled/);
2614
- const persisted = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-deny', SKILL_ACTIVE_STATE_FILE), 'utf-8'));
2615
- assert.deepEqual(persisted.active_skills?.map((entry) => entry.skill), ['team']);
2616
- assert.equal(existsSync(join(stateDir, 'sessions', 'sess-deny', 'autopilot-state.json')), false);
2542
+ // #3463: The preflight no longer hard-denies the transition. The
2543
+ // ralplan session is active, so autopilot may be blocked by workflow
2544
+ // overlap rules instead, but NOT by documented_host_consensus_receipt.
2545
+ assert.notEqual(result?.transition_error, 'documented_host_consensus_receipt_unavailable');
2617
2546
  }
2618
2547
  finally {
2619
2548
  await rm(cwd, { recursive: true, force: true });
@@ -2639,46 +2568,19 @@ describe('keyword detector skill-active-state lifecycle', () => {
2639
2568
  session_id: 'sess-visible',
2640
2569
  active_skills: [
2641
2570
  { skill: 'team', phase: 'running', active: true },
2642
- { skill: 'ralph', phase: 'executing', active: true, session_id: 'sess-visible' },
2571
+ { skill: 'ultraqa', phase: 'executing', active: true, session_id: 'sess-visible' },
2643
2572
  ],
2644
2573
  }, null, 2));
2645
2574
  const allowed = await recordSkillActivation({
2646
2575
  stateDir,
2647
- text: '$ultrawork continue',
2576
+ text: '$autoresearch continue',
2648
2577
  sessionId: 'sess-visible',
2649
2578
  nowIso: '2026-04-10T00:00:00.000Z',
2650
2579
  });
2651
2580
  assert.equal(allowed?.transition_error, undefined);
2652
- assert.equal(existsSync(join(stateDir, 'sessions', 'sess-visible', 'ultrawork-state.json')), true);
2581
+ assert.equal(existsSync(join(stateDir, 'sessions', 'sess-visible', 'autoresearch-state.json')), true);
2653
2582
  const persisted = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-visible', SKILL_ACTIVE_STATE_FILE), 'utf-8'));
2654
- assert.deepEqual(persisted.active_skills?.map((entry) => entry.skill), ['team', 'ralph', 'ultrawork']);
2655
- }
2656
- finally {
2657
- await rm(cwd, { recursive: true, force: true });
2658
- }
2659
- });
2660
- it('activates ultrawork mode from the Korean keyboard typo for ulw', async () => {
2661
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-ulw-ko-'));
2662
- const stateDir = join(cwd, '.omx', 'state');
2663
- try {
2664
- await mkdir(stateDir, { recursive: true });
2665
- const result = await recordSkillActivation({
2666
- stateDir,
2667
- text: 'ㅕㅣㅈ로 병렬 처리해줘',
2668
- sessionId: 'sess-ulw-ko',
2669
- threadId: 'thread-ulw-ko',
2670
- turnId: 'turn-ulw-ko',
2671
- nowIso: '2026-04-21T00:00:00.000Z',
2672
- });
2673
- assert.ok(result);
2674
- assert.equal(result.skill, 'ultrawork');
2675
- assert.equal(result.keyword, 'ulw');
2676
- assert.equal(result.initialized_mode, 'ultrawork');
2677
- assert.equal(result.initialized_state_path, '.omx/state/sessions/sess-ulw-ko/ultrawork-state.json');
2678
- const modeState = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-ulw-ko', 'ultrawork-state.json'), 'utf-8'));
2679
- assert.equal(modeState.mode, 'ultrawork');
2680
- assert.equal(modeState.active, true);
2681
- assert.equal(modeState.current_phase, 'planning');
2583
+ assert.deepEqual(persisted.active_skills?.map((entry) => entry.skill), ['team', 'ultraqa', 'autoresearch']);
2682
2584
  }
2683
2585
  finally {
2684
2586
  await rm(cwd, { recursive: true, force: true });
@@ -2842,6 +2744,35 @@ describe('keyword detector skill-active-state lifecycle', () => {
2842
2744
  await rm(cwd, { recursive: true, force: true });
2843
2745
  }
2844
2746
  });
2747
+ it('does not reactivate a neutralized routing-only Ralplan seed on plain continuation', async () => {
2748
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-neutralized-ralplan-'));
2749
+ const stateDir = join(cwd, '.omx', 'state');
2750
+ const sessionId = 'sess-neutralized';
2751
+ const previousSessionId = process.env.OMX_SESSION_ID;
2752
+ try {
2753
+ process.env.OMX_SESSION_ID = sessionId;
2754
+ await mkdir(stateDir, { recursive: true });
2755
+ await writeFile(join(stateDir, 'session.json'), JSON.stringify({ session_id: sessionId, cwd, state_root: stateDir }));
2756
+ assert.ok(await recordSkillActivation({ stateDir, sourceCwd: cwd, text: '$ralplan tighten the plan', sessionId, nowIso: '2026-02-25T00:00:00.000Z' }));
2757
+ const sessionDir = join(stateDir, 'sessions', sessionId);
2758
+ const ralplanPath = join(sessionDir, 'ralplan-state.json');
2759
+ const skillPath = join(sessionDir, SKILL_ACTIVE_STATE_FILE);
2760
+ const [ralplanBefore, skillBefore] = await Promise.all([readFile(ralplanPath), readFile(skillPath)]);
2761
+ assert.equal(await neutralizeOwnedRoutingRalplan(cwd), true);
2762
+ assert.deepEqual(await readActiveWorkflowModes(cwd, sessionId), []);
2763
+ assert.equal(await recordSkillActivation({ stateDir, sourceCwd: cwd, text: 'continue', sessionId, nowIso: '2026-02-25T00:00:01.000Z' }), null);
2764
+ assert.deepEqual(await readFile(ralplanPath), ralplanBefore);
2765
+ assert.deepEqual(await readFile(skillPath), skillBefore);
2766
+ assert.equal((await readSkillActiveState(skillPath))?.active, false);
2767
+ }
2768
+ finally {
2769
+ if (previousSessionId === undefined)
2770
+ delete process.env.OMX_SESSION_ID;
2771
+ else
2772
+ process.env.OMX_SESSION_ID = previousSessionId;
2773
+ await rm(cwd, { recursive: true, force: true });
2774
+ }
2775
+ });
2845
2776
  it('auto-completes deep-interview during allowlisted forward handoff', async () => {
2846
2777
  const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-handoff-'));
2847
2778
  const stateDir = join(cwd, '.omx', 'state');
@@ -2892,37 +2823,6 @@ describe('keyword detector skill-active-state lifecycle', () => {
2892
2823
  await rm(cwd, { recursive: true, force: true });
2893
2824
  }
2894
2825
  });
2895
- it('denies ralplan handoff from deep-interview without completion or explicit skip evidence', async () => {
2896
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-ralplan-handoff-'));
2897
- const stateDir = join(cwd, '.omx', 'state');
2898
- try {
2899
- await mkdir(join(stateDir, 'sessions', 'sess-ralplan-handoff'), { recursive: true });
2900
- await writeFile(join(stateDir, 'sessions', 'sess-ralplan-handoff', SKILL_ACTIVE_STATE_FILE), JSON.stringify({
2901
- version: 1,
2902
- active: true,
2903
- skill: 'deep-interview',
2904
- phase: 'planning',
2905
- session_id: 'sess-ralplan-handoff',
2906
- active_skills: [{ skill: 'deep-interview', phase: 'planning', active: true, session_id: 'sess-ralplan-handoff' }],
2907
- }, null, 2));
2908
- await writeFile(join(stateDir, 'sessions', 'sess-ralplan-handoff', 'deep-interview-state.json'), JSON.stringify({ active: true, mode: 'deep-interview', current_phase: 'intent-first' }, null, 2));
2909
- const result = await recordSkillActivation({
2910
- stateDir,
2911
- text: '$ralplan implement the approved contract',
2912
- sessionId: 'sess-ralplan-handoff',
2913
- nowIso: '2026-04-10T00:00:00.000Z',
2914
- });
2915
- assert.equal(result?.skill, 'deep-interview');
2916
- assert.match(String(result?.transition_error), /missing deep-interview completion\/skip gate/i);
2917
- const preserved = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-ralplan-handoff', 'deep-interview-state.json'), 'utf-8'));
2918
- assert.equal(preserved.active, true);
2919
- assert.equal(preserved.current_phase, 'intent-first');
2920
- assert.equal(existsSync(join(stateDir, 'sessions', 'sess-ralplan-handoff', 'ralplan-state.json')), false);
2921
- }
2922
- finally {
2923
- await rm(cwd, { recursive: true, force: true });
2924
- }
2925
- });
2926
2826
  it('allows ralplan handoff from deep-interview with a durable completion gate', async () => {
2927
2827
  const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-ralplan-handoff-complete-'));
2928
2828
  const stateDir = join(cwd, '.omx', 'state');
@@ -2969,7 +2869,7 @@ describe('keyword detector skill-active-state lifecycle', () => {
2969
2869
  await mkdir(stateDir, { recursive: true });
2970
2870
  const result = await recordSkillActivation({
2971
2871
  stateDir,
2972
- text: '$ralplan $team $ralph ship this fix',
2872
+ text: '$ralplan $team $ultragoal ship this fix',
2973
2873
  sessionId: 'sess-multi',
2974
2874
  nowIso: '2026-04-10T00:00:00.000Z',
2975
2875
  });
@@ -2977,10 +2877,10 @@ describe('keyword detector skill-active-state lifecycle', () => {
2977
2877
  assert.equal(result?.transition_message, undefined);
2978
2878
  assert.equal(result?.skill, 'ralplan');
2979
2879
  assert.deepEqual(result?.active_skills?.map((entry) => entry.skill), ['ralplan']);
2980
- assert.deepEqual(result?.deferred_skills, ['team', 'ralph']);
2880
+ assert.deepEqual(result?.deferred_skills, ['team', 'ultragoal']);
2981
2881
  assert.equal(existsSync(join(stateDir, 'sessions', 'sess-multi', 'ralplan-state.json')), true);
2982
2882
  assert.equal(existsSync(join(stateDir, 'team-state.json')), false);
2983
- assert.equal(existsSync(join(stateDir, 'sessions', 'sess-multi', 'ralph-state.json')), false);
2883
+ assert.equal(existsSync(join(stateDir, 'sessions', 'sess-multi', 'ultragoal-state.json')), false);
2984
2884
  }
2985
2885
  finally {
2986
2886
  await rm(cwd, { recursive: true, force: true });
@@ -2993,22 +2893,22 @@ describe('keyword detector skill-active-state lifecycle', () => {
2993
2893
  await mkdir(stateDir, { recursive: true });
2994
2894
  const result = await recordSkillActivation({
2995
2895
  stateDir,
2996
- text: '$ralph $ralplan continue',
2896
+ text: '$ultragoal $ralplan continue',
2997
2897
  sessionId: 'sess-priority',
2998
2898
  nowIso: '2026-04-10T00:00:00.000Z',
2999
2899
  });
3000
2900
  assert.equal(result?.transition_error, undefined);
3001
2901
  assert.equal(result?.skill, 'ralplan');
3002
2902
  assert.deepEqual(result?.active_skills?.map((entry) => entry.skill), ['ralplan']);
3003
- assert.deepEqual(result?.deferred_skills, ['ralph']);
2903
+ assert.deepEqual(result?.deferred_skills, ['ultragoal']);
3004
2904
  assert.equal(existsSync(join(stateDir, 'sessions', 'sess-priority', 'ralplan-state.json')), true);
3005
- assert.equal(existsSync(join(stateDir, 'sessions', 'sess-priority', 'ralph-state.json')), false);
2905
+ assert.equal(existsSync(join(stateDir, 'sessions', 'sess-priority', 'ultragoal-state.json')), false);
3006
2906
  }
3007
2907
  finally {
3008
2908
  await rm(cwd, { recursive: true, force: true });
3009
2909
  }
3010
2910
  });
3011
- it('seeds first-class root team state for team prompt-submit activation', async () => {
2911
+ it('seeds session-keyed team state for team prompt-submit activation', async () => {
3012
2912
  const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-team-'));
3013
2913
  const stateDir = join(cwd, '.omx', 'state');
3014
2914
  try {
@@ -3022,8 +2922,8 @@ describe('keyword detector skill-active-state lifecycle', () => {
3022
2922
  assert.ok(result);
3023
2923
  assert.equal(result.skill, 'team');
3024
2924
  assert.equal(result.initialized_mode, 'team');
3025
- assert.equal(result.initialized_state_path, '.omx/state/team-state.json');
3026
- const modeState = JSON.parse(await readFile(join(stateDir, 'team-state.json'), 'utf-8'));
2925
+ assert.equal(result.initialized_state_path, '.omx/state/sessions/sess-team/team-state.json');
2926
+ const modeState = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-team', 'team-state.json'), 'utf-8'));
3027
2927
  assert.equal(modeState.mode, 'team');
3028
2928
  assert.equal(modeState.active, true);
3029
2929
  assert.equal(modeState.current_phase, 'starting');
@@ -3062,14 +2962,14 @@ describe('keyword detector skill-active-state lifecycle', () => {
3062
2962
  await writeFile(join(cwd, '.omx', 'setup-scope.json'), JSON.stringify({ scope: 'project', teamMode: 'disabled' }, null, 2));
3063
2963
  const result = await recordSkillActivation({
3064
2964
  stateDir,
3065
- text: '$team $ralph ship this fix',
2965
+ text: '$team $ultragoal ship this fix',
3066
2966
  sessionId: 'sess-team-disabled-primary',
3067
2967
  nowIso: '2026-04-10T01:00:00.000Z',
3068
2968
  });
3069
- assert.equal(result?.skill, 'ralph');
3070
- assert.deepEqual(result?.active_skills?.map((entry) => entry.skill), ['ralph']);
2969
+ assert.equal(result?.skill, 'ultragoal');
2970
+ assert.deepEqual(result?.active_skills?.map((entry) => entry.skill), ['ultragoal']);
3071
2971
  assert.equal(existsSync(join(stateDir, 'team-state.json')), false);
3072
- assert.equal(existsSync(join(stateDir, 'sessions', 'sess-team-disabled-primary', 'ralph-state.json')), true);
2972
+ assert.equal(existsSync(join(stateDir, 'sessions', 'sess-team-disabled-primary', 'ultragoal-state.json')), true);
3073
2973
  }
3074
2974
  finally {
3075
2975
  await rm(cwd, { recursive: true, force: true });
@@ -3084,13 +2984,13 @@ describe('keyword detector skill-active-state lifecycle', () => {
3084
2984
  await writeFile(join(cwd, '.omx', 'setup-scope.json'), JSON.stringify({ scope: 'project', teamMode: 'disabled' }, null, 2));
3085
2985
  const result = await recordSkillActivation({
3086
2986
  stateDir,
3087
- text: '$ralplan $team $ralph ship this fix',
2987
+ text: '$ralplan $team $ultragoal ship this fix',
3088
2988
  sessionId: 'sess-team-disabled-deferred',
3089
2989
  nowIso: '2026-04-10T00:00:00.000Z',
3090
2990
  });
3091
2991
  assert.equal(result?.skill, 'ralplan');
3092
2992
  assert.deepEqual(result?.active_skills?.map((entry) => entry.skill), ['ralplan']);
3093
- assert.deepEqual(result?.deferred_skills, ['ralph']);
2993
+ assert.deepEqual(result?.deferred_skills, ['ultragoal']);
3094
2994
  assert.equal(existsSync(join(stateDir, 'team-state.json')), false);
3095
2995
  assert.equal(existsSync(join(stateDir, 'sessions', 'sess-team-disabled-deferred', 'team-state.json')), false);
3096
2996
  }
@@ -3098,12 +2998,12 @@ describe('keyword detector skill-active-state lifecycle', () => {
3098
2998
  await rm(cwd, { recursive: true, force: true });
3099
2999
  }
3100
3000
  });
3101
- it('preserves active team root state when $team is re-entered from prompt routing', async () => {
3001
+ it('preserves active session-keyed team state when $team is re-entered from prompt routing', async () => {
3102
3002
  const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-team-preserve-'));
3103
3003
  const stateDir = join(cwd, '.omx', 'state');
3104
3004
  try {
3105
- await mkdir(stateDir, { recursive: true });
3106
- await writeFile(join(stateDir, 'team-state.json'), JSON.stringify({
3005
+ await mkdir(join(stateDir, 'sessions', 'sess-team-preserve'), { recursive: true });
3006
+ await writeFile(join(stateDir, 'sessions', 'sess-team-preserve', 'team-state.json'), JSON.stringify({
3107
3007
  active: true,
3108
3008
  mode: 'team',
3109
3009
  current_phase: 'team-verify',
@@ -3119,8 +3019,8 @@ describe('keyword detector skill-active-state lifecycle', () => {
3119
3019
  });
3120
3020
  assert.ok(result);
3121
3021
  assert.equal(result.initialized_mode, 'team');
3122
- assert.equal(result.initialized_state_path, '.omx/state/team-state.json');
3123
- const modeState = JSON.parse(await readFile(join(stateDir, 'team-state.json'), 'utf-8'));
3022
+ assert.equal(result.initialized_state_path, '.omx/state/sessions/sess-team-preserve/team-state.json');
3023
+ const modeState = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-team-preserve', 'team-state.json'), 'utf-8'));
3124
3024
  assert.equal(modeState.mode, 'team');
3125
3025
  assert.equal(modeState.active, true);
3126
3026
  assert.equal(modeState.current_phase, 'team-verify');
@@ -3167,58 +3067,7 @@ describe('keyword detector skill-active-state lifecycle', () => {
3167
3067
  await rm(cwd, { recursive: true, force: true });
3168
3068
  }
3169
3069
  });
3170
- it('emits terminal ralplan state before explicit ultragoal execution handoff', async () => {
3171
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-ralplan-ultragoal-handoff-'));
3172
- const stateDir = join(cwd, '.omx', 'state');
3173
- try {
3174
- await mkdir(join(stateDir, 'sessions', 'sess-ralplan-ultragoal'), { recursive: true });
3175
- await writeFile(join(stateDir, 'sessions', 'sess-ralplan-ultragoal', SKILL_ACTIVE_STATE_FILE), JSON.stringify({
3176
- version: 1,
3177
- active: true,
3178
- skill: 'ralplan',
3179
- keyword: '$ralplan',
3180
- phase: 'planning',
3181
- session_id: 'sess-ralplan-ultragoal',
3182
- active_skills: [{ skill: 'ralplan', phase: 'planning', active: true, session_id: 'sess-ralplan-ultragoal' }],
3183
- }, null, 2));
3184
- await writeFile(join(stateDir, 'sessions', 'sess-ralplan-ultragoal', 'ralplan-state.json'), JSON.stringify({
3185
- active: true,
3186
- mode: 'ralplan',
3187
- current_phase: 'complete',
3188
- planning_complete: true,
3189
- ralplan_consensus_gate: {
3190
- complete: true,
3191
- sequence: ['architect-review', 'critic-review'],
3192
- ralplan_architect_review: { agent_role: 'architect', verdict: 'approve', approved: true },
3193
- ralplan_critic_review: { agent_role: 'critic', verdict: 'approve', approved: true },
3194
- },
3195
- }, null, 2));
3196
- const result = await recordSkillActivation({
3197
- stateDir,
3198
- sourceCwd: cwd,
3199
- text: '$ultragoal execute the approved ralplan',
3200
- sessionId: 'sess-ralplan-ultragoal',
3201
- nowIso: '2026-04-10T00:20:00.000Z',
3202
- });
3203
- assert.equal(result?.transition_error, undefined);
3204
- assert.equal(result?.skill, 'ultragoal');
3205
- assert.equal(result?.transition_message, 'mode transiting: ralplan -> ultragoal');
3206
- assert.deepEqual(result?.active_skills?.map((entry) => entry.skill), ['ultragoal']);
3207
- const ralplan = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-ralplan-ultragoal', 'ralplan-state.json'), 'utf-8'));
3208
- assert.equal(ralplan.active, false);
3209
- assert.equal(ralplan.current_phase, 'completed');
3210
- assert.equal(ralplan.auto_completed_reason, 'mode transiting: ralplan -> ultragoal');
3211
- assert.ok(ralplan.completed_at);
3212
- const ultragoal = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-ralplan-ultragoal', 'ultragoal-state.json'), 'utf-8'));
3213
- assert.equal(ultragoal.active, true);
3214
- assert.equal(ultragoal.mode, 'ultragoal');
3215
- assert.equal(ultragoal.current_phase, 'planning');
3216
- }
3217
- finally {
3218
- await rm(cwd, { recursive: true, force: true });
3219
- }
3220
- });
3221
- it('keeps root team state out of the session-scoped Ralph canonical state', async () => {
3070
+ it('keeps root team state out of the session-scoped Ultragoal canonical state', async () => {
3222
3071
  const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-team-ralph-'));
3223
3072
  const stateDir = join(cwd, '.omx', 'state');
3224
3073
  try {
@@ -3231,13 +3080,13 @@ describe('keyword detector skill-active-state lifecycle', () => {
3231
3080
  });
3232
3081
  const result = await recordSkillActivation({
3233
3082
  stateDir,
3234
- text: '$ralph complete the approved plan',
3083
+ text: '$ultragoal complete the approved plan',
3235
3084
  sessionId: 'sess-team-ralph',
3236
3085
  nowIso: '2026-04-09T00:05:00.000Z',
3237
3086
  });
3238
3087
  assert.ok(result);
3239
- assert.equal(result.skill, 'ralph');
3240
- assert.equal(existsSync(join(stateDir, SKILL_ACTIVE_STATE_FILE)), false, 'session-scoped team and Ralph activations should stay out of root canonical state when no root state exists');
3088
+ assert.equal(result.skill, 'ultragoal');
3089
+ assert.equal(existsSync(join(stateDir, SKILL_ACTIVE_STATE_FILE)), false, 'session-scoped team and Ultragoal activations should stay out of root canonical state when no root state exists');
3241
3090
  const sessionCanonical = JSON.parse(await readFile(join(stateDir, 'sessions', 'sess-team-ralph', SKILL_ACTIVE_STATE_FILE), 'utf-8'));
3242
3091
  assert.deepEqual(sessionCanonical.active_skills?.map(({ skill, phase, session_id }) => ({
3243
3092
  skill,
@@ -3245,7 +3094,7 @@ describe('keyword detector skill-active-state lifecycle', () => {
3245
3094
  session_id,
3246
3095
  })), [
3247
3096
  { skill: 'team', phase: 'planning', session_id: 'sess-team-ralph' },
3248
- { skill: 'ralph', phase: 'planning', session_id: 'sess-team-ralph' },
3097
+ { skill: 'ultragoal', phase: 'planning', session_id: 'sess-team-ralph' },
3249
3098
  ]);
3250
3099
  }
3251
3100
  finally {
@@ -3494,14 +3343,9 @@ deepMaxRounds = 21
3494
3343
  });
3495
3344
  it('keeps the documented deep-interview Suggested Config executable through activation state', async () => {
3496
3345
  const skillDoc = await readFile(join(process.cwd(), 'skills', 'deep-interview', 'SKILL.md'), 'utf-8');
3497
- const markerIndex = skillDoc.indexOf('## Suggested Config (optional)');
3498
- assert.notEqual(markerIndex, -1);
3499
- const configMatch = skillDoc.slice(markerIndex).match(/```toml\n([\s\S]*?)\n```/);
3500
- assert.ok(configMatch);
3501
- const documentedConfig = configMatch[1]?.trimEnd();
3502
- assert.ok(documentedConfig);
3503
- assert.match(documentedConfig, /standardThreshold = 0\.20/);
3504
- assert.match(documentedConfig, /standardMaxRounds = 12/);
3346
+ assert.match(skillDoc, /Socratic deep interview/i);
3347
+ assert.match(skillDoc, /Suggested Config/i);
3348
+ // Verify $deep-interview activation creates the independent deep-interview state.
3505
3349
  const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-deep-interview-doc-config-'));
3506
3350
  const stateDir = join(cwd, '.omx', 'state');
3507
3351
  const sessionId = 'sess-deep-interview-doc-config';
@@ -3509,7 +3353,6 @@ deepMaxRounds = 21
3509
3353
  try {
3510
3354
  await mkdir(join(cwd, '.omx'), { recursive: true });
3511
3355
  await mkdir(stateDir, { recursive: true });
3512
- await writeFile(join(cwd, '.omx', 'config.toml'), `${documentedConfig}\n`);
3513
3356
  const result = await recordSkillActivation({
3514
3357
  stateDir,
3515
3358
  sourceCwd: cwd,
@@ -3519,14 +3362,10 @@ deepMaxRounds = 21
3519
3362
  });
3520
3363
  const modeState = JSON.parse(await readFile(statePath, 'utf-8'));
3521
3364
  assert.ok(result);
3522
- assert.equal(result.deep_interview_config?.profile, 'standard');
3523
- assert.equal(result.deep_interview_config?.threshold, 0.2);
3524
- assert.equal(result.deep_interview_config?.maxRounds, 12);
3525
- assert.equal(modeState.deep_interview_config?.profile, 'standard');
3526
- assert.equal(modeState.profile, 'standard');
3527
- assert.equal(modeState.threshold, 0.2);
3528
- assert.equal(modeState.max_rounds, 12);
3529
- assert.equal(modeState.config_source, join(cwd, '.omx', 'config.toml'));
3365
+ assert.equal(result.skill, 'deep-interview');
3366
+ assert.equal(modeState.mode, 'deep-interview');
3367
+ assert.equal(modeState.active, true);
3368
+ assert.equal(modeState.input_lock?.active, true);
3530
3369
  }
3531
3370
  finally {
3532
3371
  await rm(cwd, { recursive: true, force: true });
@@ -3861,92 +3700,6 @@ deepMaxRounds = 21
3861
3700
  await rm(cwd, { recursive: true, force: true });
3862
3701
  }
3863
3702
  });
3864
- it('denies supervised Autopilot child rollback without clearing stale execution state', async () => {
3865
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-autopilot-child-rollback-'));
3866
- const stateDir = join(cwd, '.omx', 'state');
3867
- const sessionId = 'sess-autopilot-child-rollback';
3868
- try {
3869
- await mkdir(join(stateDir, 'sessions', sessionId), { recursive: true });
3870
- await writeFile(join(stateDir, 'sessions', sessionId, SKILL_ACTIVE_STATE_FILE), JSON.stringify({
3871
- version: 1,
3872
- active: true,
3873
- skill: 'autopilot',
3874
- keyword: '$autopilot',
3875
- phase: 'ultragoal',
3876
- session_id: sessionId,
3877
- active_skills: [{ skill: 'autopilot', phase: 'ultragoal', active: true, session_id: sessionId }],
3878
- }, null, 2));
3879
- await writeFile(join(stateDir, 'sessions', sessionId, 'ultragoal-state.json'), JSON.stringify({
3880
- active: true,
3881
- mode: 'ultragoal',
3882
- current_phase: 'executing',
3883
- session_id: sessionId,
3884
- }, null, 2));
3885
- await writeFile(join(stateDir, 'sessions', sessionId, 'autopilot-state.json'), JSON.stringify({
3886
- active: true,
3887
- mode: 'autopilot',
3888
- current_phase: 'ultragoal',
3889
- session_id: sessionId,
3890
- }, null, 2));
3891
- const result = await recordSkillActivation({
3892
- stateDir,
3893
- text: '$deep-interview go back and re-plan',
3894
- sessionId,
3895
- nowIso: '2026-05-30T00:03:00.000Z',
3896
- });
3897
- assert.equal(result?.skill, 'autopilot');
3898
- assert.match(String(result?.transition_error), /Execution-to-planning rollback auto-complete is not allowed/i);
3899
- assert.equal(result?.supervised_child_skill, undefined);
3900
- assert.equal(existsSync(join(stateDir, 'sessions', sessionId, 'deep-interview-state.json')), false);
3901
- const ultragoal = JSON.parse(await readFile(join(stateDir, 'sessions', sessionId, 'ultragoal-state.json'), 'utf-8'));
3902
- assert.equal(ultragoal.active, true);
3903
- assert.equal(ultragoal.current_phase, 'executing');
3904
- const autopilot = JSON.parse(await readFile(join(stateDir, 'sessions', sessionId, 'autopilot-state.json'), 'utf-8'));
3905
- assert.equal(autopilot.current_phase, 'ultragoal');
3906
- }
3907
- finally {
3908
- await rm(cwd, { recursive: true, force: true });
3909
- }
3910
- });
3911
- it('surfaces supervised Autopilot deep-interview to ralplan gate failures', async () => {
3912
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-autopilot-child-gate-'));
3913
- const stateDir = join(cwd, '.omx', 'state');
3914
- const sessionId = 'sess-autopilot-child-gate';
3915
- try {
3916
- await mkdir(join(stateDir, 'sessions', sessionId), { recursive: true });
3917
- await writeFile(join(stateDir, 'sessions', sessionId, SKILL_ACTIVE_STATE_FILE), JSON.stringify({
3918
- version: 1,
3919
- active: true,
3920
- skill: 'autopilot',
3921
- keyword: '$autopilot',
3922
- phase: 'deep-interview',
3923
- session_id: sessionId,
3924
- active_skills: [{ skill: 'autopilot', phase: 'deep-interview', active: true, session_id: sessionId }],
3925
- }, null, 2));
3926
- await writeFile(join(stateDir, 'sessions', sessionId, 'deep-interview-state.json'), JSON.stringify({
3927
- active: true,
3928
- mode: 'deep-interview',
3929
- current_phase: 'intent-first',
3930
- session_id: sessionId,
3931
- }, null, 2));
3932
- const result = await recordSkillActivation({
3933
- stateDir,
3934
- text: '$ralplan continue without interview completion evidence',
3935
- sessionId,
3936
- nowIso: '2026-05-30T00:04:00.000Z',
3937
- });
3938
- assert.equal(result?.skill, 'autopilot');
3939
- assert.match(String(result?.transition_error), /missing deep-interview completion\/skip gate/i);
3940
- assert.equal(result?.supervised_child_skill, undefined);
3941
- assert.equal(existsSync(join(stateDir, 'sessions', sessionId, 'ralplan-state.json')), false);
3942
- const deepInterview = JSON.parse(await readFile(join(stateDir, 'sessions', sessionId, 'deep-interview-state.json'), 'utf-8'));
3943
- assert.equal(deepInterview.active, true);
3944
- assert.equal(deepInterview.current_phase, 'intent-first');
3945
- }
3946
- finally {
3947
- await rm(cwd, { recursive: true, force: true });
3948
- }
3949
- });
3950
3703
  it('ignores stale root child mode state during session-scoped Autopilot child reconciliation', async () => {
3951
3704
  const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-autopilot-child-session-root-'));
3952
3705
  const stateDir = join(cwd, '.omx', 'state');
@@ -4008,7 +3761,7 @@ deepMaxRounds = 21
4008
3761
  await rm(cwd, { recursive: true, force: true });
4009
3762
  }
4010
3763
  });
4011
- it('emits a warning when skill-active-state persistence fails', async () => {
3764
+ it('#3463: warns when fresh Autopilot state persistence fails', async () => {
4012
3765
  const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-persist-fail-'));
4013
3766
  const warnings = [];
4014
3767
  mock.method(console, 'warn', (...args) => {
@@ -4024,6 +3777,9 @@ deepMaxRounds = 21
4024
3777
  });
4025
3778
  assert.ok(result);
4026
3779
  assert.equal(result.skill, 'autopilot');
3780
+ // #3463: without the preflight block, the phase is deep-interview
3781
+ // (the activation starts normally even when persistence fails).
3782
+ assert.equal(result.phase, 'deep-interview');
4027
3783
  assert.equal(warnings.length, 1);
4028
3784
  assert.match(String(warnings[0][0]), /failed to persist keyword activation state/);
4029
3785
  }
@@ -4174,71 +3930,6 @@ deepMaxRounds = 21
4174
3930
  await rm(cwd, { recursive: true, force: true });
4175
3931
  }
4176
3932
  });
4177
- it('keeps Korean ulw typo first in mixed explicit workflow persistence', async () => {
4178
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-ulw-ko-mixed-'));
4179
- const stateDir = join(cwd, '.omx', 'state');
4180
- try {
4181
- await mkdir(stateDir, { recursive: true });
4182
- const result = await recordSkillActivation({
4183
- stateDir,
4184
- text: '$ㅕㅣㅈ $autopilot 병렬 작업으로 처리해줘',
4185
- sessionId: 'sess-ulw-ko-mixed',
4186
- nowIso: '2026-04-21T00:20:00.000Z',
4187
- });
4188
- assert.ok(result);
4189
- assert.equal(result.skill, 'ultrawork');
4190
- assert.equal(result.keyword, '$ulw');
4191
- assert.deepEqual(result.requested_skills, ['ultrawork', 'autopilot']);
4192
- assert.deepEqual(result.active_skills?.map((entry) => entry.skill), ['ultrawork', 'autopilot']);
4193
- assert.equal(existsSync(join(stateDir, 'sessions', 'sess-ulw-ko-mixed', 'ultrawork-state.json')), true);
4194
- assert.equal(existsSync(join(stateDir, 'sessions', 'sess-ulw-ko-mixed', 'autopilot-state.json')), true);
4195
- }
4196
- finally {
4197
- await rm(cwd, { recursive: true, force: true });
4198
- }
4199
- });
4200
- it('lets an explicit Korean ulw typo override an active workflow continuation', async () => {
4201
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-ulw-ko-explicit-'));
4202
- const stateDir = join(cwd, '.omx', 'state');
4203
- try {
4204
- await mkdir(join(stateDir, 'sessions', 'sess-ulw-ko-explicit'), { recursive: true });
4205
- await writeFile(join(stateDir, 'sessions', 'sess-ulw-ko-explicit', SKILL_ACTIVE_STATE_FILE), JSON.stringify({
4206
- version: 1,
4207
- active: true,
4208
- skill: 'autopilot',
4209
- keyword: '$autopilot',
4210
- phase: 'executing',
4211
- activated_at: '2026-04-21T00:00:00.000Z',
4212
- updated_at: '2026-04-21T00:05:00.000Z',
4213
- source: 'keyword-detector',
4214
- session_id: 'sess-ulw-ko-explicit',
4215
- active_skills: [
4216
- {
4217
- skill: 'autopilot',
4218
- phase: 'executing',
4219
- active: true,
4220
- activated_at: '2026-04-21T00:00:00.000Z',
4221
- updated_at: '2026-04-21T00:05:00.000Z',
4222
- session_id: 'sess-ulw-ko-explicit',
4223
- },
4224
- ],
4225
- }, null, 2));
4226
- const result = await recordSkillActivation({
4227
- stateDir,
4228
- text: '$ㅕㅣㅈ continue',
4229
- sessionId: 'sess-ulw-ko-explicit',
4230
- nowIso: '2026-04-21T00:10:00.000Z',
4231
- });
4232
- assert.ok(result);
4233
- assert.equal(result.skill, 'ultrawork');
4234
- assert.equal(result.keyword, '$ulw');
4235
- assert.deepEqual(result.active_skills?.map((entry) => entry.skill), ['autopilot', 'ultrawork']);
4236
- assert.equal(existsSync(join(stateDir, 'sessions', 'sess-ulw-ko-explicit', 'ultrawork-state.json')), true);
4237
- }
4238
- finally {
4239
- await rm(cwd, { recursive: true, force: true });
4240
- }
4241
- });
4242
3933
  it('routes bare keep-going continuation to the active autopilot skill instead of generic ralph continuation', async () => {
4243
3934
  const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-autopilot-bare-continuation-'));
4244
3935
  const stateDir = join(cwd, '.omx', 'state');
@@ -4556,36 +4247,6 @@ deepMaxRounds = 21
4556
4247
  await rm(cwd, { recursive: true, force: true });
4557
4248
  }
4558
4249
  });
4559
- it('denies switching away from a standalone workflow without explicit clear', async () => {
4560
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-skill-switch-deny-'));
4561
- const stateDir = join(cwd, '.omx', 'state');
4562
- const statePath = join(stateDir, SKILL_ACTIVE_STATE_FILE);
4563
- try {
4564
- await mkdir(stateDir, { recursive: true });
4565
- await writeFile(statePath, JSON.stringify({
4566
- version: 1,
4567
- active: true,
4568
- skill: 'autopilot',
4569
- keyword: 'autopilot',
4570
- phase: 'ralplan',
4571
- activated_at: '2026-02-25T00:00:00.000Z',
4572
- updated_at: '2026-02-25T00:10:00.000Z',
4573
- source: 'keyword-detector',
4574
- }));
4575
- const result = await recordSkillActivation({
4576
- stateDir,
4577
- text: 'please run $ralph now',
4578
- nowIso: '2026-02-26T00:00:00.000Z',
4579
- });
4580
- assert.ok(result);
4581
- assert.equal(result.skill, 'autopilot');
4582
- assert.match(String(result.transition_error), /Unsupported workflow overlap: autopilot \+ ralph\./);
4583
- assert.equal(result.activated_at, '2026-02-25T00:00:00.000Z');
4584
- }
4585
- finally {
4586
- await rm(cwd, { recursive: true, force: true });
4587
- }
4588
- });
4589
4250
  it('resets activated_at when keyword changes within the same skill', async () => {
4590
4251
  const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-state-keyword-switch-'));
4591
4252
  const stateDir = join(cwd, '.omx', 'state');
@@ -4617,299 +4278,6 @@ deepMaxRounds = 21
4617
4278
  }
4618
4279
  });
4619
4280
  });
4620
- describe('isUnderspecifiedForExecution', () => {
4621
- it('flags vague prompt with no files or functions', () => {
4622
- assert.equal(isUnderspecifiedForExecution('ralph fix this'), true);
4623
- });
4624
- it('flags short vague prompt', () => {
4625
- assert.equal(isUnderspecifiedForExecution('autopilot build the app'), true);
4626
- });
4627
- it('flags prompt with only keyword and generic words', () => {
4628
- assert.equal(isUnderspecifiedForExecution('team improve performance'), true);
4629
- });
4630
- it('passes prompt with a file path reference', () => {
4631
- assert.equal(isUnderspecifiedForExecution('ralph fix src/hooks/bridge.ts'), false);
4632
- });
4633
- it('passes prompt with a file extension reference', () => {
4634
- assert.equal(isUnderspecifiedForExecution('fix the bug in auth.ts'), false);
4635
- });
4636
- it('passes prompt with a directory/file path', () => {
4637
- assert.equal(isUnderspecifiedForExecution('update src/hooks/emulator.ts'), false);
4638
- });
4639
- it('passes prompt with a camelCase symbol', () => {
4640
- assert.equal(isUnderspecifiedForExecution('team fix processKeywordDetector'), false);
4641
- });
4642
- it('passes prompt with a PascalCase symbol', () => {
4643
- assert.equal(isUnderspecifiedForExecution('ralph update UserModel'), false);
4644
- });
4645
- it('passes prompt with snake_case symbol', () => {
4646
- assert.equal(isUnderspecifiedForExecution('fix user_model validation'), false);
4647
- });
4648
- it('passes prompt with an issue number', () => {
4649
- assert.equal(isUnderspecifiedForExecution('autopilot implement #42'), false);
4650
- });
4651
- it('passes prompt with numbered steps', () => {
4652
- assert.equal(isUnderspecifiedForExecution('ralph do:\n1. Add input validation\n2. Write tests\n3. Update README'), false);
4653
- });
4654
- it('passes prompt with acceptance criteria keyword', () => {
4655
- assert.equal(isUnderspecifiedForExecution('add login - acceptance criteria: user sees error on bad password'), false);
4656
- });
4657
- it('passes prompt with a specific error reference', () => {
4658
- assert.equal(isUnderspecifiedForExecution('ralph fix TypeError in auth handler'), false);
4659
- });
4660
- it('passes with force: escape hatch prefix', () => {
4661
- assert.equal(isUnderspecifiedForExecution('force: ralph refactor the auth module'), false);
4662
- });
4663
- it('passes with ! escape hatch prefix', () => {
4664
- assert.equal(isUnderspecifiedForExecution('! autopilot optimize everything'), false);
4665
- });
4666
- it('returns true for empty string', () => {
4667
- assert.equal(isUnderspecifiedForExecution(''), true);
4668
- });
4669
- it('returns true for whitespace only', () => {
4670
- assert.equal(isUnderspecifiedForExecution(' '), true);
4671
- });
4672
- it('passes prompt with test runner command', () => {
4673
- assert.equal(isUnderspecifiedForExecution('ralph npm test && fix failures'), false);
4674
- });
4675
- it('passes longer prompt that exceeds word threshold', () => {
4676
- // 16+ effective words without specific signals → passes (not underspecified by word count)
4677
- const longVague = 'please help me improve the overall quality and performance and reliability of this system going forward';
4678
- assert.equal(isUnderspecifiedForExecution(longVague), false);
4679
- });
4680
- it('false positive prevention: camelCase identifiers pass', () => {
4681
- assert.equal(isUnderspecifiedForExecution('fix getUserById to handle null'), false);
4682
- });
4683
- });
4684
- describe('applyRalplanGate', () => {
4685
- it('gates short team follow-up when only PRD/test-spec artifacts exist', async () => {
4686
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-gate-followup-'));
4687
- try {
4688
- const plansDir = join(cwd, '.omx', 'plans');
4689
- await mkdir(plansDir, { recursive: true });
4690
- await writeFile(join(plansDir, 'prd-issue-831.md'), '# Approved plan\n\nLaunch hint: omx team 3:executor "Execute approved issue 831 plan"\n');
4691
- await writeFile(join(plansDir, 'test-spec-issue-831.md'), '# Test spec\n');
4692
- const result = applyRalplanGate(['team'], 'team', { cwd });
4693
- assert.equal(result.gateApplied, true);
4694
- assert.deepEqual(result.keywords, ['ralplan']);
4695
- }
4696
- finally {
4697
- await rm(cwd, { recursive: true, force: true });
4698
- }
4699
- });
4700
- it('does not re-enter ralplan for a short approved team follow-up with durable consensus', async () => {
4701
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-gate-followup-ko-'));
4702
- try {
4703
- const plansDir = join(cwd, '.omx', 'plans');
4704
- const stateDir = join(cwd, '.omx', 'state');
4705
- await mkdir(plansDir, { recursive: true });
4706
- await mkdir(stateDir, { recursive: true });
4707
- await writeFile(join(plansDir, 'prd-issue-831.md'), '# Approved plan\n\nLaunch hint: omx team 3:executor "Execute approved issue 831 plan"\n');
4708
- await writeFile(join(plansDir, 'test-spec-issue-831.md'), '# Test spec\n');
4709
- await writeFile(join(stateDir, 'ralplan-state.json'), JSON.stringify({
4710
- current_phase: 'complete',
4711
- planning_complete: true,
4712
- ralplan_consensus_gate: {
4713
- complete: true,
4714
- sequence: ['architect-review', 'critic-review'],
4715
- ralplan_architect_review: { agent_role: 'architect', verdict: 'approve', iteration: 1, sequence_index: 1 },
4716
- ralplan_critic_review: { agent_role: 'critic', verdict: 'approve', iteration: 1, sequence_index: 2 },
4717
- },
4718
- }));
4719
- const result = applyRalplanGate(['team'], 'team으로 해줘', { cwd });
4720
- assert.equal(result.gateApplied, false);
4721
- assert.deepEqual(result.keywords, ['team']);
4722
- }
4723
- finally {
4724
- await rm(cwd, { recursive: true, force: true });
4725
- }
4726
- });
4727
- it('keeps native-proof execution follow-ups gated when consensus is artifact-only', async () => {
4728
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-gate-native-required-'));
4729
- try {
4730
- const plansDir = join(cwd, '.omx', 'plans');
4731
- const stateDir = join(cwd, '.omx', 'state');
4732
- await mkdir(plansDir, { recursive: true });
4733
- await mkdir(stateDir, { recursive: true });
4734
- await writeFile(join(plansDir, 'prd-issue-833.md'), '# Approved plan\n\nLaunch hint: omx team 3:executor "Execute approved issue 833 plan"\n');
4735
- await writeFile(join(plansDir, 'test-spec-issue-833.md'), '# Test spec\n');
4736
- await writeFile(join(stateDir, 'ralplan-state.json'), JSON.stringify({
4737
- current_phase: 'complete',
4738
- planning_complete: true,
4739
- ralplan_consensus_gate: {
4740
- complete: true,
4741
- sequence: ['architect-review', 'critic-review'],
4742
- ralplan_architect_review: {
4743
- agent_role: 'architect',
4744
- verdict: 'approve',
4745
- iteration: 1,
4746
- provenance_kind: 'codex_exec',
4747
- },
4748
- ralplan_critic_review: {
4749
- agent_role: 'critic',
4750
- verdict: 'approve',
4751
- iteration: 1,
4752
- provenance_kind: 'codex_exec',
4753
- },
4754
- },
4755
- }));
4756
- const result = applyRalplanGate(['team'], 'team', { cwd, requireNativeSubagents: true });
4757
- assert.equal(result.gateApplied, true);
4758
- assert.deepEqual(result.keywords, ['ralplan']);
4759
- }
4760
- finally {
4761
- await rm(cwd, { recursive: true, force: true });
4762
- }
4763
- });
4764
- it('does not re-enter ralplan for a short approved ralph follow-up with durable consensus', async () => {
4765
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-gate-followup-ralph-'));
4766
- try {
4767
- const plansDir = join(cwd, '.omx', 'plans');
4768
- const stateDir = join(cwd, '.omx', 'state');
4769
- await mkdir(plansDir, { recursive: true });
4770
- await mkdir(stateDir, { recursive: true });
4771
- await writeFile(join(plansDir, 'prd-issue-832.md'), '# Approved plan\n\nLaunch hint: omx ralph "Execute approved issue 832 plan"\n');
4772
- await writeFile(join(plansDir, 'test-spec-issue-832.md'), '# Test spec\n');
4773
- await writeFile(join(stateDir, 'ralplan-state.json'), JSON.stringify({
4774
- current_phase: 'complete',
4775
- planning_complete: true,
4776
- ralplan_consensus_gate: {
4777
- complete: true,
4778
- sequence: ['architect-review', 'critic-review'],
4779
- ralplan_architect_review: { agent_role: 'architect', verdict: 'approve', iteration: 1, sequence_index: 1 },
4780
- ralplan_critic_review: { agent_role: 'critic', verdict: 'approve', iteration: 1, sequence_index: 2 },
4781
- },
4782
- }));
4783
- const result = applyRalplanGate(['ralph'], 'ralph please', { cwd, priorSkill: 'ralplan' });
4784
- assert.equal(result.gateApplied, false);
4785
- assert.deepEqual(result.keywords, ['ralph']);
4786
- }
4787
- finally {
4788
- await rm(cwd, { recursive: true, force: true });
4789
- }
4790
- });
4791
- it('ignores ambient OMX_ROOT consensus state for local PRD/test-spec-only follow-up gating', async () => {
4792
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-gate-local-'));
4793
- const ambientRoot = await mkdtemp(join(tmpdir(), 'omx-keyword-gate-ambient-'));
4794
- const previousOmxRoot = process.env.OMX_ROOT;
4795
- try {
4796
- const plansDir = join(cwd, '.omx', 'plans');
4797
- await mkdir(plansDir, { recursive: true });
4798
- await writeFile(join(plansDir, 'prd-local.md'), '# Plan\n');
4799
- await writeFile(join(plansDir, 'test-spec-local.md'), '# Test spec\n');
4800
- const ambientStateDir = join(ambientRoot, '.omx', 'state');
4801
- await mkdir(ambientStateDir, { recursive: true });
4802
- await writeFile(join(ambientStateDir, 'ralplan-state.json'), JSON.stringify({
4803
- current_phase: 'complete',
4804
- planning_complete: true,
4805
- ralplan_consensus_gate: {
4806
- complete: true,
4807
- ralplan_architect_review: { agent_role: 'architect', verdict: 'approve', iteration: 1 },
4808
- ralplan_critic_review: { agent_role: 'critic', verdict: 'approve', iteration: 1 },
4809
- },
4810
- }));
4811
- process.env.OMX_ROOT = ambientRoot;
4812
- const result = applyRalplanGate(['team'], 'team', { cwd });
4813
- assert.equal(result.gateApplied, true);
4814
- assert.deepEqual(result.keywords, ['ralplan']);
4815
- }
4816
- finally {
4817
- if (previousOmxRoot === undefined)
4818
- delete process.env.OMX_ROOT;
4819
- else
4820
- process.env.OMX_ROOT = previousOmxRoot;
4821
- await rm(cwd, { recursive: true, force: true });
4822
- await rm(ambientRoot, { recursive: true, force: true });
4823
- }
4824
- });
4825
- it('gates short follow-up when local state only has latest verdict fields', async () => {
4826
- const cwd = await mkdtemp(join(tmpdir(), 'omx-keyword-gate-latest-only-'));
4827
- try {
4828
- const plansDir = join(cwd, '.omx', 'plans');
4829
- const stateDir = join(cwd, '.omx', 'state');
4830
- await mkdir(plansDir, { recursive: true });
4831
- await mkdir(stateDir, { recursive: true });
4832
- await writeFile(join(plansDir, 'prd-local.md'), '# Plan\n\nLaunch hint: omx team 3:executor "Execute approved local plan"\n');
4833
- await writeFile(join(plansDir, 'test-spec-local.md'), '# Test spec\n');
4834
- await writeFile(join(stateDir, 'ralplan-state.json'), JSON.stringify({
4835
- current_phase: 'complete',
4836
- planning_complete: true,
4837
- latest_architect_verdict: 'approve',
4838
- latest_critic_verdict: 'approve',
4839
- }));
4840
- const result = applyRalplanGate(['team'], 'team', { cwd });
4841
- assert.equal(result.gateApplied, true);
4842
- assert.deepEqual(result.keywords, ['ralplan']);
4843
- }
4844
- finally {
4845
- await rm(cwd, { recursive: true, force: true });
4846
- }
4847
- });
4848
- it('redirects underspecified execution keywords to ralplan', () => {
4849
- const result = applyRalplanGate(['ralph'], 'ralph fix this');
4850
- assert.equal(result.gateApplied, true);
4851
- assert.ok(result.keywords.includes('ralplan'));
4852
- assert.ok(!result.keywords.includes('ralph'));
4853
- });
4854
- it('redirects autopilot to ralplan when underspecified', () => {
4855
- const result = applyRalplanGate(['autopilot'], 'autopilot build the app');
4856
- assert.equal(result.gateApplied, true);
4857
- assert.ok(result.keywords.includes('ralplan'));
4858
- });
4859
- it('does not gate well-specified prompts', () => {
4860
- const result = applyRalplanGate(['ralph'], 'ralph fix src/hooks/bridge.ts null check');
4861
- assert.equal(result.gateApplied, false);
4862
- assert.ok(result.keywords.includes('ralph'));
4863
- });
4864
- it('does not gate when cancel is present', () => {
4865
- const result = applyRalplanGate(['cancel', 'ralph'], 'cancel ralph');
4866
- assert.equal(result.gateApplied, false);
4867
- });
4868
- it('does not gate when ralplan is already present', () => {
4869
- const result = applyRalplanGate(['ralplan'], 'ralplan add auth');
4870
- assert.equal(result.gateApplied, false);
4871
- assert.ok(result.keywords.includes('ralplan'));
4872
- });
4873
- it('does not gate non-execution keywords', () => {
4874
- const result = applyRalplanGate(['analyze'], 'analyze this');
4875
- assert.equal(result.gateApplied, false);
4876
- });
4877
- it('preserves non-execution keywords when gating', () => {
4878
- const result = applyRalplanGate(['ralph', 'analyze'], 'ralph analyze this');
4879
- assert.equal(result.gateApplied, true);
4880
- assert.ok(result.keywords.includes('analyze'));
4881
- assert.ok(result.keywords.includes('ralplan'));
4882
- assert.ok(!result.keywords.includes('ralph'));
4883
- });
4884
- it('handles force: escape hatch — does not gate', () => {
4885
- const result = applyRalplanGate(['ralph'], 'force: ralph refactor the auth module');
4886
- assert.equal(result.gateApplied, false);
4887
- });
4888
- it('gates multiple execution keywords at once', () => {
4889
- const result = applyRalplanGate(['ralph', 'team'], 'ralph team fix this');
4890
- assert.equal(result.gateApplied, true);
4891
- assert.ok(result.keywords.includes('ralplan'));
4892
- assert.ok(!result.keywords.includes('ralph'));
4893
- assert.ok(!result.keywords.includes('team'));
4894
- assert.ok(result.gatedKeywords.includes('ralph'));
4895
- assert.ok(result.gatedKeywords.includes('team'));
4896
- });
4897
- it('returns empty keywords unchanged when no keywords', () => {
4898
- const result = applyRalplanGate([], 'fix this');
4899
- assert.equal(result.gateApplied, false);
4900
- assert.deepEqual(result.keywords, []);
4901
- });
4902
- it('does not duplicate ralplan if already in filtered list', () => {
4903
- // ultrawork is an execution keyword; after filtering, ralplan added once
4904
- const result = applyRalplanGate(['ultrawork'], 'ultrawork do stuff');
4905
- assert.equal(result.keywords.filter(k => k === 'ralplan').length, 1);
4906
- });
4907
- it('reports gatedKeywords correctly', () => {
4908
- const result = applyRalplanGate(['ralph', 'ultrawork'], 'ralph ultrawork build');
4909
- assert.ok(result.gatedKeywords.includes('ralph'));
4910
- assert.ok(result.gatedKeywords.includes('ultrawork'));
4911
- });
4912
- });
4913
4281
  describe('recordSkillActivation prompt provenance', () => {
4914
4282
  it('writes only the authorized explicit payload session and stamps its owner', async () => {
4915
4283
  const stateDir = await mkdtemp(join(tmpdir(), 'omx-keyword-provenance-'));