feat: enable durable local-led and nested mixed-agent teams - #4688
Conversation
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机
#4574(R2/R3/R6)与 #4684 已经承认的方向是:DSH 有受治理的 Turn host,但云端等价物与本地工具路径都不是可复用包。结果是"混合 managed team"只能停在设计上——一个云端协调者没法把有界工作委派给已注册的本地 worker,还保持同一个 LoopX 拥有的验收边界。
这个 head 做三件事:把签名请求/候选转换从 DSH adapter 里抽出来成为共享模块;新增一个独立可选包 packages/loopx-ark-turn 实现云端 host;再用一个合成研究团队示例把"云端协调者 + 本地 worker + 独立验收"这条组合跑通。相对 main:+2178/−248,其中约 270 行是搬走的,不是新逻辑。
改动思路
- 共享契约,而不是复制契约:转换(
extract_turn_authority、render_prompt、parse_model_json、build_result)搬到loopx/control_plane/turn_driver/host_candidate.py,DSH adapter 改为 re-export + 委托。两个 host 从此共用同一份"签名请求进、typed 候选出"的边界——这正是执行与验收分离的载体,重复一份就等于给 host 留了一条自证的路。 - 可选分发,而不是核心依赖:新 host 走
packages/<id>/,通过已有的--host generic-cli+ host-command argv 显式选择;核心包不 import 它(rg 确认零引用),根 wheel 的include=['loopx*']也不会把它打进去——默认安装不获得这个 SDK。 - 凭据与身份只按名字暴露:
ARK_API_KEY只从环境读、绝不作为命令行参数,且禁止把ARK_API_KEY或LOOPX_TURN_*转发进 MCP 子进程环境;endpoint 必须 https 且不得内嵌凭据;receipt 必须在任务工作区之外。 - 失败闭合:候选缺失或
result_kind不认识时,build_result返回wait(不伪造进展、不记账);上一轮 receipt 未完成时必须先对账而不是静默重试。
具体改动
关键代码讲解
loopx/control_plane/turn_driver/host_candidate.py:共享转换 +TEXT_LIMITS有界截断 +build_result的 fail-closed 分支。packages/loopx-ark-turn/src/loopx_ark_turn/{config,cli,host,mcp_tools,receipt}.py:Config.__post_init__的边界校验;cli的 argv-only 入口与--doctor/--inspect-turn-key/--cleanup-turn-key只读路径;host.run的 single-flight receipt + 重新读取 provider session 并核对 model/tools 且拒绝额外 skills/mcp_servers/multiagent;mcp_tools的显式工具选择、分页环检测、结果大小上限。examples/managed-research-team/**+packages/loopx-ark-turn/tests/test_scenario.py:合成研究团队示例,含"拒绝错误结论与未被采纳的依赖"的 oracle。.github/workflows/ark-turn.yml:contents: read、路径过滤触发、3.11/3.13 矩阵、跑包测试 + DSH/executor 相关仓库测试 + ruff。
我实跑的证据(exact head f0d99a60)
# 可选包测试(39 条:SDK 契约、真实 stdio MCP、负面事件路径、预算)
PYTHONPATH=<隔离后的 arkruntime 依赖> pytest -q packages/loopx-ark-turn/tests → 39 passed in 17.03s
# 仓库侧:DSH 与 executor 绑定(抽取的行为保持)
pytest -q tests/test_dsh_goal_mode.py tests/test_turn_managed_executor_binding.py \
tests/test_ark_managed_agent_host.py → 97 passed in 17.20s
python -m ruff check packages/loopx-ark-turn examples/managed-research-team → All checks passed
一个必须写出来的取证教训:我第一次运行时把整个临时 site-packages 放在 PYTHONPATH 前面,遮蔽了仓库环境里的 httpx/anyio,于是 test_host.py 出现 9 条失败(报 ExceptionGroup('unhandled errors in a TaskGroup') 而不是 adapter 的有界 reason)。把共享库交回原环境、只暴露 arkruntime 及其独有依赖后,39 条全绿。也就是说那 9 条是我环境的版本错位,不是这个 head 的缺陷——我按后者记录,并把它写进 note 以免下一位复现者误判。
我另外核了 3 件与"可选能力"相关的事:arkruntime 0.8.0 在 PyPI 上公开存在且与声明的 >=0.8.0,<0.9 相符;新 workflow 与仓库其它 workflow 一致使用 pip(仓库里没有 uv-based workflow);examples/managed-research-team/** 与包内代码的私有上下文扫描只命中 demo.py 写出的 .gitignore(.local/) 与测试里的 api_key="public-fixture"。
对主干的风险
无阻塞发现。两点 P3 与一条我未能验证的边界:
- P3:包测试直接
import httpx,但[test]extra 没有声明它——目前靠arkruntime传递依赖(该 SDK 同时装了httpx2),一旦依赖解析变化,CI 会在 collect 阶段红,而它看起来像产品缺陷。建议在包或根[test]里显式声明。 - P3:roadmap 里用
#4683指代"可复用的验收边界"——该 PR 目前仍开着(今天被我复审两次)。说法本身合理,但把在飞 PR 写成契约来源会让文档随 PR 老化;建议改成指契约,或在 #4683 落地时回读一次。 - 我未验证的边界(明确记录):本环境没有
ARK_API_KEY,所以 README 里那行真实 provider 运行我没有复现。我的证据覆盖契约、负面路径与本地 MCP 绑定(provider 用httpx.MockTransport固定装置),live qualification 仍属 operator/CI 之外的那一行。
关于"默认关闭":核心包对新包零引用,DSH 套件在抽取后原样通过,因此"不选择该 host 的安装与之前完全一致"这条我按可执行证据确认,而不是从"没有功能对象"推断。
我的整体评价
这是少见的"先把共用边界收进一个家,再让第二个 host 接上"的做法:抽取是行为保持的搬运(DSH 的名字用 re-export 保住、套件不改),新能力放在可选分发里,凭据/身份/工作区/预算/清理五个边界都写成了代码里的拒绝而不是文档里的口号——尤其"重新读取 provider session 并核对实际可执行面"这一步,挡住了"声明了工具、实际给了别的"这类最容易自证的情形。
文档的克制也值得记:RFC 与 roadmap 明确把 persistent supervision、完整 inbox/queue/steer、共享 authority、前端/Lark 团队交付留给 R2/R3/R6,没有把这次可复用 host 说成 G1 完成。代码侧我没有阻塞项;上面两条 P3 与那条 live-row 的边界已如实记录。
English verdict: APPROVE (author-owned PR; published as a COMMENTED review because GitHub blocks formal self-approval) - head f0d99a6 extracts the signed request/candidate conversion into loopx/control_plane/turn_driver/host_candidate.py so the DSH adapter and the new optional Ark host share one contract instead of duplicating it, ships the cloud host as a separate package selected by explicit argv through the existing generic-cli entrypoint, and adds a synthetic research-team example that composes a cloud coordinator with registered local workers under independent acceptance; I verified it by running the optional package's suites (39 passed: SDK contract, real stdio MCP, negative event paths, tool budget), the DSH/executor repo suites that cover the extraction (97 passed), and ruff (clean), and by reading the boundaries in code - the API key is environment-only and explicitly barred from the MCP tool environment along with LOOPX_TURN_* identities, receipts must live outside the task workspace under a single-flight staged receipt, at most eight explicitly selected tools are exposed, the re-read provider session must match the requested model and tools and expose no extra skills/mcp_servers/multiagent, and a missing or unsupported candidate fails closed to result_kind wait; feature-off parity holds because the core package contains no reference to the new package and the DSH suites pass unchanged, and the root wheel's package discovery still excludes it; the two P3 notes are that the package tests import httpx while the test extra does not declare it (it arrives transitively through arkruntime, which also installs httpx2) and that the roadmap cites the still-open PR #4683 as the source of the acceptance boundary; I also record an honest limit - no ARK_API_KEY in my environment, so the README's live provider row is not reproduced here, and my evidence is the contract and the negative paths against a fixture provider.
…ration Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…undation-20260918 Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
Reviewed exact head: efc36e171629648305b1ca5a0367d90c8482aa0e (base 06ff9208; PR is currently BEHIND origin/main).
动机
这个 PR 继续 #4574 R2/R3/R6,落在 #4683 已合并的 TS Goal acceptance authority 之上,交付三件事:让"验收"在任务完成时不再自我否定、让一次 Turn 可以绑定到一个当前就绪的 Todo、以及给多云成员提供一个可选 Turn provider。
在这之前有两个真实缺口。第一,no_followup 属于 work digest 的输入字段,而完成一个任务时恰好会写入它,于是"刚通过验收的任务"会在同一笔完成里把自己的绑定打回 stale,护栏随即拒绝它刚刚放行的工作。第二,外部只有 advisory 的 controller 选择,没有"精确选中某个当前就绪 Todo、不可用时失败而不是替换"的能力,协调者无法证明哪个子任务跑了哪份工作。
判定为 justified_increment:修好 digest 规则是正确的最小修复,但单独修它无法证明这套 authority 能承受一次真实的多成员协作;provider 与示例正是最便宜的真实调用方。剩余缺口(持久任务附着、Inbox/queue/steer、动态派生新工作、fleet 监督、取消重启)已在 PR 说明与 roadmap checkpoint 中明确留给 R2/R3,不属于本次验收范围。
改动思路
入口是既有的 loopx turn plan|run-once --todo-id 与沿用 generic-cli Turn 契约的 loopx-ark-turn;权威状态仍是 canonical authority head(Todo、lease、goal_acceptance sidecar),TS 拥有 revision、binding digest、准入、guard 与 CAS,Python 只读 owner 声明的 criteria 并执行校验命令,provider 只写自己的私有 receipt。
复用而非另起一套:provider 与 DSH 共用 host_candidate 的签名请求/候选转换,--todo-id 走既有 quota owner 判定资格,验收命令走既有 completion validation runner。为让"共用"成为结构事实,本次把 DSH adapter 里的转换逻辑原样抽到 loopx/control_plane/turn_driver/host_candidate.py,DSH 侧改为 re-export;这是纯搬移,loopx.dsh_goal_mode 的 18 个公开名字仍可导入,python -m loopx.dsh_goal_mode --help 正常。
具体改动
38 个文件、+3037/-254。真正的生产行为改动很小:digest 字段集合 1 行、Turn CLI 选择逻辑约 30 行;其余是新可选 provider 分发、它的测试,以及一个一次性示例(被 provider 测试直接 import 复用)。文档侧更新了 goal-acceptance 参考页与 roadmap/RFC checkpoint。
关键代码讲解
loopx/control_plane/goals/acceptance_contract.ts的NON_WORK_FIELDS/goalAcceptanceTodoDigest(第 149 行):把no_followup归入"观察类"字段。关键不变量是注释写明的两条——执行观察与展示不得撤销已确认的工作声明,同时被护栏方也不能靠改字段跑出去;text、completion_validation_required仍属于 work 字段,所以真实需求变更依旧会让绑定 stale。loopx/cli_commands/turn_decision.py的FreshTurnDecisionOwner.resolve(第 157 行):默认路径完全不变(仍走 controller advisory primary),只有显式传入requested_todo_id时才用该 Todo 构造决策,并在选中结果不等于请求时抛错而不是替换;读回时标记selected_by=turn_explicit_todo。turn.py另外拒绝--todo-id与 resume 参数同用,turn managed-step干脆不注册该选项。packages/loopx-ark-turn/src/loopx_ark_turn/host.py的_custom_tool/cleanup(第 71 行):本地工具副作用按 receipt 分阶段(EXECUTING/SENDING/SENT),事件重放不会重复执行;清理只回收本次尝试创建的资源,创建响应丢失时保留已知 label 并标unknown_creation=reconcile_required,不假装资源不存在,也不把 provider 原始错误写进 receipt。config.py额外禁止把ARK_API_KEY/LOOPX_TURN_*转发进 MCP 环境、要求 HTTPS 且不得内嵌凭据、强制 receipt 目录位于工作区之外。
对主干的风险
最强的回归场景就是上面那条:开启验收的 Goal 完成一个已绑定任务时,把绑定打成 stale,随后拒绝自己刚放行的工作。我在真实三条 provider(File、SQLite、以及在隔离的本地 PostgreSQL 16.15 上)复现了修复:node --test tests/control_plane_ts/goal_acceptance_{authority,runtime}.test.ts 得到 54 通过 / 0 跳过;把 no_followup 从字段集合里删掉的变异会让 3 个测试失败并报出 successful completion must not invalidate the just-checked work binding(含两个 provider 的运行),说明覆盖是真实的回归护栏。
负路径同样成立:--todo-id 指向不存在、已完成或他人认领的 Todo 时退出码 1 且明确"no alternate task",与 resume 组合直接报 "cannot retarget",不会静默替换。Python 侧 103 个 turn/acceptance 测试通过。
默认关闭隔离已证实而非推断:验收缺失时完成路径字节级保留原有 receipt 与无关字段;不传 --todo-id 时 selected_by 仍是 turn_controller_advisory_primary;provider 未显式选择 host command 时不会被调用,其测试也从默认 pytest 发现中排除。行为变更披露到位:参考页写明了规则变化、受影响车道与"需 owner 重新确认、不改写历史 receipt"。
权限语义与实现一致:configure/verify 拒绝非空 actor_agent_id,CLI 的 verify 不接受调用方传入的 pass/fail 而只运行 owner 声明的命令,--todo-id 只做选择、不授予任务/租约/预算/完成权限,且激活从不提升 provider。契约措辞保持 domain-neutral,guard 是机器强制而非文字建议。
两个非阻塞问题:
- P2 依赖声明:
packages/loopx-ark-turn/pyproject.toml只声明arkruntime[mcp]>=0.8.0,<0.9,而该 extra 允许mcp<3,>=1.0。在全新 Python 3.13 环境里解析到 mcp 2.2.0 时,mcp.server.fastmcp已是硬报错的 shim,包内 stdio fixture 导入失败,47 个测试里 10 个失败。文档与 CI 目前能过,是因为 LoopX 自身 pin 了mcp==1.28.1;建议在该包元数据里补mcp<2(或在 README 明确"必须与 LoopX 同一环境安装"),让"被声明的环境"与"被验证的环境"一致。我验证过补 pin 后就是 47 passed。 - P3 文档:roadmap checkpoint 里出现拼接残留 "Shared acceptance work in The example now consumes [#4683]'s merged TS acceptance authority",建议合并成一句,便于规范文档引用。
合并门槛(非代码缺陷):当前 head 落后 main(base 06ff9208,main 已是 28b1c9f6),4 个失败检查全部是级联——kernel-static-checks 在 15 分钟上限被取消,pytest/checks/merge-gate 只在"require upstream"步骤失败;main 已通过 #4686 把该上限提到 30 分钟。请先同步 main 重新跑 CI,再确认 pr-review --check-merge-readiness 4688@<new head> 为 ready。
语义与 CI 对齐
本次确实改动了共享契约(work digest 的字段集合)并新增 provider 侧 host 契约,因此按 reuse_existing 做了对齐检查:受影响契约是 loopx_goal_acceptance_v0 的 work digest、loopx_turn_host_request_v0/turn_result_v0 的共用转换,以及 roadmap R2/R3 checkpoint;三处与 docs/reference/goal-acceptance-observations.md、host_candidate.py 及默认关闭证据一致。新增的 ark-turn.yml 用路径过滤限定触发面,不改变既有必需检查的语义。
我的整体评价
approve。目标侧:修掉了一个可复现的验收自相矛盾,并交付了可独立评审、可回滚的 R2/R3 能力切片(精确选择 + 可选云 provider),剩余缺口与随后归属都写清了。架构侧:状态与效果仍归 TS/既有 quota owner,Python 仅适配,provider 是单独可选分发而非新 capability,抽取共用转换是降低未来漂移的正向重构。验证侧:三条 provider 的真实存储、真实 stdio MCP fixture、真实进程与负路径都跑过,变异测试证明护栏敏感。
残余风险:作者在真实付费 Ark 上的五次 canonical completion、超时后的清理重试与子任务 host deadline 预算修正,我没有重跑付费实跑;我验证的是 provider 的契约逻辑、receipt 幂等与负路径,真实 provider 行为仍需在合并后的实跑里保留观测。另需先同步 main 再走一次 CI 与 merge-readiness 门。
English verdict: APPROVE - 4688@efc36e171629648305b1ca5a0367d90c8482aa0e; strongest evidence: 54/54 TS acceptance tests on file+SQLite+isolated PostgreSQL, 103 Python turn/acceptance tests, one-line digest mutation fails 3 tests, provider suite 47/47 with the LoopX mcp pin; two non-blocking findings (package mcp declaration P2, roadmap wording P3); merge requires syncing origin/main and a ready check-merge-readiness on the new head.
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…undation-20260918 Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Request changes conclusion (author-owned PR; GitHub blocks formal self-review)
评审 head:a0a43a8759afc7f2b1c0f74cf8de36e16790c3b3(base main,merge-base 28b1c9f60,当前 main 已到 657902286,分支落后)。上一次我在 efc36e17 的通过随 head 前移失效,本 head 需要重新给结论:PR 在此期间新增了 durable delegation 切片,并且本 head 有 4 个必需检查失败,我在本地同一解释器下全部复现,而同样的测试在当前 main 上全部通过。
动机
上次评审后,这版把 PR 从"验收 digest 修复 + 精确 Todo 选择 + 可选云 provider"扩到"可复用的、显式授权的本地委派":本地 lead 可以把工作交给 peer,对方独立验收后返回,请求方即使对话中断也能回到原操作;示例也改成走这条共享路径,删掉了自带的调度器与尝试计数。这个方向与 #4574 R2/R3 一致,属于同一条叙事下的自然下一片,不是无关扩张。
问题在于落地状态。新增契约本身设计是好的,但本 head 同时踩坏/未经记录地改变了仓库三条既有契约,并且新增的 provider 委派套件在不同环境给出不同结果。交付判定为 justified_increment(切片有价值),但剩余缺口是必须修完的契约项,不是可以带着合并的小瑕疵。
改动思路
授权边界设计得清楚:操作方提供 loopx_local_delegation_v0 配置,绑定精确的 agent/todo/workspace/host_args/timeout 与相对 output_refs;模型只能给语义 brief 与稳定 operation id,不能给可执行文件、凭据、工作区或验收规则。规则仍在 TS(loopx/control_plane/collaboration/delegation.ts):selectDelegationBinding 要求调用方出现在 requesters 且不得自派,transitionDelegationObservation 用显式迁移表把 prepared→running→turn_returned→accepted/rejected 管起来,且 accepted 必须同时满足 canonical_done && acceptance_ready && artifacts_current。Python 侧(delegation.py)只做持久执行与 receipt,并复用 peers/inbox、acceptance inspect、turn journal 等既有 owner,没有另起 task/lease/acceptance 权威。
默认关闭是结构性的:collaboration_mcp.create_server(..., execution_config=None) 时只注册原有五个工具,委派工具组仅在显式传入配置时注册,且每次工具调用都会重新走绑定授权检查。receipt 被明确定义为观察记录而非权威,失败尝试保留供修复。
具体改动
47 个文件、+3732/-271(较上次 +3037 增长约 700 行,含 38→47 个文件)。生产代码约 700 行:新委派模块对、MCP 工具组门控、provider 的 resume/配置支持、acceptance 条件暴露;其余为测试、文档与示例重写。
关键代码讲解
loopx/control_plane/collaboration/delegation.ts的selectDelegationBinding:唯一的入口授权点。校验 schema 版本、绑定数量上限、绑定 id 唯一、调用方在requesters内、不得自派、必须给出 host_args 与有界 timeout、输出引用必须是仓内相对路径且不越界。- 同文件
transitionDelegationObservation:把观察生命周期变成显式迁移表,accepted需要canonical_done、acceptance_ready、artifacts_current三个真实事实,否则抛错,避免"模型说完成就算完成"。 loopx/control_plane/collaboration/delegation.py的_observe/_cli:Python 侧执行与持久化;_cli在绑定工作区内调用 canonical CLI 并解析 JSON。这一处正是本 head 唯一新增的 UTF-8 子进程契约违反(第 130 行subprocess.run(..., text=True)未带encoding)。
对主干的风险
四个必需检查在本 head 失败,且我逐一在本地复现(同一 .venv 解释器下 head 失败、origin/main 657902286 上 137 passed):
- UTF-8 子进程 pin(P1 阻塞):
tests/test_runtime_subprocess_utf8.py报loopx/control_plane/collaboration/delegation.py:130。这是仓库对"所有 text 模式子进程调用"的既有不变量;非 UTF-8 默认 locale 下委派 CLI 的 JSON 会按平台编码解码。最小修复:加encoding="utf-8"或复用既有的 pinned 调用助手。 - 维护型 py/ts 双实现预算(P1 阻塞):
tests/architecture/test_turn_contract_generation.py与tests/architecture/test_semantic_vocabulary_drift.py同时报44 independently maintained py/ts twins; budget is 43。新增的collaboration/delegation.py+delegation.ts同 basename 且非 generated,把dual_runtime_twins.module_budget从 43 顶到 44;registry 里写明"该数只能下降,提高必须把维护者批准记录在 RFC decision log",本 head 没有任何记录。最小修复:三者择一并记录——单源化(只保留一侧 owner)、声明为 generated(coordination_state_contract.generated.ts那种形式)、或走批准流程提预算并把 registry 与 anchor 字面量一起改;单纯改名规避计数不算修复。 - 语义事故回溯冻结基线(P1 阻塞):
tests/architecture/test_semantic_incident_retrodiction.py报测量(13, 15)与冻结基线(12, 15)不一致("a lesson that was caught must stay caught")。该测试的规则是记录与测量必须一致;本 head 改变了测量却没有对应的批准记录。最小修复:确认这次多抓到的一条是否合理,并按该测试自身的记录流程同步基线;否则调整改动使测量不变。 - 新增 provider 委派套件不确定(P1 阻塞):CI 中
adapter-contract (3.11)失败在test_delegation.py::test_model_success_without_receiver_adoption_cannot_complete[file](操作停在prepared、worker_active False、recovery_required True),而adapter-contract (3.13)同一套件通过;我在装了真实 SDK 与 LoopX 的mcp==1.28.1环境下跑该文件,则由test_detached_result_reconnects_without_duplicate_execution[file]与[sqlite]失败(team/host-started未生成)。一个必需套件在自己矩阵的两端、以及干净安装环境下给出不同结果,无法为 resume 路径背书。最小修复:让 detached worker 的启动/恢复可确定(或断言在工作区真实产生的信号),并要求两个 Python 版本都绿。 - P2 非阻塞(上次遗留,未处理):
packages/loopx-ark-turn/pyproject.toml仍只写arkruntime[mcp]>=0.8.0,<0.9,该 extra 允许mcp<3,>=1.0;mcp 2.x 下包内mcp.server.fastmcpfixture 直接导入失败。本 head 还把这个套件变成了必需检查,声明环境与验证环境的落差更值得一并修掉。
另外,PR 说明里"frozen source 的 19 项 canary 全通过"与本 head 的必需检查结果不符——原因是其 canary 选集不含上述三个架构/运行时契约测试与委派套件,这类"绿"不能替代必需检查。
已经修正的上次项:roadmap checkpoint 里那句拼接残留文本已改掉;acceptance.py 的 criteria 暴露、示例改为走共享委派路径、provider 的 resume/配置支持这些改动本身没有引入新的权限面(默认关闭为结构性,规则仍归 TS)。
我的整体评价
授权契约层 approve:绑定式授权、显式迁移表、accepted 需要三项真实事实、模型不能提供可执行文件/凭据/验收规则、默认关闭结构性成立,这些正是这个仓库想看到的形状;示例删掉自带调度器也是正确的"压缩而非追加"。
但本 head 不可合并:4 个必需检查失败,其中 3 项是仓库既有契约被本切片破坏或未经记录地改变,1 项是新增必需套件的不确定;另有一项上次提出的依赖声明问题仍未处理。修完这五项(并更新 base)后在不变的 head上重跑必需检查与 pr-review --check-merge-readiness 4688@<head>,我再复审。我未重跑付费 Ark 全流程与示例端到端,那部分仍是作者的证据。
English verdict: REQUEST_CHANGES - 4688@a0a43a8759afc7f2b1c0f74cf8de36e16790c3b3; the new delegation contract's authority model and default-off gating are sound, but four required checks fail and reproduce locally while the same tests pass on origin/main: the UTF-8 subprocess pin (loopx/control_plane/collaboration/delegation.py:130), the maintained py/ts twin budget (44 vs 43 from the new delegation pair), the frozen incident-retrodiction baseline ((13,15) vs (12,15)), and the new provider delegation suite (CI 3.11 fails while 3.13 passes; two detached-reconnect cases fail locally with the real SDK). The previously reported package mcp declaration is still unaddressed (P2). Repair these, update the base, and re-run the required checks on the unchanged head.
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
评审 head:8bad02eba6dbeb841b0690e82c61b4dc6449fdaa(较我上轮评审的 a0a43a87 前进两次:先修掉我报的四项契约违反,再有最后一个仅测试的提交修复仓库级失败文件)。
动机
这个 PR 继续 #4574 R2/R3/R6,交付三块:验收 digest 规则修复(完成不再把自己刚通过验收的绑定打成 stale)、turn plan|run-once --todo-id 的精确工作选择,以及可选的 Ark provider 与本地/云端混合委派。上轮我在 a0a43a87 给出 request changes,原因不是设计,而是该 head 踩坏了仓库既有契约并带来不确定的必需套件。
本 head 判定 goal_achieved:四项契约违反全部修复并可验证,最后一个提交还顺手修好了当前挡住所有 PR 的两个仓库级失败测试文件。剩下的唯一红灯是 Sonar 新代码质量门(非仓库契约、非本 PR 独有机制),需要 owner 决策而非代码修复。
改动思路
授权边界保持我上轮认可的形状:操作方以 loopx_local_delegation_v0 绑定精确的 agent/todo/workspace/host_args/timeout 与相对输出引用,模型只能给语义 brief 与稳定 operation id;规则仍在 TS(selectDelegationBinding 要求调用方在 requesters 内且不得自派,transitionDelegationObservation 用显式迁移表约束 accepted 必须具备 canonical_done && acceptance_ready && artifacts_current),Python 只做持久执行与 receipt。默认关闭是结构性的:create_server(..., execution_config=None) 时只暴露原有五个工具。
本 head 关键的结构收敛是删除 Python 侧的委派模块、把宿主能力并回本地 MCP 宿主,这样同 basename 的 py/ts 双实现对消失,仓库"迁移型双实现只能下降"的预算是按设计回归而不是靠改名绕过。
具体改动
相较我上轮的 head,变化集中在四处:委派实现合并回 loopx/collaboration_mcp.py(+311)并移除 loopx/control_plane/collaboration/delegation.py(-316);UTF-8 子进程调用随之下沉到带 encoding pin 的宿主代码;packages/loopx-ark-turn/pyproject.toml 显式声明 mcp==1.28.1;最后一个提交仅改两个测试文件(tests/control_plane_ts/local_authority_provider.test.ts、tests/control_plane/test_runtime_shadow_bounded_e2e.py),恢复被 main 漂移打坏的 provider 故障探针与影子诊断。
关键代码讲解
loopx/control_plane/collaboration/delegation.ts的selectDelegationBinding:唯一的授权入口;要求 schema 版本、绑定数量上限、id 唯一、调用方在requesters内、不得自派,并强制 host_args、有界 timeout 与仓内相对输出引用。- 同文件
transitionDelegationObservation:把观察生命周期变成显式迁移表,accepted需要三项真实事实,避免"模型说完成即完成"。 loopx/collaboration_mcp.py的宿主函数:委派工具组只在显式传入 operator 执行配置时注册,且每次调用重新做绑定授权;合并后这里也是唯一执行本机 CLI 的位置,子进程带 UTF-8 pin。- 最后一提交修的两个测试文件:
local_authority_provider.test.ts的 provider 故障/无回退断言在origin/main 657902286上是 27 pass / 8 fail,本 head 恢复为 35 passed;test_runtime_shadow_bounded_e2e.py10 passed。
对主干的风险
上轮四项阻塞项已逐项复验通过:UTF-8 pin(4 passed)、架构套件 133 passed(双实现回到 43 预算内、冻结回溯基线一致)、provider 委派套件在真实安装环境下 8/8 通过、mcp==1.28.1 显式声明消掉了"被声明的环境与验证的环境不一致"的落差。上轮我在自己拼装的环境里观察到的两个 detached-resume 失败,经用 pip install -e 正确安装后在 CI 与本地都通过——那部分是我上一轮复现方式的问题,在此更正记录。
当前唯一红灯是 SonarCloud 新代码质量门:新代码覆盖率 45.0%(要求 ≥80%)、新代码重复率 14.4%。同一分析的 GitHub Actions job 命名为 "non-blocking" 且为 SUCCESS,main 也没有分支保护,所以它不是平台强制项,而是仓库自己的质量信号;正因为它不自动拦截,更需要显式处置——要么给新增的 provider/示例/协作代码补测试并消掉 Sonar 报出的重复块,要么记录一次明确的 owner 豁免,不要带着未解释的红灯合并。
合并门:pr-review --check-merge-readiness 4688@8bad02eb… 目前 ready=false(status_checks_failed、status_checks_incomplete、repository_merge_state_blocked),需要在同一 head 上满足该门后再合并;若按规则需要维护者本人批准,本评审即该精确 head 的结论记录。
我的整体评价
approve。目标侧:这一版既修好了我上轮指出的全部契约违反,又把仓库级失败测试一并修复,交付面(验收 digest 修复 + 精确工作选择 + 可选 provider + 有界授权委派)内聚且可回滚。架构侧:授权规则仍在 TS,Python 只适配;把委派宿主并回既有 MCP 宿主消除了一次不必要的跨语言重复实现,是"压缩而非追加"的正向收敛。验证侧:三套我关心的契约(UTF-8、双实现预算、冻结基线)与 provider 套件都在本 head 通过,两个修复目标测试也在本地复现通过。
残余风险与其他未验证项:我没有重跑付费 Ark 全流程与示例端到端,那部分仍是作者证据;Sonar 质量门需要 owner 决策;合并前需让 merge-readiness 在同一 head 转 ready。
English verdict: APPROVE - 4688@8bad02eba6dbeb841b0690e82c61b4dc6449fdaa; all four findings from my previous review are repaired and re-verified (UTF-8 pin 4 passed, architecture suites 133 passed with the py/ts twin pair removed instead of renamed, frozen retrodiction baseline agreeing, provider suite 8/8 with mcp==1.28.1 now declared), and the final test-only commit also repairs the repo-wide failing local_authority_provider and shadow e2e files (35 + 10 passing locally vs 27/8 on origin/main). One non-code gate remains: the SonarCloud new-code quality gate (coverage 45% vs 80%, duplication 14.4%), which is labelled non-blocking in Actions and needs an explicit owner decision, and merge readiness must return ready on this unchanged head before merge.
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
Exact head: 4688@002cc14ea3b1afdbadaf588e8431e36e02bce43e; base: 657902286b01e7c81a5f4b13ff1b16a3a5dbb9c4.
动机
本 PR 继续 #4574 的混合团队方向,复用已合并 #4683 的 TS 验收权威,让本地主 Agent 与普通成员都能委派已授权工作、接收独立验收后的产物,并在连接中断后接回原执行。它交付的是可选的本地可信宿主底座,不是完整持久数字团队或 G1/G3 完成。
本次同时重新检查整个 base-to-head 改动、前序 REQUEST_CHANGES 以及后续 Sonar 阻塞。已定位的原有 CI 阻塞、终态发布竞态,以及主干升级后的两处测试夹具漂移已修复;没有提高双实现预算、改写事故基线或放宽验收断言。Sonar 暴露的覆盖采集、重复转换和多余 worker 参数已通过测试归属调整与代码收敛修复,质量门阈值和排除项均未改动。
改动思路
共享控制面继续拥有授权、Todo、claim、quota、Turn 与 acceptance。Python 负责本机进程、stdio、文件与 SDK IO;Ark 是单独安装、显式选择的 provider。主协调员和普通成员使用相同执行授权,不增加管家专属调度器。
复用性检查覆盖既有 peer 请求/采用/返回、Turn journal、DSH 转换器、native Ark goal_once 与 TS 验收。DSH、Ark 和 Trae 的签名解析/候选转换归到 host_candidate;Trae 保留自己的输出 schema、prompt 和公开返回格式;MCP 服务、detached worker 和验证入口合并到已有 collaboration_mcp,删除新增的 Python 控制面 delegation 模块及其独立 CLI。原生 Ark Goal 驱动与 LoopX Turn 驱动保持不同执行档位,不同时控制同一绑定。
具体改动
- 显式绑定限定 requester、member、Todo、workspace、host 参数和输出;模型不能通过工具参数注入命令、凭据或验证规则。不传执行配置时,真实 stdio 仍是原来的五个工具。
- operation ID、原 Turn key 和内核锁承担本地执行恢复;accepted 必须先有 receiver adoption,再经当前 pinned 验证、普通
todo complete的独立验证/TS 提交、canonical 与产物哈希读回。 turn --todo-id只选择当前可执行的精确任务,不退回其他任务,也不能修改 resume 的目标;未传参数仍使用原 controller。- Ark profile 复用 generic-cli,记录确认的 Session/input、工具 ACK 和原期限;不明 ACK/副作用保留为 reconciliation。MCP 依赖固定到已验证的 1.28.1,普通安装不引入可选 SDK。
- 示例用本地 lead、两个 DSH、两个 Ark,包含云端成员再委派本地成员以及精确上游产物采用;领域验证留在示例,通用代码不包含投研特例。RFC/使用文档明确开关、恢复和未交付范围。
关键代码讲解
- Delegations:把现有 peer→Turn→验收→返回串起来。启动时采用有界锁等待,短暂状态读取不会丢掉已准入任务;拒绝原因和 rejected 状态一次写入,读取者不会看到不完整终态。worker 在启动边界复用 peer operation ID 的格式校验,并使用单个
--operation-id=…参数。worker 不再把 receipt 中的 workspace 复制到 argv,而是直接使用既有绑定;普通 MCP 服务仍强制要求 workspace,journal 中原验证命令的 argv 保持不变,保证旧 Turn 续跑兼容。 - selectDelegationBinding / transitionDelegationObservation:TS 校验执行授权与显式迁移表;观察状态不取代 canonical 完成事实。
- validate_goal_task_acceptance:从 TS 读取精确任务的当前标准,前后核对绑定;只验证,不提交完成。真正完成仍经普通 Todo 入口。
no_followup是完成后的衔接元数据,本次将它排除出工作语义摘要,避免普通完成操作使既有验收绑定失效;任务实质和验证器变更仍会使绑定失效,这一默认路径修复已单独回归。 - Ark run:provider 只执行本次受控工作;重连复用已确认的 Session/input,未知副作用不猜测重发。
- build_result:DSH、Ark 与 Trae 共用候选转换;模型输出不是 acceptance 或 quota authority。
正向路径是显式授权→成员采用请求→执行→双重验证→canonical 完成→精确产物返回→父 Agent 综合。反向路径验证了无授权、无采用、输入/产物或验证器变动、重复恢复、停止 Goal 等情况;工具成功、模型自称完成或 JSON 中的 accepted 均不能替代完成条件。
对主干的风险
主要风险是执行/恢复竞态和共享 DSH 转换回归。本次不是只重跑测试:先让旧实现分别在“读锁挡住 worker”和“终态发布时立即读”两个确定性反例上失败(各 File/SQLite 两例),再验证修复。旧主干的 builtin DSH 与 generic-cli 实际 CLI smoke 同输入对照,完整返回 JSON、状态写入、quota 与 replay 观测一致;默认关闭的真实 stdio 也通过原测试。
语义与 CI 验证
- 最终 head 的 GitHub Python 3.11、3.13 可选 adapter-contract 各 278 项通过,包含真实 stdio、CLI、两项竞态回归和负向验收;两版 lint 通过。
- TS 授权与验收 57 项通过,覆盖 File、SQLite 和隔离真实 PostgreSQL;无跳过。TS 类型检查、lint 和公开边界扫描通过。最终 kernel-static 的 TS 总套件为 1959 通过、18 个 PostgreSQL 条件用例跳过;本次修改涉及的验收 PostgreSQL 用例已在上述隔离真实服务器的 57 项中实际执行,另有 CI 真实 PostgreSQL store/service 检查通过,未把静态套件中的跳过计作执行。
- 原失败分片对应的架构检查 133 项通过。双实现预算保持 43;修正 owning boundary 后,事故回溯自然回到原 12/15 基线。
- 新主干移动 Todo 更新诊断后,Stage 2C 的一个 mutant 仍定位旧模块。本次只修改定位路径;原 oracle 通过、截断诊断后的 mutant 被同一断言杀死,其余 53 个定位均有效。
- Windows/新版 Node 的存储故障矩阵把 v2-only 的 revision/grant 字段放进 v0/v1 请求,实际先触发了协议拒绝。夹具现在使用合法旧版输入;35 项 provider 检查以及两项版本降级拒绝检查通过,原来的 source/diagnostic/无回退/字节不变断言未修改。
- 前一 head 的 Stage 2C lease-cursor 用例出现一次 qualification 失败;相关 runtime 和该用例原先均不在本 PR 的改动中。本地首次重放、另八个独立 workspace 重放、整个10项模块均通过,没有确认其根因。本次只补全失败诊断,保留全部断言;最终相同 head 的 Stage 2C e2e 2 共 112 项通过,日志确认执行了该 lease-cursor 用例。这条历史非确定性仍作为剩余风险记录,不声称它被诊断格式修改修好。
- 通用的委派、canonical team 与合成场景测试已从可选 Ark 包移到主测试集;不依赖 Ark SDK,真实进程路径进入主 CI 覆盖率采集。30 项本地通过,包含 5 种非法 worker 参数;247 项宿主兼容和 19 项 peer 检查通过。Trae 12 项现有 smoke、真实 CLI(fixture backend)前后完整结果对照通过,DSH builtin/generic 两条前后对照也在本次冻结源码重新通过。
- 最终冻结源码 canary:19 项通过、零失败/警告/人工 hold;额外的架构、委派和真实 PostgreSQL 验证补足其自动选集没有覆盖的部分。最终 CI:27 项检查通过,4 项按工作流条件跳过(presentation、deploy、release upload、PyPI publish),无失败或等待项(本轮 GitHub Actions)。Sonar:Quality Gate 通过,新增覆盖率 83.7%、重复率 0%,新增问题与 accepted issues 均为 0,安全/可靠性/可维护性均为 A。
- 既有真实混合团队与 SIGKILL 恢复证据来自
a0a43a875:四个 accepted operation、五个完成 Todo、Goal active;原 Session/input 接回并清理自有资源。最终 head 没有再次调用付费云模型。已核对 provider 协议未改变,改变的宿主入口/锁/发布顺序通过本次实际 subprocess/MCP 验证;不把历史云实验写成最终 head 重跑。
没有新的 Dashboard/Lark 设置或默认执行器变更:入口是显式 CLI/stdio 配置,既有配置 owner 不变。持久会话、动态创建/工作派生、完整 inbox/queue/steer、认证远端共享权威和前端/Lark 团队管理仍是 RFC 的后续边界。临时诊断产物与私有实验文件未进入 PR;公开 diff 不含内部文档、凭据或本机路径。
我的整体评价
APPROVE。这个切片有实际可复用的调用方和完整的有限任务验收链路,体量主要来自可选 provider、回归验证与一个复杂组合示例;继续复用现有 owner 比保留示例调度器或引入第二套任务状态更合适。本次相关重构已应用:统一宿主入口、将 Trae 也接入共享转换、复用 operation ID 校验和验收 effect 映射;没有为未来动态 fleet 加入空框架。
后续修复保证失败反馈原子可见,并让迁移后的变异测试和版本化请求夹具继续检验原有边界。当前没有未解决阻塞。按 maintainer 对本 PR 的明确授权,在相同 head 的 merge-readiness 返回 ready 后自合并;本 review 本身不代替该检查。
English verdict: APPROVE - 4688@002cc14ea3b1afdbadaf588e8431e36e02bce43e; reusable opt-in mixed/nested delegation preserves TS authority and default host behavior. Worker startup and terminal-result publication races are fixed with failing-before/passing-after regressions; the moved diagnostic mutant is retargeted without weakening its oracle. Python matrices, real PostgreSQL/TS validation, architecture gates, canary and final CI pass. Historical paid-cloud evidence is explicitly revision-scoped; persistent fleet lifecycle remains outside this slice.
Outcome
A local Agent can organize a mixed DSH/Ark team through reusable, explicitly authorized delegation, receive independently accepted artifacts, and reconnect to the original execution after interruption. An ordinary Ark member can delegate to DSH using the same interface. This continues #4574 R2/R3/R6 on #4683's merged TS acceptance authority.
Changes
todo completeindependently execute pinned checks; accepted returns re-read canonical completion, bindings and artifacts. The Goal is not automatically completed. Completion-onlyno_followupmetadata no longer invalidates the work digest; real semantic/validator changes still invalidate acceptance.Usage and boundaries: local delegation, Ark adapter.
Validation
Prior live qualification at the pre-CI-repair implementation (
a0a43a875): real local DSH lead + two DSH members + two Ark members, including nested Ark→DSH delegation: four accepted member operations and five completed canonical Todos. Independent aggregate verification passes; Goal remains active. Normalized FCF is 40→25, delta −15; periods are incomparable and the current evidence has one source family.Prior live qualification on the same implementation: real process-group kill after Ark's input ACK: cloud waits for a local tool; the original operation resumes the same Session/input to canonical completion. One provider receipt, no new input, all owned resources and disposable Environment confirmed absent.
File/SQLite CLI integration rejects missing receiver adoption, conflicting operation ids, ungranted actors, modified artifacts and stale criteria. Actual stdio requester disconnection, concurrent resume, stopped-Goal readback and preserved member conclusions are covered.
57 TS checks pass on File, SQLite and an isolated real PostgreSQL server, without skips. At final head
002cc14ea, GitHub Python 3.11 and 3.13 adapter-contract matrices each pass 278 tests and lint. All four core Python shards, Stage 2C, Windows, dashboard/build and real PostgreSQL jobs pass. The final source also passes 15 worker/MCP rechecks, including the ordinary-server input guard, and preserves all 78 characterized candidate-value results. Earlier local qualification includes 247 host, 30 core collaboration and 19 peer tests. Type checking, lint and public/private scans pass.Two deterministic race counterexamples fail on the earlier implementation (File/SQLite each): a status reader can discard the starting worker, and a terminal reader can observe rejection before its reason. Both pass after repair. Architecture checks pass 133 tests with the twin budget and incident baseline unchanged. The Stage 2C diagnostic mutant follows its moved admission owner; the unchanged oracle passes and truncation still fails by assertion.
SDK-independent delegation, canonical-team and scenario tests now run in the main collection and coverage report, while the optional SDK matrix continues to include them. No coverage thresholds or source exclusions were changed. Trae’s former duplicate conversion is removed; its 12 adapter checks and actual CLI with a fixture backend preserve complete before/after observations. Builtin DSH and generic-cli were also freshly compared with the baseline and match.
Versioned provider fault fixtures now use valid v0/v1 inputs, so they reach the intended storage boundary instead of failing on v2-only fields. All 35 provider cases and two downgrade-rejection checks pass; failure and no-effect assertions are unchanged.
A prior-head Stage 2C lease qualification failed once. Its root cause remains unconfirmed after nine independent local passes, the full ten-case module and
8bad02ebaCI passing. The final-head Stage 2C e2e 2 job passes all 112 cases, including the named lease-cursor test. Full failure diagnostics were added without changing its runtime or assertions; this remains a recorded intermittent risk.Earlier real integration failures exposed reply ownership, inline argv length and leaf credential-forwarding problems; those were fixed and the full mixed run repeated successfully. Failed attempts are retained privately, with owned cloud resources cleaned. No provider model calls run in CI. Paid cloud runs were not repeated for the CI repair; provider protocol code is unchanged and the changed host wiring is requalified through real subprocess/MCP tests.
Final frozen-source
loopx canary premerge --from-git-diff --timeout-seconds 120: all 19 selected checks and the direct checks passed, with zero failures, skips or tracked side effects. Coverage includes the changed collaboration/Turn/acceptance/provider boundaries, risk-selected control-plane regressions and public-boundary scanning; this is not a full repository suite.Final CI and Sonar: 27 checks passed; 4 conditionally skipped (presentation/deploy/release publication); no failure or pending check. Actions and Sonar Quality Gate pass; new-code coverage is 83.7%, duplication 0.0%, and no new or accepted issues. TS static suite: 1959 pass / 18 conditional PostgreSQL skips; the affected acceptance tests did run against the isolated real PostgreSQL server above.
Scope and remaining work
This is fixed, explicitly authorized local work, not generic Agent creation, dynamic Goal decomposition, complete inbox/queue/steer, an authenticated remote authority service or a persistent Codex-task attachment. The live model profile was
doubao-seed-2-1-pro-260628and DSHdeepseek-v4-flash@high; this does not qualify other model versions.No Dashboard/Lark settings or default executor changes: activation is an explicit stdio/CLI binding, and existing product configuration owners are unchanged. The related refactor removes example-owned lifecycle logic and consolidates the shared acceptance-effect mapping; it adds no second task or acceptance authority.
The maintainer explicitly authorized self-merge after CI repair; exact-head review and merge-readiness checks remain required.