fix: unified_exec yield_time_ms behaves as floor instead of ceiling

Resolved 💬 2 comments Opened Apr 9, 2026 by zazula Closed Apr 9, 2026

Summary

unified_exec yield timeouts act as a minimum wait (floor) rather than a maximum wait (ceiling). Every shell tool call blocks for the full yield_time_ms even after the child process has exited and output is available.

Steps to reproduce

  1. Run any fast command (e.g. echo hello) via the shell tool with yield_time_ms=5000
  2. Observe the yield always takes ~5 seconds despite echo completing in <10ms

Root cause

In codex-rs/core/src/unified_exec/process_manager.rs, collect_output_until_deadline only breaks when Instant::now() >= deadline:

exit_signal_received |= cancellation_token.is_cancelled();
if Instant::now() >= deadline {
    break;
}

Chunks are collected but the loop continues waiting for the full timeout.

Proposed fix

Break as soon as output is available:

if !collected.is_empty() {
    break;
}

This treats yield_time_ms as a ceiling — return immediately when data is ready, wait up to the timeout if the process hasn't produced anything yet.

Diff

2 files, +28 / -3: zazula/codex-1#fix/yield-time-ceiling

Impact

  • All fast shell commands return instantly instead of blocking for the full yield timeout
  • Commands that genuinely need the timeout to produce output are unaffected
  • Cancellation handling is preserved

Test

Added unified_exec_yield_time_is_ceiling_not_floor — runs echo done with a 5s yield and asserts wall time < 1.5s. Fails under the current behavior (~5s).

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