oh-my-codex 0.17.0 → 0.17.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 (178) hide show
  1. package/Cargo.lock +5 -5
  2. package/Cargo.toml +1 -1
  3. package/dist/cli/__tests__/question.test.js +2 -0
  4. package/dist/cli/__tests__/question.test.js.map +1 -1
  5. package/dist/cli/__tests__/ralph-goal-mode-contract.test.js +3 -0
  6. package/dist/cli/__tests__/ralph-goal-mode-contract.test.js.map +1 -1
  7. package/dist/cli/__tests__/ralph.test.js +0 -124
  8. package/dist/cli/__tests__/ralph.test.js.map +1 -1
  9. package/dist/cli/__tests__/setup-install-mode.test.js +156 -3
  10. package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
  11. package/dist/cli/__tests__/setup-refresh.test.js +3 -3
  12. package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
  13. package/dist/cli/__tests__/team.test.js +166 -42
  14. package/dist/cli/__tests__/team.test.js.map +1 -1
  15. package/dist/cli/doctor.js +9 -4
  16. package/dist/cli/doctor.js.map +1 -1
  17. package/dist/cli/plugin-marketplace.d.ts +5 -1
  18. package/dist/cli/plugin-marketplace.d.ts.map +1 -1
  19. package/dist/cli/plugin-marketplace.js +31 -2
  20. package/dist/cli/plugin-marketplace.js.map +1 -1
  21. package/dist/cli/question.d.ts +1 -1
  22. package/dist/cli/question.d.ts.map +1 -1
  23. package/dist/cli/question.js +98 -4
  24. package/dist/cli/question.js.map +1 -1
  25. package/dist/cli/ralph.d.ts.map +1 -1
  26. package/dist/cli/ralph.js +1 -49
  27. package/dist/cli/ralph.js.map +1 -1
  28. package/dist/cli/setup.d.ts +1 -0
  29. package/dist/cli/setup.d.ts.map +1 -1
  30. package/dist/cli/setup.js +75 -9
  31. package/dist/cli/setup.js.map +1 -1
  32. package/dist/cli/team.d.ts.map +1 -1
  33. package/dist/cli/team.js +21 -29
  34. package/dist/cli/team.js.map +1 -1
  35. package/dist/config/generator.d.ts +4 -0
  36. package/dist/config/generator.d.ts.map +1 -1
  37. package/dist/config/generator.js +58 -0
  38. package/dist/config/generator.js.map +1 -1
  39. package/dist/hooks/__tests__/agents-overlay.test.js +29 -0
  40. package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
  41. package/dist/hooks/__tests__/session.test.js +126 -1
  42. package/dist/hooks/__tests__/session.test.js.map +1 -1
  43. package/dist/hooks/agents-overlay.d.ts.map +1 -1
  44. package/dist/hooks/agents-overlay.js +6 -3
  45. package/dist/hooks/agents-overlay.js.map +1 -1
  46. package/dist/hooks/session.d.ts +11 -3
  47. package/dist/hooks/session.d.ts.map +1 -1
  48. package/dist/hooks/session.js +68 -6
  49. package/dist/hooks/session.js.map +1 -1
  50. package/dist/hud/__tests__/reconcile.test.js +63 -0
  51. package/dist/hud/__tests__/reconcile.test.js.map +1 -1
  52. package/dist/hud/__tests__/tmux.test.d.ts +2 -0
  53. package/dist/hud/__tests__/tmux.test.d.ts.map +1 -0
  54. package/dist/hud/__tests__/tmux.test.js +92 -0
  55. package/dist/hud/__tests__/tmux.test.js.map +1 -0
  56. package/dist/hud/reconcile.d.ts +2 -0
  57. package/dist/hud/reconcile.d.ts.map +1 -1
  58. package/dist/hud/reconcile.js +14 -1
  59. package/dist/hud/reconcile.js.map +1 -1
  60. package/dist/hud/tmux.d.ts +12 -0
  61. package/dist/hud/tmux.d.ts.map +1 -1
  62. package/dist/hud/tmux.js +88 -0
  63. package/dist/hud/tmux.js.map +1 -1
  64. package/dist/mcp/__tests__/hermes-bridge.test.js +82 -1
  65. package/dist/mcp/__tests__/hermes-bridge.test.js.map +1 -1
  66. package/dist/mcp/hermes-bridge.d.ts +34 -1
  67. package/dist/mcp/hermes-bridge.d.ts.map +1 -1
  68. package/dist/mcp/hermes-bridge.js +75 -0
  69. package/dist/mcp/hermes-bridge.js.map +1 -1
  70. package/dist/mcp/hermes-server.d.ts +111 -6
  71. package/dist/mcp/hermes-server.d.ts.map +1 -1
  72. package/dist/mcp/hermes-server.js +38 -1
  73. package/dist/mcp/hermes-server.js.map +1 -1
  74. package/dist/pipeline/__tests__/stages.test.js +18 -9
  75. package/dist/pipeline/__tests__/stages.test.js.map +1 -1
  76. package/dist/pipeline/stages/team-exec.d.ts.map +1 -1
  77. package/dist/pipeline/stages/team-exec.js +2 -7
  78. package/dist/pipeline/stages/team-exec.js.map +1 -1
  79. package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.js +111 -269
  80. package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.js.map +1 -1
  81. package/dist/planning/__tests__/approved-launch-hint-lineage-matrix.test.js +31 -72
  82. package/dist/planning/__tests__/approved-launch-hint-lineage-matrix.test.js.map +1 -1
  83. package/dist/planning/__tests__/artifacts.test.js +27 -372
  84. package/dist/planning/__tests__/artifacts.test.js.map +1 -1
  85. package/dist/planning/artifacts.d.ts +1 -14
  86. package/dist/planning/artifacts.d.ts.map +1 -1
  87. package/dist/planning/artifacts.js +11 -31
  88. package/dist/planning/artifacts.js.map +1 -1
  89. package/dist/question/__tests__/state.test.js +349 -1
  90. package/dist/question/__tests__/state.test.js.map +1 -1
  91. package/dist/question/__tests__/ui.test.js +6 -6
  92. package/dist/question/__tests__/ui.test.js.map +1 -1
  93. package/dist/question/events.d.ts +53 -0
  94. package/dist/question/events.d.ts.map +1 -0
  95. package/dist/question/events.js +201 -0
  96. package/dist/question/events.js.map +1 -0
  97. package/dist/question/state.d.ts +30 -2
  98. package/dist/question/state.d.ts.map +1 -1
  99. package/dist/question/state.js +276 -5
  100. package/dist/question/state.js.map +1 -1
  101. package/dist/question/types.d.ts +1 -0
  102. package/dist/question/types.d.ts.map +1 -1
  103. package/dist/question/types.js.map +1 -1
  104. package/dist/question/ui.d.ts.map +1 -1
  105. package/dist/question/ui.js +3 -18
  106. package/dist/question/ui.js.map +1 -1
  107. package/dist/ralph/__tests__/completion-audit.test.js +39 -0
  108. package/dist/ralph/__tests__/completion-audit.test.js.map +1 -1
  109. package/dist/scripts/__tests__/codex-native-hook.test.js +111 -1
  110. package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
  111. package/dist/scripts/__tests__/run-test-files.test.js +22 -0
  112. package/dist/scripts/__tests__/run-test-files.test.js.map +1 -1
  113. package/dist/scripts/codex-native-hook.d.ts.map +1 -1
  114. package/dist/scripts/codex-native-hook.js +93 -1
  115. package/dist/scripts/codex-native-hook.js.map +1 -1
  116. package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
  117. package/dist/scripts/codex-native-pre-post.js +12 -6
  118. package/dist/scripts/codex-native-pre-post.js.map +1 -1
  119. package/dist/scripts/run-test-files.js +12 -1
  120. package/dist/scripts/run-test-files.js.map +1 -1
  121. package/dist/team/__tests__/approved-execution.test.js +25 -24
  122. package/dist/team/__tests__/approved-execution.test.js.map +1 -1
  123. package/dist/team/__tests__/runtime.test.js +173 -26
  124. package/dist/team/__tests__/runtime.test.js.map +1 -1
  125. package/dist/team/__tests__/scaling.test.js +66 -17
  126. package/dist/team/__tests__/scaling.test.js.map +1 -1
  127. package/dist/team/__tests__/tmux-session.test.js +42 -0
  128. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  129. package/dist/team/__tests__/worker-bootstrap.test.js +205 -0
  130. package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
  131. package/dist/team/approved-execution.d.ts +13 -0
  132. package/dist/team/approved-execution.d.ts.map +1 -1
  133. package/dist/team/approved-execution.js +65 -30
  134. package/dist/team/approved-execution.js.map +1 -1
  135. package/dist/team/runtime.d.ts.map +1 -1
  136. package/dist/team/runtime.js +28 -24
  137. package/dist/team/runtime.js.map +1 -1
  138. package/dist/team/scaling.d.ts.map +1 -1
  139. package/dist/team/scaling.js +7 -8
  140. package/dist/team/scaling.js.map +1 -1
  141. package/dist/team/tmux-session.d.ts.map +1 -1
  142. package/dist/team/tmux-session.js +48 -2
  143. package/dist/team/tmux-session.js.map +1 -1
  144. package/dist/team/ultragoal-context.d.ts +35 -0
  145. package/dist/team/ultragoal-context.d.ts.map +1 -0
  146. package/dist/team/ultragoal-context.js +191 -0
  147. package/dist/team/ultragoal-context.js.map +1 -0
  148. package/dist/ultragoal/__tests__/docs-contract.test.js +19 -0
  149. package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -1
  150. package/package.json +1 -1
  151. package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
  152. package/plugins/oh-my-codex/skills/plan/SKILL.md +3 -3
  153. package/plugins/oh-my-codex/skills/ralph/SKILL.md +2 -2
  154. package/plugins/oh-my-codex/skills/ralplan/SKILL.md +1 -1
  155. package/plugins/oh-my-codex/skills/team/SKILL.md +6 -0
  156. package/plugins/oh-my-codex/skills/ultragoal/SKILL.md +11 -0
  157. package/skills/plan/SKILL.md +3 -3
  158. package/skills/ralph/SKILL.md +2 -2
  159. package/skills/ralplan/SKILL.md +1 -1
  160. package/skills/team/SKILL.md +6 -0
  161. package/skills/ultragoal/SKILL.md +11 -0
  162. package/src/scripts/__tests__/codex-native-hook.test.ts +133 -1
  163. package/src/scripts/__tests__/run-test-files.test.ts +32 -0
  164. package/src/scripts/codex-native-hook.ts +121 -2
  165. package/src/scripts/codex-native-pre-post.ts +12 -6
  166. package/src/scripts/run-test-files.ts +13 -2
  167. package/dist/planning/__tests__/context-pack-status.test.d.ts +0 -2
  168. package/dist/planning/__tests__/context-pack-status.test.d.ts.map +0 -1
  169. package/dist/planning/__tests__/context-pack-status.test.js +0 -795
  170. package/dist/planning/__tests__/context-pack-status.test.js.map +0 -1
  171. package/dist/planning/__tests__/ready-context-pack-role-refs.test.d.ts +0 -2
  172. package/dist/planning/__tests__/ready-context-pack-role-refs.test.d.ts.map +0 -1
  173. package/dist/planning/__tests__/ready-context-pack-role-refs.test.js +0 -612
  174. package/dist/planning/__tests__/ready-context-pack-role-refs.test.js.map +0 -1
  175. package/dist/planning/context-pack-status.d.ts +0 -73
  176. package/dist/planning/context-pack-status.d.ts.map +0 -1
  177. package/dist/planning/context-pack-status.js +0 -745
  178. package/dist/planning/context-pack-status.js.map +0 -1
