Skip to content

fix(chat): avoid holding source routes during recovery provider reads - #7525

Merged
loopx-agent merged 1 commit into
mainfrom
codex/fix-recovery-source-verification-20261028
Oct 27, 2026
Merged

loopx-agent merged 1 commit into
mainfrom
codex/fix-recovery-source-verification-20261028

Conversation

@loopx-agent

@loopx-agent loopx-agent commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

恢复旧请求时,渠道身份及原消息读取仍会持有共享 source 路由锁;慢读取会阻挡同一会话的新输入。此修复将这些只读调用移到路由锁外,取得锁后再用当前 binding、既有 typed owner 和 canonical Session/Turn/请求快照核验。路由正忙时保留原请求,让既有 worker 下次重新读取,避免等待后采用旧观察;同请求锁、已准入回执采用及原队列继续保留。

这是现有 Chat/Lark 恢复入口的 IO 边界修复,未增加消费者、配置、权限或重放策略。延迟恢复、unknown 和后续输入仍不能授权重执行业务;完整双端同步及自然故障恢复仍需独立验收。

Validation:

  • 新回归在原 base 的 status/route-busy 两种情况均失败;修复后新七种边界及既有 native 探测七种边界共 14 项通过。
  • 同一隔离 File/真实 stdio/TS workload,在原消息读取固定延迟 2 秒时,三个 base 样本的新输入耗时 2.098–2.118 秒,修复后 0.066–0.075 秒。旧失败 Turn 字节保持,三个样本均没有模型启动;这是合成争用对照,不是生产 p95。
  • 扩大后的原 worker/恢复/回传/feedback 套件457项全部通过;标准 premerge 的4项 direct checks、编译与2项 catalog canary 通过;Ruff/编译/diff通过。全部新用例在同一base为5通过、2个预期回归失败。

顺序重测在扩大套件结束后执行,安装版对应输入耗时0.072–0.088秒。初次头样本曾与扩大套件并行,记录保留但不作为受控性能结论;未改超时或断言。

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · reasoning_effort=max

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

动机 / Motivation

原 Chat 在检查历史失败时,用户的新输入和状态查询也会被同源的慢消息读取阻挡。原消息读取等待两秒时,旧路径把新状态请求一起拖住;修复后新输入可先受理,旧恢复若已过时则保留原请求。隔离真实入口的三组对照中,新输入从约2.1秒降为66–75毫秒,旧失败字节不变且没有模型启动。此改动不认证自然故障全部恢复、账号切换、完整双端同步或全部历史业务完成。生产安装采用与持续锁指标、真实原业务和各自最终回传仍需分别核验。

改动思路 / Approach

远端读取属于既有 Python provider IO,恢复资格仍由原 TypeScript owner 判定;局部重排无需新状态或执行器。本 PR 只交付原恢复路径的读取与共享路由锁隔离,以及忙路由下保留请求后重新核验。继续只把 provider IO 放在 Python 适配层;当前 binding、canonical Session/Turn 和 source 请求快照仍在既有 typed owner 与原路由 fence 下决定是否准入。路由忙时不是成功或拒绝业务,而是原 journal 不变、既有 worker 下次重新读源。这个边界能独立交付并回退,无需新 scheduler、cache 或消费者。单纯扩大超时仍阻挡新输入,直接去锁会失去序列化,两者均不如当前修复。

同一合成负载 base 当前 head
原消息读取延迟2秒时,新状态请求准入 2.098–2.118秒 0.066–0.075秒
旧失败字节与新模型启动 字节保持;0次 字节保持;0次

这里用表格解释变化,没有另画或声称验证过渲染图。测量属于隔离真实 File/stdio/TS 入口与合成 provider,不是生产 p95。

具体改动 / Changes

关键代码讲解

ChatExternalConversations.recover_failed_request(loopx/capabilities/native_chat/external_conversations.py:120)仍先持有本请求锁,读原 Turn 与 native 完整证据,随后在共享 source 路由锁外读取当前渠道身份及原消息。它使用现有 try_exclusive_file_lock;若其他路由正在持有,原请求直接保持不变。成功取锁后,当前绑定必须逐值等于实际观察的绑定,再调用既有 _resolve_observed。原 Session、Turn 与完整同源请求快照还要一致;新输入可以先准入,过时的旧恢复不会覆盖它。已准入 receipt 的例外仍交原 TS 分支准确采用,不重新执行业务。

