Conversation
上游实现深度依赖 POSIX 能力(O_NOFOLLOW/dir_fd 目录锚定、fcntl.flock、 POSIX shell 引号、killpg/SIGKILL 进程组),在 Windows 上从启动引导到 运行循环多处直接失败,导致 `lh-harness run` 无法使用。本补丁为这些 路径增加平台感知回退,不改变 POSIX 平台的既有行为: - supervisor/control_bus.py:新增能力检测 _SECURE_DIRFD;无锚定目录 fd 的平台回退为「路径创建 + 符号链接扫描」;fcntl 缺失时以 msvcrt 字节锁实现等价跨进程互斥(_process_lock);_open_nofollow、 _open_private_regular_at、_atomic_bytes_write、_append_jsonl 与 ControlBus._locked 均增加路径分支 - utils/platform_shell.py(新增):shell_quote/cd_command/env_prefix 按 platform 生成 cmd.exe 兼容的双引号转义、`cd /d` 与 `set "K=V"` 前缀,替代硬编码的 POSIX 单引号语法 - adapters/cli_agent.py、opencode.py、codex.py、claude_code.py、 deepseek_harness.py:命令模板统一改用平台感知引号与环境变量前缀 - environment/local.py:新增原生 ensure_dir/chmod 方法; environment/remote_files.py 优先使用原生实现,父目录推导同时兼容 POSIX 与 Windows 路径分隔符 - utils/process_group.py:无 killpg 的平台回退为按 PID 发信号;信号 枚举按存在性收集(Windows 无 SIGHUP) - manager.py:事件追加在无 O_NOFOLLOW 平台走「校验后普通追加」分支 - dashboard/state.py:审批日志追加改用 _process_lock 并兼容路径模式 - supervisor/service.py:监督锁增加 Windows 回退;4 处 killpg 调用 加平台护栏 验证环境:Windows 11 (10.0.22631) + Python 3.12 - `python -m compileall src/lh_harness` 通过 - 兼容探针 5 项全过:控制总线原子写+读回、JSONL 追加互斥、 ControlBus 命令协议(append/commands/conflict)、事件追加、全部 改动模块可导入 - 端到端:opencode 后端完整跑通 Manager→Executor→Auditor 多轮闭环, 任务正常完成并产出审计报告 🤖 Generated with [opencode](https://github.com/anomalyco/opencode)
这是对 AMAP-ML#66 第一个 commit 的延续,把"Windows 能启动"推进到"Windows 全量 测试套件绿",并补上此前完全缺失的测试 CI。 ## 源码修复 - utils/win_job.py(新增):Windows Job Object 封装。按 pid 裸杀在该平台 有致命缺陷——子进程退出后 pid 可被复用,TerminateProcess 会误杀无关进 程(本机实测曾打断整个测试进程树)。Job 句柄由内核保证只杀树内进程。 - utils/process_group.py:SIGKILL 平台化(Windows 无此常量,此前超时清 理路径直接 AttributeError 崩溃);sig=0 存在性探测在 Windows 上会变成 击杀,改用只读句柄查询(win_job.pid_alive)。 - supervisor/service.py:_signal_worker 单一信号分发接缝;_open_worker_log、 _saved_task_from_rounds、_supervisor_locked 增加 Windows 回退(路径校验 + 符号链接扫描,语义与 control_bus 一致);stop/abort 路径全部走接缝。 - supervisor/control_bus.py:_open_nofollow 回退补最终符号链接检查; _atomic_bytes_write/_append_jsonl 回退先校验祖先链再建目录(此前会穿 透符号链接目录边界创建文件);ControlBus 锁与追加增加 nlink 别名拒绝。 - dashboard/state.py:自有 _open_nofollow 补 O_BINARY(此前文本模式把 \r\n 读成 \n,PNG 截图字节被静默改写)与符号链接/nlink 防护; list_round_artifacts 增加 Windows 路径枚举分支(Windows 无法 os.open 目录,os.scandir(fd) 亦为 POSIX 专属)。 - environment/local.py:chmod 平台化(POSIX 真执行,Windows no-op), 修正上一 commit 中无差别 no-op 的疏漏;子进程接入 Job Object。 ## 测试 - conftest.py 新增 write_executable_stub:适配器测试的 `#!/bin/sh` 桩在 Windows 翻译为等价 .cmd(echo/printf/exit/heredoc/if-then 小语法)。 - 18 个测试文件的平台化:killpg monkeypatch 改打 _signal_worker 接缝、 引号断言感知平台、NTFS 不支持的文件名用例显式 skip。 - 结果:Windows 11 + Python 3.12 全量 402 passed / 4 skipped / 0 failed (此前:启动即崩 → 28 failed + 21 errors + 进程树被误杀)。 ## CI - 新增 .github/workflows/ci.yml:ubuntu + windows + macos 三平台矩阵运行 pytest。此前仓库仅有 release workflow,测试从未在任何 CI 上运行过—— 本系列修的全部问题都源于此盲区。 ## 已知遗留 - test_model_catalog::test_deepseek_catalog_exposes_default_model_and_cli_ availability 在未修改的上游克隆上同样失败(期望标签与 src 的乱码不一致, 疑为上游提交时的编码问题),与本 PR 无关,建议单独处理。 🤖 Generated with [opencode](https://github.com/anomalyco/opencode)
Author
|
第二阶段已推送(c26437b),本 PR 现在包含两个 commit:
第二阶段要点:
完整说明见 PR 正文与 commit message。问题全景见 #70。 🤖 Generated with opencode |
- cli.py:Windows 上强制 stdout/stderr 为 UTF-8(reconfigure)并将控制台 输出码页切至 65001。此前 harness 的 UTF-8 产物(中文报告/事件)经 cp936 管道或控制台输出时乱码,含 ✓ 等字符时甚至直接 UnicodeEncodeError 崩溃。 - utils/platform_caps.py(新增):SECURE_DIRFD 能量检测与 validate_no_symlink_chain 的唯一权威定义,从 control_bus 上移;control_bus 保留私有别名,全部既有引用(manager/cli/tests)零改动。 - utils/platform_shell.py:IS_WINDOWS 改为引用 platform_caps,消除重复定义。 测试:全量 402 passed / 4 skipped 保持不变。 🤖 Generated with [opencode](https://github.com/anomalyco/opencode)
此前 computer-use 插件只为 claude_code 与 codex 生成配置,opencode 被硬编码
排除(cli.resolve_mcp_config 直接返回 None),opencode 用户因此没有任何
GUI 能力。本 commit 补齐整条链路:
- plugins/state.py:write_mcp_config 新增 opencode 原生格式(`{"mcp":
{name: {type: local, command, args, enabled}}}`,落盘 *.opencode.json)。
- adapters/opencode.py:构造器接受 mcp_config;与 base_url 的 provider 覆盖
合并写入同一个 OPENCODE_CONFIG 运行时文件(_write_endpoint_config 升级为
_write_runtime_config),用户自有 providers/models/MCP 不受影响。
- cli.py:resolve_mcp_config 解除 opencode 排除;_build_agent 透传
mcp_config;_MCP_AGENT_CHOICES 加入 opencode(doctor / plugin list /
plugin install --agent 全部自动获得 opencode 视图)。
- plugins/community_computer_use.py:open-computer-use 与 clawdcursor 声明
支持 opencode。
测试:新增 tests/test_opencode_mcp.py(配置格式、插件状态解析、适配器
合并/拒绝路径共 8 项);全量 410 passed / 4 skipped / 0 failed。
🤖 Generated with [opencode](https://github.com/anomalyco/opencode)
此前 auditor 的三态判定(status/integrity_status/contract_audit_status)完 全依赖对自然语言控制头的正则推断,多语言措辞漂移或模型改写句子即会误读。 - prompt_texts.py:四份 auditor 指令(en/zh × GUI/CLI)在保留三行控制头 的前提下,要求报告末尾追加一个 ```json 机器可读判定块(status/ integrity_status/contract_audit_status + integrity_findings/ deleted_artifacts),并要求与控制头一致、2000 字符以内。 - auditor_agent.py:_extract_structured_audit 提取并逐字段校验枚举(取最 后一个合法块);parse_audit_report 与 audit_report_from_episode_result 改为 JSON 字段优先、控制头正则逐字段兜底——旧格式报告(无 JSON)解析 路径与此前完全一致;violation 时的删除账本优先采用结构化 deleted_artifacts 并归一化为既有 ledger 形状。 - 验收约束守卫、violation→incomplete 降级等既有安全逻辑全部保持权威。 测试:新增 tests/test_audit_structured.py 7 项(JSON 权威、契约不一致降 级、部分字段回退、坏 JSON 兜底、无 JSON 兼容、结构化删除账本、多块取 末);全量 417 passed / 4 skipped / 0 failed。 🤖 Generated with [opencode](https://github.com/anomalyco/opencode)
- agent_logs.token_usage():跨后端解析轨迹中的 token 用量(Codex/Claude 的 顶层 usage 对象与 OpenCode 的 part.tokens/cost 两种形态,未知形态安全跳 过);CommandAgentAdapter 每个 episode 将汇总写入 metadata["token_usage"]。 - manager:ManagedRound 携带本轮 token_usage(executor+auditor 合并), report.json 新增顶层 token_usage 汇总块(无任何记录时输出空对象,保持 schema 向后兼容)。 - 新增 docs/windows-troubleshooting.md:PATH 生效、控制台编码、Store 版 codex.exe 空别名、GUI 桌面会话要求、代理与免费模型限流等实测坑位; 中英文 README 各加一节链接。 测试:新增 tests/test_token_usage.py 5 项(OpenCode/Codex 形态求和、噪声 忽略、角色合并、跨轮聚合与空块语义);全量 422 passed / 4 skipped / 0 failed。 🤖 Generated with [opencode](https://github.com/anomalyco/opencode)
prax211
added a commit
to cogniziocompany/LongHorizon-Harness
that referenced
this pull request
Sep 5, 2026
…); deploy-job defects AMAP-ML#66-AMAP-ML#68 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
prax211
added a commit
to cogniziocompany/LongHorizon-Harness
that referenced
this pull request
Sep 6, 2026
…states — owner cec370bb, run 1eeb4daf; AMAP-ML#66 must not merge Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
prax211
added a commit
to cogniziocompany/LongHorizon-Harness
that referenced
this pull request
Sep 6, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
修复 Windows 兼容:控制总线、shell 引号与进程组处理
背景
在 Windows 11(10.0.22631)上从源码安装 v0.1.7 后,
lh-harness run无法启动:引导阶段即报unsafe run directory layout: secure control-bus directory creation is unavailable。逐层排查后发现,核心循环、事件账本、适配器命令模板、监督锁等多处深度依赖 POSIX 专有能力,
Windows 上均直接失败。本 PR 为这些路径增加平台感知回退,不改变 POSIX 平台的任何既有行为。
问题与修复对照
control_bus要求O_NOFOLLOW+dir_fd锚定目录遍历,Windows 无此能力_SECURE_DIRFD能力检测;回退为「路径创建 + 逐级符号链接扫描」fcntl.flockWindows 不存在_process_lock:msvcrt 字节锁实现等价跨进程互斥O_NOFOLLOW_append_event增加「校验后普通追加」分支mkdir -p/chmod是 POSIX 命令,create_subprocess_shell在 Windows 走 cmd.exeLocalEnvironment原生ensure_dir/chmod;remote_files优先调用并兼容\路径分隔VAR=x cmd前缀,cmd.exe 不解析utils/platform_shell.py(shell_quote/cd_command/env_prefix),4 个适配器 +cli_agent全部接入os.killpg/SIGHUP缺失process_group按 PID 回退 + 信号按存在性收集;service.py4 处killpg加护栏改动范围
13 个文件,+379/−79(
git diff --stat见 commit):验证
python -m compileall src/lh_harness通过(append/commands/conflict 检测)、事件追加、全部改动模块可导入
Manager→Executor→Auditor 多轮闭环(Round 1 规划/执行/审计三角色全绿
complete/clean/aligned,Round 2 判定交付并生成中文最终报告),Executor 实际驱动本机 Edge 浏览器完成了 arXiv/GitHub 调研任务并落盘截图证据
已知遗留(后续补丁)
Executor episode 超时清理路径仍引用
signal.SIGKILL(Windows 无此常量),超时场景会以
worker_exception终止而非优雅回收——不影响正常运行,将在后续 PR 修复。🤖 Generated with opencode
更新(第二阶段 commit c26437b)
首个 commit 解决"能启动";本阶段把 Windows 推进到全量测试套件通过:
SIGKILL缺失(6 处超时/停止路径崩溃)、os.kill(pid, 0)探测在Windows 语义为 TerminateProcess 导致的 pid 复用误杀(新增 Job Object
内核级进程树管理
win_job.py)、O_BINARY缺失导致 PNG 字节被改写、回退分支的符号链接/硬链接防护缺口、
os.scandir(fd)/目录打开不可用等共 7 类问题
_signal_worker接缝、#!/bin/sh桩翻译为 .cmd、引号断言感知平台)
.github/workflows/ci.yml:ubuntu + windows + macos 三平台 pytest矩阵(此前仓库无任何测试 CI)
Fixes #70