Overnight worktree uv warmup and log-path guardrails
Use when launching unattended Codex runs in fresh worktrees, especially for Python repos that rely on uv and for nested repos like digitalmodel.
Trigger
- Overnight/background Codex batch in isolated worktrees
- Fresh worktree or fresh workspace
- Commands will run
uv run ... - You want reliable log capture with
tee
Problem patterns observed
uvfirst-run warmup can look like a hang
- In a fresh worktree, the first meaningful
uv run ...can spend 55-60 minutes compiling/importing before useful output appears. - This can make a healthy worker look blocked or dead.
- We observed this in the
digitalmodelovernight lane: the real work eventually completed and all tests passed, but the first-use warmup consumed most of the apparent runtime.
- Buffered Codex logs can stay empty for a long time
Codex -p ... | tee <log>may produce no visible log growth for a long period even when the process is healthy.- Empty logs are not sufficient evidence of failure.
teecan fail if you create the wrong log directory
mkdir -p logs && ... | tee /abs/path/to/logs/run.logis unsafe if the actualteetarget differs from the cwd-relativelogs/you created.- In the
digitalmodelovernight lane, the command completed the task but still exited non-zero becauseteecould not open the intended log path.
Recommended launch pattern
1. Pre-warm uv in the exact worktree
Before the real workload, run a disposable warmup in the same worktree:
uv run python -c "pass"
Use this especially when:
- the worktree is fresh
- the repo is large
- the lane is test-heavy
- the first useful command is a long pytest run
2. Create the exact log directory for the exact log file
Do not rely on mkdir -p logs unless tee writes to ./logs/... in that same cwd.
Safe pattern:
LOG=/abs/path/to/logs/run.log
mkdir -p "$(dirname "$LOG")"
PROMPT=$(< /abs/path/to/prompt.md)
Codex -p \
--permission-mode acceptEdits \
--no-session-persistence \
--output-format text \
--max-turns 80 \
"$PROMPT" </dev/null | tee "$LOG"
3. Monitor health by process state and artifacts, not log growth alone
Preferred signals:
- background PID still alive
- expected output/result artifacts appear
- worktree
git status --shortchanges as files are written
Only treat the run as failed after checking those, not merely because the log is empty.
Recovery pattern when a run exits non-zero after doing useful work
If the background command ends with a logging-related error:
- inspect the worktree, not just the exit code
- check
git status --short - inspect target files and test outputs
- verify whether the actual task completed despite the shell/logging failure
- if yes, continue from the resulting repo state and post the correct GitHub update
Practical rule
For overnight worktree batches:
- pre-warm
uv - use absolute log paths
- create the exact parent directory of the log file
- do not interpret empty Codex logs as immediate failure
These guardrails reduce false hang diagnoses and prevent task-success/logging-failure confusion in unattended runs.