Skip to content

fix(host): contain Windows Host descendants in an owned Job - #7602

Open
xyx2002OvO wants to merge 2 commits into
mainfrom
codex/pr5677-windows-host
Open

xyx2002OvO wants to merge 2 commits into
mainfrom
codex/pr5677-windows-host

Conversation

@xyx2002OvO

Copy link
Copy Markdown
Contributor

Goal And Delivered Outcome

Windows cannot prove managed Host descendant cleanup through POSIX process groups. Assign the bridge to an owned Job before sending its first request, retain the Job identity for drain observation, and terminate descendants when the owner closes or dies. This is the independent Host prerequisite split from #5677; it does not grant task, Stop, lease or sandbox authority.

Author Declaration

  • Written by: model_agent, OpenAI Codex.
  • Implemented against: the scope/prerequisite review on #5677 and the existing Host supervision contract.
Criterion Disposition Owner / decisive evidence
Descendants stop after leader exit, timeout, consumer failure and owner loss implemented windows_host_job.py, host_process_transport.py; real native Windows processes
Preserve existing attribution and unknown drain states implemented Existing transport owner and test_windows_host_process.py

Scope And Continuation

Complete within this prerequisite scope. #5677 retains its dependency until this proposal lands; the freshness behavior is reviewed there. The small local refactor extracts the bridge record input so containment wraps the existing transport without duplicating its supervision loop. Maintainer review/merge remains required.

Validation

  • Tested revision: implementation e44f90e0c; submitted head b1d3dd8a188f3e3bba98f64387164a7fa5f92c09 adds current main without changing these three files.
  • Run state: finished. Input classes: synthetic.
Check kind Result Evidence / limitation
real_entrypoint passed python -m pytest tests/control_plane/test_windows_host_process.py tests/control_plane/test_validation_process_cleanup.py -q: 14 passed, 5 POSIX-only skips; actual descendants and owner termination exercised.
regression_parity failed The broader tests/test_codex_operation_host.py Windows fake app-server entrypoint reports WinError 193; a focused reproduction also fails on target main fb331f45c. No native app-server qualification is claimed.
static passed Ruff on changed Python, semantic-vocabulary advisory, explicit-path public-boundary scan (3 files), diff whitespace and DCO sign-off.
integration not_run Linux/CI and exact-head maintainer review are pending. No merge or complete sandbox claim.

Signed-off-by: Tartar <xiaoyx67@mail2.sysu.edu.cn>
Signed-off-by: Tartar <xiaoyx67@mail2.sysu.edu.cn>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · reasoning_effort=max

当前完整精确 head b1d3dd8a188f3e3bba98f64387164a7fa5f92c09 有一项 P2 异常清理问题,结论为 REQUEST_CHANGES。Windows Job前置有独立价值;本次不要求它完成整个#5677。

动机 / Motivation

通过 managed Host 执行任务、需要中止和回收子进程的 Windows 操作者。

原Windows路径仅尽力结束进程树,不能凭leader退出证明后代已停;本PR在桥收到Host请求前分配Job,并以kernel计数读回整组退出。

Job IO接入原监督路径且POSIX配对验证通过;新增清理报错会跳过launch guard与输出流释放,当前仍需修复,Windows原生资格也未独立建立。

本次只审Host进程生命周期前置,不审完#5677,不授予Stop、lease、任务完成、sandbox或外部效果权限。 Job容器只负责一执行及其后代,不能把进程退出提升为任务验收或once-only settlement。

改动思路 / Approach

Windows Job属于平台kernel IO,复用现有TS监督决策和Python transport较合适;不应新建控制面或把此次修复扩成整个freshness方案。

本PR保留Windows Job平台前置和原transport集成;最小修复是在Job finish报错时也执行launch_scope及output的finally清理,并补对应失败用例。

已先读#5677的范围/前置评审:平台保护应按自己的生命周期独立验收,不能为缩小父PR而删除保护。本PR的拆分方向符合这个边界;当前问题在自己的错误清理链。

路径 进入与退出
POSIX 保持原专用进程组、TS监督和既有drain事实。
Windows 创建不继承Job handle → assign原bridge handle → 原guard/record → 首个Host请求 → 原监督循环 → Job终止/计数读回。
本次缺陷 guard进入后setup出错 → bridge取消 → finish()又抛错 → 原guard/output清理被跳过。

这张表是源码路径说明,不是Windows执行证据。Microsoft Job Objects文档支持默认子进程关联及最后handle关闭时终止的机制说明;它不能证明本实现的kernel调用已经在本轮通过。

具体改动 / Changes

完整diff三文件 +390/-109:production两文件+266/-109、tests一文件+124/0,包含原循环移动;没有新增Task/Stop/quota状态机。

  • run_host_process 在发请求前assign桥,并把Job名写入原process record;guard、事件、timeout和原caller继续复用。提取的_bridge_record_scope七条作用域语句与不可变基线AST相同,不是另建决策owner。
  • WindowsHostJob 只封装Create/Assign/Query/Terminate/Close,原process HANDLE避免把assign指向复用PID。finish()仍可能因kernel读取、终止失败或观察超时抛错。
  • _host_process_drain 重新查询带有效名的Job;旧记录没有Job仍unsupported,非法或不可读事实保持unattributable。没有把leader退出视为全组退出。

