oh-my-codex 0.18.7 → 0.18.8

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 (259) hide show
  1. package/Cargo.lock +6 -6
  2. package/Cargo.toml +1 -1
  3. package/README.md +5 -5
  4. package/crates/omx-sparkshell/tests/execution.rs +1 -1
  5. package/dist/agents/__tests__/native-config.test.js +42 -1
  6. package/dist/agents/__tests__/native-config.test.js.map +1 -1
  7. package/dist/agents/definitions.d.ts +8 -0
  8. package/dist/agents/definitions.d.ts.map +1 -1
  9. package/dist/agents/definitions.js +1 -0
  10. package/dist/agents/definitions.js.map +1 -1
  11. package/dist/agents/native-config.d.ts +5 -1
  12. package/dist/agents/native-config.d.ts.map +1 -1
  13. package/dist/agents/native-config.js +17 -2
  14. package/dist/agents/native-config.js.map +1 -1
  15. package/dist/cli/__tests__/codex-plugin-layout.test.js +512 -1
  16. package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
  17. package/dist/cli/__tests__/doctor-warning-copy.test.js +39 -0
  18. package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
  19. package/dist/cli/__tests__/index.test.js +61 -5
  20. package/dist/cli/__tests__/index.test.js.map +1 -1
  21. package/dist/cli/__tests__/package-bin-contract.test.js +8 -4
  22. package/dist/cli/__tests__/package-bin-contract.test.js.map +1 -1
  23. package/dist/cli/__tests__/ralph-goal-mode-contract.test.js +13 -0
  24. package/dist/cli/__tests__/ralph-goal-mode-contract.test.js.map +1 -1
  25. package/dist/cli/__tests__/ralph.test.js +14 -0
  26. package/dist/cli/__tests__/ralph.test.js.map +1 -1
  27. package/dist/cli/__tests__/setup-install-mode.test.js +89 -0
  28. package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
  29. package/dist/cli/__tests__/setup-refresh.test.js +65 -0
  30. package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
  31. package/dist/cli/__tests__/state.test.js +21 -0
  32. package/dist/cli/__tests__/state.test.js.map +1 -1
  33. package/dist/cli/__tests__/team.test.js +2 -2
  34. package/dist/cli/__tests__/update.test.js +110 -2
  35. package/dist/cli/__tests__/update.test.js.map +1 -1
  36. package/dist/cli/doctor.d.ts.map +1 -1
  37. package/dist/cli/doctor.js +8 -1
  38. package/dist/cli/doctor.js.map +1 -1
  39. package/dist/cli/index.d.ts +11 -2
  40. package/dist/cli/index.d.ts.map +1 -1
  41. package/dist/cli/index.js +108 -15
  42. package/dist/cli/index.js.map +1 -1
  43. package/dist/cli/plugin-marketplace.d.ts +14 -2
  44. package/dist/cli/plugin-marketplace.d.ts.map +1 -1
  45. package/dist/cli/plugin-marketplace.js +62 -15
  46. package/dist/cli/plugin-marketplace.js.map +1 -1
  47. package/dist/cli/ralph.d.ts.map +1 -1
  48. package/dist/cli/ralph.js +3 -1
  49. package/dist/cli/ralph.js.map +1 -1
  50. package/dist/cli/setup-preferences.d.ts +2 -0
  51. package/dist/cli/setup-preferences.d.ts.map +1 -1
  52. package/dist/cli/setup-preferences.js +4 -0
  53. package/dist/cli/setup-preferences.js.map +1 -1
  54. package/dist/cli/setup.d.ts +3 -0
  55. package/dist/cli/setup.d.ts.map +1 -1
  56. package/dist/cli/setup.js +166 -27
  57. package/dist/cli/setup.js.map +1 -1
  58. package/dist/cli/state.d.ts.map +1 -1
  59. package/dist/cli/state.js +8 -1
  60. package/dist/cli/state.js.map +1 -1
  61. package/dist/cli/tmux-hook.d.ts.map +1 -1
  62. package/dist/cli/tmux-hook.js +16 -0
  63. package/dist/cli/tmux-hook.js.map +1 -1
  64. package/dist/cli/update.d.ts +2 -0
  65. package/dist/cli/update.d.ts.map +1 -1
  66. package/dist/cli/update.js +47 -3
  67. package/dist/cli/update.js.map +1 -1
  68. package/dist/config/__tests__/generator-notify.test.js +1 -0
  69. package/dist/config/__tests__/generator-notify.test.js.map +1 -1
  70. package/dist/config/generator.d.ts +2 -2
  71. package/dist/config/generator.d.ts.map +1 -1
  72. package/dist/config/generator.js +2 -2
  73. package/dist/config/generator.js.map +1 -1
  74. package/dist/config/team-mode.d.ts +12 -0
  75. package/dist/config/team-mode.d.ts.map +1 -0
  76. package/dist/config/team-mode.js +91 -0
  77. package/dist/config/team-mode.js.map +1 -0
  78. package/dist/hooks/__tests__/agents-overlay.test.js +88 -0
  79. package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
  80. package/dist/hooks/__tests__/code-review-skill-contract.test.js +8 -0
  81. package/dist/hooks/__tests__/code-review-skill-contract.test.js.map +1 -1
  82. package/dist/hooks/__tests__/keyword-detector.test.js +423 -3
  83. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  84. package/dist/hooks/__tests__/notify-fallback-watcher.test.js +1 -1
  85. package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
  86. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +189 -0
  87. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
  88. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +35 -2
  89. package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
  90. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +3 -3
  91. package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
  92. package/dist/hooks/__tests__/skill-guidance-contract.test.js +21 -0
  93. package/dist/hooks/__tests__/skill-guidance-contract.test.js.map +1 -1
  94. package/dist/hooks/agents-overlay.d.ts.map +1 -1
  95. package/dist/hooks/agents-overlay.js +36 -50
  96. package/dist/hooks/agents-overlay.js.map +1 -1
  97. package/dist/hooks/extensibility/__tests__/plugin-runner.test.js +31 -0
  98. package/dist/hooks/extensibility/__tests__/plugin-runner.test.js.map +1 -1
  99. package/dist/hooks/extensibility/plugin-runner.js +17 -21
  100. package/dist/hooks/extensibility/plugin-runner.js.map +1 -1
  101. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  102. package/dist/hooks/keyword-detector.js +258 -12
  103. package/dist/hooks/keyword-detector.js.map +1 -1
  104. package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
  105. package/dist/hooks/prompt-guidance-contract.js +6 -0
  106. package/dist/hooks/prompt-guidance-contract.js.map +1 -1
  107. package/dist/hooks/session.d.ts +1 -0
  108. package/dist/hooks/session.d.ts.map +1 -1
  109. package/dist/hooks/session.js.map +1 -1
  110. package/dist/hud/__tests__/authority.test.js +435 -32
  111. package/dist/hud/__tests__/authority.test.js.map +1 -1
  112. package/dist/hud/__tests__/hud-tmux-injection.test.js +2 -1
  113. package/dist/hud/__tests__/hud-tmux-injection.test.js.map +1 -1
  114. package/dist/hud/__tests__/index.test.js +42 -0
  115. package/dist/hud/__tests__/index.test.js.map +1 -1
  116. package/dist/hud/__tests__/reconcile.test.js +521 -15
  117. package/dist/hud/__tests__/reconcile.test.js.map +1 -1
  118. package/dist/hud/__tests__/render.test.js +61 -0
  119. package/dist/hud/__tests__/render.test.js.map +1 -1
  120. package/dist/hud/__tests__/state.test.js +132 -4
  121. package/dist/hud/__tests__/state.test.js.map +1 -1
  122. package/dist/hud/__tests__/tmux.test.js +180 -21
  123. package/dist/hud/__tests__/tmux.test.js.map +1 -1
  124. package/dist/hud/authority.d.ts +5 -0
  125. package/dist/hud/authority.d.ts.map +1 -1
  126. package/dist/hud/authority.js +324 -28
  127. package/dist/hud/authority.js.map +1 -1
  128. package/dist/hud/index.d.ts +3 -2
  129. package/dist/hud/index.d.ts.map +1 -1
  130. package/dist/hud/index.js +42 -19
  131. package/dist/hud/index.js.map +1 -1
  132. package/dist/hud/reconcile.d.ts +3 -3
  133. package/dist/hud/reconcile.d.ts.map +1 -1
  134. package/dist/hud/reconcile.js +128 -19
  135. package/dist/hud/reconcile.js.map +1 -1
  136. package/dist/hud/render.d.ts.map +1 -1
  137. package/dist/hud/render.js +35 -0
  138. package/dist/hud/render.js.map +1 -1
  139. package/dist/hud/state.d.ts.map +1 -1
  140. package/dist/hud/state.js +61 -62
  141. package/dist/hud/state.js.map +1 -1
  142. package/dist/hud/tmux.d.ts +24 -6
  143. package/dist/hud/tmux.d.ts.map +1 -1
  144. package/dist/hud/tmux.js +136 -38
  145. package/dist/hud/tmux.js.map +1 -1
  146. package/dist/hud/types.d.ts +11 -0
  147. package/dist/hud/types.d.ts.map +1 -1
  148. package/dist/hud/types.js.map +1 -1
  149. package/dist/mcp/__tests__/state-paths.test.js +71 -1
  150. package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
  151. package/dist/mcp/state-paths.d.ts +32 -0
  152. package/dist/mcp/state-paths.d.ts.map +1 -1
  153. package/dist/mcp/state-paths.js +113 -17
  154. package/dist/mcp/state-paths.js.map +1 -1
  155. package/dist/mcp/state-server.d.ts +4 -4
  156. package/dist/scripts/__tests__/codex-native-hook.test.js +593 -11
  157. package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
  158. package/dist/scripts/__tests__/notify-state-io.test.js +72 -1
  159. package/dist/scripts/__tests__/notify-state-io.test.js.map +1 -1
  160. package/dist/scripts/__tests__/notify-tmux-injection.test.d.ts +2 -0
  161. package/dist/scripts/__tests__/notify-tmux-injection.test.d.ts.map +1 -0
  162. package/dist/scripts/__tests__/notify-tmux-injection.test.js +57 -0
  163. package/dist/scripts/__tests__/notify-tmux-injection.test.js.map +1 -0
  164. package/dist/scripts/__tests__/run-test-files.test.js +74 -0
  165. package/dist/scripts/__tests__/run-test-files.test.js.map +1 -1
  166. package/dist/scripts/__tests__/verify-native-agents.test.js +65 -0
  167. package/dist/scripts/__tests__/verify-native-agents.test.js.map +1 -1
  168. package/dist/scripts/codex-native-hook.d.ts.map +1 -1
  169. package/dist/scripts/codex-native-hook.js +88 -31
  170. package/dist/scripts/codex-native-hook.js.map +1 -1
  171. package/dist/scripts/eval/eval-parity-smoke.js +1 -1
  172. package/dist/scripts/eval/eval-parity-smoke.js.map +1 -1
  173. package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
  174. package/dist/scripts/notify-hook/auto-nudge.js +3 -1
  175. package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
  176. package/dist/scripts/notify-hook/ralph-session-resume.d.ts.map +1 -1
  177. package/dist/scripts/notify-hook/ralph-session-resume.js +3 -10
  178. package/dist/scripts/notify-hook/ralph-session-resume.js.map +1 -1
  179. package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
  180. package/dist/scripts/notify-hook/state-io.js +62 -38
  181. package/dist/scripts/notify-hook/state-io.js.map +1 -1
  182. package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
  183. package/dist/scripts/notify-hook/team-leader-nudge.js +7 -0
  184. package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
  185. package/dist/scripts/notify-hook/tmux-injection.d.ts +7 -0
  186. package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
  187. package/dist/scripts/notify-hook/tmux-injection.js +24 -18
  188. package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
  189. package/dist/scripts/notify-hook.js +75 -11
  190. package/dist/scripts/notify-hook.js.map +1 -1
  191. package/dist/scripts/run-test-files.js +193 -22
  192. package/dist/scripts/run-test-files.js.map +1 -1
  193. package/dist/scripts/sync-plugin-mirror.d.ts.map +1 -1
  194. package/dist/scripts/sync-plugin-mirror.js +61 -3
  195. package/dist/scripts/sync-plugin-mirror.js.map +1 -1
  196. package/dist/scripts/verify-native-agents.d.ts.map +1 -1
  197. package/dist/scripts/verify-native-agents.js +58 -1
  198. package/dist/scripts/verify-native-agents.js.map +1 -1
  199. package/dist/state/__tests__/operations.test.js +113 -0
  200. package/dist/state/__tests__/operations.test.js.map +1 -1
  201. package/dist/state/__tests__/skill-active.test.js +3 -16
  202. package/dist/state/__tests__/skill-active.test.js.map +1 -1
  203. package/dist/state/__tests__/workflow-transition.test.js +25 -0
  204. package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
  205. package/dist/state/operations.d.ts.map +1 -1
  206. package/dist/state/operations.js +57 -2
  207. package/dist/state/operations.js.map +1 -1
  208. package/dist/state/skill-active.d.ts.map +1 -1
  209. package/dist/state/skill-active.js +7 -39
  210. package/dist/state/skill-active.js.map +1 -1
  211. package/dist/state/workflow-transition-reconcile.d.ts.map +1 -1
  212. package/dist/state/workflow-transition-reconcile.js +10 -14
  213. package/dist/state/workflow-transition-reconcile.js.map +1 -1
  214. package/dist/team/__tests__/runtime.test.js +1 -1
  215. package/dist/team/__tests__/runtime.test.js.map +1 -1
  216. package/dist/team/__tests__/scaling.test.js +9 -4
  217. package/dist/team/__tests__/scaling.test.js.map +1 -1
  218. package/dist/team/__tests__/tmux-session.test.js +195 -2
  219. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  220. package/dist/team/__tests__/worker-runtime-identity.test.js +4 -2
  221. package/dist/team/__tests__/worker-runtime-identity.test.js.map +1 -1
  222. package/dist/team/scaling.d.ts.map +1 -1
  223. package/dist/team/scaling.js +3 -2
  224. package/dist/team/scaling.js.map +1 -1
  225. package/dist/team/tmux-session.d.ts +2 -0
  226. package/dist/team/tmux-session.d.ts.map +1 -1
  227. package/dist/team/tmux-session.js +142 -12
  228. package/dist/team/tmux-session.js.map +1 -1
  229. package/dist/verification/__tests__/ci-rust-gates.test.js +81 -1
  230. package/dist/verification/__tests__/ci-rust-gates.test.js.map +1 -1
  231. package/package.json +8 -8
  232. package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
  233. package/plugins/oh-my-codex/hooks/codex-native-hook.mjs +334 -21
  234. package/plugins/oh-my-codex/hooks/hooks.json +1 -2
  235. package/plugins/oh-my-codex/skills/autopilot/SKILL.md +3 -1
  236. package/plugins/oh-my-codex/skills/code-review/SKILL.md +7 -7
  237. package/plugins/oh-my-codex/skills/ralph/SKILL.md +22 -22
  238. package/plugins/oh-my-codex/skills/ultraqa/SKILL.md +9 -0
  239. package/skills/autopilot/SKILL.md +3 -1
  240. package/skills/code-review/SKILL.md +7 -7
  241. package/skills/ralph/SKILL.md +22 -22
  242. package/skills/ultraqa/SKILL.md +9 -0
  243. package/src/scripts/__tests__/codex-native-hook.test.ts +686 -13
  244. package/src/scripts/__tests__/notify-state-io.test.ts +95 -0
  245. package/src/scripts/__tests__/notify-tmux-injection.test.ts +82 -0
  246. package/src/scripts/__tests__/run-test-files.test.ts +102 -0
  247. package/src/scripts/__tests__/verify-native-agents.test.ts +75 -0
  248. package/src/scripts/codex-native-hook.ts +105 -28
  249. package/src/scripts/demo-team-e2e.sh +10 -7
  250. package/src/scripts/eval/eval-parity-smoke.ts +1 -1
  251. package/src/scripts/notify-hook/auto-nudge.ts +3 -1
  252. package/src/scripts/notify-hook/ralph-session-resume.ts +2 -8
  253. package/src/scripts/notify-hook/state-io.ts +75 -37
  254. package/src/scripts/notify-hook/team-leader-nudge.ts +7 -0
  255. package/src/scripts/notify-hook/tmux-injection.ts +35 -19
  256. package/src/scripts/notify-hook.ts +91 -4
  257. package/src/scripts/run-test-files.ts +192 -22
  258. package/src/scripts/sync-plugin-mirror.ts +98 -9
  259. package/src/scripts/verify-native-agents.ts +65 -1
