Skip to content

fix(itmux): stage only codex auth surface via allowlist (fixes codex startup)#241

Closed
NeuralEmpowerment wants to merge 3 commits into
chore/itmux-cifrom
fix/codex-readiness
Closed

fix(itmux): stage only codex auth surface via allowlist (fixes codex startup)#241
NeuralEmpowerment wants to merge 3 commits into
chore/itmux-cifrom
fix/codex-readiness

Conversation

@NeuralEmpowerment

Copy link
Copy Markdown
Contributor

Plan 2 / okrs-51p.7. Root-causes and fixes why codex never reached ready under itmux (claude did in ~634ms).

Root cause (not a readiness-heuristic bug): codex 0.139.0's ~/.codex is ~785MB (.tmp/ 250M, sessions/ 81M, logs_2.sqlite 100M, computer-use/ 53M...). The DooD credential transfer copies directories file-by-file over docker exec base64, so codex staging was a thousands-of-exec multi-minute crawl that never completed - itmux was stuck in stage_into_container before ever launching tmux. The readiness predicate + launch sequence were correct.

Fix: replace the fragile denylist ({tmp,log,logs,plugins}) with an allowlist - stage only auth.json/config.toml/config.json/AGENTS.md, skip all dirs. An allowlist can't regress when codex adds new state dirs. Applied to both Rust (auth.rs) and the Python driver (_CodexAdapter) for parity. Supersedes the denylist plugins addition from #235.

Live-validated: itmux start --agents codex -> rc=0, StartReport ready:true, duration_ms:75. New fixture-based readiness test + rewritten auth-allowlist test. cargo test/clippy/fmt green.

Note: the allowlist intentionally drops sessions/ (past transcripts, not auth) - a fresh workspace starts clean. Stacked on the Plan 1a stack (#236).

codex-cli 0.139.0's ~/.codex mixes a tiny auth/config surface (auth.json,
config.toml) with hundreds of megabytes of operational state under dirs the
old {tmp,log,logs,plugins} denylist never matched (.tmp/, sessions/,
logs_2.sqlite*, computer-use/, cache/, ...). Staging copied all of it
file-by-file over docker exec base64, turning start_workspace into a
multi-minute crawl that never completed - so itmux start --agents codex never
reached ready (claude, whose surface is one small file, works fine). The
--startup-timeout bound covers only the post-launch readiness wait, not
credential staging, so the symptom was a hang, not a timeout.

Switch codex staging from a fragile denylist to an allowlist of the actual
auth surface (auth.json, config.toml, config.json, AGENTS.md). An allowlist
cannot regress when codex adds new state directories. Empirically validated
that auth.json + config.toml is sufficient for codex to reach its ready
composer. Kept byte-for-byte parity between the Rust and Python drivers.
Capture the real codex-cli 0.139.0 first-ready pane after
itmux start --agents codex (trust banner accepted, hooks modal dismissed,
composer visible) as a fixture and assert codex_is_ready / codex_is_started
match it. Guards the start-path predicate now that the staging fix lets
start_workspace reach this pane.
@NeuralEmpowerment

Copy link
Copy Markdown
Contributor Author

Codex cross-model review: VERDICT CHANGES REQUESTED (1 must-fix)

  1. Symlinked auth files dropped (auth.rs:131): Rust DirEntry::file_type() does NOT follow symlinks, but Python Path.is_file() (interactive_tmux.py:1183) does. Dotfile managers (stow/chezmoi) symlink auth.json/config.toml - Rust would silently drop them and codex couldn't auth. Follow symlinks in Rust (or make Python match + test). Fix in progress.
    Nit: add explicit config.json/AGENTS.md assertions to the allowlist test.

Rust DirEntry::file_type() stats the link itself, not its target, so an
allowlisted auth.json/config.toml that is a symlink (common with dotfile
managers like stow/chezmoi) was silently dropped - the exact files the
allowlist exists to preserve. Use fs::metadata (follows symlinks) for the
file-type decision so a symlink-to-regular-file is staged by-value. Restores
parity with the Python driver, whose Path.is_file() already follows symlinks.

Also assert the full declared allowlist (config.json, AGENTS.md) in the
allowlist test, and add a unix symlink test proving symlinked auth files are
staged with their target's bytes.
@NeuralEmpowerment

Copy link
Copy Markdown
Contributor Author

Codex must-fix resolved (c1d5775). copy_named_files now uses fs::metadata(&path).is_file() (follows symlinks) instead of entry.file_type() (stats the link itself), so symlinked auth.json/config.toml (stow/chezmoi) are staged by-value - restores parity with Python's Path.is_file(). Added codex_stages_symlinked_auth_files test (asserts symlinked auth is staged with the target's bytes) + explicit config.json/AGENTS.md allowlist assertions. cargo test/clippy/fmt green; live smoke re-confirmed codex ready 63.6ms. Merge-ready.

@NeuralEmpowerment

Copy link
Copy Markdown
Contributor Author

Consolidated into a single itmux feature PR: #243. This work is included there (same commits); closing to reduce PR sprawl. Review/merge #243 instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant