oh-my-codex 0.16.1 → 0.16.3

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 (247) hide show
  1. package/Cargo.lock +5 -5
  2. package/Cargo.toml +1 -1
  3. package/README.md +2 -2
  4. package/dist/cli/__tests__/doctor-warning-copy.test.js +37 -1
  5. package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
  6. package/dist/cli/__tests__/explore.test.js +2 -2
  7. package/dist/cli/__tests__/explore.test.js.map +1 -1
  8. package/dist/cli/__tests__/index.test.js +173 -3
  9. package/dist/cli/__tests__/index.test.js.map +1 -1
  10. package/dist/cli/__tests__/launch-fallback.test.js +58 -0
  11. package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
  12. package/dist/cli/__tests__/ralph.test.js +1 -0
  13. package/dist/cli/__tests__/ralph.test.js.map +1 -1
  14. package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js +8 -0
  15. package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js.map +1 -1
  16. package/dist/cli/__tests__/setup-install-mode.test.js +82 -2
  17. package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
  18. package/dist/cli/__tests__/setup-scope.test.js +12 -0
  19. package/dist/cli/__tests__/setup-scope.test.js.map +1 -1
  20. package/dist/cli/__tests__/team.test.js +161 -0
  21. package/dist/cli/__tests__/team.test.js.map +1 -1
  22. package/dist/cli/__tests__/ultragoal.test.js +14 -9
  23. package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
  24. package/dist/cli/__tests__/uninstall.test.js +44 -2
  25. package/dist/cli/__tests__/uninstall.test.js.map +1 -1
  26. package/dist/cli/__tests__/update.test.js +109 -19
  27. package/dist/cli/__tests__/update.test.js.map +1 -1
  28. package/dist/cli/doctor.d.ts.map +1 -1
  29. package/dist/cli/doctor.js +17 -0
  30. package/dist/cli/doctor.js.map +1 -1
  31. package/dist/cli/explore.d.ts.map +1 -1
  32. package/dist/cli/explore.js +3 -4
  33. package/dist/cli/explore.js.map +1 -1
  34. package/dist/cli/index.d.ts.map +1 -1
  35. package/dist/cli/index.js +34 -4
  36. package/dist/cli/index.js.map +1 -1
  37. package/dist/cli/setup.d.ts.map +1 -1
  38. package/dist/cli/setup.js +72 -6
  39. package/dist/cli/setup.js.map +1 -1
  40. package/dist/cli/team.d.ts.map +1 -1
  41. package/dist/cli/team.js +54 -15
  42. package/dist/cli/team.js.map +1 -1
  43. package/dist/cli/ultragoal.d.ts +1 -1
  44. package/dist/cli/ultragoal.d.ts.map +1 -1
  45. package/dist/cli/ultragoal.js +26 -8
  46. package/dist/cli/ultragoal.js.map +1 -1
  47. package/dist/cli/uninstall.d.ts.map +1 -1
  48. package/dist/cli/uninstall.js +68 -5
  49. package/dist/cli/uninstall.js.map +1 -1
  50. package/dist/cli/update.d.ts +10 -2
  51. package/dist/cli/update.d.ts.map +1 -1
  52. package/dist/cli/update.js +99 -5
  53. package/dist/cli/update.js.map +1 -1
  54. package/dist/config/__tests__/codex-hooks.test.js +269 -2
  55. package/dist/config/__tests__/codex-hooks.test.js.map +1 -1
  56. package/dist/config/__tests__/generator-idempotent.test.js +60 -2
  57. package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
  58. package/dist/config/__tests__/generator-notify.test.js +59 -1
  59. package/dist/config/__tests__/generator-notify.test.js.map +1 -1
  60. package/dist/config/__tests__/wiki-config-contract.test.js +2 -1
  61. package/dist/config/__tests__/wiki-config-contract.test.js.map +1 -1
  62. package/dist/config/codex-hooks.d.ts +52 -4
  63. package/dist/config/codex-hooks.d.ts.map +1 -1
  64. package/dist/config/codex-hooks.js +268 -7
  65. package/dist/config/codex-hooks.js.map +1 -1
  66. package/dist/config/generator.d.ts +13 -1
  67. package/dist/config/generator.d.ts.map +1 -1
  68. package/dist/config/generator.js +207 -12
  69. package/dist/config/generator.js.map +1 -1
  70. package/dist/hooks/__tests__/keyword-detector.test.js +37 -25
  71. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  72. package/dist/hooks/__tests__/notify-fallback-watcher.test.js +29 -1
  73. package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
  74. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +20 -4
  75. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
  76. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +1 -0
  77. package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js.map +1 -1
  78. package/dist/hooks/__tests__/notify-hook-non-omx-guard.test.d.ts +2 -0
  79. package/dist/hooks/__tests__/notify-hook-non-omx-guard.test.d.ts.map +1 -0
  80. package/dist/hooks/__tests__/notify-hook-non-omx-guard.test.js +52 -0
  81. package/dist/hooks/__tests__/notify-hook-non-omx-guard.test.js.map +1 -0
  82. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +148 -0
  83. package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +1 -1
  84. package/dist/hooks/__tests__/notify-hook-session-scope.test.js +3 -0
  85. package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
  86. package/dist/hooks/__tests__/wiki-docs-contract.test.js +5 -4
  87. package/dist/hooks/__tests__/wiki-docs-contract.test.js.map +1 -1
  88. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  89. package/dist/hooks/keyword-detector.js +2 -4
  90. package/dist/hooks/keyword-detector.js.map +1 -1
  91. package/dist/mcp/__tests__/state-server.test.js +145 -6
  92. package/dist/mcp/__tests__/state-server.test.js.map +1 -1
  93. package/dist/mcp/__tests__/wiki-server.test.js +97 -1
  94. package/dist/mcp/__tests__/wiki-server.test.js.map +1 -1
  95. package/dist/mcp/wiki-server.d.ts.map +1 -1
  96. package/dist/mcp/wiki-server.js +11 -2
  97. package/dist/mcp/wiki-server.js.map +1 -1
  98. package/dist/planning/__tests__/artifacts.test.js +64 -0
  99. package/dist/planning/__tests__/artifacts.test.js.map +1 -1
  100. package/dist/planning/__tests__/ready-context-pack-role-refs.test.d.ts +2 -0
  101. package/dist/planning/__tests__/ready-context-pack-role-refs.test.d.ts.map +1 -0
  102. package/dist/planning/__tests__/ready-context-pack-role-refs.test.js +90 -0
  103. package/dist/planning/__tests__/ready-context-pack-role-refs.test.js.map +1 -0
  104. package/dist/planning/artifacts.d.ts +7 -2
  105. package/dist/planning/artifacts.d.ts.map +1 -1
  106. package/dist/planning/artifacts.js +62 -8
  107. package/dist/planning/artifacts.js.map +1 -1
  108. package/dist/planning/context-pack-status.d.ts +6 -0
  109. package/dist/planning/context-pack-status.d.ts.map +1 -1
  110. package/dist/planning/context-pack-status.js +25 -0
  111. package/dist/planning/context-pack-status.js.map +1 -1
  112. package/dist/ralph/persistence.d.ts +1 -1
  113. package/dist/ralph/persistence.d.ts.map +1 -1
  114. package/dist/ralph/persistence.js +8 -2
  115. package/dist/ralph/persistence.js.map +1 -1
  116. package/dist/scripts/__tests__/codex-native-hook.test.js +190 -1
  117. package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
  118. package/dist/scripts/codex-execution-surface.d.ts +1 -1
  119. package/dist/scripts/codex-execution-surface.d.ts.map +1 -1
  120. package/dist/scripts/codex-execution-surface.js.map +1 -1
  121. package/dist/scripts/codex-native-hook.d.ts +1 -1
  122. package/dist/scripts/codex-native-hook.d.ts.map +1 -1
  123. package/dist/scripts/codex-native-hook.js +18 -3
  124. package/dist/scripts/codex-native-hook.js.map +1 -1
  125. package/dist/scripts/notify-dispatcher.d.ts +7 -0
  126. package/dist/scripts/notify-dispatcher.d.ts.map +1 -0
  127. package/dist/scripts/notify-dispatcher.js +58 -0
  128. package/dist/scripts/notify-dispatcher.js.map +1 -0
  129. package/dist/scripts/notify-fallback-watcher.js +4 -0
  130. package/dist/scripts/notify-fallback-watcher.js.map +1 -1
  131. package/dist/scripts/notify-hook/ralph-session-resume.d.ts.map +1 -1
  132. package/dist/scripts/notify-hook/ralph-session-resume.js +96 -8
  133. package/dist/scripts/notify-hook/ralph-session-resume.js.map +1 -1
  134. package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
  135. package/dist/scripts/notify-hook/state-io.js +6 -2
  136. package/dist/scripts/notify-hook/state-io.js.map +1 -1
  137. package/dist/scripts/notify-hook/visual-verdict.js +3 -3
  138. package/dist/scripts/notify-hook/visual-verdict.js.map +1 -1
  139. package/dist/scripts/notify-hook.js +124 -0
  140. package/dist/scripts/notify-hook.js.map +1 -1
  141. package/dist/state/__tests__/operations.test.js +79 -0
  142. package/dist/state/__tests__/operations.test.js.map +1 -1
  143. package/dist/state/__tests__/skill-active.test.js +10 -18
  144. package/dist/state/__tests__/skill-active.test.js.map +1 -1
  145. package/dist/state/operations.d.ts.map +1 -1
  146. package/dist/state/operations.js +1 -20
  147. package/dist/state/operations.js.map +1 -1
  148. package/dist/state/skill-active.d.ts +1 -0
  149. package/dist/state/skill-active.d.ts.map +1 -1
  150. package/dist/state/skill-active.js +28 -18
  151. package/dist/state/skill-active.js.map +1 -1
  152. package/dist/state/workflow-transition-reconcile.d.ts.map +1 -1
  153. package/dist/state/workflow-transition-reconcile.js +1 -0
  154. package/dist/state/workflow-transition-reconcile.js.map +1 -1
  155. package/dist/team/__tests__/approved-execution.test.js +45 -1
  156. package/dist/team/__tests__/approved-execution.test.js.map +1 -1
  157. package/dist/team/__tests__/runtime.test.js +173 -19
  158. package/dist/team/__tests__/runtime.test.js.map +1 -1
  159. package/dist/team/__tests__/worker-bootstrap.test.js +37 -0
  160. package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
  161. package/dist/team/approved-execution.d.ts +1 -0
  162. package/dist/team/approved-execution.d.ts.map +1 -1
  163. package/dist/team/approved-execution.js +50 -0
  164. package/dist/team/approved-execution.js.map +1 -1
  165. package/dist/team/delivery-log.d.ts.map +1 -1
  166. package/dist/team/delivery-log.js +8 -1
  167. package/dist/team/delivery-log.js.map +1 -1
  168. package/dist/team/runtime.d.ts.map +1 -1
  169. package/dist/team/runtime.js +104 -18
  170. package/dist/team/runtime.js.map +1 -1
  171. package/dist/team/state/mailbox.d.ts +1 -0
  172. package/dist/team/state/mailbox.d.ts.map +1 -1
  173. package/dist/team/state/mailbox.js +10 -1
  174. package/dist/team/state/mailbox.js.map +1 -1
  175. package/dist/team/state-root.js +1 -1
  176. package/dist/team/state-root.js.map +1 -1
  177. package/dist/team/state.d.ts.map +1 -1
  178. package/dist/team/state.js +2 -2
  179. package/dist/team/state.js.map +1 -1
  180. package/dist/team/worker-bootstrap.d.ts +7 -2
  181. package/dist/team/worker-bootstrap.d.ts.map +1 -1
  182. package/dist/team/worker-bootstrap.js +17 -4
  183. package/dist/team/worker-bootstrap.js.map +1 -1
  184. package/dist/ultragoal/__tests__/artifacts.test.js +81 -7
  185. package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
  186. package/dist/ultragoal/__tests__/docs-contract.test.js +8 -0
  187. package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -1
  188. package/dist/ultragoal/artifacts.d.ts +4 -0
  189. package/dist/ultragoal/artifacts.d.ts.map +1 -1
  190. package/dist/ultragoal/artifacts.js +72 -4
  191. package/dist/ultragoal/artifacts.js.map +1 -1
  192. package/dist/utils/paths.d.ts +3 -1
  193. package/dist/utils/paths.d.ts.map +1 -1
  194. package/dist/utils/paths.js +6 -2
  195. package/dist/utils/paths.js.map +1 -1
  196. package/dist/wiki/__tests__/ingest.test.js +35 -1
  197. package/dist/wiki/__tests__/ingest.test.js.map +1 -1
  198. package/dist/wiki/__tests__/lint.test.js +14 -1
  199. package/dist/wiki/__tests__/lint.test.js.map +1 -1
  200. package/dist/wiki/__tests__/query.test.js +28 -3
  201. package/dist/wiki/__tests__/query.test.js.map +1 -1
  202. package/dist/wiki/__tests__/session-hooks.test.js +30 -2
  203. package/dist/wiki/__tests__/session-hooks.test.js.map +1 -1
  204. package/dist/wiki/__tests__/storage.test.js +62 -22
  205. package/dist/wiki/__tests__/storage.test.js.map +1 -1
  206. package/dist/wiki/index.d.ts +2 -2
  207. package/dist/wiki/index.d.ts.map +1 -1
  208. package/dist/wiki/index.js +2 -2
  209. package/dist/wiki/index.js.map +1 -1
  210. package/dist/wiki/ingest.js +2 -2
  211. package/dist/wiki/ingest.js.map +1 -1
  212. package/dist/wiki/lifecycle.d.ts +5 -0
  213. package/dist/wiki/lifecycle.d.ts.map +1 -1
  214. package/dist/wiki/lifecycle.js +31 -4
  215. package/dist/wiki/lifecycle.js.map +1 -1
  216. package/dist/wiki/lint.d.ts.map +1 -1
  217. package/dist/wiki/lint.js +12 -8
  218. package/dist/wiki/lint.js.map +1 -1
  219. package/dist/wiki/query.d.ts.map +1 -1
  220. package/dist/wiki/query.js +3 -2
  221. package/dist/wiki/query.js.map +1 -1
  222. package/dist/wiki/storage.d.ts +4 -0
  223. package/dist/wiki/storage.d.ts.map +1 -1
  224. package/dist/wiki/storage.js +54 -18
  225. package/dist/wiki/storage.js.map +1 -1
  226. package/package.json +1 -1
  227. package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
  228. package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +2 -2
  229. package/plugins/oh-my-codex/skills/plan/SKILL.md +4 -4
  230. package/plugins/oh-my-codex/skills/ralplan/SKILL.md +2 -2
  231. package/plugins/oh-my-codex/skills/ultragoal/SKILL.md +11 -7
  232. package/plugins/oh-my-codex/skills/wiki/SKILL.md +5 -5
  233. package/prompts/planner.md +1 -1
  234. package/skills/deep-interview/SKILL.md +2 -2
  235. package/skills/plan/SKILL.md +4 -4
  236. package/skills/ralplan/SKILL.md +2 -2
  237. package/skills/ultragoal/SKILL.md +11 -7
  238. package/skills/wiki/SKILL.md +5 -5
  239. package/src/scripts/__tests__/codex-native-hook.test.ts +218 -1
  240. package/src/scripts/codex-execution-surface.ts +2 -0
  241. package/src/scripts/codex-native-hook.ts +22 -3
  242. package/src/scripts/notify-dispatcher.ts +74 -0
  243. package/src/scripts/notify-fallback-watcher.ts +6 -2
  244. package/src/scripts/notify-hook/ralph-session-resume.ts +117 -8
  245. package/src/scripts/notify-hook/state-io.ts +4 -2
  246. package/src/scripts/notify-hook/visual-verdict.ts +3 -3
  247. package/src/scripts/notify-hook.ts +116 -0