@@ -1,10 +1,162 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawn } from 'node:child_process';
3
- import { readFileSync } from 'node:fs';
4
- import { dirname, join } from 'node:path';
3
+ import { existsSync, readFileSync, realpathSync } from 'node:fs';
4
+ import { dirname, join, resolve } from 'node:path';
5
5
  import { fileURLToPath } from 'node:url';
6
6
 
7
7
  const hookDir = dirname(fileURLToPath(import.meta.url));
8
+ // sync-plugin-mirror verifies this stable marker; runtime behavior is tested separately.
9
+ const OMX_PLUGIN_HOOK_LAUNCHER_CONTRACT_MARKER = 'omx-plugin-hook-launcher:v1';
10
+ const MAX_WRAPPER_STDIN_BYTES = 1024 * 1024;
11
+ const RAW_EVENT_SCAN_BYTES = 64 * 1024;
12
+ const CODEX_HOOK_EVENT_NAMES = new Set([
13
+ 'SessionStart',
14
+ 'PreToolUse',
15
+ 'PostToolUse',
16
+ 'UserPromptSubmit',
17
+ 'PreCompact',
18
+ 'PostCompact',
19
+ 'Stop',
20
+ ]);
21
+
22
+ function skipJsonWhitespace(raw, index) {
23
+ while (index < raw.length && /\s/.test(raw[index] ?? '')) index += 1;
24
+ return index;
25
+ }
26
+
27
+ function readJsonStringLiteral(raw, quoteIndex) {
28
+ if (raw[quoteIndex] !== '"') return null;
29
+ let value = '';
30
+ for (let index = quoteIndex + 1; index < raw.length; index += 1) {
31
+ const char = raw[index];
32
+ if (char === '"') return { value, endIndex: index + 1 };
33
+ if (char !== '\\') {
34
+ value += char;
35
+ continue;
36
+ }
37
+
38
+ index += 1;
39
+ if (index >= raw.length) return null;
40
+ const escaped = raw[index];
41
+ switch (escaped) {
42
+ case '"':
43
+ case '\\':
44
+ case '/':
45
+ value += escaped;
46
+ break;
47
+ case 'b':
48
+ value += '\b';
49
+ break;
50
+ case 'f':
51
+ value += '\f';
52
+ break;
53
+ case 'n':
54
+ value += '\n';
55
+ break;
56
+ case 'r':
57
+ value += '\r';
58
+ break;
59
+ case 't':
60
+ value += '\t';
61
+ break;
62
+ case 'u': {
63
+ const hex = raw.slice(index + 1, index + 5);
64
+ if (!/^[0-9a-fA-F]{4}$/.test(hex)) return null;
65
+ value += String.fromCharCode(Number.parseInt(hex, 16));
66
+ index += 4;
67
+ break;
68
+ }
69
+ default:
70
+ return null;
71
+ }
72
+ }
73
+ return null;
74
+ }
75
+
76
+ function extractTopLevelStringField(rawInput, fieldNames) {
77
+ const raw = rawInput.slice(0, RAW_EVENT_SCAN_BYTES);
78
+ const wanted = new Set(fieldNames);
79
+ let depth = 0;
80
+ let index = 0;
81
+
82
+ while (index < raw.length) {
83
+ const char = raw[index];
84
+ if (char === '"') {
85
+ const key = readJsonStringLiteral(raw, index);
86
+ if (!key) return null;
87
+ index = key.endIndex;
88
+ const afterKey = skipJsonWhitespace(raw, index);
89
+ if (depth === 1 && raw[afterKey] === ':' && wanted.has(key.value)) {
90
+ const valueStart = skipJsonWhitespace(raw, afterKey + 1);
91
+ const value = readJsonStringLiteral(raw, valueStart);
92
+ return value?.value ?? null;
93
+ }
94
+ continue;
95
+ }
96
+ if (char === '{') depth += 1;
97
+ else if (char === '}') depth = Math.max(0, depth - 1);
98
+ index += 1;
99
+ }
100
+
101
+ return null;
102
+ }
103
+
104
+ function extractTopLevelHookEventName(rawInput) {
105
+ const eventName = extractTopLevelStringField(rawInput, ['hook_event_name', 'hookEventName', 'event', 'name']);
106
+ return CODEX_HOOK_EVENT_NAMES.has(eventName) ? eventName : null;
107
+ }
108
+
109
+ function detectStopHookInput(input) {
110
+ const text = input.toString('utf8');
111
+ try {
112
+ const parsed = JSON.parse(text);
113
+ const eventName = parsed?.hook_event_name ?? parsed?.hookEventName ?? parsed?.event ?? parsed?.name;
114
+ return eventName === 'Stop';
115
+ } catch {
116
+ return extractTopLevelHookEventName(text) === 'Stop';
117
+ }
118
+ }
119
+
120
+ async function readBoundedStdin() {
121
+ const chunks = [];
122
+ let totalBytes = 0;
123
+ for await (const rawChunk of process.stdin) {
124
+ const chunk = Buffer.isBuffer(rawChunk) ? rawChunk : Buffer.from(rawChunk);
125
+ totalBytes += chunk.length;
126
+ if (totalBytes > MAX_WRAPPER_STDIN_BYTES) {
127
+ const remaining = MAX_WRAPPER_STDIN_BYTES - Buffer.concat(chunks).length;
128
+ if (remaining > 0) chunks.push(chunk.subarray(0, remaining));
129
+ return { input: Buffer.concat(chunks), oversized: true, totalBytes };
130
+ }
131
+ chunks.push(chunk);
132
+ }
133
+ return { input: Buffer.concat(chunks), oversized: false, totalBytes };
134
+ }
135
+
136
+ function stopFallbackOutput(stopReason, detail) {
137
+ const reason = 'OMX plugin Stop hook launcher failed before valid native Stop JSON could be produced. Continue once, preserve runtime state, inspect hook launcher diagnostics, and retry.';
138
+ return {
139
+ decision: 'block',
140
+ reason,
141
+ stopReason,
142
+ systemMessage: detail ? `${reason} Failure: ${detail}` : reason,
143
+ };
144
+ }
145
+
146
+ function writeStopFallback(stopReason, detail) {
147
+ process.stdout.write(`${JSON.stringify(stopFallbackOutput(stopReason, detail))}\n`);
148
+ process.exitCode = 0;
149
+ }
150
+
151
+ function failLauncher(error, isStop, stopReason = 'plugin_stop_hook_launcher_failure') {
152
+ const detail = error instanceof Error ? error.message : String(error);
153
+ console.error(`[oh-my-codex] ${detail}`);
154
+ if (isStop) {
155
+ writeStopFallback(stopReason, detail);
156
+ return;
157
+ }
158
+ process.exitCode = 1;
159
+ }
8
160
 