ChatExternalConversations._context_recovery_plan(loopx/capabilities/native_chat/external_conversations.py:49)新增的 selected_binding 只在本次调用中传递已经完成 typed 验证的绑定,避免在 source fence 内再做一次 provider 读取。普通及 discovery 调用仍沿原分支;候选、unknown、read-only review、unfinished work 和资格判断仍来自原 collaboration.conversation.request,没有新增 Python 决策 owner。生产 +22/-7 行,另76行测试覆盖 status、correction、revoked、source-changed、unknown、unchanged 和 route-busy 后再次推进。

规范:docs/reference/protocols/manager-evidence-and-continuity-v0.md,不可变 revision f63647e2e867a30dd8761baaa1df69cba9c9860b。MC-1 对应 Core 状态与资格 owner 保留;MC-2 对应原来源、绑定/授权、空闲与纠正/停止重检;MC-3 对应原 worker/原 transport 和回执恢复,未把准入等同业务完成。三项均按本修复边界 implemented;整体 App、账号和自然生产验收没有在此结清。

对主干的风险 / Risks

最强反例是 source 读取期间已撤权或新纠正到达,却用旧观察准入。精确绑定比较、同一 typed resolver、canonical 快照和原 TS 资格共同防止这种误执行;新的 source 延迟用例补上了仅延迟 native RPC 的旧测试盲点。忙路由会等到既有 worker 的下一次自然访问,这是明确的安全延迟;用例同时检查忙时不写 reservation 和释放后以新源证明推进。没有增加重试引擎、账号操作或消费者。

PASS:14项聚焦;扩大原 worker/路由/unfinished-work/绑定/回传/feedback 套件 457 passed in 545.49s (0:09:05);Ruff、编译、4项 direct checks、2项 catalog premerge 均通过。FAIL 作为回归证据保留:相同新 status/route-busy 测试在精确 base 失败,三次 base 协议对照均不满足独立响应性 oracle。Speedscope 主线程捕获成功,只说明读源等待仍存在,不能把堆栈权重相加当耗时或业务收益。初次头样本与扩大套件重叠,原记录保留但不用于受控性能结论;以上数字来自验证停止后的顺序重测,安装版另为0.072–0.088秒。当前 Goal 的 change-quality policy 为 disabled;按 managed review 配置没有查询、轮询或等待 CI。

语义与 CI 对齐

本改动复用现有 typed vocabulary 与 provider IO,不添加状态协议、角色或权限。默认行为变化已在 PR 与测试明确:busy recovery 从等待变为保留 journal 后重新核验,普通 intake 的锁和授权不变。原三次尝试、backoff、未知效果与精确已准入回执合同保留。没有通过提高 timeout、删失败断言或声称 backend 迁移来规避问题。

我的整体评价 / Verdict

未发现阻塞本精确头的缺陷。long_horizon 与 user_experience 在这个已复现边界上 improved:新输入不用为旧读源再手工确认/重试,旧恢复只在当前证明仍有效时推进。已检查两文件完整 diff:只改既有 Python 恢复 IO 与合成测试,没有渲染、消息文案、布局或导航变化。本评审未将浏览器或原生 App 完整同步、生产持续延迟和自然业务完成计为通过。兼容性保留的是已有持久 journal/失败及 receipt,不是并行新旧决策代码;生产只复用原 owner,比例合适。远端读取属于既有 Python provider IO,恢复资格仍由原 TypeScript owner 判定;局部重排无需新状态或执行器。本 PR 只交付原恢复路径的读取与共享路由锁隔离,以及忙路由下保留请求后重新核验。生产安装采用与持续锁指标、真实原业务和各自最终回传仍需分别核验。这个有用增量可以评审合入,安装采用与持续生产闭环继续由原维护责任核验。

English verdict: APPROVE — cc70b352a4c2777c5535a6a503d8f97a12d4fcc8 removes provider-read source-route blocking while preserving typed authority, original receipts and unknown-effect safety; focused, real-protocol and repository-native checks passed.

@loopx-agent
loopx-agent merged commit 78bd4ff into main Oct 27, 2026
5 of 7 checks passed
@loopx-agent
loopx-agent deleted the codex/fix-recovery-source-verification-20261028 branch October 27, 2026 20:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant