Repository navigation
Preserve original task recovery during status reads - #8732
Conversation
Signed-off-by: LoopX Agent <[email protected]>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · reasoning_effort=max
Request changes conclusion (author-owned PR; GitHub blocks formal self-review)
评审提交 6455a7c7cfd7df4122c95f557bdc72c1a6afa6d6;对照目标基线 78e936f9d1f1a00505c4026ee0a5857de95cee27。
[P2] 状态读锁尚未登记时,复核仍需再点一次。 修好被拒绝任务的产物后,在团队视图点「复核原任务」。让并发状态查询刚取得同一把锁、尚未写入持有者记录。 初次尝试锁失败后,旧记录仍显示上一次已释放的 single_flight。复核回退到只读;此时查询已释放锁,但接口仍返回 200、rejected、worker_active=false,原操作未推进。再点一次才验收。 触发分支
动机 / Motivation
修复产物后在团队视图复核原委派任务的操作者。 这项改动希望团队视图的被动刷新不再吞掉一次明确的原任务复核。 主干第一次抢锁失败即只读返回。 接口显示没有 worker 占用,但已经确认的操作没有推进,操作者只能再确认一次。 候选能在状态读锁已登记且及时释放时第一次就继续原 Turn;长占锁仍只读,释放后可验收,三种情形的 Host 总调用都保持一次。 File/SQLite 用实际本地 HTTP、内核锁和合成 Host 验证;未运行真实模型、安装态桌面或托管 CI。本差异只调整 UI smoke,未改变渲染。
改动思路 / Approach
Delegations 继续持有操作围栏、原 Turn 独立验收和停止校验;file_lock 提供内核围栏及单独发布的诊断记录。 改动位置正确。用现有围栏证明能进入效果分支;诊断记录能帮助缩短等待,但不能证明最新持有者。 显式复核仍在原围栏内继续;状态接口只读。
具体改动 / Changes
关键代码讲解
revalidate 现在检查锁用途,读锁已登记时最多等 250 ms,成功后才按现有规则核对停止和原绑定。_read_current 增加本地用途标记。3 个文件,+78/-7;前端变更只涉及 smoke。原复核服务 先取内核锁再发布持有者记录 已登记读锁的回归测试
按 docs/reference/local-delegation.md 的当前基线约束,original-turn-on-published-status-read 已验证;no-repeat-and-authority 已验证;status-reader-publication-window 未满足。基线验收依据
对主干的风险 / Risks
用同一套实际本地 HTTP,在 File/SQLite 上把状态查询分别阻塞在拿锁后、记录写入前后。记录已写时,候选首次返回 turn_returned;记录未写时,基线和候选都是 rejected,且无活跃 worker、操作文件字节不变。释放后用同一操作 ID 再点一次,两版都接受同一个原 Turn,Host 总共运行一次。这个窄窗口是本次尚未修复的旧缺口。
语义与 CI 对齐
File 和 SQLite 的对照各覆盖三种锁交错;14 个复核测试、8 个相关停止和恢复测试及 Standard 的 4 个选中检查通过。 File/SQLite 用实际本地 HTTP、内核锁和合成 Host 验证;未运行真实模型、安装态桌面或托管 CI。本差异只调整 UI smoke,未改变渲染。
我的整体评价 / Verdict
请求修改。把持有者记录当作选择等待策略的提示。当记录缺失、已释放或不能证明是当前持有者时,先在同一预算内重试拿锁;拿到后重新核对停止、授权、来源和原任务状态。仍被活跃 worker 占用时,继续只读返回。 请在现有 HTTP/File/SQLite 夹具增加「取得内核锁、持有者记录未写入」交错,断言首次复核继续原 Turn,并回归真实 worker 持有、超时、停止和撤权。
English verdict: REQUEST_CHANGES at 6455a7c. A passive status read can own the kernel fence before its holder record is published. Both base and head then leave the first revalidation rejected after release; retry the fence on stale holder metadata without weakening stop or worker exclusion.
| # Terminal publication can precede the original worker's release. | ||
| return self.read(operation_id) | ||
| _, holder = lock_holder_liveness(path) | ||
| if holder.get("operation") != _DELEGATION_STATUS_READ: |
There was a problem hiding this comment.
[P2] 状态读锁尚未登记时,复核仍需再点一次。 修好被拒绝任务的产物后,在团队视图点「复核原任务」。让并发状态查询刚取得同一把锁、尚未写入持有者记录。 初次尝试锁失败后,旧记录仍显示上一次已释放的 single_flight。复核回退到只读;此时查询已释放锁,但接口仍返回 200、rejected、worker_active=false,原操作未推进。再点一次才验收。 把持有者记录当作选择等待策略的提示。当记录缺失、已释放或不能证明是当前持有者时,先在同一预算内重试拿锁;拿到后重新核对停止、授权、来源和原任务状态。仍被活跃 worker 占用时,继续只读返回。 请在现有 HTTP/File/SQLite 夹具增加「取得内核锁、持有者记录未写入」交错,断言首次复核继续原 Turn,并回归真实 worker 持有、超时、停止和撤权。
…-recovery-contention Signed-off-by: LoopX Agent <[email protected]>
Signed-off-by: LoopX Agent <[email protected]>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · reasoning_effort=max
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
评审提交 8983c84,目标基线 4604f93。源码复审通过。短暂的状态读取释放锁后,第一次点击可以继续验收原任务。
动机 / Motivation
修复产物后,通过 Chat 团队视图、CLI 或 MCP 复核原委派任务的操作者。 原任务因独立验收失败而被拒绝。修好原产物后,操作者点「复核原任务」,此时并发状态读取刚拿到同一把内核锁。 主干第一次拿锁失败即返回只读状态。此前评审的候选会等待已登记的读锁,登记前看到上一次的持有者仍会提前返回。 现在两种状态读取都在同一把锁上等待一次。及时拿锁时,第一次显式复核就能继续原 Turn。持续占锁时仍返回原状态,等待期间撤权则拒绝。 本轮运行隔离的真实 File/SQLite、Chat HTTP、内核锁与可执行验收。打包桌面页面由真实同提交后端处理原复核,外围 Goal 导航采用合成数据。已安装版本、原生 Windows、真实模型与 390px 布局未独立验收。
改动思路 / Approach
Delegations 继续负责原 operation、当前权限与同一个 Turn,file_lock 负责真实内核围栏。 用现有内核锁的一次有界等待代替根据诊断记录选择是否等待,拿锁后复查 Stop、原授权和当前拒绝状态。 持有者记录在内核拿锁之后才写入,用它判断是否要等会漏掉一个实测窗口。保留已明确授权的复核入口和原身份即可完成这次修复。
具体改动 / Changes
关键代码讲解
- original-retry-after-lock 已验证。 在 File 和 SQLite 上把状态请求分别停在持有者记录发布之前和之后。主干四个首次请求仍为 rejected。当前四个都继续原验收,保留同一 Turn 和原产物。原评审发现 · 同一内核锁的 250 ms 等待
- timeout-current-stop-and-grant 已验证。 读锁占满等待时仍返回 rejected 与 worker_active,原 operation 和 journal 字节保持。把撤权放在两个拿锁尝试之间,两后端返回 409,没有写原 operation 或 journal。已发布拒绝、但实际 worker 尚持锁的情况同样只返回观察。超时与授权核验 · HTTP 四个交错、两种后端
- once-only-delivery-and-readback 已验证。 复核沿原失败的 Turn 使用现有验证与结算。20 项测试覆盖原 Host 仍运行、提交响应丢失、源身份变化、撤权和重放;打包桌面复核后读到原 output.json,后端 Host 调用仍为一次。浏览器 smoke 还在后端确认为 accepted 后继续验证产物。Chat 原 operation 入口 · 打包验证
原任务复核与权限合同 对同一个 origin 保留失败证据和既有验证。全 diff 3 文件、+162/−9,生产改动集中在现有锁与诊断记录。没有新的执行路径或页面布局。
对主干的风险 / Risks
复核可能多等一次 250 ms 的拿锁窗口。达到时限便返回原状态。真实 Chat HTTP 同组八例由基线 4/8 到当前 8/8,复核相关 20 项通过。四项选中的标准预合并检查通过。摘要所有权专项两版均为 243 通过、同一条失败。 重复的失败指向 result_files_api 中同一条摘要字面规则,两树逐字相同,单独保留为合并验证项。托管 CI 未查询。
我的整体评价 / Verdict
通过。先前未登记读锁的反例在当前提交的 File 和 SQLite 均已消失。两个后端都验证了超时保持只读、等待期间撤权拒绝和原 Host 只调用一次。已有讨论和摘要所有权检查仍需按现行合并规则处理。
English verdict: APPROVE at 8983c84. A first explicit revalidation now recovers the same task when the status reader releases the kernel fence, before or after owner publication. Timeout and revocation preserve the original record, and Host work runs once.
Clicking Revalidate original task while a status read held the operation lock could return HTTP 200 with the task still rejected. In particular, the reader could already hold the kernel lock while its owner record still described a previous invocation that had released it. The first request then switched to read-only status, and the user had to click again.
Revalidation now waits for the same kernel lock for up to 250 ms without choosing a route from holder metadata. If it acquires the lock, it checks Stop, the current grant, and the original operation before retrying validation. If the lock is still held, it returns the existing observation. It never reruns Host work. This also removes the two-stage lock acquisition and its stale-owner branch.
The race reproduced through Chat HTTP with both File and SQLite. Eight HTTP cases now cover the reader before and after owner publication, a reader held through the deadline, and a grant revoked while revalidation waits. The original Turn and artifact recover on the first request, with one Host invocation. The broader local regression had 87 passes and 10 platform skips. The rebuilt Chat bundle passed its desktop and 390px recovery scenario. All ten validators selected by standard premerge passed. This changes the recovery behavior behind an existing control and does not change the layout.
Full merge qualification is pending. The digest ownership check fails on this head and the same main revision; the separate #8758 patch passes all 17 matches when composed locally. That result is not qualification for this head. Native Windows and independent review of this head are pending. The previous showcase catalog failure passed on this checkout.