9
161
  function readPinnedLauncher() {
10
162
  const launcherPath = join(hookDir, 'omx-command.json');
@@ -20,8 +172,7 @@ function readPinnedLauncher() {
20
172
  return { command: raw.command, argsPrefix };
21
173
  } catch (error) {
22
174
  if (error?.code === 'ENOENT') return null;
23
- console.error(`[oh-my-codex] invalid plugin hook launcher ${launcherPath}: ${error.message}`);
24
- process.exit(1);
175
+ throw new Error(`invalid plugin hook launcher ${launcherPath}: ${error.message}`);
25
176
  }
26
177
  }
27
178
 
@@ -32,25 +183,187 @@ function readConfiguredLauncher() {
32
183
  return readPinnedLauncher() ?? { command: 'omx', argsPrefix: [] };
33
184
  }
34
185
 
35
- const { command, argsPrefix } = readConfiguredLauncher();
36
- const child = spawn(command, [...argsPrefix, 'codex-native-hook'], {
37
- stdio: ['pipe', 'pipe', 'pipe'],
38
- env: process.env,
39
- shell: process.platform === 'win32',
40
- });
186
+ function readJsonFile(path) {
187
+ try {
188
+ return JSON.parse(readFileSync(path, 'utf8'));
189
+ } catch {
190
+ return null;
191
+ }
192
+ }
41
193
 
