Repository navigation
fix(todos): enforce scheduled waits during canonical execution - #5926
huangruiteng merged 3 commits into
Conversation
hhyykk
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; gpt-6.1-sol; OpenAI; reasoning_effort=ultra; runtime_reported.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval).
动机
一个已设置未来恢复时间的待办会在任务列表里显示“尚未就绪”,但旧的规范执行入口仍可能接受领取或完成。执行者因此能提前做本应等待的工作,甚至留下错误的完成记录。相同的合成 File 场景在基线提交 159f00f 上重放旧领取返回成功;在本次提交 10ff24e 上被拒绝,待办仍保持 open。本次只修复日期等待的规范执行准入,既有完成依赖已由合并的 #5884 负责。完整 TypeScript 迁移、其他等待类型和安装版桌面及 Lark 流程仍是独立范围。
改动思路
规范 provider 的当前待办记录和本次操作的时间决定能否执行;历史租约收据、缓存的 ready 标记和日期到期收据都不能代替新的执行权限。改动在原有 TypeScript todoExecutionDependencyRejection 内复用已注册的日期规范化、评估和诊断规则,再把每个操作已有的 clock 传入共同守卫。这样领取、续租、继续执行、Monitor、完成和检查由同一条件判断约束。这个正确性规则属于既有 typed owner,provider 仍只负责持久化;未增加定时器、Python 决策源或权限例外。最小的可审查边界就是日期守卫与十个调用点的时间传递、文档和真实入口验证,后续恢复诊断 #5910 与本次规则分开。
具体改动
规范依据是 docs/reference/protocols/typed-date-resume-trigger-v0.md 在提交 159f00fc8ababa088e8f6cde3ef06653bc4c0511 的已接受文本。Consumer behavior: receipt is not execution authority 由共同守卫和当前租约证明落实;Acceptance 2 在到期前继续保持等待,并新增执行拒绝;Acceptance 3 的到期重规划和收据身份沿用原评估器,本次不修改该规则;Acceptance 5 的前端检查与打包构建已通过,界面实现不是本次新增。相应的租约参考补充中英双语说明,保留释放、历史终态读回、授权清理与原 owner 的暂停/清除 → 读回 → 重新打开 → 新租约顺序。
关键代码讲解
todoExecutionDependencyRejection 在 loopx/control_plane/coordination/todo_execution_dependency.ts:20 从当前待办的 resume_when 识别 resume_at,通过既有解析器与 evaluateTodoResumeConditions 使用操作时间判断:未来返回 pending,非法日期返回 invalid,精确到期后不再阻挡;todo_done 和其他类型保留原分支。executeCanonicalTaskLeaseLifecycle 在 task_lease_lifecycle.ts:102 对新续租、转交及历史收据重试做当前条件读回,释放仍可用。executeCoordinationTodoTerminalLifecycle 在 todo_terminal_lifecycle.ts:1208 只对新的完成应用日期守卫,历史 no-change 和授权 supersede 保持原权限。inspectTaskLease 在 task_lease_inspection.ts:54 以单一检查时间报告有效 active=false,不抹掉原租约。
其余生产改动覆盖 continuation_adoption.ts 的继续执行、lease_acquisition_proof.ts 的现时证明、task_lease_acquire.ts 的新领取、task_lease_proof.ts 的恢复建议、todo_claim.ts 的原子认领和 todo_monitor_cycle.ts 的 Monitor 执行,都仅把本次操作时间交给守卫。六个测试文件分别验证公开 File/SQLite CLI、真实 provider 的完成与 owner 恢复、委托 Host 启动前拒绝、旧租约收据与继续证明、检查投影、毫秒与时区边界。文档两处说明日期等待执行约束及恢复顺序;没有新协议字面值,复用现有 TODO_RESUME_KINDS。
对主干的风险
最强的回归风险是过度拒绝:已到期任务、同一 Goal 的无关任务或 owner 的合法清理若被拦住,会使等待变成永久停工。公开 CLI 的到期、新租约、清除和暂停/重新打开路径通过;守卫的固定时钟用例覆盖精确毫秒、偏移时区、未来时刻的旧 ready=true 与到期后的旧 ready=false。基线与本次使用完全相同的 File 测试文件,SHA-256 为 e75782558d5374283b1bcfe9e9c1b6355b1d9631b65c0ecfd137e7d76ec2cff3:基线错误返回 exit 0/ok true,本次按预期拒绝。真实 PostgreSQL 隔离套件 347 项无跳过;File/SQLite CLI 20 项、安装版 wheel 与 sdist 各 20 项、Host、类型检查和风险 canary 通过。最初两个 PostgreSQL 检查用例因缺 URL 跳过,随后配置 provider 的 7 项检查全部通过。远程 CI 在发布前读回时仍有三项排队或运行,属于合并就绪门槛,不能当作已通过。打包 App 仅验证真实 File 后端的拒绝、陈旧预览无写入、到期完成和 CLI 修复后的 App 读回;未验证安装版桌面与 Lark,也未做付费模型对文案理解的验证。
文案逐条比较了执行主体、时间顺序、当前 provider revision 来源、旧 proof 禁用、其他权限检查和停止/恢复条件。新增的日期拒绝是有意语义变更;未删去“释放仍可用、历史收据只供读回、修复不授予执行权限”的义务。文案是否被模型实际遵循仍未实测。当前 diff 没有新增状态词汇、默认开启选项或跨域特例,其他 resume kind 继续原路径;相关的未来重构检查未找到比复用现有守卫更小且保留所有调用点的安全删减。
我的整体评价
APPROVE 结论,未发现阻塞性代码问题。 独立 Sol/high 复核在相同公开 File CLI 场景执行了基线与当前版本对照,并单独验证 File/SQLite 六项和固定时钟守卫四项;发布评审的 Root 执行了当前源码 PostgreSQL、公开 CLI、Host、打包 App 和风险检查,并整合了 Luna/high 的安装产物验证。上述证据确认了基线上的实际越权、当前提交上的拒绝与到期/修复后重新进展;长期任务不会因日期等待阻断无关工作,用户可从公开 CLI 和已打包 App 的现有入口读回状态并完成恢复。此结论只针对精确提交 10ff24ef2ee03eae57a7243d0cf297945e58abd3 的日期执行修复,不宣称父级迁移或桌面/Lark 完结。等待远程必需检查和维护者合并;本评审不代替合并权限。
English verdict: APPROVE conclusion for exact head 10ff24ef2ee03eae57a7243d0cf297945e58abd3. No blocking finding; base File CLI admitted a future wait, while head rejects it and real File/SQLite, PostgreSQL, installed artifacts, Host and packaged App cover rejection plus recovery. Remote CI remains a separate merge hold.
|
This pull request has merge conflicts with Choose the remote for the base repository, not an out-of-date fork. git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEADFor a same-repository clone whose Keep the DCO |
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: actor_kind=model_agent; model=gpt-6.1-sol; provider=OpenAI; declaration_source=runtime_reported; reasoning_effort=xhigh
Reviewed exact head: 10ff24ef2ee03eae57a7243d0cf297945e58abd3.
动机
设置了定时恢复任务的 Agent会遇到这一问题。同一个任务先取得 lease(执行租约),再设置未来恢复时间;旧版展示为等待,却仍允许重放旧租约并完成任务。新版在实际执行入口拒绝提前执行,到期或经授权清除等待后恢复正常路径。
File/SQLite 的真实 CLI 和干净 wheel 均拒绝未来日期下的旧租约重放与新完成;到期、释放、清除等待及暂停再打开的恢复回归通过。
不新增计时器、配置开关、租约授权或其它 resume condition 规则,也不宣称整个状态迁移或长期运行验收完成。
剩余边界:当前 head 与主干 task_lease_proof.ts 有冲突;解冲突后的新 head 需重验,当前结论不授权合并。
改动思路
复用 TypeScript resume evaluator 和现有 execution guard,把每次操作的时钟传到实际执行入口;现有释放和 owner 暂停/重新打开流程承担恢复。
当前交付边界:本 PR 只闭合 canonical resume_at 的实际执行围栏及已有授权恢复路径;不重建 scheduler 或改写其他等待条件。
最强的不合并理由:current integration conflict must not discard newer owner recovery。单纯扩大显示容量、保存新的 ready cache 或再建一套状态规则,均不能解决已复现的来源/执行边界问题;本方案在现有 owner 内闭合。
具体改动
当前主干与 head 的实际 merge base 为 159f00fc8ababa088e8f6cde3ef06653bc4c0511,独立差异 18 文件 +275/-41。此前作者 exact-head 评论不是本次独立证据;本次重新核验完整18文件及现有caller。
- todoExecutionDependencyRejection(loopx/control_plane/coordination/todo_execution_dependency.ts:20):把 canonical resume_at 送至现有 normalize/evaluate/diagnose owner;用操作时钟拒绝 pending/invalid,不信任缓存 ready。
- executeCanonicalTaskLeaseLifecycle(loopx/control_plane/coordination/task_lease_lifecycle.ts:102):新 renew/transfer 及重放都检查当前等待;release 保留原路径。
- executeCoordinationTodoTerminalLifecycle(loopx/control_plane/coordination/todo_terminal_lifecycle.ts:1208):只在新 complete 的 apply 分支执行等待 guard;历史读回和 supersede 沿原规则。
- inspectTaskLease(loopx/control_plane/work_items/task_lease_inspection.ts:54):同一 inspection 时钟判断时间活性和等待约束;保留旧 lease 记录但 active=false。
spec_ref: docs/reference/protocols/typed-date-resume-trigger-v0.md;spec_revision: 159f00fc8ababa088e8f6cde3ef06653bc4c0511。判断依据是本 PR 改动之前的 accepted contract。criterion_id:Consumer behavior;Acceptance 2;Acceptance 3;Acceptance 5。这些 criteria 的实现位置和实际验证见以上符号及下列实测;当前 PR 编辑过的文档不是独立验收来源。
对主干的风险
未发现本 exact head 逻辑的阻塞问题。主干 task_lease_proof.ts 的 owner-pause 恢复已前进,本地 merge-tree 和远端均确认冲突;必须保留该恢复逻辑、整合 now 参数,并以新 head 重验后才谈合并。
独立验证:16 Python CLI tests;389 File/SQLite/Host/inspection/guard TS tests;真实 PostgreSQL 342 tests 和另外 2 个 PostgreSQL inspection tests;typecheck;日期前端 smoke 和 packaged Chat build;标准 canary 4 direct + 19 selected 全过;干净 wheel 5 个安装阶段和 File/SQLite 两组提前执行反例通过。
初次 File/SQLite TS run 的2个 PostgreSQL inspection skip 已在隔离的 PostgreSQL17 上单独执行通过;不是把 skip 当pass。
两次最初 wheel build 因干净 checkout 尚未生成 Chat bundle 拒绝构建;按仓库流程生成 packaged Chat 后两者 build/isolated installation 均通过,未放宽校验。补充 paired probe 最初有 fixture import 与临时 compile-cache 清理错误,保留失败记录;修正私有 probe 的 setup/证据目录后,原本的执行/提示 assertions 不变,base/head/wheel 对照通过。没有把 fixture 清理结果解释为产品恢复证明。
machine-enforced execution admission。没有新增跨 Agent、审批、quota、结算 authority;既有 owner、exclusion、lease 和其他义务仍各自生效。另外补跑的 tests/test_chat_todo_detail.py 在 base/head 都因原来的 --todo-id ... --thin 成功预期不符合当前 CLI 契约而失败(File/SQLite 两个同名参数项,均在进入 HTTP 前)。本 PR 未改测试或 thin 规则,单独保留已有门禁问题。原测试未编辑;另行核验支持的完整读取路径及真实 HTTP 的 Origin/非法目标/缺失来源/恢复,两组 File/SQLite 均通过;typed resume suite 13 项通过。
没有做无限期 soak、真实桌面或 Lark 账户操作,未声称这些验收完成。界面相关依赖沿已有入口;没有新增配置按钮或手工同步要求。
我的整体评价
APPROVE,仅绑定上述 exact head。本 PR 只闭合 canonical resume_at 的实际执行围栏及已有授权恢复路径;不重建 scheduler 或改写其他等待条件。
长程效果预期正向:避免定时等待被旧执行凭据绕过;等待仍有到期与授权修正后的真实继续路径。 体验方面,同一个任务先取得 lease(执行租约),再设置未来恢复时间;旧版展示为等待,却仍允许重放旧租约并完成任务。新版在实际执行入口拒绝提前执行,到期或经授权清除等待后恢复正常路径。 这些是已实测的有界前后差异,不能据此宣称无限活性或总体算力吞吐提升。效率价值来自减少重复误判/无效纠正和共用状态规则;单次延迟采样不作为性能增益结论。
future-facing pass:复用 TypeScript resume evaluator 和现有 execution guard,把每次操作的时钟传到实际执行入口;现有释放和 owner 暂停/重新打开流程承担恢复。 已满足本次相关 owner 收敛;更大范围 snapshot/provider cutover 不并入这一修复。当前 head 与主干 task_lease_proof.ts 有冲突;解冲突后的新 head 需重验,当前结论不授权合并。
English verdict: APPROVE on exact head 10ff24ef2ee03eae57a7243d0cf297945e58abd3. The scheduled-wait execution invariant is independently validated through real CLI, File/SQLite/PostgreSQL, and isolated installed-wheel paths; release and authorized recovery remain available. Preserve the newer main recovery branch, resolve the integration conflict, and validate the new exact head before merging.
10ff24e to
11db4a8
Compare
Signed-off-by: hyk <4408344+hhyykk@users.noreply.github.com>
Signed-off-by: hyk <4408344+hhyykk@users.noreply.github.com>
Signed-off-by: hyk <4408344+hhyykk@users.noreply.github.com>
11db4a8 to
a50732c
Compare
loopx-agent
left a comment
There was a problem hiding this comment.
APPROVE:当前 head a50732cc9a0462af16a2c7c386cee424a0294efe 未发现阻塞性实现问题。两次主干整合保留了已存在的 owner 等待修复和 explore 依赖准入。实际基线/当前源码/当前安装包对照证明:未来等待无法再被旧 acquire 回执或新 complete 绕过。合并仍以随后读取的原生 exact-head 合并门为准。
Reviewer: actor_kind=model_agent; model=gpt-6.1-sol; provider=OpenAI; declaration_source=runtime_reported; reasoning_effort=xhigh.
动机
受影响的是 canonical 定时任务:以往能提前执行的调用现在返回 todo_dependency_pending/invalid。没有第二个计时器、手动同步 readiness、Python 决策源或新权限。实际安装 desktop/Lark 交互及无限期 soak 未执行,不声称本切片关闭这些验收。
任务的展示和 quota 已能表达“还没到执行时间”,但实际执行入口仍可能接受此前取得的 lease。相同真实 File/SQLite CLI 旅程中,主干 4bdcb2eeed64582b99cfc46b213ed755839a69b8 允许未来等待下重放 acquire 和完成任务;当前源码及隔离安装的 wheel 均拒绝二者,并保持原记录。只修展示、缓存 ready 或扩大轮询间隔无法堵住实际 effect。
审查基准是改动前已接受的 docs/reference/protocols/typed-date-resume-trigger-v0.md,spec_revision=4bdcb2eeed64582b99cfc46b213ed755839a69b8;不以本 PR 修改后的规范倒推正确性。
改动思路
扩展既有 TypeScript execution dependency guard,调用原有 normalize/evaluate/diagnose 日期 owner,并传入每次操作自己的时钟。没有第二个计时器、手动同步 readiness、Python 决策源或新权限。未来时间及非法 token 拒绝执行;到期仅证明条件满足,仍须既有 claim/lease/CAS 准入。
当前整合保留 task_lease_proof.ts 的 released-owner dependencyPause:合法暂停、独立清除等待、读回、重新打开、再取得新 lease;不能把一次混合 update 或旧 proof 当作恢复授权。同时保留最新主干 explore plan 的等待/handoff/完成回归。
具体改动
18 文件、+275/-41:10 个生产入口接入同一规则,2 份协议/操作文档披露行为,6 个测试文件刻画实际执行与恢复。
关键代码讲解
todoExecutionDependencyRejection(todo_execution_dependency.ts:20):从 exact canonical Todo 的 resume_when 识别既有 token,规范化并按本次操作时钟判断;不信任缓存 resume_ready。毫秒边界、时区 offset、非法时间和 stale true/false 已验证,其他 resume 类型维持现有规则。executeCanonicalTaskLeaseLifecycle(task_lease_lifecycle.ts:43):新 renew/transfer 和历史操作重放都核对当前等待。旧 receipt 仍是历史记录,不能代替当前可执行证明;release 沿既有清理路径。executeCoordinationTodoTerminalLifecycle(todo_terminal_lifecycle.ts:1024):新 complete 的 apply 分支受 guard 约束;历史 terminal readback 和 supersede 仍用原有决策,避免阻断已发生结果的恢复。inspectTaskLease(task_lease_inspection.ts:26):用同一 inspection 时钟计算过期及依赖;保留旧 lease 记录,但等待期间不报告有效执行资格。
正向旅程:日期到期/合法 owner 修正 → 读回 canonical 状态 → 新 lease → 完成。负向旅程:先取得 lease 再声明未来等待 → acquire 重放/proof/claim/renew/transfer/Host/continuation/monitor/新 completion 拒绝;release、授权修复与同 Goal 无关可执行工作保持。
协议逐项映射:
| Criterion | 当前证据与边界 |
|---|---|
| Consumer behavior | receipt 不授予执行权或隐式 reopen;真实 base/head/wheel 反例及 owner recovery。 |
| Acceptance 1 | 原日期 owner 保留 UTC 归一;13 个 typed date 与 adapter 用例,另测恰好到期与非法 token。 |
| Acceptance 2 | 同一 resume owner 为 CLI/quota/Turn 提供等待事实;实际 effect 增补硬围栏,43 个集成用例、provider conformance 与原生 quota canaries 验证。 |
| Acceptance 3 | 既有 adapter 覆盖 successor_replan_required 与 receipt identity;到期实际执行恢复,不另建 replan owner。 |
| Acceptance 4 | 既有 timezone/ticks/summary-restart 用例验证原 receipt 恒定;此 PR 不改 receipt 身份。 |
| Acceptance 5 | UI typecheck/date smoke、打包 Chat 和同一 route smoke 经 Vite SSR 均通过;原 npm recipe 的已归因失败单列如下,未冒充通过。 |
对主干的风险
有意改变 canonical 定时任务的实际准入:以往能提前执行的调用现在返回 todo_dependency_pending/invalid。两份文档明确这是一项硬围栏;普通无日期任务、其他条件、原历史读回和授权恢复不新增义务。
当前 head:43 个真实 CLI 集成用例;原生 premerge 4 direct + 19 selected;重新打包 Chat/wheel;隔离 site-packages 的 File/SQLite 反例均通过。真实 HTTP current/archive 完整读及拒绝/恢复 2 用例通过。
11db4a8 上另有 424 个本地 TS、343 个真实 PostgreSQL 16.15 store + 2 个 PostgreSQL inspection、21 个恢复/adapter、214 个全树语义用例通过。最终 head 的全部受影响生产 TS 以及这些 provider 测试字节一致,证据仅用于该不变边界;新的 main CLI/explore/argument 恢复已在当前 head 重验。初始 2 个 PG skip 后已在隔离真实 server 执行,未用 mock 代替。
保留失败:npm run smoke:chat-route 在固定 base 与当前 head 都 exit 1,完整归一错误相同:脚本指向不存在的编译产物;159 个传递输入的内容和工具环境摘要相同。这项 recipe 没有修复。以 Vite SSR 构建并运行同一个 smoke 正文后通过,另有 typecheck、日期 smoke、真实 HTTP 和 packaged build 覆盖。它是原有独立 runner 风险,不要求本 PR 增加无关 package 修改;不能将其标作 passed。
早期命令路径/wheel 构建 cwd/依赖准备错误保留为执行设置失败,均通过正确来源重新执行;没有修改有效断言或绕过打包源码一致性检查。未取、轮询或等待 CI。实际安装 desktop/Lark 交互及无限期 soak 未执行,不声称本切片关闭这些验收。
我的整体评价
最强反对理由是更严 guard 可能堵死正常恢复或覆盖无关任务;释放、独立 owner 修正、恰好到期、历史 readback 和 explore fallback 的实际回归解除这一担忧。未来向重构已在现有 owner 完成:共享判定及操作时钟复用,保留主干恢复,没有新增框架。当前切片修复一个实际绕过,不证明整个迁移/默认或退役计划完成。
English verdict: APPROVE — exact head a50732cc9a0462af16a2c7c386cee424a0294efe. The shared typed execution guard now rejects premature dated execution across actual canonical entrypoints while preserving cleanup, historical readback, authorized recovery, and unrelated work. Paired immutable-base/source/installed-wheel File and SQLite observations reproduce and close the bypass; isolated real PostgreSQL checks qualify the unchanged affected owner. The original UI route npm recipe remains failed identically on both revisions; the same smoke body passes via Vite SSR and is explicitly distinguished. Native merge readiness, desktop/Lark interaction, and long-running qualification remain separate judgments.
A legally authored future
resume_atwait was excluded from runnable selection, but canonical acquisition and completion could still execute it. This follow-up to merged #5884 closes that bypass through the existing TypeScript execution guard and registered date evaluator. Each caller passes its operation clock; cached readiness and historical lease receipts cannot authorize early execution.The change covers acquisition/atomic claim, current proof, renewal/transfer, continuation, Monitor execution and new completion. Exact due instants remain eligible under the usual authority checks. Release, historical terminal readback, authorized wait repair and other resume kinds retain their existing rules. The reference explains the existing owner pause/clear → reopen → fresh lease recovery after release; no authority exception or Python decision owner is added.
Validation on head
10ff24ef2ee03eae57a7243d0cf297945e58abd3, based on159f00fc8ababa088e8f6cde3ef06653bc4c0511:Placement follows the TypeScript control-plane migration RFC. The bounded companion refactor reuses one operation-clock snapshot in the existing guard. Full R4/Stage 3 migration, other resume kinds, installed desktop and Lark journeys are outside this slice. Merge remains maintainer-owned.