oh-my-codex 0.18.1 → 0.18.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/Cargo.lock +6 -6
  2. package/Cargo.toml +1 -1
  3. package/README.md +4 -2
  4. package/dist/agents/__tests__/definitions.test.js +14 -0
  5. package/dist/agents/__tests__/definitions.test.js.map +1 -1
  6. package/dist/agents/__tests__/native-config.test.js +19 -0
  7. package/dist/agents/__tests__/native-config.test.js.map +1 -1
  8. package/dist/agents/definitions.d.ts.map +1 -1
  9. package/dist/agents/definitions.js +30 -0
  10. package/dist/agents/definitions.js.map +1 -1
  11. package/dist/agents/native-config.d.ts +1 -0
  12. package/dist/agents/native-config.d.ts.map +1 -1
  13. package/dist/agents/native-config.js +4 -0
  14. package/dist/agents/native-config.js.map +1 -1
  15. package/dist/catalog/__tests__/generator.test.js +4 -0
  16. package/dist/catalog/__tests__/generator.test.js.map +1 -1
  17. package/dist/cli/__tests__/doctor-warning-copy.test.js +61 -5
  18. package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
  19. package/dist/cli/__tests__/index.test.js +161 -21
  20. package/dist/cli/__tests__/index.test.js.map +1 -1
  21. package/dist/cli/__tests__/launch-fallback.test.js +51 -3
  22. package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
  23. package/dist/cli/__tests__/question.test.js +2 -2
  24. package/dist/cli/__tests__/question.test.js.map +1 -1
  25. package/dist/cli/doctor.d.ts.map +1 -1
  26. package/dist/cli/doctor.js +178 -7
  27. package/dist/cli/doctor.js.map +1 -1
  28. package/dist/cli/index.d.ts +7 -1
  29. package/dist/cli/index.d.ts.map +1 -1
  30. package/dist/cli/index.js +143 -43
  31. package/dist/cli/index.js.map +1 -1
  32. package/dist/config/__tests__/codex-hooks.test.js +3 -3
  33. package/dist/config/__tests__/codex-hooks.test.js.map +1 -1
  34. package/dist/config/codex-hooks.d.ts +1 -0
  35. package/dist/config/codex-hooks.d.ts.map +1 -1
  36. package/dist/config/codex-hooks.js +2 -4
  37. package/dist/config/codex-hooks.js.map +1 -1
  38. package/dist/config/generator.d.ts +14 -0
  39. package/dist/config/generator.d.ts.map +1 -1
  40. package/dist/config/generator.js +100 -1
  41. package/dist/config/generator.js.map +1 -1
  42. package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js +21 -0
  43. package/dist/goal-workflows/__tests__/codex-goal-snapshot.test.js.map +1 -1
  44. package/dist/goal-workflows/codex-goal-snapshot.d.ts +3 -0
  45. package/dist/goal-workflows/codex-goal-snapshot.d.ts.map +1 -1
  46. package/dist/goal-workflows/codex-goal-snapshot.js +45 -2
  47. package/dist/goal-workflows/codex-goal-snapshot.js.map +1 -1
  48. package/dist/hooks/__tests__/autopilot-skill-contract.test.js +17 -0
  49. package/dist/hooks/__tests__/autopilot-skill-contract.test.js.map +1 -1
  50. package/dist/hooks/__tests__/keyword-detector.test.js +170 -15
  51. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  52. package/dist/hooks/__tests__/prometheus-strict-contract.test.d.ts +2 -0
  53. package/dist/hooks/__tests__/prometheus-strict-contract.test.d.ts.map +1 -0
  54. package/dist/hooks/__tests__/prometheus-strict-contract.test.js +320 -0
  55. package/dist/hooks/__tests__/prometheus-strict-contract.test.js.map +1 -0
  56. package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js +12 -0
  57. package/dist/hooks/__tests__/prompt-guidance-wave-two.test.js.map +1 -1
  58. package/dist/hooks/__tests__/research-workflow-boundaries.test.d.ts +2 -0
  59. package/dist/hooks/__tests__/research-workflow-boundaries.test.d.ts.map +1 -0
  60. package/dist/hooks/__tests__/research-workflow-boundaries.test.js +35 -0
  61. package/dist/hooks/__tests__/research-workflow-boundaries.test.js.map +1 -0
  62. package/dist/hooks/keyword-detector.d.ts +1 -1
  63. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  64. package/dist/hooks/keyword-detector.js +28 -6
  65. package/dist/hooks/keyword-detector.js.map +1 -1
  66. package/dist/hooks/keyword-registry.d.ts.map +1 -1
  67. package/dist/hooks/keyword-registry.js +1 -0
  68. package/dist/hooks/keyword-registry.js.map +1 -1
  69. package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
  70. package/dist/hooks/prompt-guidance-contract.js +11 -0
  71. package/dist/hooks/prompt-guidance-contract.js.map +1 -1
  72. package/dist/hud/__tests__/hud-tmux-injection.test.js +22 -0
  73. package/dist/hud/__tests__/hud-tmux-injection.test.js.map +1 -1
  74. package/dist/hud/__tests__/reconcile.test.js +121 -10
  75. package/dist/hud/__tests__/reconcile.test.js.map +1 -1
  76. package/dist/hud/__tests__/render.test.js +84 -0
  77. package/dist/hud/__tests__/render.test.js.map +1 -1
  78. package/dist/hud/__tests__/state.test.js +51 -1
  79. package/dist/hud/__tests__/state.test.js.map +1 -1
  80. package/dist/hud/__tests__/tmux.test.js +69 -23
  81. package/dist/hud/__tests__/tmux.test.js.map +1 -1
  82. package/dist/hud/index.d.ts +1 -1
  83. package/dist/hud/index.d.ts.map +1 -1
  84. package/dist/hud/index.js +8 -3
  85. package/dist/hud/index.js.map +1 -1
  86. package/dist/hud/reconcile.d.ts.map +1 -1
  87. package/dist/hud/reconcile.js +6 -3
  88. package/dist/hud/reconcile.js.map +1 -1
  89. package/dist/hud/render.d.ts.map +1 -1
  90. package/dist/hud/render.js +26 -0
  91. package/dist/hud/render.js.map +1 -1
  92. package/dist/hud/state.d.ts +2 -1
  93. package/dist/hud/state.d.ts.map +1 -1
  94. package/dist/hud/state.js +62 -1
  95. package/dist/hud/state.js.map +1 -1
  96. package/dist/hud/tmux.d.ts +10 -3
  97. package/dist/hud/tmux.d.ts.map +1 -1
  98. package/dist/hud/tmux.js +59 -10
  99. package/dist/hud/tmux.js.map +1 -1
  100. package/dist/hud/types.d.ts +22 -0
  101. package/dist/hud/types.d.ts.map +1 -1
  102. package/dist/hud/types.js.map +1 -1
  103. package/dist/pipeline/__tests__/orchestrator.test.js +63 -1
  104. package/dist/pipeline/__tests__/orchestrator.test.js.map +1 -1
  105. package/dist/pipeline/__tests__/stages.test.js +410 -4
  106. package/dist/pipeline/__tests__/stages.test.js.map +1 -1
  107. package/dist/pipeline/orchestrator.d.ts.map +1 -1
  108. package/dist/pipeline/orchestrator.js +29 -2
  109. package/dist/pipeline/orchestrator.js.map +1 -1
  110. package/dist/pipeline/stages/ralplan.d.ts.map +1 -1
  111. package/dist/pipeline/stages/ralplan.js +41 -6
  112. package/dist/pipeline/stages/ralplan.js.map +1 -1
  113. package/dist/question/__tests__/ui.test.js +43 -10
  114. package/dist/question/__tests__/ui.test.js.map +1 -1
  115. package/dist/question/ui.d.ts +12 -0
  116. package/dist/question/ui.d.ts.map +1 -1
  117. package/dist/question/ui.js +83 -46
  118. package/dist/question/ui.js.map +1 -1
  119. package/dist/ralplan/__tests__/runtime.test.js +200 -10
  120. package/dist/ralplan/__tests__/runtime.test.js.map +1 -1
  121. package/dist/ralplan/consensus-gate.d.ts +23 -0
  122. package/dist/ralplan/consensus-gate.d.ts.map +1 -0
  123. package/dist/ralplan/consensus-gate.js +212 -0
  124. package/dist/ralplan/consensus-gate.js.map +1 -0
  125. package/dist/ralplan/runtime.d.ts +25 -0
  126. package/dist/ralplan/runtime.d.ts.map +1 -1
  127. package/dist/ralplan/runtime.js +144 -8
  128. package/dist/ralplan/runtime.js.map +1 -1
  129. package/dist/scripts/__tests__/codex-native-hook.test.js +626 -7
  130. package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
  131. package/dist/scripts/__tests__/docs-site-contract.test.d.ts +2 -0
  132. package/dist/scripts/__tests__/docs-site-contract.test.d.ts.map +1 -0
  133. package/dist/scripts/__tests__/docs-site-contract.test.js +42 -0
  134. package/dist/scripts/__tests__/docs-site-contract.test.js.map +1 -0
  135. package/dist/scripts/__tests__/notify-dispatcher.test.js +115 -2
  136. package/dist/scripts/__tests__/notify-dispatcher.test.js.map +1 -1
  137. package/dist/scripts/__tests__/run-test-files.test.js +57 -0
  138. package/dist/scripts/__tests__/run-test-files.test.js.map +1 -1
  139. package/dist/scripts/__tests__/verify-native-agents.test.js +2 -2
  140. package/dist/scripts/__tests__/verify-native-agents.test.js.map +1 -1
  141. package/dist/scripts/codex-native-hook.d.ts.map +1 -1
  142. package/dist/scripts/codex-native-hook.js +214 -34
  143. package/dist/scripts/codex-native-hook.js.map +1 -1
  144. package/dist/scripts/notify-dispatcher.js +188 -4
  145. package/dist/scripts/notify-dispatcher.js.map +1 -1
  146. package/dist/scripts/run-test-files.js +13 -0
  147. package/dist/scripts/run-test-files.js.map +1 -1
  148. package/dist/state/__tests__/workflow-transition.test.js +6 -0
  149. package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
  150. package/dist/state/workflow-transition.d.ts +1 -1
  151. package/dist/state/workflow-transition.d.ts.map +1 -1
  152. package/dist/state/workflow-transition.js +7 -0
  153. package/dist/state/workflow-transition.js.map +1 -1
  154. package/dist/subagents/tracker.d.ts.map +1 -1
  155. package/dist/subagents/tracker.js +4 -3
  156. package/dist/subagents/tracker.js.map +1 -1
  157. package/dist/team/__tests__/runtime.test.js +36 -44
  158. package/dist/team/__tests__/runtime.test.js.map +1 -1
  159. package/dist/team/__tests__/tmux-session.test.js +58 -18
  160. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  161. package/dist/team/runtime.d.ts.map +1 -1
  162. package/dist/team/runtime.js +10 -20
  163. package/dist/team/runtime.js.map +1 -1
  164. package/dist/team/tmux-session.d.ts.map +1 -1
  165. package/dist/team/tmux-session.js +15 -6
  166. package/dist/team/tmux-session.js.map +1 -1
  167. package/dist/ultragoal/__tests__/artifacts.test.js +50 -0
  168. package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
  169. package/dist/ultragoal/artifacts.d.ts.map +1 -1
  170. package/dist/ultragoal/artifacts.js +28 -2
  171. package/dist/ultragoal/artifacts.js.map +1 -1
  172. package/package.json +1 -1
  173. package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
  174. package/plugins/oh-my-codex/skills/autopilot/SKILL.md +16 -4
  175. package/plugins/oh-my-codex/skills/autoresearch/SKILL.md +4 -0
  176. package/plugins/oh-my-codex/skills/autoresearch-goal/SKILL.md +1 -1
  177. package/plugins/oh-my-codex/skills/best-practice-research/SKILL.md +1 -1
  178. package/plugins/oh-my-codex/skills/pipeline/SKILL.md +1 -1
  179. package/plugins/oh-my-codex/skills/plan/SKILL.md +1 -1
  180. package/plugins/oh-my-codex/skills/prometheus-strict/README.md +35 -0
  181. package/plugins/oh-my-codex/skills/prometheus-strict/SKILL.md +219 -0
  182. package/plugins/oh-my-codex/skills/ralplan/SKILL.md +18 -3
  183. package/prompts/prometheus-strict-metis.md +274 -0
  184. package/prompts/prometheus-strict-momus.md +82 -0
  185. package/prompts/prometheus-strict-oracle.md +107 -0
  186. package/prompts/researcher.md +22 -3
  187. package/skills/autopilot/SKILL.md +16 -4
  188. package/skills/autoresearch/SKILL.md +4 -0
  189. package/skills/autoresearch-goal/SKILL.md +1 -1
  190. package/skills/best-practice-research/SKILL.md +1 -1
  191. package/skills/pipeline/SKILL.md +1 -1
  192. package/skills/plan/SKILL.md +1 -1
  193. package/skills/prometheus-strict/README.md +35 -0
  194. package/skills/prometheus-strict/SKILL.md +219 -0
  195. package/skills/ralplan/SKILL.md +18 -3
  196. package/src/scripts/__tests__/codex-native-hook.test.ts +769 -8
  197. package/src/scripts/__tests__/docs-site-contract.test.ts +47 -0
  198. package/src/scripts/__tests__/notify-dispatcher.test.ts +132 -3
  199. package/src/scripts/__tests__/run-test-files.test.ts +67 -0
  200. package/src/scripts/__tests__/verify-native-agents.test.ts +2 -2
  201. package/src/scripts/codex-native-hook.ts +237 -30
  202. package/src/scripts/notify-dispatcher.ts +202 -4
  203. package/src/scripts/run-test-files.ts +13 -0
  204. package/templates/catalog-manifest.json +22 -0
@@ -884,7 +884,7 @@ esac
884
884
  await rm(cwd, { recursive: true, force: true });
885
885
  }
886
886
  });
887
- it('startTeam records recoverable issue when tmux fallback never produces worker startup evidence', { skip: skipSlowLifecycleUnderCoverage }, async () => {
887
+ it('startTeam rejects tmux fallback when worker startup evidence stays missing', { skip: skipSlowLifecycleUnderCoverage }, async () => {
888
888
  const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-startup-no-evidence-'));
889
889
  const prevTmux = process.env.TMUX;
890
890
  const prevTmuxPane = process.env.TMUX_PANE;
@@ -985,17 +985,14 @@ esac
985
985
  }
986
986
  })();
987
987
  }, 20);
988
- const runtime = await withoutTeamWorkerEnv(() => startTeam('team-startup-no-evidence', 'interactive startup records missing worker evidence without aborting live panes', 'executor', 1, [{ subject: 's', description: 'd', owner: 'worker-1' }], cwd));
988
+ await assert.rejects(withoutTeamWorkerEnv(() => startTeam('team-startup-no-evidence', 'interactive startup rejects missing worker evidence without false task evidence', 'executor', 1, [{ subject: 's', description: 'd', owner: 'worker-1' }], cwd)), /worker_notify_failed:worker-1:codex_startup_no_evidence_after_fallback/);
989
989
  if (receiptFailer) {
990
990
  clearInterval(receiptFailer);
991
991
  receiptFailer = null;
992
992
  }
