feat(benchmark): separate seeded task entry from LoopX planning - #4676
huangruiteng merged 7 commits into
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): reviewed exact head fc77656d4e4d25779f8f31f51e7c0776b45cfa78, no blocking finding. Required CI was still running when I reviewed (named below), and the real Harbor conformance is still in progress per the PR body. Merge remains the maintainer's decision.
动机
共享 benchmark runner 在每个原生阶段开始前就写一条通用的 [P0] Execute benchmark phase N Todo,等于替模型先把计划做掉了:想比较"LoopX 自己规划"和"直接执行"两种 entry,就被这个预置动作抹平了。这个 PR 把任务入口拆成可选的 task_entry: seeded-todo(默认,行为不变)与 loopx-planned,并把产品的规划契约以只读形式暴露成 loopx todo plan,让 benchmark 消费真实计划而不是自己造一个。它是 #4671 的 follow-up,目标分支就是 #4671 的分支,所以 diff 只包含 task-entry 规划这一层。
改动思路
- 规划契约只留一份。把
build_goal_start_contract里内联的 planner dict 提取成goal_planner_contract(fine_grained=...),todo plan与/loopxstart 共用同一份;fine-grained 的额外字段仍在同一个 flag 下追加。我独立对比了 base 与 head 的 planner 输出(standard 与 fine 两种),逐字节一致。 - 只读检查点。
build_task_planning_packet只读注册表与 Todo 投影,返回 planner、ordered_steps、现有 Todos、runnable/blocking ids、goal_waiting_on、结果 schema 和一份execution_handoff{owner: caller, starts_host_loop: false, spends_quota: false, planning_is_advancement: false}。CLI 侧validate_todo_plan_options只允许--goal-id/--agent-id/--text/--project/--format。 - 读回是强制校验,不是文案。
validate_plan_readback重新读取 packet,比对input_digest前后一致,要求 status 类型化、id 唯一非空、必须存在于现有 Todos,且ready ⊆ runnable(该 agent 已认领)/blocked ⊆ blocking;任何不满足都失败,绝不回退到通用 Todo。 - 阶段边界修正(对两种 entry 都生效):新阶段不再
--clear-waiting-on/--agent-work-mode active(新输入不等于等待已解除),每个阶段保留自己的任务文档,存在未解决 Turn 时拒绝替换阶段输入。 - 预算按阶段统一。规划与准备共同消耗
scheduler_timeout_sec;最后一次提交进一步把结算余量从 150 提到 160,并在 worker 里让迟到的调度唤醒先检查剩余 deadline:装不下一次执行加结算就记一条budget_exhausted空操作返回,不再开一个注定被外层超时打断的 host 执行。
具体改动
相对 #4671 分支共 23 个文件、+998/-79:产品侧是 loopx/control_plane/goals/task_planning.py(151 行新检查点)、benchmark/runtime/planning.py(78 行读回校验)、benchmark/runtime/harbor.py(约 100 行)、worker.py 的阶段分支,以及 CLI/slash_command_install 的小接线;其余是文档、RFC 检查点与约 300 行测试。
关键符号:
task_planning.py:41build_task_planning_packet:读两个 role 的 Todo,避免只看压缩 lane 而漏掉完整 frontier。start_contract.py:8goal_planner_contract:planner 的唯一所有者(提取而非新增语义)。cli_commands/todo.py:219:严格选项子集的只读plan分支。benchmark/runtime/planning.py:44validate_plan_readback:digest/身份/id/归属四重校验。benchmark/runtime/worker.py:247plan 阶段:用features.goals=false+--output-schema起一次独立 fresh 的codex exec;:234新增迟到唤醒的预算短路。benchmark/runtime/harbor.py:305_prepare_phase:pending Turn 拦截 + 按阶段的任务文档;:600起 160s 预留与 deadline 计算。
我实际复跑、可依赖的部分
- 在被审 head 上跑
test_task_planning.py、test_fine_grained_turn_mode.py、test_start_goal_compact_projection.py、benchmark/tests/test_task_entry.py、benchmark/tests/test_shared_codex_runtime.py→ 109 passed / 9 skipped。 - 手动验证
todo plan是真只读:临时 registry 上跑完后 registry 与 state 的 sha256 不变、目录里没有新增文件,输出read_only/dry_run=true、starts_host_loop=false、spends_quota=false,并正确带出goal_waiting_on。 - 负例手动验证:未注册 agent、未知 Goal、空
--text、多传--status都返回清晰的ok=false错误,没有静默降级。 - planner 契约独立对比:base
587b48c2与 headfc77656d输出完全一致。 - 评审期间 head 动过一次(
db236f32→fc77656d),delta 是预算预留守卫;我把它拉进来重跑并更新了结论,没有沿用旧 head 的结论。
对主干的风险
CI 在换 head 后重新开始跑,我评审时只有 3 项 pass、2 项在跑,其余排队,所以我把 repository_required_checks 记为 unverified 而不是 pass。
其他边界:
- 真实 Harbor/Codex 的 planning-to-execution conformance 作者自己写着 "in progress",我这边只有单测 + 真实 worker 入口的桩化运行,所以"两种 entry 在真实 arm 下可比较"这一层没有独立证据。
- 本 PR 叠在未合并的 #4671 分支上:base 是
codex/benchmark-runtime-unification,必须先落 #4671 或改 base,才能谈合并。 - 去掉了无条件的阶段 reset(对默认 seeded-todo 同样生效):依赖旧"新阶段自动清等待/置 active"的既有配置,行为会变,前后结果不可直接比较;这一点 PR body、RUNTIME.md 和 todo 契约文档都写明了。
- body 写着 "This PR remains draft until that evidence is checked",但 PR 实际不是 draft,评审队列会当成可合并候选处理(见下)。
一处非阻塞观察(P3)
Body 的 draft 声明与 GitHub 状态不一致:要么重新置为 draft 等真实 conformance,要么改掉那句话,别让读者以为它还没准备好。
我的整体评价
形状是对的,而且和仓库规则高度一致:规划契约只留一份并共享(我用逐字节对比确认提取没有夹带语义变化)、检查点是只读且明确把执行权留给 caller、读回用类型化校验而不是文案承诺、失败时不回退到通用 Todo,默认 entry 保持不变。最后一个提交也修得实在——把"迟到唤醒开了一个装不下的 Turn"这类隐蔽的预算 bug 变成可测的 no-op。
我给出的是契约与读回这一半的批准结论:请先让 #4671 落地或改 base,并等 CI 与真实 conformance;这条评论不构成合并许可。
English verdict: APPROVE — at fc77656d4e4d25779f8f31f51e7c0776b45cfa78 the benchmark can now select task_entry: seeded-todo (unchanged default) or loopx-planned, which consumes a genuinely read-only loopx todo plan checkpoint built from the single shared planner contract (independently verified byte-identical to the base) and requires typed Todo readback with no fallback to a generic Todo. 109 focused tests pass locally, todo plan was shown to write nothing, and the last commit adds a phase-deadline reserve plus a budget-exhausted no-op for late wakes. Residual: required CI restarted with the new head and was still running, real Harbor conformance is explicitly in progress, the PR is stacked on the unmerged #4671 branch, the phase-reset removal also affects the default entry, and the body's draft claim contradicts the PR's non-draft state (P3).
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 458ae13596e1c10a8d44c412bdc3b64ae038b9e6, no blocking finding. This supersedes my review at fc77656d; the head moved twice during this pass and both deltas were the phase-budget refinement. Required CI restarted with the push and was still running; real Harbor conformance is still in progress per the body. Merge remains the maintainer's decision.
动机
共享 benchmark runner 在每个原生阶段前先写一条通用 [P0] Execute benchmark phase N Todo,等于替模型把计划做掉了——想比较"LoopX 自己规划"和"直接执行"两种 entry 就被抹平。这个 PR(#4671 的 follow-up,目标分支即 #4671 分支)把入口拆成可选的 task_entry: seeded-todo(默认不变)与 loopx-planned,并把产品规划契约以只读形式暴露为 loopx todo plan。
改动思路
- 规划契约只留一份:从
build_goal_start_contract抽出goal_planner_contract(fine_grained=...),todo plan与/loopxstart 共用;我对比了 base 与 head 的 planner 输出(standard/fine 两种),逐字节一致。 - 只读检查点:
build_task_planning_packet只读注册表与 Todo 投影,返回 planner/ordered_steps/现有 Todos/runnable-blocking ids/goal_waiting_on/结果 schema,以及execution_handoff{owner: caller, starts_host_loop: false, spends_quota: false};CLI 只接受--goal-id/--agent-id/--text/--project/--format。 - 读回强制校验:
validate_plan_readback重新读 packet,校验input_digest前后一致、status 类型化、id 唯一且存在于现有 Todos,ready ⊆ runnable(已认领)/blocked ⊆ blocking;失败即 entry 失败,不回退到通用 Todo。 - 阶段边界修正(两种 entry 都生效):新阶段不再清等待/强置 active,每阶段保留自己的任务文档,未解决 Turn 阻止替换阶段输入。
- 预算按阶段统一,并逐次收紧:规划与准备共享
scheduler_timeout_sec;本轮两次提交把它做成"每次唤醒都按剩余阶段预算封顶 host 窗口",只剩启动+结算余量(160s)时记一条budget_exhausted空操作返回,不再开一个注定被外层超时打断的执行。
具体改动
相对 #4671 分支共 23 个文件、+1021/-79:产品侧是 task_planning.py(151 行检查点)、benchmark/runtime/planning.py(78 行读回校验)、benchmark/runtime/harbor.py(约 100 行)、worker.py 的阶段分支与预算封顶,加上 CLI/slash_command_install 的小接线;其余是文档、RFC 检查点与约 305 行测试。
关键符号:
task_planning.py:41build_task_planning_packet(读 agent+user 两个 role,避免只看压缩 lane 漏掉完整 frontier)。start_contract.py:8goal_planner_contract(planner 唯一所有者)。cli_commands/todo.py:219严格子集的只读plan分支。benchmark/runtime/planning.py:44validate_plan_readback。worker.py:247plan 阶段(features.goals=false+--output-schema的独立 freshcodex exec);worker.py:236每次唤醒按min(timeout, remaining-160)封顶,remaining <= 160时 no-op。harbor.py:305_prepare_phase(pending Turn 拦截 + 分阶段任务文档);harbor.py:600起 160s 预留与 deadline。
我实际复跑、可依赖的部分
- 在被审 head 上跑
test_task_planning.py、test_fine_grained_turn_mode.py、test_start_goal_compact_projection.py、benchmark/tests/test_task_entry.py、benchmark/tests/test_shared_codex_runtime.py→ 110 passed / 9 skipped。 - 手动验证
todo plan真只读:registry/state 的 sha256 不变、目录无新增文件、read_only/dry_run=true、starts_host_loop=false、spends_quota=false,并带出goal_waiting_on。 - 负例:未注册 agent、未知 Goal、空
--text、多传--status都返回清晰ok=false,无静默降级。 - planner 契约 base↔head 完全一致;两次 head 迁移(
db236f32→fc77656d→458ae135)都把 delta 拉进来重跑,未沿用旧结论。
对主干的风险
换 head 后 CI 重新开始跑,我评审时 7 项 pass、3 skip、12 项在跑,没有失败;因此 repository_required_checks 记为 unverified。
其他边界:真实 Harbor/Codex conformance 作者标注仍在进行,我只有单测与真实 worker 入口的桩化运行;本 PR 叠在未合并的 #4671 分支,必须先落 #4671 或改 base;去掉无条件阶段 reset 也影响默认 seeded-todo,前后结果不可直接比较(body/RUNTIME.md/契约文档均已披露)。
一处非阻塞观察(P3)
Body 写 "This PR remains draft until that evidence is checked",但 PR 实际不是 draft,评审队列会当作可合并候选;请二选一对齐。
我的整体评价
方向正确且与仓库规则一致:规划契约只留一份并共享(逐字节对比确认提取无夹带语义)、检查点只读且明确把执行权留给 caller、读回是类型化校验而非文案承诺、失败不回退通用 Todo、默认 entry 不变。两次 follow-up 提交把"迟到唤醒开了装不下的 Turn"这一隐蔽预算缺陷变成可测的封顶与 no-op,属于实打实的收尾。
我给出的是契约与读回这一半的批准结论;请先处理 #4671 依赖与 CI/conformance。这条评论不构成合并许可。
English verdict: APPROVE — at 458ae13596e1c10a8d44c412bdc3b64ae038b9e6 the benchmark can select task_entry: seeded-todo (unchanged default) or loopx-planned, which consumes a genuinely read-only loopx todo plan checkpoint built from the single shared planner contract (independently verified byte-identical to the base) and requires typed Todo readback with no fallback to a generic Todo; 110 focused tests pass locally, todo plan was shown to write nothing, and the two follow-up commits cap each wake's host window to the remaining phase budget with a budget-exhausted no-op. Residual: CI restarted with the head and was still running, real Harbor conformance is in progress, the PR is stacked on the unmerged #4671, the phase-reset removal also affects the default entry, and the body's draft claim contradicts the non-draft state (P3).
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)
Reviewed head: fe76e6caf25b5af5c4ab6449bfc6eec113896043; base: 587b48c25a7087df4e86d2e3c298d2757b67aead (#4671).
当前结论为 REQUEST_CHANGES,原因是最终验证尚未闭合。已发现的实现问题已修复,本地检查通过;不能把先前提交的真实运行结果替代最后一次续跑修复的验证。
动机
共享 runner 原先先写通用执行 Todo,无法独立比较“预写任务”与“模型按 LoopX 产品契约规划”。本 PR 将 task_entry 与 heartbeat、Turn fresh/resume、LoopX Goal 分开,且作为 #4671 上的独立后续 PR。它解决任务入口与原生 phase 续跑,未声称规划效果提升、完整 benchmark 结果或交互式同会话启动等价。
改动思路
权威状态仍在既有 Goal/Todo、quota 和 Turn 实现。todo plan 只读已有注册身份、完整角色视图及共享 planner/Todo delta;模型通过原有 CLI 写任务,worker 重新读取状态后才交给执行 driver。新建“调用 skill 的 Todo”会混淆 advancement,复制 planner 则会制造第二套规则,因此选择抽取既有契约。
规划会话独立且禁用 native Goal,不进入执行会话绑定。结果文件是派生回执,不授予执行权。规划的“不要执行任务”是模型行为契约,不是新增的 OS 沙箱;结构读回也不能证明计划质量。
具体改动
关键代码讲解
build_task_planning_packet:注册身份校验后复用goal_planner_contract和todo_authoring_steps,显式读取 agent/user Todo,避免 compact 展示截断;返回本 agent 可执行 ID 和仍有效的阻塞 ID。已完成、延期 gate 不再被误判为当前阻塞。validate_plan_readback:检查输入 digest、唯一且真实存在的 Todo ID,以及 owned runnable / unresolved blocker 集合。零退出但伪造 ID 仍失败,worker 将ok复位,不静默回退预写任务。BenchmarkCodex.run/_seed_phase:规划计入 phase 总预算;新输入保留 waits 与原始任务文档。预写入口更新自己仍 live 且 owned 的通用 Todo,done/deferred 时新建,避免新任务被旧通用 Todo 挡住。所有状态转换继续通过公共 Todo CLI。run_once:每次 scheduler wake 按剩余 phase 时间缩短 host window,预留启动与结算时间;只剩预留时间时不调用 host、不创建 pending Turn。真实未结算 Turn 仍阻止下一 phase 替换输入。
LHTB render/preflight、SWE 示例配置及共享运行文档暴露入口选项;installed skill 增加显式 planning packet 分支。CLI、skill、Harbor 配置是实际入口;没有 frontend/Lark 配置编辑器拥有这些 headless trial 设置。
对主干的风险
真实两阶段探针揭示了两个问题:末尾 wake 被外层截止截断,留下 pending Turn;预写新 Todo 排在旧 open Todo 后方,导致执行旧任务。最终实现分别修复预算准入和 seeded Todo delta,并加入反例。后者尚缺最终真实模型复验。
默认仍是 seeded-todo,不会多出规划模型调用;普通 Goal-start 在 standard/fine × new/connected 四种组合下完整契约保持一致。phase wait 保留、不可变输入、每轮 deadline 和 seeded continuation 是对两种入口都生效的有意修正,已在运行文档披露。状态判断使用确切状态/类型与既有语义 helper;核心规划契约保持领域中立,不创建新的 agent、权限或结算权威。
语义与 CI 对齐
最终 head 的 148 项相关测试通过,包含真实 Todo CLI 的 open/blocked/done/deferred 续跑转换、假 ID、过期输入、错 claim、终态 gate、超过展示上限及 deadline 反例。lint、契约 parity 和公共边界扫描通过。19 项所选 canary 在最后 seeded-only 修复之前全部通过;该修复另有定向公共 CLI 覆盖,但不能冒充完整最终真实模型验证。
先前真实 Harbor/Codex 运行证明了 planning→driver 交接,Turn 独立验证及 committed 结算;会话读回确认 fresh 两轮使用两个执行会话、resume 两轮共用一个执行会话,规划另占一个会话。Goal 试验产物通过,但在 120 秒截止时仍 active,未证明 Goal 收尾。最新两阶段规划遇到 provider usage limit;最终 seeded 修复未获得真实模型复验。最终 Sign-off / merge-gate 也必须读回,不能将 pending CI 视为通过。
我的整体评价
设计落在现有 Goal/Todo owner,抽取共享 planner 和复用公共生命周期写入是合理的有界重构。新增机制与任务入口消融、续跑故障对应,没有增加评分或权限逻辑。但当前交付验证尚未闭合,应保持 draft,不批准、不合并。
最小补证:模型可用后,在此 exact head 对 seeded-todo、loopx-planned 各跑同一两阶段 Harbor fixture,分别核验后续产物、实际 Todo/Turn lineage、结算和规划/执行会话;随后确认必需 CI。保留已经观察到的失败与超时,不将结构回执、产物评分或先前 head 的通过结果替代这些证据。
English verdict: REQUEST_CHANGES - fe76e6c. The task-entry design and local regressions are implemented; 148 focused tests pass. Final live multi-phase qualification remains incomplete after a provider usage-limit response, and final required CI must pass. No merge approval.
5728591
into
codex/benchmark-runtime-unification
Depends on #4671 and targets its branch so this PR contains only the task-entry ablation and its continuation fixes. The shared runner previously preseeded a generic Todo. Callers can now choose
task_entry: seeded-todoorloopx-planned, independently of heartbeat, governed Turn and LoopX Goal execution.loopx todo planis a read-only checkpoint sharing the existing Goal planner and continuation-aware Todo delta. The installed skill plans actual work; the worker verifies the returned IDs against product state before handing execution to the caller. Planning uses a separate fresh session, consumes the phase budget and never becomes a planning/advancement Todo. This is not a claim of same-conversation interactive startup parity.Native follow-up phases preserve waits and immutable input documents. Seeded entry updates its own live generic Todo instead of stranding new input behind an unfinished predecessor; completed/deferred work gets a new Todo. Each scheduler wake caps its host window against the remaining phase budget and reserves startup/settlement time, preventing late admission from leaving a pending Turn solely because the outer deadline cuts it off. Real unresolved Turns still block input replacement.
Validation: 148 focused tests passed on the final head, including real Todo CLI lifecycle transitions; full Goal-start contract parity; lint and public-boundary scans. The 19 selected canaries passed before the final seeded-continuation fix. Earlier real Harbor/Codex trials verified planning-to-driver handoff, committed Turn validation and fresh/resume session separation. The native Goal trial produced a passing artifact but remained active at its 120-second execution deadline; this does not establish Goal completion. Multi-phase probes exposed and drove the continuation fixes. Final live requalification is incomplete after a provider usage-limit response; final CI remains required. No full benchmark or effectiveness claim.
Affected entrypoints are the CLI, installed skill and Harbor/LHTB configuration. No frontend/Lark editor owns these headless trial settings. The bounded refactor shares the existing planner rather than creating another policy owner. Leave this runtime/control-plane change for maintainer review and merge after the remaining evidence is complete.