@@ -1906,6 +1906,116 @@ esac
1906
1906
  await rm(cwd, { recursive: true, force: true });
1907
1907
  }
1908
1908
  });
1909
+ it('startTeam rejects ready-prompt timeout when dispatch never produces startup evidence', async () => {
1910
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-ready-timeout-no-evidence-'));
1911
+ const previousTmux = process.env.TMUX;
1912
+ const previousTmuxPane = process.env.TMUX_PANE;
1913
+ const previousLaunchMode = process.env.OMX_TEAM_WORKER_LAUNCH_MODE;
1914
+ const previousWorkerCli = process.env.OMX_TEAM_WORKER_CLI;
1915
+ const previousReadyTimeout = process.env.OMX_TEAM_READY_TIMEOUT_MS;
1916
+ const previousStartupEvidenceTimeout = process.env.OMX_TEAM_STARTUP_EVIDENCE_TIMEOUT_MS;
1917
+ const previousStartupDispatchRetries = process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES;
1918
+ const teamName = `trt-${process.pid}-${Date.now().toString(36)}`;
1919
+ let receiptNotifier = null;
1920
+ let runtimeTeamName = null;
1921
+ try {
1922
+ await withMockTmuxFixture({
1923
+ dirPrefix: 'omx-runtime-ready-timeout-no-evidence-bin-',
1924
+ tmuxScript: (tmuxLogPath) => `#!/bin/sh
1925
+ set -eu
1926
+ printf '%s\\n' "$*" >> "${tmuxLogPath}"
1927
+ case "$1" in
1928
+ -V)
1929
+ echo "tmux 3.4"
1930
+ exit 0
1931
+ ;;
1932
+ display-message)
1933
+ case "$*" in
1934
+ *"#{window_width}"*) echo "120" ;;
1935
+ *) echo "leader:0 %1" ;;
1936
+ esac
1937
+ exit 0
1938
+ ;;
1939
+ list-panes)
1940
+ case "$*" in
1941
+ *"pane_current_command"*) printf "%%1\\tnode\\t'codex'\\n" ;;
1942
+ *"#{pane_dead} #{pane_pid}"*) echo "0 4242" ;;
1943
+ *"#{pane_dead}"*) echo "0" ;;
1944
+ *"#{pane_pid}"*) echo "4242" ;;
1945
+ *) exit 0 ;;
1946
+ esac
1947
+ exit 0
1948
+ ;;
1949
+ capture-pane)
1950
+ printf 'worker process is still starting; no agent prompt yet\\n'
1951
+ exit 0
1952
+ ;;
1953
+ split-window)
1954
+ echo "%2"
1955
+ exit 0
1956
+ ;;
1957
+ set-hook|run-shell|select-layout|set-window-option|select-pane|send-keys|kill-pane|kill-session|resize-pane)
1958
+ exit 0
1959
+ ;;
1960
+ *)
1961
+ exit 0
1962
+ ;;
1963
+ esac
1964
+ `,
1965
+ binaries: [{ name: 'codex', content: fakeCodexNodeScript('process.stdin.resume();\n') }],
1966
+ }, async ({ tmuxLogPath }) => {
1967
+ delete process.env.TMUX;
1968
+ process.env.TMUX_PANE = '%1';
1969
+ process.env.OMX_TEAM_WORKER_LAUNCH_MODE = 'interactive';
1970
+ process.env.OMX_TEAM_WORKER_CLI = 'codex';
1971
+ process.env.OMX_TEAM_READY_TIMEOUT_MS = '5000';
1972
+ process.env.OMX_TEAM_STARTUP_EVIDENCE_TIMEOUT_MS = '500';
1973
+ process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES = '1';
1974
+ receiptNotifier = setInterval(() => {
1975
+ void markPendingInboxDispatchesNotified(teamName, cwd);
1976
+ }, 20);
1977
+ await assert.rejects(withoutTeamWorkerEnv(() => startTeam(teamName, 'ready prompt timeout should not count a draft-only worker as started', 'executor', 1, [{ subject: 'w1', description: 'worker one', owner: 'worker-1' }], cwd)), /worker_notify_failed:worker-1:codex_startup_no_evidence_after_fallback/);
1978
+ const tmuxLog = await readFile(tmuxLogPath, 'utf-8');
1979
+ assert.match(tmuxLog, /send-keys -t %2 -l --/);
1980
+ runtimeTeamName = await resolveRuntimeTeamName(cwd, teamName).catch(() => null);
1981
+ });
1982
+ }
1983
+ finally {
1984
+ if (receiptNotifier)
1985
+ clearInterval(receiptNotifier);
1986
+ if (runtimeTeamName)
1987
+ await shutdownTeam(runtimeTeamName, cwd, { force: true }).catch(() => { });
1988
+ if (typeof previousTmux === 'string')
1989
+ process.env.TMUX = previousTmux;
1990
+ else
1991
+ delete process.env.TMUX;
1992
+ if (typeof previousTmuxPane === 'string')
1993
+ process.env.TMUX_PANE = previousTmuxPane;
1994
+ else
1995
+ delete process.env.TMUX_PANE;
1996
+ if (typeof previousLaunchMode === 'string')
1997
+ process.env.OMX_TEAM_WORKER_LAUNCH_MODE = previousLaunchMode;
1998
+ else
1999
+ delete process.env.OMX_TEAM_WORKER_LAUNCH_MODE;
2000
+ if (typeof previousWorkerCli === 'string')
2001
+ process.env.OMX_TEAM_WORKER_CLI = previousWorkerCli;
2002
+ else
2003
+ delete process.env.OMX_TEAM_WORKER_CLI;
2004
+ if (typeof previousReadyTimeout === 'string')
2005
+ process.env.OMX_TEAM_READY_TIMEOUT_MS = previousReadyTimeout;
2006
+ else
2007
+ delete process.env.OMX_TEAM_READY_TIMEOUT_MS;
2008
+ if (typeof previousStartupEvidenceTimeout === 'string')
2009
+ process.env.OMX_TEAM_STARTUP_EVIDENCE_TIMEOUT_MS = previousStartupEvidenceTimeout;
2010
+ else
2011
+ delete process.env.OMX_TEAM_STARTUP_EVIDENCE_TIMEOUT_MS;
2012
+ if (typeof previousStartupDispatchRetries === 'string')
2013
+ process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES = previousStartupDispatchRetries;
2014
+ else
2015
+ delete process.env.OMX_TEAM_STARTUP_DISPATCH_RETRIES;
2016
+ await rm(cwd, { recursive: true, force: true });
2017
+ }
2018
+ });
1909
2019
  it('startTeam starts worker-2 readiness before delayed worker-1 readiness settles', async () => {
1910
2020
  const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-parallel-ready-'));
1911
2021
  const previousTmux = process.env.TMUX;
@@ -5236,7 +5346,7 @@ esac
5236
5346
  await rm(cwd, { recursive: true, force: true });
5237
5347
  }
5238
5348
  });