42
- process.stdin.pipe(child.stdin);
43
- child.stdout.pipe(process.stdout);
44
- child.stderr.pipe(process.stderr);
45
- child.on('error', (error) => {
46
- console.error(`[oh-my-codex] failed to launch ${command} codex-native-hook: ${error.message}`);
47
- process.exitCode = 1;
48
- });
49
- child.on('exit', (code, signal) => {
50
- if (signal) {
51
- console.error(`[oh-my-codex] codex-native-hook terminated by ${signal}`);
194
+ function isTerminalOutcome(value) {
195
+ return ['finish', 'finished', 'complete', 'completed', 'done', 'blocked', 'blocked-on-user', 'blocked_on_user', 'failed', 'fail', 'error', 'cancelled', 'canceled', 'cancel', 'aborted', 'abort', 'userinterlude', 'user-interlude', 'interrupted', 'interrupt', 'askuserquestion', 'ask-user-question', 'askuser', 'question'].includes(String(value ?? '').trim().toLowerCase());
196
+ }
197
+
198
+ function isTerminalRunStateForMode(state, mode) {
199
+ if (!state) return false;
200
+ const runMode = String(state.mode ?? '').trim();
201
+ if (runMode && runMode !== mode) return false;
202
+ return isTerminalOutcome(state.outcome)
203
+ || isTerminalOutcome(state.run_outcome)
204
+ || isTerminalOutcome(state.lifecycle_outcome)
205
+ || isTerminalOutcome(state.terminal_outcome);
206
+ }
207
+
208
+ function canonicalPath(path) {
209
+ const absolute = resolve(path);
210
+ if (!existsSync(absolute)) return absolute;
211
+ try {
212
+ return typeof realpathSync.native === 'function' ? realpathSync.native(absolute) : realpathSync(absolute);
213
+ } catch {
214
+ return absolute;
215
+ }
216
+ }
217
+
218
+ function sameFilePath(leftPath, rightPath) {
219
+ return canonicalPath(leftPath) === canonicalPath(rightPath);
220
+ }
221
+
222
+ function isSessionStateAuthoritativeForCwd(state, cwd) {
223
+ if (!isSafeSessionId(state?.session_id)) return false;
224
+ const sessionCwd = typeof state.cwd === 'string' ? state.cwd.trim() : '';
225
+ return !sessionCwd || sameFilePath(sessionCwd, cwd);
226
+ }
227
+
228
+ function listAuthoritativeStateBaseDirs(cwd) {
229
+ if (process.env.OMX_TEAM_STATE_ROOT?.trim()) return [process.env.OMX_TEAM_STATE_ROOT.trim()];
230
+ if (process.env.OMX_ROOT?.trim()) return [join(process.env.OMX_ROOT.trim(), '.omx', 'state')];
231
+ if (process.env.OMX_STATE_ROOT?.trim()) return [join(process.env.OMX_STATE_ROOT.trim(), '.omx', 'state')];
232
+ return [join(cwd, '.omx', 'state')];
233
+ }
234
+
235
+ function isSafeSessionId(sessionId) {
236
+ return typeof sessionId === 'string' && /^[A-Za-z0-9_-]{1,64}$/.test(sessionId.trim());
237
+ }
238
+
239
+ function readCurrentSessionId(stateBaseDirs, cwd) {
240
+ for (const stateDir of stateBaseDirs) {
241
+ const session = readJsonFile(join(stateDir, 'session.json'));
242
+ if (isSessionStateAuthoritativeForCwd(session, cwd)) return session.session_id.trim();
243
+ }
244
+ const envSessionId = process.env.OMX_SESSION_ID || process.env.CODEX_SESSION_ID;
245
+ return isSafeSessionId(envSessionId) ? envSessionId.trim() : null;
246
+ }
247
+
248
+ function shouldContinueAutopilotState(state) {
249
+ if (state?.active !== true) return false;
250
+ return !(isTerminalOutcome(state.current_phase)
251
+ || isTerminalOutcome(state.run_outcome)
252
+ || isTerminalOutcome(state.lifecycle_outcome)
253
+ || isTerminalOutcome(state.terminal_outcome)
254
+ || isTerminalOutcome(state.outcome)
255
+ || (typeof state.completed_at === 'string' && state.completed_at.trim() !== ''));
256
+ }
257
+
258
+ function hasActiveAutopilotStateForOversizedStop(input) {
259
+ const text = input.toString('utf8');
260
+ const cwd = extractTopLevelStringField(text, ['cwd']) || process.cwd();
261
+ const stateBaseDirs = listAuthoritativeStateBaseDirs(cwd);
262
+ const sessionId = readCurrentSessionId(stateBaseDirs, cwd);
263
+ if (!isSafeSessionId(sessionId)) return false;
264
+
265
+ const sessionDir = join(stateBaseDirs[0], 'sessions', sessionId.trim());
266
+ const terminalRunState = readJsonFile(join(sessionDir, 'run-state.json'));
267
+ if (isTerminalRunStateForMode(terminalRunState, 'autopilot')) return false;
268
+
269
+ const sessionState = readJsonFile(join(sessionDir, 'autopilot-state.json'));
270
+ return shouldContinueAutopilotState(sessionState);
271
+ }
272
+
273
+ function writeJsonNoop() {
274
+ process.stdout.write(`${JSON.stringify({})}\n`);
275
+ process.exitCode = 0;
276
+ }
277
+
278
+ async function main() {
279
+ const { input, oversized, totalBytes } = await readBoundedStdin();
280
+ const isStop = detectStopHookInput(input);
281
+
282
+ if (oversized) {
283
+ const message = `plugin hook stdin exceeded ${MAX_WRAPPER_STDIN_BYTES} bytes before launcher delegation; totalBytes>${totalBytes}`;
284
+ if (isStop) {
285
+ if (hasActiveAutopilotStateForOversizedStop(input)) {
286
+ console.error(`[oh-my-codex] ${message}`);
287
+ writeStopFallback('plugin_stop_hook_stdin_oversized_active_workflow', message);
288
+ return;
289
+ }
290
+ writeJsonNoop();
291
+ return;
292
+ }
293
+ console.error(`[oh-my-codex] ${message}`);
52
294
  process.exitCode = 1;
53
295
  return;
54
296
  }
55
- process.exitCode = code ?? 0;
297
+
298
+ let launcher;
299
+ try {
300
+ launcher = readConfiguredLauncher();
301
+ } catch (error) {
302
+ failLauncher(error, isStop);
303
+ return;
304
+ }
305
+
306
+ const { command, argsPrefix } = launcher;
307
+ const child = spawn(command, [...argsPrefix, 'codex-native-hook'], {
308
+ stdio: ['pipe', 'pipe', 'pipe'],
309
+ env: process.env,
310
+ shell: process.platform === 'win32',
311
+ });
312
+
313
+ let stdoutBytes = 0;
314
+ let childSpawnError = null;
315
+ let childStdinError = null;
316
+
317
+ child.stdout.on('data', (chunk) => {
318
+ stdoutBytes += Buffer.byteLength(chunk);
319
+ process.stdout.write(chunk);
320
+ });
321
+ child.stderr.pipe(process.stderr);
322
+ child.stdin.on('error', (error) => {
323
+ childStdinError = error;
324
+ });
325
+ child.on('error', (error) => {
326
+ childSpawnError = error;
327
+ });
328
+ child.on('close', (code, signal) => {
329
+ if (isStop && stdoutBytes === 0) {
330
+ if (childSpawnError) {
331
+ writeStopFallback('plugin_stop_hook_launcher_spawn_error', `failed to launch ${command} codex-native-hook: ${childSpawnError.message}`);
332
+ return;
333
+ }
334
+ if (signal) {
335
+ writeStopFallback('plugin_stop_hook_launcher_signal', `codex-native-hook terminated by ${signal}`);
336
+ return;
337
+ }
338
+ if (code && code !== 0) {
339
+ if (childStdinError) {
340
+ writeStopFallback('plugin_stop_hook_launcher_stdin_error', `codex-native-hook stdin failed: ${childStdinError.message}`);
341
+ return;
342
+ }
343
+ writeStopFallback('plugin_stop_hook_launcher_exit', `codex-native-hook exited with code ${code}`);
344
+ return;
345
+ }
346
+ writeStopFallback('plugin_stop_hook_launcher_empty_stdout', 'codex-native-hook exited successfully without producing Stop hook JSON');
347
+ return;
348
+ }
349
+
350
+ if (childSpawnError) {
351
+ console.error(`[oh-my-codex] failed to launch ${command} codex-native-hook: ${childSpawnError.message}`);
352
+ process.exitCode = 1;
353
+ return;
354
+ }
355
+ if (signal) {
356
+ console.error(`[oh-my-codex] codex-native-hook terminated by ${signal}`);
357
+ process.exitCode = 1;
358
+ return;
359
+ }
360
+ process.exitCode = code ?? 0;
361
+ });
362
+
363
+ child.stdin.end(input);
364
+ }
365
+
366
+ main().catch((error) => {
367
+ console.error(`[oh-my-codex] plugin hook launcher failed: ${error instanceof Error ? error.message : String(error)}`);
368
+ process.exitCode = 1;
56
369
  });
@@ -18,8 +18,7 @@
18
18
  "type": "command",
19
19
  "command": "node \"${PLUGIN_ROOT}/hooks/codex-native-hook.mjs\""
20
20
  }
21
- ],
22
- "matcher": "Bash"
21
+ ]
23
22
  }
24
23
  ],
25
24
  "PostToolUse": [
@@ -68,12 +68,14 @@ Before Phase `deep-interview` or `ralplan` starts or resumes:
68
68
  1. Derive a task slug from the request.
69
69
  2. Reuse the latest relevant `.omx/context/{slug}-*.md` snapshot when available.
70
70
  3. If none exists, create `.omx/context/{slug}-{timestamp}.md` (UTC `YYYYMMDDTHHMMSSZ`) with:
71
- - task statement
71
+ - activation prompt / task seed
72
+ - original task status (`activation-prompt`, `legacy-unverified`, or `unavailable`)
72
73
  - desired outcome
73
74
  - known facts/evidence
74
75
  - constraints
75
76
  - unknowns/open questions
76
77
  - likely codebase touchpoints
78
+ - a scope note that the seed is the Autopilot activation prompt, not guaranteed prior conversation context
77
79
  4. If brownfield facts are missing, run `explore` first before or during `$deep-interview` (`$deep-interview --quick <task>` remains acceptable for bounded low-ambiguity intake); do not skip the clarification gate merely because the task sounds actionable.
78
80
  5. Carry the snapshot path in Autopilot state and all handoff artifacts.
79
81
  </Pre-context Intake>
@@ -31,7 +31,7 @@ Delegates to the `code-reviewer` and `architect` agents in parallel for a two-la
31
31
  2. **Launch Parallel Review Lanes**
32
32
  - **`code-reviewer` lane** - owns spec compliance, security, code quality, performance, and maintainability findings
33
33
  - **`architect` lane** - owns the devil's-advocate / design-tradeoff perspective
34
- - Both lanes run in parallel and produce distinct outputs before final synthesis
34
+ - Both lanes run in parallel on a clean context with explicit scope and artifacts, and produce distinct outputs before final synthesis
35
35
  - If either lane cannot be launched or does not return evidence, report `independent review unavailable`; do **not** substitute the current/authoring lane, and do **not** approve or mark the review merge-ready.
36
36
 
37
37
  3. **Review Categories**
@@ -72,9 +72,9 @@ Delegates to the `code-reviewer` and `architect` agents in parallel for a two-la
72
72
  Do not self-review as a fallback. If the `code-reviewer` or `architect` agent path is missing, unavailable, skipped, or fails, emit a clear unavailable-review result and block approval until the independent lane evidence exists.
73
73
 
74
74
  ```
75
- delegate(
76
- role="code-reviewer",
77
- tier="THOROUGH",
75
+ task(
76
+ agent_type="code-reviewer",
77
+ reasoning_effort="xhigh",
78
78
  prompt="CODE REVIEW TASK
79
79
 
80
80
  Review code changes for quality, security, and maintainability.
@@ -98,9 +98,9 @@ Output: Code review report with:
98
98
  - Approval recommendation (APPROVE / REQUEST CHANGES / COMMENT)"
99
99
  )
100
100
 
101
- delegate(
102
- role="architect",
103
- tier="THOROUGH",
101
+ task(
102
+ agent_type="architect",
103
+ reasoning_effort="xhigh",
104
104
  prompt="ARCHITECTURE / DEVIL'S-ADVOCATE REVIEW TASK
105
105
 
106
106
  Review the same code changes from the architecture/tradeoff perspective.
@@ -26,14 +26,14 @@ Ralph is a persistence loop that keeps working on a task until it is fully compl
26
26
  </Do_Not_Use_When>
27
27
 
28
28
  <Why_This_Exists>
29
- Complex tasks often fail silently: partial implementations get declared "done", tests get skipped, edge cases get forgotten. Ralph prevents this by looping until work is genuinely complete, requiring fresh verification evidence before allowing completion, and using tiered architect review to confirm quality.
29
+ Complex tasks often fail silently: partial implementations get declared "done", tests get skipped, edge cases get forgotten. Ralph prevents this by looping until work is genuinely complete, requiring fresh verification evidence before allowing completion, and using explicit architect native-subagent verification to confirm quality.
30
30
  </Why_This_Exists>
31
31
 
32
32
  <Execution_Policy>
33
33
  - Fire independent agent calls simultaneously -- never wait sequentially for independent work
34
34
  - Use `run_in_background: true` for long operations (installs, builds, test suites)
35
- - Always pass the `model` parameter explicitly when delegating to agents
36
- - Read `docs/shared/agent-tiers.md` before first delegation to select correct agent tiers
35
+ - Always set `agent_type` when spawning native subagents; use `reasoning_effort` for per-dispatch intensity when needed
36
+ - Preserve legacy Ralph tier intent through native reasoning effort: LOW -> `low`, STANDARD -> `medium`, THOROUGH -> `xhigh`
37
37
  - Deliver the full implementation: no scope reduction, no partial completion, no deleting tests to make them pass
38
38
  - Apply the shared workflow guidance pattern: outcome-first framing, concise visible updates for multi-step execution, local overrides for the active workflow branch, validation proportional to risk, explicit stop rules, and automatic continuation for safe reversible steps. Ask only for material, destructive, credentialed, external-production, or preference-dependent branches.
39
39
  - Integrate with Codex goal mode when goal tools are available: inspect the active thread goal with `get_goal`, preserve it as the top-level stop condition, and only call `update_goal({status: "complete"})` after a Ralph completion audit proves the objective is actually achieved.
@@ -54,10 +54,10 @@ Complex tasks often fail silently: partial implementations get declared "done",
54
54
  - Do not begin Ralph execution work (delegation, implementation, or verification loops) until snapshot grounding exists. If forced to proceed quickly, note explicit risk tradeoffs.
55
55
  1. **Review progress**: Check TODO list and any prior iteration state
56
56
  2. **Continue from where you left off**: Pick up incomplete tasks
57
- 3. **Delegate in parallel**: Route tasks to specialist agents at appropriate tiers
58
- - Simple lookups: LOW tier -- "What does this function return?"
59
- - Standard work: STANDARD tier -- "Add error handling to this module"
60
- - Complex analysis: THOROUGH tier -- "Debug this race condition"
57
+ 3. **Delegate in parallel**: Route tasks to specialist native agents with explicit `agent_type` and appropriate `reasoning_effort`
58
+ - Simple lookups: `reasoning_effort="low"` -- "What does this function return?"
59
+ - Standard work: `reasoning_effort="medium"` -- "Add error handling to this module"
60
+ - Complex analysis: `reasoning_effort="xhigh"` -- "Debug this race condition"
61
61
  - When Ralph is entered as a ralplan follow-up, start from the approved **available-agent-types roster** and make the delegation plan explicit: implementation lane, evidence/regression lane, and final sign-off lane using only known agent types
62
62
  4. **Run long operations in background**: Builds, installs, test suites use `run_in_background: true`
63
63
  5. **Visual task gate (when screenshot/reference images are present)**:
@@ -72,11 +72,11 @@ Complex tasks often fail silently: partial implementations get declared "done",
72
72
  b. Run verification (test, build, lint)
73
73
  c. Read the output -- confirm it actually passed
74
74
  d. Check: zero pending/in_progress TODO items
75
- 7. **Architect verification** (tiered):
76
- - <5 files, <100 lines with full tests: STANDARD tier minimum (architect role)
77
- - Standard changes: STANDARD tier (architect role)
78
- - >20 files or security/architectural changes: THOROUGH tier (architect role)
79
- - Ralph floor: always at least STANDARD, even for small changes
75
+ 7. **Architect verification** (native role):
76
+ - <5 files, <100 lines with full tests: `task(agent_type="architect", reasoning_effort="medium", prompt="...")` minimum
77
+ - Standard changes: `task(agent_type="architect", reasoning_effort="medium", prompt="...")`
78
+ - >20 files or security/architectural changes: `task(agent_type="architect", reasoning_effort="xhigh", prompt="...")`
79
+ - Ralph floor: always run an explicit `architect` native subagent, even for small changes
80
80
  7.5 **Mandatory Deslop Pass**:
81
81
  - After Step 7 passes, run `oh-my-codex:ai-slop-cleaner` on **all files changed during the Ralph session**.
82
82
  - Scope the cleaner to **changed files only**; do not widen the pass beyond Ralph-owned edits.
@@ -87,7 +87,7 @@ Complex tasks often fail silently: partial implementations get declared "done",
87
87
  - If post-deslop regression fails, roll back cleaner changes or fix and retry. Then rerun Step 7.5 and Step 7.6 until the regression is green.
88
88
  - Do not proceed to completion until post-deslop regression is green (unless `--no-deslop` explicitly skipped the deslop pass).
89
89
  8. **On approval**: If Codex goal mode is active, call `update_goal({status: "complete"})` before `/cancel`; report final elapsed time and token-budget usage when the tool returns it. Then run `/cancel` to cleanly exit and clean up all state files.
90
- 9. **On rejection**: Fix the issues raised, then re-verify at the same tier
90
+ 9. **On rejection**: Fix the issues raised, then re-verify with the same `agent_type` and `reasoning_effort` profile
91
91
  </Steps>
92
92
 
93
93
  <Tool_Usage>
@@ -150,11 +150,11 @@ Use the CLI-first state surface for Ralph lifecycle state (`omx state write/read
150
150
  <Good>
151
151
  Correct parallel delegation:
152
152
  ```
153
- delegate(role="executor", tier="LOW", task="Add type export for UserConfig")
154
- delegate(role="executor", tier="STANDARD", task="Implement the caching layer for API responses")
155
- delegate(role="executor", tier="THOROUGH", task="Refactor auth module to support OAuth2 flow")
153
+ task(agent_type="executor", reasoning_effort="low", prompt="Add type export for UserConfig")
154
+ task(agent_type="executor", reasoning_effort="medium", prompt="Implement the caching layer for API responses")
155
+ task(agent_type="executor", reasoning_effort="xhigh", prompt="Refactor auth module to support OAuth2 flow")
156
156
  ```
157
- Why good: Three independent tasks fired simultaneously at appropriate tiers.
157
+ Why good: Three independent tasks fired simultaneously while explicitly selecting the installed `executor` native role, so the UI/tracker does not show default subagents; legacy tier intent is preserved through native reasoning effort (`LOW` -> `low`, `STANDARD` -> `medium`, `THOROUGH` -> `xhigh`).
158
158
  </Good>
159
159
 
160
160
  <Good>
@@ -163,7 +163,7 @@ Correct verification before completion:
163
163
  1. Run: npm test → Output: "42 passed, 0 failed"
164
164
  2. Run: npm run build → Output: "Build succeeded"
165
165
  3. Run: lsp_diagnostics → Output: 0 errors
166
- 4. Delegate to architect at STANDARD tier → Verdict: "APPROVED"
166
+ 4. task(agent_type="architect", reasoning_effort="medium", prompt="verify completion") → Verdict: "APPROVED"
167
167
  5. Run /cancel
168
168
  ```
169
169
  Why good: Fresh evidence at each step, architect verification, then clean exit.
@@ -178,9 +178,9 @@ Why bad: Uses "should" and "look good" -- no fresh test/build output, no archite
178
178
  <Bad>
179
179
  Sequential execution of independent tasks:
180
180
  ```
181
- delegate(executor, LOW, "Add type export") → wait →
182
- delegate(executor, STANDARD, "Implement caching") → wait →
183
- delegate(executor, THOROUGH, "Refactor auth")
181
+ task(agent_type="executor", reasoning_effort="low", prompt="Add type export") → wait →
182
+ task(agent_type="executor", reasoning_effort="medium", prompt="Implement caching") → wait →
183
+ task(agent_type="executor", reasoning_effort="xhigh", prompt="Refactor auth")
184
184
  ```
185
185
  Why bad: These are independent tasks that should run in parallel, not sequentially.
186
186
  </Bad>
@@ -200,7 +200,7 @@ Why bad: These are independent tasks that should run in parallel, not sequential
200
200
  - [ ] Fresh test run output shows all tests pass
201
201
  - [ ] Fresh build output shows success
202
202
  - [ ] lsp_diagnostics shows 0 errors on affected files
203
- - [ ] Architect verification passed (STANDARD tier minimum)
203
+ - [ ] Architect verification passed through explicit `task(agent_type="architect", reasoning_effort="medium"...)` minimum
204
204
  - [ ] Codex goal-mode completion audit passed, and `update_goal({status: "complete"})` was called when an active goal exists
205
205
  - [ ] ai-slop-cleaner pass completed on changed files (or --no-deslop specified)
206
206
  - [ ] Post-deslop regression tests pass
@@ -58,6 +58,15 @@ The matrix must include normal-path coverage plus adversarial dynamic e2e scenar
58
58
  - Validate exit codes and output semantics; do not trust success-looking text alone.
59
59
  - Do not delete, rewrite, or mask unrelated user work. Capture dirty-worktree evidence before and after generated harness work.
60
60
 
61
+ ### Temporary Harness Generation Guardrails
62
+
63
+ Generated harnesses are part of the QA evidence chain; until setup succeeds, they are evidence about the harness apparatus, not product behavior.
64
+
65
+ - **Use absolute repo imports for built artifacts.** When a harness runs from `/tmp` or another scratch directory but imports repository code, resolve the repository root explicitly from the verified repo cwd and import built modules with an absolute path or `pathToFileURL(join(repoRoot, "dist", ...)).href`. Never rely on `./dist/...` from the harness file's temporary directory.
66
+ - **Use a safe file writer for JS/TS harness bodies.** Prefer a small Node/Python writer or another non-interpolating file-write mechanism for harness source that contains backticks, `${...}`, shell metacharacters, or prompt-injection strings. If a shell heredoc is unavoidable, quote the delimiter and verify the written file before execution; do not use interpolating heredocs for JavaScript assertions.
67
+ - **Sanitize OMX runtime env for isolated probes.** When the scenario creates a temporary repo/state tree or intentionally checks local isolation, run the probe with `OMX_ROOT` and `OMX_STATE_ROOT` unset (for example `env -u OMX_ROOT -u OMX_STATE_ROOT ...`) so ambient boxed runtime state cannot redirect reads/writes away from the scenario fixture.
68
+ - **Classify harness setup failures separately.** If a generated harness fails before exercising product behavior because of import paths, shell interpolation, environment leakage, or fixture construction, record it as harness debris, fix the harness, and rerun the scenario before declaring a product defect.
69
+
61
70
  ## Cycle Workflow
62
71
 
63
72
  ### Cycle N (Max 5)
@@ -68,12 +68,14 @@ Before Phase `deep-interview` or `ralplan` starts or resumes:
68
68
  1. Derive a task slug from the request.
69
69
  2. Reuse the latest relevant `.omx/context/{slug}-*.md` snapshot when available.
70
70
  3. If none exists, create `.omx/context/{slug}-{timestamp}.md` (UTC `YYYYMMDDTHHMMSSZ`) with:
71
- - task statement
71
+ - activation prompt / task seed
72
+ - original task status (`activation-prompt`, `legacy-unverified`, or `unavailable`)
72
73
  - desired outcome
73
74
  - known facts/evidence
74
75
  - constraints
75
76
  - unknowns/open questions
76
77
  - likely codebase touchpoints
78
+ - a scope note that the seed is the Autopilot activation prompt, not guaranteed prior conversation context
77
79
  4. If brownfield facts are missing, run `explore` first before or during `$deep-interview` (`$deep-interview --quick <task>` remains acceptable for bounded low-ambiguity intake); do not skip the clarification gate merely because the task sounds actionable.
78
80
  5. Carry the snapshot path in Autopilot state and all handoff artifacts.
79
81
  </Pre-context Intake>
@@ -31,7 +31,7 @@ Delegates to the `code-reviewer` and `architect` agents in parallel for a two-la
31
31
  2. **Launch Parallel Review Lanes**
32
32
  - **`code-reviewer` lane** - owns spec compliance, security, code quality, performance, and maintainability findings
33
33
  - **`architect` lane** - owns the devil's-advocate / design-tradeoff perspective
34
- - Both lanes run in parallel and produce distinct outputs before final synthesis
34
+ - Both lanes run in parallel on a clean context with explicit scope and artifacts, and produce distinct outputs before final synthesis
35
35
  - If either lane cannot be launched or does not return evidence, report `independent review unavailable`; do **not** substitute the current/authoring lane, and do **not** approve or mark the review merge-ready.
36
36
 
37
37
  3. **Review Categories**
@@ -72,9 +72,9 @@ Delegates to the `code-reviewer` and `architect` agents in parallel for a two-la
72
72
  Do not self-review as a fallback. If the `code-reviewer` or `architect` agent path is missing, unavailable, skipped, or fails, emit a clear unavailable-review result and block approval until the independent lane evidence exists.
73
73
 
74
74
  ```
75
- delegate(
76
- role="code-reviewer",
77
- tier="THOROUGH",
75
+ task(
76
+ agent_type="code-reviewer",
77
+ reasoning_effort="xhigh",
78
78
  prompt="CODE REVIEW TASK
79
79
 
80
80
  Review code changes for quality, security, and maintainability.
@@ -98,9 +98,9 @@ Output: Code review report with:
98
98
  - Approval recommendation (APPROVE / REQUEST CHANGES / COMMENT)"
99
99
  )
100
100
 
101
- delegate(
102
- role="architect",
103
- tier="THOROUGH",
101
+ task(
102
+ agent_type="architect",
103
+ reasoning_effort="xhigh",
104
104
  prompt="ARCHITECTURE / DEVIL'S-ADVOCATE REVIEW TASK
105
105
 
106
106
  Review the same code changes from the architecture/tradeoff perspective.