feat(dsh): promote deepseek-harness adapter to first-class goal-mode subpackage - #3364
Conversation
…subpackage Move the DeepSeek Harness Turn host adapter from the loose scripts/dsh_turn_host_adapter.py launcher into loopx/dsh_goal_mode/, matching the pi/opencode/kunluncode goal-mode packaging pattern: - loopx/dsh_goal_mode/turn_host_adapter.py is the canonical implementation; run it with python -m loopx.dsh_goal_mode. - scripts/dsh_turn_host_adapter.py stays as a backward-compatible launcher re-exporting the subpackage, so existing commands, examples, and docs keep working. - Point the agent-type catalog, host-loop activation packet, onboarding instruction, and bootstrap command-pack description at the new module while keeping the legacy path documented. - Add README and package-data entry, cover the subpackage and the compat launcher with tests (hermetic fake dsh runner), and update README/docs. Signed-off-by: now-ing <24534365+now-ing@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
详细中文评审(exact head dc784371a0531dbd4ff1b822c9aa7659deb9cf52)
动机
这个 PR 解决的是一个真实的交付断层:DeepSeek Harness 已经进入 agent type、start-goal、onboarding 与 host-loop activation 契约,但执行适配器仍只存在于 scripts/dsh_turn_host_adapter.py。脚本路径适合源码 checkout,却不是稳定的 wheel 内模块入口。把 canonical 实现放进 loopx.dsh_goal_mode,同时保留旧脚本兼容入口,使“已注册的一等 host surface”和“可安装、可导入、可用 python -m 启动的实现”终于一致。
改动思路
实现采用了低风险的搬迁方案,而不是重写 Turn 语义:
loopx/dsh_goal_mode/turn_host_adapter.py承接原脚本实现,只把仓库根目录的sys.path注入改成包内相对导入;__main__.py提供python -m loopx.dsh_goal_mode,__init__.py暴露现有 adapter API 与 schema 常量。scripts/dsh_turn_host_adapter.py缩成兼容 launcher,并把公开符号重新导向同一实现,因此旧的文件路径调用与 import 仍可工作。host_loop_activation.py、agent_onboarding.py、bootstrap_command_pack.py把新模块标成 canonical 入口,同时保留 legacy launcher 提示;pyproject.toml把子包 README 纳入 wheel。- 两份主 README、DeepSeek Harness connector、runtime connector catalog 与 Turn v0 协议统一到新入口;测试补齐 package/import/CLI/compat 这条新边界。
具体改动
- Authority 与 prompt 路径保持不变:
extract_turn_authority仍核对matches、source_hash、envelope_hash与重新计算的签名文档,只把签名覆盖的primary_action、required_reads、write_scope和workspace_guard交给 dsh;render_prompt要求唯一、公开安全的 typed JSON 结果。 - Result 路径保持 fail-closed:
parse_model_json支持纯 JSON、代码围栏和外层文字;build_result只接受受控的 result kind,缺失或未知 kind 都降为wait,material kind 才补齐delivery_batch_scale=single_surface、delivery_outcome=outcome_progress与必要的 bounded 字段。 - Host 执行路径保持不变:
main校验 stdin schema 和签名,隔离本地 session root,构造稳定 session id,经run_dsh_turn或显式 runner 执行,再只向 stdout 写一个loopx_turn_result_v0。请求/签名错误返回 2,SDK/runner 错误返回 1;无法解析最终 JSON 时返回非 material 的wait。 - 正向链路是:
start-goal/activation packet →quota should-run→turn run-once→python -m loopx.dsh_goal_mode→ dsh SDK → typed result → LoopX 独立验证和结算。负向链路在 adapter 边界就关闭:被篡改的 envelope 不会进入 host,异常或无效结果也不会伪造进展或获得 quota spend。 - 17 个变更文件的职责是完整且聚合的:4 个新子包文件承载实现与说明,legacy script 保持兼容,3 个 host 注册/引导文件切换 canonical 入口,
pyproject.toml固化 wheel 数据,5 个公开文档入口同步用户路径,3 个测试/runner 文件验证相同对象身份、模块与旧脚本的 subprocess 契约及 activation packet。
对主干的风险
主要风险是 packaging/compat,而不是业务语义。独立验证结果:
- focused pytest:
184 passed;另有 2 个与本 PR 变更面无关的环境型用例无法在本次 exact-head archive 评审中复现(一个要求测试环境允许临时 git commit,另一个要求 checkout revision metadata),未将它们归因于本 PR。 examples/dsh-turn-host-adapter-smoke.py:11 checks passed。examples/loopx-turn-dsh-e2e-smoke.py:通过,含一次写回/一次 quota spend,以及 replay 不重复 host/write/spend 的断言。- changed Python surfaces 的 Ruff 检查通过;公开边界扫描 clean。
- wheel 构建通过,并确认包含
loopx/dsh_goal_mode/{README.md,__init__.py,__main__.py,turn_host_adapter.py}。 - GitHub 在评审时没有返回该 exact head 的 status-check rollup;本结论基于上述独立验证,不代表未上报的外部检查。
残余风险主要是未在本次评审中启动真实 DeepSeek Harness/真实凭据路径;但 PR 没有改变原有 SDK 调用或 provider/model 配置,只改变代码归属和入口,并由 fake-runner 与端到端 Turn smoke 覆盖新 packaging seam,所以这个风险可接受。
我的整体评价
APPROVE。 这是一个主题单一、可回滚且有兼容层的一等化搬迁:新模块入口解决 wheel/源码路径不一致,旧调用不被切断,typed state、domain-neutral Turn 契约、默认行为、guidance/obligation 边界都没有静默变化。测试覆盖了本 PR 真正新增的 package/launcher/activation seam,文档也与运行入口同步;没有发现需要阻塞合并的正确性、权限或公开边界问题。
English verdict: APPROVE at exact head dc784371a0531dbd4ff1b822c9aa7659deb9cf52. The PR moves the unchanged fail-closed DeepSeek Harness Turn adapter into an installable loopx.dsh_goal_mode package, preserves the legacy launcher, updates activation/docs, and validates both entry paths. Focused validation produced 184 passing tests, both hermetic dsh smokes passed, Ruff and the public-boundary scan were clean, and the built wheel contains the new package; no blocking finding remains.
Motivation
deepseek-harness已经是一等 host surface(start-goal --host-surface deepseek-harness、agent-onboard、host-loop activation packet 都支持),但它的 Turn host adapter 一直是一个 loose 脚本scripts/dsh_turn_host_adapter.py。其他 host(pi / opencode / opencode2 / kunluncode / claude)都有自己的loopx/<host>_goal_mode/子包。本 PR 把 dsh 升级为同样的一等loopx/dsh_goal_mode/子包,行为与边界完全不变,只改变打包与注册方式。What changed
loopx/dsh_goal_mode/子包(对齐 pi/opencode/kunluncode goal_mode 模式):turn_host_adapter.py:canonical 实现(从 loose 脚本整体迁移,仅把sys.pathhack 换成包内相对导入);__init__.py:re-export 全部公开 API 与 schema 常量;__main__.py:支持python -m loopx.dsh_goal_mode直接运行 adapter;README.md:surface、运行方式、requirements、boundary 说明。scripts/dsh_turn_host_adapter.py保留为 compat launcher,re-export 新子包的全部符号;按文件路径 import(如examples/dsh-turn-host-adapter-smoke.py)与命令行调用都不变。loopx/host_loop_activation.py:agent-type catalogentry与_deepseek_harness_activation的entry_command_hint/ activation steps;loopx/agent_onboarding.py:deepseek-harness start instruction;loopx/bootstrap_command_pack.py:host-surface selection 描述;pyproject.toml:package-data 增加"loopx.dsh_goal_mode" = ["README.md"]。tests/test_dsh_goal_mode.py(11 个用例):子包 API、compat shim 与子包符号同一性、签名 authority 提取 fail-closed、prompt 契约、JSON 解析容错、结果整形(fail-closed / 不支持 kind / material 字段补齐)、python -m loopx.dsh_goal_mode与 legacy launcher 的 hermetic subprocess 全链路(fake dsh runner);tests/test_host_loop_activation.py的 dsh 用例,断言 activation packet 同时引用loopx.dsh_goal_mode与 legacy script。docs/integrations/deepseek-harness-connector.md、docs/reference/protocols/loopx-turn-v0.md、docs/integrations/runtime-connector-catalog.md指向新模块。Test evidence
venv(
python -m venv+pip install -e ".[test]")内运行:start-goal 冒烟(临时项目,注册 agent 后取 activation packet):
Notes
examples/(它们通过 compat launcher 继续工作,已被 smoke 验证)。