macOS: External process identity observation for codex exec fork has returned EPERM; root cause remains unconfirmed
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
版本與環境
- Standalone Codex CLI:
0.154.0。2026-09-11 查核的最新 stable 為此版。 - Desktop:
26.903.71938,build8576。 - macOS
26.6.2(25G83),Darwin25.6.0,arm64。 - 對照的 Desktop bundled CLI:
0.153.4。各入口結果分開記錄。 - 執行入口是 Desktop 的
exec_command;本輪外層workspace-write/use_default,內層 CLI 為read-only。舊失敗 receipt 沒有綁定完整外層 context,因此不能視為完全相同的實驗條件。 - 公開 login status 為 ChatGPT;訂閱方案未提供。此回報未取得失敗 session 的模型資訊。
- 未執行
codex doctor --json:本次診斷限定不讀取或匯出私人 runtime state/config/logs;不能把缺少 doctor 資料解讀為該命令不可用。
已觀測的問題
外部 Python supervisor 透過公開的 codex exec fork --json 路徑啟動一個有界、唯讀、synthetic workspace 操作時,程序 identity observer 曾收到權限錯誤。以下是第三方 adapter receipt 的去識別投影,不是 Codex 原生錯誤格式:
{
"operation": "fork",
"failure_class": "termination_error",
"native_stage": "child-identity",
"errno": 1,
"session_call_performed": true,
"session_id": null,
"exit_status": null,
"terminal_event": null
}
Adapter 在 macOS 使用 /usr/lib/libproc.dylib,針對已知 parent 列舉子程序,再由 _process_identity 呼叫 proc_pidinfo(pid, 3 /* PROC_PIDTBSDINFO */, ...) 取得 parent PID/start token。上述 stage 是 helper 呼叫點標籤;helper 內的載入/查詢都可能拋出錯誤,舊 receipt 不足以唯一確定是哪個 syscall 被拒,也不足以確認 Codex、macOS sandbox 或 supervisor 的責任歸屬。
Session subprocess 已建立,但沒有可驗證的 UUID/exit/terminal;因此我們保留未知狀態,不自動重送。影響是 supervisor 無法安全確認 fork 的生命週期完成。
保存的執行方式與重現限制
這是間歇性觀察,目前沒有可靠、每次必現的最小重現。
- 在獨立 synthetic Git fixture 使用第三方 adapter;adapter 建立 private clone、移除 origin、固定 source HEAD。
- 序列執行有界 start、resume、fork;每個 child 使用
--sandbox read-only --ask-for-approval never,exec子命令指定--ignore-user-config --json,prompt 由 stdin 傳入,fork 使用先前成功取得的明確 session UUID。 - Observer 只查自己啟動的 root 與已知 descendants,使用 PID/start token,沒有全機程序掃描。失敗時不忽略 EPERM、不省略 identity、不放寬 sandbox。
- 在已保存的失敗序列,start/resume 成功,fork observer 回報上述錯誤。相同 standalone
0.154.0在較早一組測試也曾 start/resume/fork 全通過;adapter revision 與外層 context 沒有完全控制,不能據此宣稱此 CLI 版本必定失敗或已定位回歸。 - 2026-09-11 的新 fixture 只到 start 就得到
nonzero_exit/exit 1,沒有相同 observer 錯誤;因此停止,未跑 resume/fork。Adapter 不保留 raw stderr,這個 exit 1 原因未知,不是原 fork EPERM 的重現。 - 同一外層 workspace-write 下,只啟動 synthetic Python parent 與兩秒 sleep child 的最小 observer 檢查成功,顯示不是所有 libproc query 都被拒。這不證明複雜 CLI 子孫在整個生命週期都可觀測。
使用者回憶更新前沒有此症狀,但缺少固定 OS/context/adapter/binary 的更新前後配對量測;我們將「更新回歸」保留為假說。
期望與希望協助釐清的事項
- 在受支援的 macOS sandbox 組合中,外部 supervisor 是否應能觀測它啟動的 Codex 子孫程序之 parent/start identity?若某類 Codex helper 刻意不允許,請說明適用條件與受支援的生命週期完成判斷方式。
- 哪個公開、有界且可去識別的診斷能區分 libproc query、sandbox policy 與 helper 生命週期,並保留 native failure stage/errno?
- 是否有已知的 0.154.0 或上述 Desktop/macOS 組合問題及已確認修復版本?目前沒有證據支持修改 supervisor 的 fail-closed 政策。
公開證據與查重
已查閱 #23505 的 ps/pgrep/Mach service 問題、#35482 的 child lifecycle 問題及 #42398 的 installation_id writable-open EPERM。它們是相關線索,但失敗位置不同,尚未建立同根因;若本案應歸入既有 tracker,請協助指向。
本次沒有 runtime 修正、升降級、配置變更、sandbox bypass 或未知 session 重試。此回報未附私人 UUID、主機名、機器路徑、原始 transcript 或 credentials。
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked investigation and the referenced cli_session_handoff.py supervisor source, then review the saved fork sequence and the libproc proc_pidinfo observation stage. A useful outcome would distinguish the libproc query, sandbox policy, and helper lifecycle, while preserving the native failure stage and errno; the report does not yet identify a confirmed code change or reliable reproduction.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, python, rust
- Domain
- cli, operating-systems
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100