@@ -9,7 +9,7 @@ Use when the user asks for `ultragoal`, `create-goals`, `complete-goals`, durabl
9
9
 
10
10
  ## Purpose
11
11
 
12
- `ultragoal` turns a brief into repo-native artifacts and then drives one goal at a time through Codex goal tools:
12
+ `ultragoal` turns a brief into repo-native artifacts and then drives a Codex goal safely through goal tools. New plans default to an aggregate Codex goal for the whole ultragoal run while OMX tracks G001/G002 story progress in the ledger.
13
13
 
14
14
  - `.omx/ultragoal/brief.md`
15
15
  - `.omx/ultragoal/goals.json`
@@ -21,6 +21,7 @@ Use when the user asks for `ultragoal`, `create-goals`, `complete-goals`, durabl
21
21
  - `omx ultragoal create-goals --brief "<brief>"`
22
22
  - `omx ultragoal create-goals --brief-file <path>`
23
23
  - `cat <brief> | omx ultragoal create-goals --from-stdin`
24
+ - `omx ultragoal create-goals --codex-goal-mode per-story --brief "<brief>"` only when one fresh Codex thread per story is explicitly preferred
24
25
  2. Inspect `.omx/ultragoal/goals.json` and refine if needed.
25
26
 
26
27
  ## Complete goals
@@ -30,20 +31,23 @@ Loop until `omx ultragoal status` reports all goals complete:
30
31
  1. Run `omx ultragoal complete-goals`.
31
32
  2. Read the printed handoff.
32
33
  3. Call `get_goal`.
33
- 4. If no active Codex goal exists, call `create_goal` with the printed payload.
34
- 5. Complete that single goal only.
35
- 6. Run a completion audit against the objective and real artifacts/tests.
36
- 7. When complete, call `update_goal({status: "complete"})`, then call `get_goal` again for a fresh completion snapshot.
34
+ 4. If no active Codex goal exists, call `create_goal` with the printed payload. In aggregate mode, if the same aggregate Codex objective is already active, continue the current OMX story without creating a new Codex goal.
35
+ 5. Complete the current OMX story only.
36
+ 6. Run a completion audit against the story objective and real artifacts/tests.
37
+ 7. In aggregate mode, do **not** call `update_goal` for intermediate stories; checkpoint with a fresh `get_goal` snapshot whose aggregate objective is still `active`. On the final story only, call `update_goal({status: "complete"})`, then call `get_goal` again for a fresh `complete` snapshot.
37
38
  8. Checkpoint the durable ledger with that snapshot:
38
39
  `omx ultragoal checkpoint --goal-id <id> --status complete --evidence "<evidence>" --codex-goal-json <get_goal-json-or-path>`
39
40
  9. If blocked or failed, checkpoint failure:
40
41
  `omx ultragoal checkpoint --goal-id <id> --status failed --evidence "<blocker/evidence>"`
41
- 10. Resume failed goals with `omx ultragoal complete-goals --retry-failed`.
42
+ 10. For legacy per-story completed-goal blockers, preserve the non-terminal blocker with:
43
+ `omx ultragoal checkpoint --goal-id <id> --status blocked --evidence "<completed legacy Codex goal blocks create_goal in this thread>" --codex-goal-json <get_goal-json-or-path>`
44
+ 11. Resume failed goals with `omx ultragoal complete-goals --retry-failed`.
42
45
 
43
46
  ## Constraints
44
47
 
45
48
  - The shell command cannot directly invoke Codex interactive `/goal`; it emits a model-facing handoff for the active Codex agent.
46
49
  - Never call `create_goal` when `get_goal` reports a different active goal.
47
- - Never call `update_goal` unless the current goal is actually complete.
50
+ - Never call `update_goal` unless the aggregate run or legacy per-story goal is actually complete.
51
+ - In aggregate mode, intermediate story checkpoints require a matching `active` Codex snapshot; final story completion requires a matching `complete` snapshot after `update_goal`.
48
52
  - Completion checkpoints require read-only Codex snapshot reconciliation: pass fresh `get_goal` JSON/path with `--codex-goal-json`; shell commands and hooks must not mutate Codex goal state.
49
53
  - Treat `ledger.jsonl` as the durable audit trail; checkpoint after every success or failure.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: wiki
3
- description: Persistent markdown project wiki stored under .omx/wiki with keyword search and lifecycle capture
3
+ description: Persistent markdown project wiki stored under repository omx_wiki with keyword search and lifecycle capture
4
4
  triggers: ["wiki add", "wiki lint", "wiki query", "wiki read", "wiki delete"]
5
5
  ---
6
6
 
@@ -42,9 +42,9 @@ wiki_refresh()
42
42
  `architecture`, `decision`, `pattern`, `debugging`, `environment`, `session-log`, `reference`, `convention`
43
43
 
44
44
  ## Storage
45
- - Pages: `.omx/wiki/*.md`
46
- - Index: `.omx/wiki/index.md`
47
- - Log: `.omx/wiki/log.md`
45
+ - Pages: `omx_wiki/*.md`
46
+ - Index: `omx_wiki/index.md`
47
+ - Log: `omx_wiki/log.md`
48
48
 
49
49
  ## Cross-References
50
50
  Use `[[page-name]]` wiki-link syntax to create cross-references between pages.
@@ -54,4 +54,4 @@ At session end, discoveries can be captured as `session-log-*` pages. Configure
54
54
 
55
55
  ## Hard Constraints
56
56
  - No vector embeddings — query uses keyword + tag matching only
57
- - Wiki files remain local project state under `.omx/wiki/`
57
+ - Wiki files are repository project knowledge under `omx_wiki/`; legacy `.omx/wiki/` is read-only compatibility input when no canonical wiki exists
@@ -59,7 +59,7 @@ Leave execution with a right-sized, evidence-grounded plan: scope, steps, accept
59
59
  - Codebase facts come from inspection.
60
60
  - Plan is saved to `.omx/plans/{name}.md`.
61
61
  - User confirmation is obtained before handoff.
62
- - Consensus mode includes complete RALPLAN-DR, ADR, an explicit available-agent-types roster, staffing guidance for team and ralph follow-up paths, product-facing goal-mode follow-up suggestions (`$ultragoal` generally, `$autoresearch-goal` for research projects, `$performance-goal` for optimization/performance projects), suggested reasoning levels by lane, launch hints, and a team verification path when needed.
62
+ - Consensus mode includes complete RALPLAN-DR, ADR, an explicit available-agent-types roster, staffing guidance for team and ralph follow-up paths, product-facing goal-mode follow-up suggestions (`$ultragoal` generally and by default, `$autoresearch-goal` for research projects, `$performance-goal` for optimization/performance projects), suggested reasoning levels by lane, launch hints, and a team verification path when needed.
63
63
  </success_criteria>
64
64
 
65
65
  <tools>
@@ -365,7 +365,7 @@ Present execution options after artifact generation using explicit handoff contr
365
365
 
366
366
  Include these product-facing suggestions when they fit the clarified spec, without removing the existing `$ralplan`, `$autopilot`, `$ralph`, and `$team` handoff options:
367
367
 
368
- - **`$ultragoal`** — use for general goal-oriented follow-up when the spec should be converted into durable Codex goals with sequential completion tracking.
368
+ - **`$ultragoal`** — default goal-mode follow-up for implementation or general goal-oriented follow-up specs that should be converted into durable Codex/OMX goals with sequential completion tracking.
369
369
  - **`$autoresearch-goal`** — use when the clarified context is a research project: a research question, reference/literature gathering, evaluator-backed analysis, or professor/critic-style deliverable.
370
370
  - **`$performance-goal`** — use when the clarified context is an optimization or performance project with measurable speed, latency, throughput, memory, benchmark, or evaluator criteria.
371
371
 
@@ -378,7 +378,7 @@ Preserve `$ralph` for persistent single-owner execution/verification and `$team`
378
378
  - **Skipped / Already-Satisfied Stages:** Requirements discovery, ambiguity clarification, and early intent-boundary elicitation
379
379
  - **Expected Output:** Canonical planning artifacts under `.omx/plans/`, especially `prd-*.md` and `test-spec-*.md`
380
380
  - **Best When:** Requirements are clear enough to stop interviewing, but architectural validation / consensus planning is still desirable
381
- - **Next Recommended Step:** Use the approved planning artifacts with `$autopilot`, `$ralph`, `$team`, or a goal-mode follow-up (`$ultragoal`, `$autoresearch-goal`, `$performance-goal`) depending on whether the next need is direct execution, coordination, durable goals, research validation, or measurable optimization
381
+ - **Next Recommended Step:** Use the approved planning artifacts with `$autopilot`, `$ralph`, `$team`, or `$ultragoal` as the default goal-mode follow-up; choose `$autoresearch-goal` for research validation or `$performance-goal` for measurable optimization
382
382
 
383
383
  ### 2. **`$autopilot`**
384
384
  - **Input Artifact:** `.omx/specs/deep-interview-{slug}.md`
@@ -95,12 +95,12 @@ Jumping into code without understanding requirements leads to rework, scope cree
95
95
  c. Update the plan file in `.omx/plans/` with the accepted improvements (add missing details, refine steps, strengthen acceptance criteria, ADR updates, etc.)
96
96
  d. Note which improvements were applied in a brief changelog section at the end of the plan
97
97
  e. Before any execution handoff, derive an explicit **available-agent-types roster** from the known prompt catalog and add concrete **follow-up staffing guidance** for both `$ralph` and `$team` (recommended roles, counts, suggested reasoning levels by lane, and why each lane exists)
98
- f. Add a product-facing **Goal-Mode Follow-up Suggestions** section: suggest `$ultragoal` for general goal-oriented follow-up, `$autoresearch-goal` when the context is a research project, and `$performance-goal` when the context is an optimization or performance project. Keep these suggestions alongside the Ralph/team paths rather than replacing them when implementation delivery is still the main need.
98
+ f. Add a product-facing **Goal-Mode Follow-up Suggestions** section: recommend `$ultragoal` by default for general goal-oriented follow-up, `$autoresearch-goal` when the context is a research project, and `$performance-goal` when the context is an optimization or performance project. Keep these suggestions alongside the Ralph/team paths rather than replacing them when implementation delivery is still the main need.
99
99
  g. For the `$team` path, add an explicit launch-hint block with concrete `omx team` / `$team` commands and a **team verification path** (what team proves before shutdown, what Ralph verifies after handoff)
100
100
  7. On Critic approval (with improvements applied): *(--interactive only)* If running with `--interactive`, use `AskUserQuestion` / the structured question UI to present the plan with these options:
101
101
  - **Approve and execute** — proceed to implementation via ralph+ultrawork
102
102
  - **Approve and implement via team** — proceed to implementation via coordinated parallel team agents
103
- - **Start goal-mode follow-up** — proceed via `$ultragoal`, `$autoresearch-goal`, or `$performance-goal` when the approved plan fits durable goals, research validation, or measurable optimization
103
+ - **Start goal-mode follow-up** — proceed via `$ultragoal` by default, or `$autoresearch-goal` / `$performance-goal` when the approved plan specifically fits research validation or measurable optimization
104
104
  - **Request changes** — return to step 1 with user feedback
105
105
  - **Reject** — discard the plan entirely
106
106
  If NOT running with `--interactive`, output the final approved plan and stop. Do NOT auto-execute.
@@ -108,7 +108,7 @@ Jumping into code without understanding requirements leads to rework, scope cree
108
108
  9. On user approval (--interactive only):
109
109
  - **Approve and execute**: **MUST** invoke `$ralph` with the approved plan path from `.omx/plans/` as context **plus the explicit available-agent-types roster, suggested reasoning levels, concrete role allocation guidance, and direct launch hints for Ralph follow-up work**. Do NOT implement directly. Do NOT edit source code files in the planning agent. The ralph skill handles execution via ultrawork parallel agents.
110
110
  - **Approve and implement via team**: **MUST** invoke `$team` with the approved plan path from `.omx/plans/` as context **plus the explicit available-agent-types roster, suggested reasoning levels, concrete staffing / worker-role allocation guidance, explicit `omx team` / `$team` launch hints, and the team verification path**. Do NOT implement directly. The team skill coordinates parallel agents across the staged pipeline for faster execution on large tasks.
111
- - **Start goal-mode follow-up**: **MUST** invoke the selected goal workflow with the approved plan path and appropriate success context: `$ultragoal` for general goal-oriented follow-up, `$autoresearch-goal` for research projects, or `$performance-goal` for optimization/performance projects with measurable evaluator criteria. Do NOT implement directly in the planning agent.
111
+ - **Start goal-mode follow-up**: **MUST** invoke the selected goal workflow with the approved plan path and appropriate success context: `$ultragoal` as the default goal-mode path, `$autoresearch-goal` for research projects, or `$performance-goal` for optimization/performance projects with measurable evaluator criteria. Do NOT implement directly in the planning agent.
112
112
 
113
113
  ### Review Mode (`--review`)
114
114
 
@@ -150,7 +150,7 @@ Plans are saved to `.omx/plans/`. Drafts go to `.omx/drafts/`.
150
150
  - In consensus mode, default to RALPLAN-DR short mode; enable deliberate mode on `--deliberate` or explicit high-risk signals (auth/security, migrations, destructive changes, production incidents, compliance/PII, public API breakage)
151
151
  - In consensus mode with `--interactive`: use `AskUserQuestion` / the structured question UI for the user feedback step (step 2) and the final approval step (step 7) -- never ask for approval in plain text when a structured surface is available. Without `--interactive`, auto-proceed through planning steps without pausing. Output the final plan without execution.
152
152
  - In consensus mode with `--interactive`, on user approval **MUST** invoke the selected follow-up lane from step 9 (`$ralph`, `$team`, `$ultragoal`, `$autoresearch-goal`, or `$performance-goal`) -- never implement directly in the planning agent
153
- - In consensus mode, execution follow-up handoff **MUST** include an explicit available-agent-types roster plus concrete staffing / role-allocation guidance grounded in that roster, suggested reasoning levels by lane, product-facing goal-mode follow-up suggestions (`$ultragoal` generally, `$autoresearch-goal` for research projects, `$performance-goal` for optimization/performance projects), explicit `omx team` / `$team` launch hints, and a team verification path
153
+ - In consensus mode, execution follow-up handoff **MUST** include an explicit available-agent-types roster plus concrete staffing / role-allocation guidance grounded in that roster, suggested reasoning levels by lane, product-facing goal-mode follow-up suggestions (`$ultragoal` by default, `$autoresearch-goal` for research projects, `$performance-goal` for optimization/performance projects), explicit `omx team` / `$team` launch hints, and a team verification path
154
154
  </Tool_Usage>
155
155
 
156
156
 
@@ -54,7 +54,7 @@ The consensus workflow:
54
54
  d. Return to Critic evaluation
55
55
  e. Repeat this loop until Critic returns `APPROVE` or 5 iterations are reached
56
56
  f. If 5 iterations are reached without `APPROVE`, present the best version to the user
57
- 6. On Critic approval *(--interactive only)*: If `--interactive` is set, use the structured question UI to present the plan with approval options (Approve and execute via ralph / Approve and implement via team / Start a goal-mode follow-up / Request changes / Reject). Final plan must include ADR (Decision, Drivers, Alternatives considered, Why chosen, Consequences, Follow-ups), an explicit available-agent-types roster, concrete follow-up staffing guidance for both `ralph` and `team`, suggested reasoning levels by lane, explicit `omx team` / `$team` launch hints, a concrete **team verification** path, and a product-facing **Goal-Mode Follow-up Suggestions** section. Suggest `$ultragoal` for general goal-oriented follow-up, `$autoresearch-goal` when the context is a research project, and `$performance-goal` when the context is an optimization or performance project. Otherwise, output the final plan and stop.
57
+ 6. On Critic approval *(--interactive only)*: If `--interactive` is set, use the structured question UI to present the plan with approval options (Approve and execute via ralph / Approve and implement via team / Start a goal-mode follow-up / Request changes / Reject). Final plan must include ADR (Decision, Drivers, Alternatives considered, Why chosen, Consequences, Follow-ups), an explicit available-agent-types roster, concrete follow-up staffing guidance for both `ralph` and `team`, suggested reasoning levels by lane, explicit `omx team` / `$team` launch hints, a concrete **team verification** path, and a product-facing **Goal-Mode Follow-up Suggestions** section. Recommend `$ultragoal` by default for goal-mode follow-up, use `$autoresearch-goal` instead when the context is a research project, and use `$performance-goal` instead when the context is an optimization or performance project. Otherwise, output the final plan and stop.
58
58
  7. *(--interactive only)* User chooses: Approve (ralph, team, or a goal-mode follow-up), Request changes, or Reject
59
59
  8. *(--interactive only)* On approval: invoke `$ralph` for sequential execution, `$team` for parallel team execution, or the selected goal-mode follow-up (`$ultragoal`, `$autoresearch-goal`, or `$performance-goal`) with the approved plan and matching success/evaluator context -- never implement directly. Preserve the explicit available-agent-types roster, reasoning-by-lane guidance, role/staffing allocation guidance, launch hints, and verification-path guidance from the approved plan for Ralph/team paths.
60
60
 
@@ -66,7 +66,7 @@ Follow the Plan skill's full documentation for consensus mode details.
66
66
 
67
67
  When ralplan outputs a final handoff or asks the user to choose a next lane, include product-facing goal-mode suggestions alongside the existing Ralph and team options:
68
68
 
69
- - `$ultragoal` — general goal-oriented follow-up when the plan should become one or more durable Codex goals with sequential completion tracking.
69
+ - `$ultragoal` — **default goal-mode follow-up** for implementation or general goal-oriented follow-up plans that should become durable Codex/OMX goals with sequential completion tracking.
70
70
  - `$autoresearch-goal` — research-project follow-up when the plan centers on a question, literature/reference gathering, evaluator-backed research, or a professor/critic-style research deliverable.
71
71
  - `$performance-goal` — optimization/performance follow-up when the plan centers on speed, latency, throughput, memory, benchmark, or other measurable performance work.
72
72
 
@@ -9,7 +9,7 @@ Use when the user asks for `ultragoal`, `create-goals`, `complete-goals`, durabl
9
9
 
10
10
  ## Purpose
11
11
 
12
- `ultragoal` turns a brief into repo-native artifacts and then drives one goal at a time through Codex goal tools:
12
+ `ultragoal` turns a brief into repo-native artifacts and then drives a Codex goal safely through goal tools. New plans default to an aggregate Codex goal for the whole ultragoal run while OMX tracks G001/G002 story progress in the ledger.
13
13
 
14
14
  - `.omx/ultragoal/brief.md`
15
15
  - `.omx/ultragoal/goals.json`
@@ -21,6 +21,7 @@ Use when the user asks for `ultragoal`, `create-goals`, `complete-goals`, durabl
21
21
  - `omx ultragoal create-goals --brief "<brief>"`
22
22
  - `omx ultragoal create-goals --brief-file <path>`
23
23
  - `cat <brief> | omx ultragoal create-goals --from-stdin`
24
+ - `omx ultragoal create-goals --codex-goal-mode per-story --brief "<brief>"` only when one fresh Codex thread per story is explicitly preferred
24
25
  2. Inspect `.omx/ultragoal/goals.json` and refine if needed.
25
26
 
26
27
  ## Complete goals
@@ -30,20 +31,23 @@ Loop until `omx ultragoal status` reports all goals complete:
30
31
  1. Run `omx ultragoal complete-goals`.
31
32
  2. Read the printed handoff.
32
33
  3. Call `get_goal`.
33
- 4. If no active Codex goal exists, call `create_goal` with the printed payload.
34
- 5. Complete that single goal only.
35
- 6. Run a completion audit against the objective and real artifacts/tests.
36
- 7. When complete, call `update_goal({status: "complete"})`, then call `get_goal` again for a fresh completion snapshot.
34
+ 4. If no active Codex goal exists, call `create_goal` with the printed payload. In aggregate mode, if the same aggregate Codex objective is already active, continue the current OMX story without creating a new Codex goal.
35
+ 5. Complete the current OMX story only.
36
+ 6. Run a completion audit against the story objective and real artifacts/tests.
37
+ 7. In aggregate mode, do **not** call `update_goal` for intermediate stories; checkpoint with a fresh `get_goal` snapshot whose aggregate objective is still `active`. On the final story only, call `update_goal({status: "complete"})`, then call `get_goal` again for a fresh `complete` snapshot.
37
38
  8. Checkpoint the durable ledger with that snapshot:
38
39
  `omx ultragoal checkpoint --goal-id <id> --status complete --evidence "<evidence>" --codex-goal-json <get_goal-json-or-path>`
39
40
  9. If blocked or failed, checkpoint failure:
40
41
  `omx ultragoal checkpoint --goal-id <id> --status failed --evidence "<blocker/evidence>"`
41
- 10. Resume failed goals with `omx ultragoal complete-goals --retry-failed`.
42
+ 10. For legacy per-story completed-goal blockers, preserve the non-terminal blocker with:
43
+ `omx ultragoal checkpoint --goal-id <id> --status blocked --evidence "<completed legacy Codex goal blocks create_goal in this thread>" --codex-goal-json <get_goal-json-or-path>`
44
+ 11. Resume failed goals with `omx ultragoal complete-goals --retry-failed`.
42
45
 
43
46
  ## Constraints
44
47
 
45
48
  - The shell command cannot directly invoke Codex interactive `/goal`; it emits a model-facing handoff for the active Codex agent.
46
49
  - Never call `create_goal` when `get_goal` reports a different active goal.
47
- - Never call `update_goal` unless the current goal is actually complete.
50
+ - Never call `update_goal` unless the aggregate run or legacy per-story goal is actually complete.
51
+ - In aggregate mode, intermediate story checkpoints require a matching `active` Codex snapshot; final story completion requires a matching `complete` snapshot after `update_goal`.
48
52
  - Completion checkpoints require read-only Codex snapshot reconciliation: pass fresh `get_goal` JSON/path with `--codex-goal-json`; shell commands and hooks must not mutate Codex goal state.
49
53
  - Treat `ledger.jsonl` as the durable audit trail; checkpoint after every success or failure.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: wiki
3
- description: Persistent markdown project wiki stored under .omx/wiki with keyword search and lifecycle capture
3
+ description: Persistent markdown project wiki stored under repository omx_wiki with keyword search and lifecycle capture
4
4
  triggers: ["wiki add", "wiki lint", "wiki query", "wiki read", "wiki delete"]
5
5
  ---
6
6
 
@@ -42,9 +42,9 @@ wiki_refresh()
42
42
  `architecture`, `decision`, `pattern`, `debugging`, `environment`, `session-log`, `reference`, `convention`
43
43
 
44
44
  ## Storage
45
- - Pages: `.omx/wiki/*.md`
46
- - Index: `.omx/wiki/index.md`
47
- - Log: `.omx/wiki/log.md`
45
+ - Pages: `omx_wiki/*.md`
46
+ - Index: `omx_wiki/index.md`
47
+ - Log: `omx_wiki/log.md`
48
48
 
49
49
  ## Cross-References
50
50
  Use `[[page-name]]` wiki-link syntax to create cross-references between pages.
@@ -54,4 +54,4 @@ At session end, discoveries can be captured as `session-log-*` pages. Configure
54
54
 
55
55
  ## Hard Constraints
56
56
  - No vector embeddings — query uses keyword + tag matching only
57
- - Wiki files remain local project state under `.omx/wiki/`
57
+ - Wiki files are repository project knowledge under `omx_wiki/`; legacy `.omx/wiki/` is read-only compatibility input when no canonical wiki exists
@@ -24,6 +24,8 @@ import { writeSessionStart } from "../../hooks/session.js";
24
24
  import { resetTriageConfigCache } from "../../hooks/triage-config.js";
25
25
  import { executeStateOperation } from "../../state/operations.js";
26
26
  import { OMX_TMUX_HUD_OWNER_ENV } from "../../hud/reconcile.js";
27
+ import { writePage } from "../../wiki/storage.js";
28
+ import { WIKI_SCHEMA_VERSION } from "../../wiki/types.js";
27
29
 
28
30
  function nativeHookScriptPath(): string {
29
31
  return join(process.cwd(), "dist", "scripts", "codex-native-hook.js");
@@ -225,6 +227,8 @@ describe("codex native hook config", () => {
225
227
  "PreToolUse",
226
228
  "PostToolUse",
227
229
  "UserPromptSubmit",
230
+ "PreCompact",
231
+ "PostCompact",
228
232
  "Stop",
229
233
  ]);
230
234
 
@@ -272,6 +276,20 @@ describe("codex native hook config", () => {
272
276
  hooks?: Array<Record<string, unknown>>;
273
277
  };
274
278
  assert.equal(stop.hooks?.[0]?.timeout, 30);
279
+
280
+ const postCompact = config.hooks.PostCompact[0] as {
281
+ matcher?: string;
282
+ hooks?: Array<Record<string, unknown>>;
283
+ };
284
+ assert.equal(postCompact.matcher, undefined);
285
+ assert.match(
286
+ String(postCompact.hooks?.[0]?.command || ""),
287
+ /codex-native-hook\.js"?$/,
288
+ );
289
+ assert.doesNotMatch(
290
+ String(postCompact.hooks?.[0]?.command || ""),
291
+ /PostCompact Nudge|additionalContext|printf/,
292
+ );
275
293
  });
276
294
  });
277
295
 
@@ -511,9 +529,109 @@ describe("codex native hook dispatch", () => {
511
529
  assert.equal(mapCodexHookEventToOmxEvent("UserPromptSubmit"), "keyword-detector");
512
530
  assert.equal(mapCodexHookEventToOmxEvent("PreToolUse"), "pre-tool-use");
513
531
  assert.equal(mapCodexHookEventToOmxEvent("PostToolUse"), "post-tool-use");
532
+ assert.equal(mapCodexHookEventToOmxEvent("PreCompact"), "pre-compact");
533
+ assert.equal(mapCodexHookEventToOmxEvent("PostCompact"), "post-compact");
514
534
  assert.equal(mapCodexHookEventToOmxEvent("Stop"), "stop");
515
535
  });
516
536
 
537
+
538
+
539
+ it("does not write PreCompact stdout that Codex rejects as hook JSON", async () => {
540
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-precompact-"));
541
+ try {
542
+ writePage(cwd, {
543
+ filename: "architecture.md",
544
+ frontmatter: {
545
+ title: "Architecture",
546
+ tags: ["architecture"],
547
+ created: "2026-05-08T00:00:00.000Z",
548
+ updated: "2026-05-08T00:00:00.000Z",
549
+ sources: [],
550
+ links: [],
551
+ category: "architecture",
552
+ confidence: "high",
553
+ schemaVersion: WIKI_SCHEMA_VERSION,
554
+ },
555
+ content: "\n# Architecture\n\nCompaction-relevant architecture note.\n",
556
+ });
557
+
558
+ const result = await dispatchCodexNativeHook({
559
+ hook_event_name: "PreCompact",
560
+ cwd,
561
+ session_id: "sess-precompact",
562
+ });
563
+
564
+ assert.equal(result.hookEventName, "PreCompact");
565
+ assert.equal(result.omxEventName, "pre-compact");
566
+ assert.equal(result.outputJson, null);
567
+ } finally {
568
+ await rm(cwd, { recursive: true, force: true });
569
+ }
570
+ });
571
+
572
+ it("emits no CLI stdout for PreCompact when no Codex action is needed", async () => {
573
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-precompact-cli-"));
574
+ try {
575
+ writePage(cwd, {
576
+ filename: "architecture.md",
577
+ frontmatter: {
578
+ title: "Architecture",
579
+ tags: ["architecture"],
580
+ created: "2026-05-08T00:00:00.000Z",
581
+ updated: "2026-05-08T00:00:00.000Z",
582
+ sources: [],
583
+ links: [],
584
+ category: "architecture",
585
+ confidence: "high",
586
+ schemaVersion: WIKI_SCHEMA_VERSION,
587
+ },
588
+ content: "\n# Architecture\n\nCompaction-relevant architecture note.\n",
589
+ });
590
+
591
+ const stdout = runNativeHookCli({
592
+ hook_event_name: "PreCompact",
593
+ cwd,
594
+ session_id: "sess-precompact-cli",
595
+ });
596
+
597
+ assert.equal(stdout, "");
598
+ } finally {
599
+ await rm(cwd, { recursive: true, force: true });
600
+ }
601
+ });
602
+
603
+ it("does not write PostCompact stdout that Codex rejects as hook JSON", async () => {
604
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-postcompact-"));
605
+ try {
606
+ const result = await dispatchCodexNativeHook({
607
+ hook_event_name: "PostCompact",
608
+ cwd,
609
+ session_id: "sess-postcompact",
610
+ });
611
+
612
+ assert.equal(result.hookEventName, "PostCompact");
613
+ assert.equal(result.omxEventName, "post-compact");
614
+ assert.equal(result.outputJson, null);
615
+ } finally {
616
+ await rm(cwd, { recursive: true, force: true });
617
+ }
618
+ });
619
+
620
+ it("emits no CLI stdout for PostCompact when no Codex action is needed", async () => {
621
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-postcompact-cli-"));
622
+ try {
623
+ const stdout = runNativeHookCli({
624
+ hook_event_name: "PostCompact",
625
+ cwd,
626
+ session_id: "sess-postcompact-cli",
627
+ });
628
+
629
+ assert.equal(stdout, "");
630
+ } finally {
631
+ await rm(cwd, { recursive: true, force: true });
632
+ }
633
+ });
634
+
517
635
  it("writes SessionStart state against the long-lived session owner pid and injects environment context", async () => {
518
636
  const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-session-start-"));
519
637
  try {
@@ -1101,7 +1219,12 @@ describe("codex native hook dispatch", () => {
1101
1219
  assert.ok(result.outputJson, "UserPromptSubmit should emit developer context");
1102
1220
  assert.match(JSON.stringify(result.outputJson), /skill: ralplan activated and initial state initialized at \.omx\/state\/sessions\/sess-1\/ralplan-state\.json; write subsequent updates via omx_state MCP\./);
1103
1221
 
1104
- const statePath = join(cwd, ".omx", "state", "skill-active-state.json");
1222
+ assert.equal(
1223
+ existsSync(join(cwd, ".omx", "state", "skill-active-state.json")),
1224
+ false,
1225
+ "session-scoped keyword activation should not write root skill-active-state.json",
1226
+ );
1227
+ const statePath = join(cwd, ".omx", "state", "sessions", "sess-1", "skill-active-state.json");
1105
1228
  assert.equal(existsSync(statePath), true);
1106
1229
  const state = JSON.parse(await readFile(statePath, "utf-8")) as {
1107
1230
  skill?: string;
@@ -1170,6 +1293,100 @@ describe("codex native hook dispatch", () => {
1170
1293
  }
1171
1294
  });
1172
1295
 
1296
+ it("does not block Stop for non-passing autoresearch-goal professor-critic verdicts", async () => {
1297
+ for (const verdict of ["blocked", "fail", "failed"]) {
1298
+ const cwd = await mkdtemp(join(tmpdir(), `omx-native-hook-autoresearch-${verdict}-stop-`));
1299
+ const slug = `${verdict}-mission`;
1300
+ try {
1301
+ await writeJson(join(cwd, ".omx", "goals", "autoresearch", slug, "mission.json"), {
1302
+ version: 1,
1303
+ workflow: "autoresearch-goal",
1304
+ slug,
1305
+ topic: "Blocked research",
1306
+ status: verdict === "blocked" ? "blocked" : "failed",
1307
+ });
1308
+ await writeJson(join(cwd, ".omx", "goals", "autoresearch", slug, "completion.json"), {
1309
+ verdict,
1310
+ passed: false,
1311
+ });
1312
+
1313
+ const result = await dispatchCodexNativeHook({
1314
+ hook_event_name: "Stop",
1315
+ cwd,
1316
+ session_id: `sess-autoresearch-${verdict}-stop`,
1317
+ thread_id: `thread-autoresearch-${verdict}-stop`,
1318
+ last_assistant_message: "Autoresearch goal complete; next call update_goal({status: \"complete\"}).",
1319
+ }, { cwd });
1320
+
1321
+ assert.notEqual(result.outputJson?.decision, "block");
1322
+ assert.doesNotMatch(JSON.stringify(result.outputJson), new RegExp(`autoresearch-goal complete --slug ${slug}`));
1323
+ assert.doesNotMatch(JSON.stringify(result.outputJson), /get_goal snapshot reconciliation/);
1324
+ } finally {
1325
+ await rm(cwd, { recursive: true, force: true });
1326
+ }
1327
+ }
1328
+ });
1329
+
1330
+ it("blocks Stop for passing autoresearch-goal professor-critic verdicts that need reconciliation", async () => {
1331
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-autoresearch-pass-stop-"));
1332
+ try {
1333
+ await writeJson(join(cwd, ".omx", "goals", "autoresearch", "passing-mission", "mission.json"), {
1334
+ version: 1,
1335
+ workflow: "autoresearch-goal",
1336
+ slug: "passing-mission",
1337
+ topic: "Passing research",
1338
+ status: "validation_passed",
1339
+ });
1340
+ await writeJson(join(cwd, ".omx", "goals", "autoresearch", "passing-mission", "completion.json"), {
1341
+ verdict: "fail",
1342
+ passed: true,
1343
+ });
1344
+
1345
+ const result = await dispatchCodexNativeHook({
1346
+ hook_event_name: "Stop",
1347
+ cwd,
1348
+ session_id: "sess-autoresearch-pass-stop",
1349
+ thread_id: "thread-autoresearch-pass-stop",
1350
+ last_assistant_message: "Autoresearch goal complete; next call update_goal({status: \"complete\"}).",
1351
+ }, { cwd });
1352
+
1353
+ assert.equal(result.outputJson?.decision, "block");
1354
+ assert.match(JSON.stringify(result.outputJson), /get_goal snapshot reconciliation/);
1355
+ assert.match(JSON.stringify(result.outputJson), /omx autoresearch-goal complete --slug passing-mission/);
1356
+ } finally {
1357
+ await rm(cwd, { recursive: true, force: true });
1358
+ }
1359
+ });
1360
+
1361
+ it("blocks Stop for autoresearch-goal verdict=pass even when passed is omitted", async () => {
1362
+ const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-autoresearch-verdict-pass-stop-"));
1363
+ try {
1364
+ await writeJson(join(cwd, ".omx", "goals", "autoresearch", "verdict-pass-mission", "mission.json"), {
1365
+ version: 1,
1366
+ workflow: "autoresearch-goal",
1367
+ slug: "verdict-pass-mission",
1368
+ topic: "Passing research",
1369
+ status: "validation_passed",
1370
+ });
1371
+ await writeJson(join(cwd, ".omx", "goals", "autoresearch", "verdict-pass-mission", "completion.json"), {
1372
+ verdict: "pass",
1373
+ });
1374
+
1375
+ const result = await dispatchCodexNativeHook({
1376
+ hook_event_name: "Stop",
1377
+ cwd,
1378
+ session_id: "sess-autoresearch-verdict-pass-stop",
1379
+ thread_id: "thread-autoresearch-verdict-pass-stop",
1380
+ last_assistant_message: "Autoresearch goal complete; next call update_goal({status: \"complete\"}).",
1381
+ }, { cwd });
1382
+
1383
+ assert.equal(result.outputJson?.decision, "block");
1384
+ assert.match(JSON.stringify(result.outputJson), /omx autoresearch-goal complete --slug verdict-pass-mission/);
1385
+ } finally {
1386
+ await rm(cwd, { recursive: true, force: true });
1387
+ }
1388
+ });
1389
+
1173
1390
  it("treats workflow keywords in native subagent prompt text as literal delegation text", async () => {
1174
1391
  const cwd = await mkdtemp(join(tmpdir(), "omx-native-hook-subagent-keyword-literal-"));
1175
1392
  try {
@@ -6,6 +6,8 @@ type CodexHookEventName =
6
6
  | "PreToolUse"
7
7
  | "PostToolUse"
8
8
  | "UserPromptSubmit"
9
+ | "PreCompact"
10
+ | "PostCompact"
9
11
  | "Stop";
10
12
 
11
13
  type CodexHookPayload = Record<string, unknown>;
@@ -70,7 +70,10 @@ import {
70
70
  import type { HookEventEnvelope } from "../hooks/extensibility/types.js";
71
71
  import { dispatchHookEventRuntime } from "../hooks/extensibility/runtime.js";
72
72
  import { reconcileHudForPromptSubmit } from "../hud/reconcile.js";
73
- import { onSessionStart as buildWikiSessionStartContext } from "../wiki/lifecycle.js";
73
+ import {
74
+ onPreCompact as buildWikiPreCompactContext,
75
+ onSessionStart as buildWikiSessionStartContext,
76
+ } from "../wiki/lifecycle.js";
74
77
  import { readAutoresearchCompletionStatus, readAutoresearchModeStateForActiveDecision } from "../autoresearch/skill-validation.js";
75
78
  import { readRunState } from "../runtime/run-state.js";
76
79
  import { getRunContinuationSnapshot, shouldContinueRun } from "../runtime/run-loop.js";
@@ -99,6 +102,8 @@ type CodexHookEventName =
99
102
  | "PreToolUse"
100
103
  | "PostToolUse"
101
104
  | "UserPromptSubmit"
105
+ | "PreCompact"
106
+ | "PostCompact"
102
107
  | "Stop";
103
108
 
104
109
  type CodexHookPayload = Record<string, unknown>;
@@ -358,6 +363,8 @@ function readHookEventName(payload: CodexHookPayload): CodexHookEventName | null
358
363
  || raw === "PreToolUse"
359
364
  || raw === "PostToolUse"
360
365
  || raw === "UserPromptSubmit"
366
+ || raw === "PreCompact"
367
+ || raw === "PostCompact"
361
368
  || raw === "Stop"
362
369
  ) {
363
370
  return raw;
@@ -377,6 +384,10 @@ export function mapCodexHookEventToOmxEvent(
377
384
  return "post-tool-use";
378
385
  case "UserPromptSubmit":
379
386
  return "keyword-detector";
387
+ case "PreCompact":
388
+ return "pre-compact";
389
+ case "PostCompact":
390
+ return "post-compact";
380
391
  case "Stop":
381
392
  return "stop";
382
393
  default:
@@ -1642,7 +1653,10 @@ async function findActiveGoalWorkflowReconciliationRequirement(cwd: string): Pro
1642
1653
  if (!entry.isDirectory()) continue;
1643
1654
  const mission = await readJsonIfExists(join(autoresearchRoot, entry.name, "mission.json"));
1644
1655
  const status = safeString(mission?.status);
1645
- if (mission?.workflow === "autoresearch-goal" && status && status !== "complete") {
1656
+ const completion = await readJsonIfExists(join(autoresearchRoot, entry.name, "completion.json"));
1657
+ const completionVerdict = safeString(completion?.verdict);
1658
+ const completionPassed = completion?.passed === true || completionVerdict === "pass";
1659
+ if (mission?.workflow === "autoresearch-goal" && status && status !== "complete" && completionPassed) {
1646
1660
  return {
1647
1661
  workflow: "autoresearch-goal",
1648
1662
  command: `omx autoresearch-goal complete --slug ${safeString(mission.slug) || entry.name} --codex-goal-json '<get_goal JSON or path>'`,
@@ -3010,7 +3024,12 @@ export async function dispatchCodexNativeHook(
3010
3024
  });
3011
3025
  }
3012
3026
 
3013
- if ((hookEventName === "SessionStart" && !skipCanonicalSessionStartContext) || hookEventName === "UserPromptSubmit") {
3027
+ if (hookEventName === "PreCompact") {
3028
+ // Codex native PreCompact currently accepts only the common continuation fields.
3029
+ // Keep the OMX lifecycle dispatch above, but do not emit `hookSpecificOutput`
3030
+ // unless Codex defines a supported PreCompact output contract.
3031
+ buildWikiPreCompactContext({ cwd });
3032
+ } else if ((hookEventName === "SessionStart" && !skipCanonicalSessionStartContext) || hookEventName === "UserPromptSubmit") {
3014
3033
  const additionalContext = hookEventName === "SessionStart"
3015
3034
  ? await buildSessionStartContext(cwd, canonicalSessionId || nativeSessionId, {
3016
3035
  hookEventName,