fix: add macOS support for foreground execution - #2
Conversation
- Implement _read_process_identity_darwin() using ps lstart - Implement _darwin_process_group_alive() using ps pgid - Add launch_macos_terminal() fallback to open -a Terminal - Fix foreground_child_and_group_status() to support macOS Resolves: macOS foreground execution fails with 'identity is unverifiable' Tested: wrapper generates artifacts, Terminal launcher works via fallback Fixes: issue with macOS v1.1 acceptance tests blocked by missing macOS support
|
Withdrawn: incomplete testing, will resubmit after full acceptance pass |
Xuan0629
left a comment
There was a problem hiding this comment.
Request changes — macOS foreground execution gate not yet met
感谢推进 macOS 支持。方向可以继续:Darwin process identity、process-group liveness 和 Terminal.app launcher 都是需要补齐的边界;但这个 PR 目前不能合并,也不能作为 v1.1.0 的 macOS release gate 证据。
0. 当前阻塞:CI 必须先恢复绿色
PR run 29722204297 已失败。基于 PR head bc1af54 在干净 worktree 复现:
56 passed, 2 failed
失败的是现有两个 macOS launcher 用例:
test_launches_terminal_app_with_wrapper_command_and_returns_handoff_pidtest_macos_launcher_encodes_special_character_paths_as_one_command
根因是 launcher 已从 osascript-only 改为 osascript -> open -a Terminal 两段式 fallback,但测试仍断言 osascript argv;stub 中 returncode 未显式设为 0,因此走入 fallback。请不要仅为了让旧断言通过而删除 fallback;请将测试改为准确验证新契约。
1. 必须补齐的单元测试(本 PR 内)
请添加/更新测试,至少覆盖下列可验证行为:
-
Darwin process identity
ps -o lstart= -p PID有效输出时产生稳定的darwin:<identity>;- 空输出、超时、
ps/OSError、无效 PID 时返回None;这些情况不能被上层当作已退出。
-
Darwin child/group liveness 与 fail-closed resume
- child identity 相同:
live; - child 已消失且 group 确认为空:
dead; - child 已消失但 group 仍有成员:
live; - 任何
ps错误、空/畸形数据、identity 不可验证:unknown; unknown时必须阻止 duplicate dispatch 和 resume,不能将其降级推断成dead。
- child identity 相同:
-
Terminal.app launcher
- osascript 成功(明确
returncode == 0)时只走 primary path; - osascript 非零退出时走
open -a Terminalfallback; - osascript 的
Popen()本身抛出OSError时也走 fallback;当前该异常发生在 try 之外,会直接中断; - osascript 超时后的 fail-closed/fallback 行为;
- fallback 成功和失败;
- 含空格、引号、
;、$的 workdir/invocation path 仍生成安全、单一的 wrapper command; - 维持不注入 Terminal 后续输入、不自动审批、不回退 headless 的边界。
- osascript 成功(明确
2. 必须提供真实 macOS Terminal.app 验证证据
Linux 单测不能替代此 gate。请依据 docs/foreground-execution-macos-validation.md,在真实 macOS 的可见原生 Terminal.app 上分别对 Claude 和 Codex 运行并在 PR 中贴出可复现命令、环境版本、artifact 路径/关键 JSON 与结果摘要。六项均须通过:
- 原生人工审批可见且由人操作;
- zero exit 后正确 completion/reconcile;
- non-zero exit 不会被写成 success;
- 关闭/中断 Terminal.app 后 fail closed;
- wrapper 或 child/process group 可能仍活时,duplicate dispatch 被阻止;
- 仅在 child/process group 已被证明死亡后允许 resume。
若 ps lstart 的实际 macOS 行为无法提供足够的 process-identity 证据,必须保持 unknown/拒绝恢复,或换成可证明满足该安全条件的实现;不能以“看起来存在/不存在”替代死亡证明。
3. PR hygiene / scope
- PR 描述提到
MACOS_FIX.md,但该文件不在分支中。请提交该验证材料,或删掉该失效引用并将完整步骤和证据写进 PR body。 - 保持变更限于 macOS foreground 支持及其测试/验证文档;不要顺带修改版本、tag、PyPI/GitHub Release 或加入其他产品功能。
- 完成后请重新跑并贴出:
PYTHONPATH=$PWD:$PWD/src .venv/bin/python -m pytest -q
PYTHONPATH=$PWD:$PWD/src .venv/bin/python -m pytest -q -W error::DeprecationWarning并等待 GitHub Actions 对新 head 变为 green 后再请求复审。
Acceptance criteria
重新审查的前提:CI 全绿、以上单测存在且通过、真实 macOS Claude/Codex 六项验证证据完整,并且仍严格维持 native manual approval、无输入注入、无自动审批、无重试/无 headless fallback、serial-only、未知状态 fail-closed。
See MACOS_FIX.md for details. Resolves macOS foreground execution blocked by missing process identity and launcher support.