5239
- it('resumeTeam fails closed when the persisted approved binding is nonready', async () => {
5349
+ it('resumeTeam accepts persisted approved bindings that still resolve to a baseline-ready hint', async () => {
5240
5350
  const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-approved-resume-nonready-'));
5241
5351
  try {
5242
5352
  await initTeamState('team-approved-resume', 'approved resume test', 'executor', 1, cwd);
@@ -5256,7 +5366,8 @@ esac
5256
5366
  prd_path: prdPath,
5257
5367
  task: 'Execute approved issue 2112 plan',
5258
5368
  });
5259
- await assert.rejects(() => resumeTeam('team-approved-resume', cwd), /approved_execution_binding_nonready:invalid:.*Execute approved issue 2112 plan/);
5369
+ const resumed = await resumeTeam('team-approved-resume', cwd);
5370
+ assert.equal(resumed, null);
5260
5371
  }
5261
5372
  finally {
5262
5373
  await rm(cwd, { recursive: true, force: true });
@@ -5496,6 +5607,38 @@ esac
5496
5607
  await rm(cwd, { recursive: true, force: true });
5497
5608
  }
5498
5609
  });
5610
+ it('startTeam treats a completed Ultragoal plan without activeGoalId as no active bridge context', async () => {
5611
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-ultragoal-idle-start-'));
5612
+ const binDir = join(cwd, 'bin');
5613
+ const fakeCodexPath = join(binDir, 'codex');
5614
+ await mkdir(binDir, { recursive: true });
5615
+ await mkdir(join(cwd, '.omx', 'ultragoal'), { recursive: true });
5616
+ await writeFile(join(cwd, '.omx', 'ultragoal', 'goals.json'), `${JSON.stringify({
5617
+ version: 1,
5618
+ codexGoalMode: 'aggregate',
5619
+ goals: [{
5620
+ id: 'G001-completed-story',
5621
+ title: 'Completed story',
5622
+ status: 'complete',
5623
+ }],
5624
+ })}\n`);
5625
+ await writeFakePromptWorkerBinary(fakeCodexPath, `setTimeout(() => {}, 5000);`);
5626
+ let runtime = null;
5627
+ try {
5628
+ runtime = await withPromptModeCodexEnv(binDir, {}, () => withoutTeamWorkerEnv(() => startTeam('team-ultragoal-idle-start', 'completed Ultragoal artifacts must not block unrelated team startup', 'executor', 1, [{ subject: 's', description: 'd', owner: 'worker-1' }], cwd)));
5629
+ const teamStateRoot = runtime.config.team_state_root ?? join(cwd, '.omx', 'state');
5630
+ assert.equal(existsSync(join(teamStateRoot, 'team', runtime.teamName, 'ultragoal-context.json')), false);
5631
+ const inbox = await readFile(join(teamStateRoot, 'team', runtime.teamName, 'workers', 'worker-1', 'inbox.md'), 'utf-8');
5632
+ assert.doesNotMatch(inbox, /Leader-owned Ultragoal context/);
5633
+ assert.doesNotMatch(inbox, /omx ultragoal checkpoint --goal-id G001-completed-story/);
5634
+ }
5635
+ finally {
5636
+ if (runtime) {
5637
+ await shutdownTeam(runtime.teamName, cwd, { force: true }).catch(() => { });
5638
+ }
5639
+ await rm(cwd, { recursive: true, force: true });
5640
+ }
5641
+ });
5499
5642
  it('startTeam injects approved handoff context into ready approved worker inboxes', async () => {
5500
5643
  const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-approved-handoff-'));
5501
5644
  const binDir = join(cwd, 'bin');
@@ -5505,7 +5648,6 @@ esac
5505
5648
  await mkdir(join(cwd, '.omx', 'plans'), { recursive: true });
5506
5649
  const prdPath = join(cwd, '.omx', 'plans', 'prd-issue-1314-handoff.md');
5507
5650
  const testSpecPath = join(cwd, '.omx', 'plans', 'test-spec-issue-1314-handoff.md');
5508
- const contextPackPath = join(cwd, canonicalContextPackRelativePath('issue-1314-handoff'));
5509
5651
  await writeFile(prdPath, [
5510
5652
  '# Approved plan',
5511
5653
  '',
@@ -5530,13 +5672,10 @@ esac
5530
5672
  assert.match(inbox, /## Approved Handoff Context/);
5531
5673
  assert.match(inbox, new RegExp(`Approved plan: ${prdPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`));
5532
5674
  assert.match(inbox, new RegExp(`Test specs: ${testSpecPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`));
5533
- assert.match(inbox, new RegExp(`Approved context pack: ${contextPackPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`));
5534
5675
  assert.match(inbox, /Approved repository context summary source: .*repo-context-issue-1314-handoff\.md/);
5535
5676
  assert.match(inbox, /Read the approved repository slice first\./);
5536
- assert.match(inbox, /Build refs \(read first\): src\/build-1\.ts/);
5537
- assert.match(inbox, /Verify refs: src\/verify-2\.ts/);
5538
- assert.match(inbox, /Scope refs: src\/scope-0\.ts/);
5539
- assert.doesNotMatch(inbox, /query the canonical pack|Context pack index/);
5677
+ assert.match(inbox, /Use the approved plan and matching test specs as the execution baseline/);
5678
+ assert.doesNotMatch(inbox, /Approved context pack|Build refs|Verify refs|Scope refs|query the canonical pack|Context pack index/);
5540
5679
  }
5541
5680
  finally {
5542
5681
  if (runtime) {
@@ -5545,7 +5684,7 @@ esac
5545
5684
  await rm(cwd, { recursive: true, force: true });
5546
5685
  }
5547
5686
  });
5548
- it('startTeam keeps explicit plan-only approved bindings on the generic path', async () => {
5687
+ it('startTeam carries explicit baseline-ready approved bindings without context-pack metadata', async () => {
5549
5688
  const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-approved-binding-plan-only-'));
5550
5689
  const binDir = join(cwd, 'bin');
5551
5690
  const fakeCodexPath = join(binDir, 'codex');
@@ -5564,9 +5703,12 @@ esac
5564
5703
  },
5565
5704
  })));
5566
5705
  const bindingPath = join(runtime.config.team_state_root ?? join(cwd, '.omx', 'state'), 'team', runtime.teamName, 'approved-execution.json');
5567
- assert.equal(existsSync(bindingPath), false);
5706
+ assert.equal(existsSync(bindingPath), true);
5568
5707
  const inbox = await readFile(join(cwd, '.omx', 'state', 'team', runtime.teamName, 'workers', 'worker-1', 'inbox.md'), 'utf-8');
5569
- assert.doesNotMatch(inbox, /## Approved Handoff Context/);
5708
+ assert.match(inbox, /## Approved Handoff Context/);
5709
+ assert.match(inbox, /Approved plan: .*prd-issue-1314-plan-only\.md/);
5710
+ assert.match(inbox, /Test specs: .*test-spec-issue-1314-plan-only\.md/);
5711
+ assert.doesNotMatch(inbox, /Approved context pack|Context pack index/);
5570
5712
  }
5571
5713
  finally {
5572
5714
  if (runtime) {
@@ -5575,13 +5717,13 @@ esac
5575
5717
  await rm(cwd, { recursive: true, force: true });
5576
5718
  }
5577
5719
  });
5578
- it('startTeam fails closed when an explicit approved execution binding is nonready', async () => {
5579
- const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-approved-binding-nonready-'));
5720
+ it('startTeam carries explicit baseline-ready bindings despite obsolete context-pack markers', async () => {
5721
+ const cwd = await mkdtemp(join(tmpdir(), 'omx-runtime-approved-binding-obsolete-marker-'));
5580
5722
  const binDir = join(cwd, 'bin');
5581
5723
  const fakeCodexPath = join(binDir, 'codex');
5582
5724
  await mkdir(binDir, { recursive: true });
5583
5725
  await mkdir(join(cwd, '.omx', 'plans'), { recursive: true });
5584
- const prdPath = join(cwd, '.omx', 'plans', 'prd-issue-1314-nonready.md');
5726
+ const prdPath = join(cwd, '.omx', 'plans', 'prd-issue-1314-obsolete-marker.md');
5585
5727
  await writeFile(prdPath, [
5586
5728
  '# Approved plan',
5587
5729
  '',
@@ -5589,20 +5731,29 @@ esac
5589
5731
  '',
5590
5732
  '- pack: created `.omx/context/context-20260507T120000Z-other.json`',
5591
5733
  '',
5592
- 'Launch via omx team 1:executor "Execute approved issue 1314 nonready plan"',
5734
+ 'Launch via omx team 1:executor "Execute approved issue 1314 obsolete-marker plan"',
5593
5735
  ].join('\n'));
5594
- await writeFile(join(cwd, '.omx', 'plans', 'test-spec-issue-1314-nonready.md'), '# Test spec\n');
5736
+ await writeFile(join(cwd, '.omx', 'plans', 'test-spec-issue-1314-obsolete-marker.md'), '# Test spec\n');
5595
5737
  await writeFakePromptWorkerBinary(fakeCodexPath, `setTimeout(() => {}, 5000);`);
5738
+ let runtime = null;
5596
5739
  try {
5597
- await assert.rejects(() => withPromptModeCodexEnv(binDir, {}, () => withoutTeamWorkerEnv(() => startTeam('team-approved-binding-nonready', 'approved binding nonready start test', 'executor', 1, [{ subject: 's', description: 'd', owner: 'worker-1' }], cwd, {
5740
+ runtime = await withPromptModeCodexEnv(binDir, {}, () => withoutTeamWorkerEnv(() => startTeam('team-approved-binding-obsolete-marker', 'approved binding obsolete-marker start test', 'executor', 1, [{ subject: 's', description: 'd', owner: 'worker-1' }], cwd, {
5598
5741
  approvedExecution: {
5599
5742
  prd_path: prdPath,
5600
- task: 'Execute approved issue 1314 nonready plan',
5743
+ task: 'Execute approved issue 1314 obsolete-marker plan',
5601
5744
  },
5602
- }))), /approved_execution_binding_nonready:invalid:.*Execute approved issue 1314 nonready plan/);
5603
- assert.equal(existsSync(join(cwd, '.omx', 'state', 'team', 'team-approved-binding-nonready')), false);
5745
+ })));
5746
+ assert.equal(existsSync(join(runtime.config.team_state_root ?? join(cwd, '.omx', 'state'), 'team', runtime.teamName, 'approved-execution.json')), true);
5747
+ const inbox = await readFile(join(cwd, '.omx', 'state', 'team', runtime.teamName, 'workers', 'worker-1', 'inbox.md'), 'utf-8');
5748
+ assert.match(inbox, /## Approved Handoff Context/);
5749
+ assert.match(inbox, /Approved plan: .*prd-issue-1314-obsolete-marker\.md/);
5750
+ assert.match(inbox, /Test specs: .*test-spec-issue-1314-obsolete-marker\.md/);
5751
+ assert.doesNotMatch(inbox, /Approved context pack|Context pack index/);
5604
5752
  }
5605
5753
  finally {
5754
+ if (runtime) {
5755
+ await shutdownTeam(runtime.teamName, cwd, { force: true }).catch(() => { });
5756
+ }
5606
5757
  await rm(cwd, { recursive: true, force: true });
5607
5758
  }
5608
5759
  });
@@ -5764,7 +5915,6 @@ esac
5764
5915
  await mkdir(plansDir, { recursive: true });
5765
5916
  const prdPath = join(plansDir, 'prd-issue-1320.md');
5766
5917
  const testSpecPath = join(plansDir, 'test-spec-issue-1320.md');
5767
- const contextPackPath = join(cwd, canonicalContextPackRelativePath('issue-1320'));
5768
5918
  await writeFile(prdPath, [
5769
5919
  '# Approved plan',
5770
5920
  '',
@@ -5802,12 +5952,9 @@ esac
5802
5952
  assert.match(inbox, /## Approved Handoff Context/);
5803
5953
  assert.match(inbox, new RegExp(`Approved plan: ${prdPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`));
5804
5954
  assert.match(inbox, new RegExp(`Test specs: ${testSpecPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`));
5805
- assert.match(inbox, new RegExp(`Approved context pack: ${contextPackPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`));
5806
- assert.match(inbox, /Build refs \(read first\): src\/build-1\.ts/);
5807
- assert.match(inbox, /Verify refs: src\/verify-2\.ts/);
5808
- assert.match(inbox, /Scope refs: src\/scope-0\.ts/);
5955
+ assert.match(inbox, /Use the approved plan and matching test specs as the execution baseline/);
5809
5956
  assert.match(inbox, /Follow the approved repository slice before broader repo exploration\./);
5810
- assert.doesNotMatch(inbox, /query the canonical pack|Context pack index/);
5957
+ assert.doesNotMatch(inbox, /Approved context pack|Build refs|Verify refs|Scope refs|query the canonical pack|Context pack index/);
5811
5958
  }
5812
5959
  finally {
5813
5960
  await rm(cwd, { recursive: true, force: true });