993
- assert.ok(await readTeamConfig(runtime.teamName, cwd));
994
- const workerStatus = await readWorkerStatus(runtime.teamName, 'worker-1', cwd);
995
- assert.ok(['unknown', 'idle'].includes(workerStatus.state));
996
993
  const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
997
994
  assert.match(tmuxLog, /send-keys -t %2 -l --/);
998
- await shutdownTeam(runtime.teamName, cwd, { force: true }).catch(() => { });
995
+ await shutdownTeam(expectedTeamName, cwd, { force: true }).catch(() => { });
999
996
  });
1000
997
  }
1001
998
  finally {
@@ -1659,7 +1656,7 @@ esac
1659
1656
  assert.equal(applyIndex < saveIndex, true);
1660
1657
  assert.equal(saveIndex < readyIndex, true);
1661
1658
  });
1662
- it('startTeam sends startup direct trigger before slow readiness wait when pane is safe', async () => {
1659
+ it('startTeam rejects startup direct trigger success when Codex startup evidence is missing', async () => {
1663
1660
  const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-startup-direct-fast-'));
1664
1661
  const previousTmux = process.env.TMUX;
1665
1662
  const previousTmuxPane = process.env.TMUX_PANE;
@@ -1668,13 +1665,14 @@ esac
1668
1665
  const previousReadyTimeout = process.env.OMX_TEAM_READY_TIMEOUT_MS;
1669
1666
  const previousStartupEvidenceTimeout = process.env.OMX_TEAM_STARTUP_EVIDENCE_TIMEOUT_MS;
1670
1667
  const previousStartupDispatchRetries = process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES;
1671
- let runtimeTeamName = null;
1668
+ const teamName = `tsd-${process.pid}-${Date.now().toString(36)}`;
1672
1669
  try {
1673
1670
  await withMockTmuxFixture({
1674
1671
  dirPrefix: 'omx-runtime-startup-direct-fast-bin-',
1675
1672
  tmuxScript: () => `#!/bin/sh
1676
1673
  set -eu
1677
1674
  order_file="${cwd}/startup-order.log"
1675
+ count_file="${cwd}/startup-capture-count"
1678
1676
  case "$1" in
1679
1677
  -V)
1680
1678
  echo "tmux 3.4"
@@ -1699,7 +1697,15 @@ case "$1" in
1699
1697
  ;;
1700
1698
  capture-pane)
1701
1699
  printf '%s\n' capture >> "$order_file"
1702
- printf 'OpenAI Codex\nmodel: test\ndirectory: /tmp/demo\n'
1700
+ count=0
1701
+ if [ -f "$count_file" ]; then count=$(cat "$count_file"); fi
1702
+ count=$((count + 1))
1703
+ printf '%s' "$count" > "$count_file"
1704
+ if [ "$count" -eq 1 ]; then
1705
+ printf 'OpenAI Codex\nmodel: test\ndirectory: /tmp/demo\n'
1706
+ else
1707
+ printf 'worker process is still starting; no agent prompt yet\n'
1708
+ fi
1703
1709
  exit 0
1704
1710
  ;;
1705
1711
  send-keys)
@@ -1725,26 +1731,15 @@ esac
1725
1731
  process.env.OMX_TEAM_WORKER_LAUNCH_MODE = 'interactive';
1726
1732
  process.env.OMX_TEAM_WORKER_CLI = 'codex';
1727
1733
  process.env.OMX_TEAM_READY_TIMEOUT_MS = '5000';
1728
- process.env.OMX_TEAM_STARTUP_EVIDENCE_TIMEOUT_MS = '50';
1734
+ process.env.OMX_TEAM_STARTUP_EVIDENCE_TIMEOUT_MS = '500';
1729
1735
  process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES = '1';
1730
- const runtime = await withoutTeamWorkerEnv(() => startTeam('team-startup-direct-fast', 'startup direct trigger falls back to evidence-gated dispatch', 'executor', 1, [{ subject: 'w1', description: 'worker one', owner: 'worker-1' }], cwd));
1731
- runtimeTeamName = runtime.teamName;
1736
+ await assert.rejects(withoutTeamWorkerEnv(() => startTeam(teamName, 'startup direct trigger falls back to evidence-gated dispatch', 'executor', 1, [{ subject: 'w1', description: 'worker one', owner: 'worker-1' }], cwd)), /worker_notify_failed:worker-1:codex_startup_no_evidence_after_fallback/);
1732
1737
  const order = (await readFile(join(cwd, 'startup-order.log'), 'utf-8')).trim().split('\n');
1733
1738
  assert.ok(order.includes('send-keys'), `expected direct send-keys, got ${order.join(',')}`);
1734
- const timing = JSON.parse(await readFile(join(cwd, '.omx', 'state', 'team', runtime.teamName, 'startup-timing.json'), 'utf-8'));
1735
- assert.ok(timing.events.some((event) => event.phase === 'split_returned'));
1736
- assert.ok(timing.events.some((event) => event.phase === 'identity_inbox_written'));
1737
- assert.ok(timing.events.some((event) => event.phase === 'direct_fallback' && /startup_direct_trigger_sent/.test(event.reason ?? '')));
1738
- assert.ok(timing.events.some((event) => event.phase === 'startup_evidence' && event.reason === 'none' && event.ok === false));
1739
- assert.equal(timing.events.some((event) => event.phase === 'ready_wait_start'), false);
1740
- const workerStatus = await readWorkerStatus(runtime.teamName, 'worker-1', cwd);
1741
- assert.equal(workerStatus?.state, 'unknown');
1742
- assert.match(workerStatus?.reason ?? '', /startup_direct_no_evidence/);
1739
+ assert.ok(order.filter((entry) => entry === 'send-keys').length >= 2, `expected evidence-gated dispatch after startup-direct no-evidence, got ${order.join(',')}`);
1743
1740
  });
1744
1741
  }
1745
1742
  finally {
1746
- if (runtimeTeamName)
1747
- await shutdownTeam(runtimeTeamName, cwd, { force: true }).catch(() => { });
1748
1743
  if (typeof previousTmux === 'string')
1749
1744
  process.env.TMUX = previousTmux;
1750
1745
  else
@@ -1858,12 +1853,16 @@ esac
1858
1853
  assert.equal(workerStatus.state, 'unknown');
1859
1854
  assert.equal(workerStatus.reason, undefined);
1860
1855
  const requests = await listDispatchRequests(runtime.teamName, cwd, { kind: 'inbox' });
1861
- assert.equal(requests.at(-1)?.status, 'notified');
1856
+ assert.ok(requests.some((request) => request.status === 'notified')
1857
+ || requests.some((request) => /fallback_confirmed/.test(request.last_reason ?? '')), `expected hook notification or ready-prompt fallback confirmation, got ${JSON.stringify(requests)}`);
1862
1858
  const captureCount = Number.parseInt(await readFile(join(cwd, 'capture-count'), 'utf-8'), 10);
1863
1859
  assert.ok(captureCount >= 2, `expected ready wait capture after bootstrapping, got ${captureCount}`);
1864
- const timing = JSON.parse(await readFile(join(cwd, '.omx', 'state', 'team', runtime.teamName, 'startup-timing.json'), 'utf-8'));
1865
- assert.ok(timing.events.some((event) => event.phase === 'ready_wait_start'));
1866
- assert.ok(timing.events.some((event) => event.phase === 'ready_wait_end' && event.ok === true));
1860
+ const timingPath = join(cwd, '.omx', 'state', 'team', runtime.teamName, 'startup-timing.json');
1861
+ if (existsSync(timingPath)) {
1862
+ const timing = JSON.parse(await readFile(timingPath, 'utf-8'));
1863
+ assert.ok(timing.events.some((event) => event.phase === 'ready_wait_start'));
1864
+ assert.ok(timing.events.some((event) => event.phase === 'ready_wait_end' && event.ok === true));
1865
+ }
1867
1866
  });
1868
1867
  }
1869
1868
  finally {
@@ -2158,7 +2157,7 @@ esac
2158
2157
  await rm(cwd, { recursive: true, force: true });
2159
2158
  }
2160
2159
  });
2161
- it('startTeam records recoverable startup issues per worker instead of failing launch early when panes stay alive', { skip: skipSlowLifecycleUnderCoverage }, async () => {
2160
+ it('startTeam rejects no-evidence startup issues instead of treating live panes as recoverable', { skip: skipSlowLifecycleUnderCoverage }, async () => {
2162
2161
  const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-no-startup-evidence-'));
2163
2162
  const previousTmux = process.env.TMUX;
2164
2163
  const previousTmuxPane = process.env.TMUX_PANE;
@@ -2171,6 +2170,7 @@ esac
2171
2170
  let receiptFailer = null;
2172
2171
  let runtime = null;
2173
2172
  const teamName = 'team-no-startup-evidence';
2173
+ let observedNoEvidenceRequest = false;
2174
2174
  try {
2175
2175
  await withMockTmuxFixture({
2176
2176
  dirPrefix: 'omx-runtime-no-startup-evidence-bin-',
@@ -2255,29 +2255,21 @@ process.on('SIGTERM', () => process.exit(0));
2255
2255
  process.env.OMX_TEAM_STARTUP_DISPATCH_RETRY_DELAY_MS = '50';
2256
2256
  receiptFailer = setInterval(() => {
2257
2257
  void (async () => {
2258
- const requests = await listDispatchRequests(await resolveRuntimeTeamName(cwd, teamName), cwd, { kind: 'inbox' }).catch(() => []);
2258
+ const runtimeTeamName = await resolveRuntimeTeamName(cwd, teamName);
2259
+ const requests = await listDispatchRequests(runtimeTeamName, cwd, { kind: 'inbox' }).catch(() => []);
2259
2260
  for (const request of requests) {
2261
+ observedNoEvidenceRequest ||= /startup_no_evidence|fallback_attempted_but_unconfirmed/.test(request.last_reason ?? '');
2260
2262
  if (request.status !== 'pending')
2261
2263
  continue;
2262
2264
  await transitionDispatchRequest(teamName, request.request_id, 'pending', 'failed', { last_reason: 'test_failed_receipt' }, cwd).catch(() => { });
2263
2265
  }
2264
2266
  })();
2265
2267
  }, 20);
2266
- runtime = await withoutTeamWorkerEnv(() => startTeam(teamName, 'interactive startup should keep evaluating per-worker startup issues while panes stay alive', 'executor', 2, [
2268
+ await assert.rejects(withoutTeamWorkerEnv(() => startTeam(teamName, 'interactive startup should reject no-evidence startup even while panes stay alive', 'executor', 2, [
2267
2269
  { subject: 'worker-1 task', description: 'd', owner: 'worker-1' },
2268
2270
  { subject: 'worker-2 task', description: 'd', owner: 'worker-2' },
2269
- ], cwd));
2270
- const runtimeTeamName = runtime.teamName;
2271
- const worker1Status = await readWorkerStatus(runtimeTeamName, 'worker-1', cwd);
2272
- const worker2Status = await readWorkerStatus(runtimeTeamName, 'worker-2', cwd);
2273
- assert.equal(worker1Status.state, 'unknown');
2274
- assert.equal(worker2Status.state, 'unknown');
2275
- assert.match(worker1Status.reason ?? '', /startup_no_evidence|fallback_attempted_but_unconfirmed/);
2276
- assert.match(worker2Status.reason ?? '', /startup_no_evidence|fallback_attempted_but_unconfirmed/);
2277
- const task1 = await readTask(runtimeTeamName, '1', cwd);
2278
- const task2 = await readTask(runtimeTeamName, '2', cwd);
2279
- assert.equal(task1?.status, 'pending');
2280
- assert.equal(task2?.status, 'pending');
2271
+ ], cwd)), /worker_notify_failed:worker-\d+:(codex_startup_no_evidence_after_fallback|fallback_attempted_but_unconfirmed)/);
2272
+ assert.equal(observedNoEvidenceRequest, true);
2281
2273
  });
2282
2274
  }
2283
2275
  finally {
@@ -3375,7 +3367,7 @@ exit 0
3375
3367
  const standaloneHudSplitRe = new RegExp(`split-window -v -l ${HUD_TMUX_TEAM_HEIGHT_LINES} -t %1 -d -P -F #\\{pane_id\\}`, 'g');
3376
3368
  assert.equal(tmuxLog.match(teamHudSplitRe)?.length ?? 0, 2);
3377
3369
  assert.equal(tmuxLog.match(standaloneHudSplitRe)?.length ?? 0, 1);
3378
- assert.equal(tmuxLog.match(/set-hook -w -t leader:0 window-resized\[\d+\]/g)?.length ?? 0, 2);
3370
+ assert.equal(tmuxLog.match(/set-hook -t leader:0 client-resized\[\d+\]/g)?.length ?? 0, 2);
3379
3371
  assert.equal(tmuxLog.match(/set-hook -t leader:0 client-attached\[\d+\]/g)?.length ?? 0, 2);
3380
3372
  assert.equal(tmuxLog.match(/run-shell -b sleep \d+; tmux resize-pane -t %3 -y \d+ >/g)?.length ?? 0, 3);
3381
3373
  assert.equal(tmuxLog.match(/run-shell tmux resize-pane -t %3 -y \d+ >/g)?.length ?? 0, 3);
@@ -4718,7 +4710,7 @@ esac
4718
4710
  const teamRoot = teamStateTestPath(cwd, 'team', 'team-shutdown-gate-failed');
4719
4711
  assert.equal(existsSync(teamRoot), false);
4720
4712
  const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
4721
- assert.match(tmuxLog, /set-hook -u -w -t omx-team-team-shutdown-gate-failed:0 window-resized\[\d+\]/);
4713
+ assert.match(tmuxLog, /set-hook -u -t omx-team-team-shutdown-gate-failed:0 client-resized\[\d+\]/);
4722
4714
  assert.match(tmuxLog, /kill-session -t omx-team-team-shutdown-gate-failed/);
4723
4715
  });
4724
4716
  }