规范依据:spec_ref docs/reference/protocols/loopx-turn-v0.md,spec_revision 898363635d4737f84b6a673a9a11265a121b6f57。Managed Host Process Lifetime 区分leader、管道与后代,要求错误/owner loss走监督清理;process supervision 明确其不授予任务、lease或sandbox权限。旧文档只承诺Windows尽力tree cleanup,不把POSIX等价或整个父RFC强加给本PR;新增Job路径需要自己的实际资格。

对主干的风险 / Risks

P2:Job finish失败会跳过其余已注册资源清理

位置:host_process_transport.py:405–411。

windows_job.finish()被放在launch_scope.close()和guarded.close_output()之前。同一finally里的前一条语句抛错,后两条就不会运行。外层Job的__exit__会再尝试自身finish/handle关闭,但不会替代launch guard和stdout的清理。对未实现GC补救的context manager,退出回调直接遗漏;其他调用者也不应依赖回收时机释放guard/pipe。

独立探针使用真实public run_host_process及真实Node桥;临时record目标是一个目录,使guard进入后的record setup失败,只对Windows Job IO注入QueryInformationJobObject异常,未替换桥、结果、持久后端或原清理断言。输入、fixture和断言在三次比较中相同:

revision/变体 guard退出 bridge stdout关闭 结果
基线 898363635d4737f84b6a673a9a11265a121b6f57 true true 保留原record写入错误。
提交head b1d3dd8a188f3e3bba98f64387164a7fa5f92c09 false false Job错误短路原finally;独立oracle失败。
head仅内存补finally true true 仍抛Job错误,不伪造成功/drained。

这是确定的Python异常路径反例,不是Windows内核实测。最小修复是把Job finish包在try内,以finally保证已注册的launch guard与output清理执行;如果清理仍失败,保留错误和unknown,而非返回成功。回归应在真实桥上组合record/setup失败与Job query/terminate/timeout异常,断言context退出、输出关闭;原Windows后代/owner丢失矩阵继续保留。

其他验证 结果与限制
Host、leased Host、validation、Codex operation五模块 PASS:78 passed、9 skipped;其中6项新Windows、1项既有Windows stdin与2项显式live-host未运行。
同命令不可变base/head核心模块 PASS:两端各28 passed、1既有Windows条件skip;不以总数代替上面的资源释放反例。
TS原监督器 PASS:21 cases,0 skip。
本地静态/仓库门 PASS:改动Python Ruff、配置内17文件mypy、完整control-plane TypeScript typecheck、diff/DCO/双语门通过;明确路径public scan零错误/警告。 标准source premerge四direct、Python compile、两catalog及八risk-profile通过;diff-scoped advisory先于full semantic smoke,二者通过。
Windows kernel实机 UNVERIFIED:Windows内核六项新用例和一项既有Windows stdin用例在Mac上跳过;两项显式live-host资格未运行。作者报告的e44f90e0c Windows结果保留为声明,不冒充本轮独立原生执行。

作者已经披露的Windows fake app-server WinError 193保留为作者报告,本轮未独立重现该平台签名,不将其归为本PR新缺陷,也不据此抹去当前cleanup反例。未查询或等待CI,未运行付费模型。

精确scope的CQR:cqr_e31a3ad2266870625228,FAIL / invalid_receipt;cleanup反例失败和所需Windows实机验证跳过均保留,不能作为通过资格。

我的整体评价 / Verdict

Windows Job属于平台kernel IO,复用现有TS监督决策和Python transport较合适;不应新建控制面或把此次修复扩成整个freshness方案。

本PR保留Windows Job平台前置和原transport集成;最小修复是在Job finish报错时也执行launch_scope及output的finally清理,并补对应失败用例。

改动规模与独立平台问题相称,Python模块是kernel IO placement;原typed监督决策和业务authority保持。当前long_horizon/user_experience仍 not_yet_proven:错误时遗漏guard/pipe清理会削弱后续工作恢复,不能因正常进程用例通过就批准。

已检查三个改动文件及CLI/Host消费者;没有渲染页面或交互布局改动,视觉评审不适用。 Windows内核六项新用例和一项既有Windows stdin用例在Mac上跳过;两项显式live-host资格未运行。作者报告的e44f90e0c Windows结果保留为声明,不冒充本轮独立原生执行。

修复和独立Windows资格完成后,需要重审新精确head。没有要求新控制面、新配置、额外用户确认或无关跟进任务;本轮没有修改提交源码、合并或安装。

English verdict: REQUEST_CHANGES — b1d3dd8a188f3e3bba98f64387164a7fa5f92c09 can skip launch-guard and output cleanup when WindowsHostJob.finish() raises. A real Python/Node fault probe fails at head and passes at base and with the minimal in-memory finally repair. Native Windows qualification remains unverified.

proc.kill()
proc.wait()
finally:
if windows_job is not None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Job finish 抛错时仍需执行其余 finally 清理。launch_guard 已进入、随后 record/setup 失败时,finish 内的 Query/Terminate 或观察超时可以再次抛错,使下方 launch_scope.close() 和 output cleanup 都不执行。真实 public run_host_process/Node 桥故障探针(仅 Windows Job IO 为替身)在基线释放 guard/关闭 stdout,在此 head 两者均未清理,内存中加一层 finally 后恢复。请用 finally 保证这两类资源释放,继续保留 Job 清理错误/unknown,并补 setup+finish 双失败回归;这项探针不宣称 Windows 内核资格。

This branch has not been deployed

No deployments
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.

2 participants