Skip to content

fix(chat): recover original messages after account preparation fails - #8187

Merged
loopx-agent merged 3 commits into
mainfrom
codex/account-preparation-recovery-20261106
Nov 6, 2026
Merged

loopx-agent merged 3 commits into
mainfrom
codex/account-preparation-recovery-20261106

Conversation

@loopx-agent

@loopx-agent loopx-agent commented Nov 6, 2026 •

Copy link
Copy Markdown
Collaborator

A quota continuation could fail during account transport preparation, before the native model Turn started, and remain permanently unanswered under a misleading resume_failed notice.

This change preserves model_auth_unavailable and lets the existing original-source worker recover exact pre-dispatch failures. The typed planner requires the canonical queued/failed sequence, null durable start checkpoints, unchanged source and authority, no native result, no stop or equivalent later submission, and fresh account transport readiness. Preparation continues the existing quota/routing/preparation counter (at most three); started or unknown work cannot gain a new retry budget. The failed Turn and original failure delivery remain unchanged. Lark describes the conditional recovery without promising a replay.

Validation:

  • New source-to-Core-to-Lark recovery, readback, duplicate, stop, changed-source, route-unavailable and admission-crash tests pass.
  • Conversation binding TypeScript tests: 57 passed; control-plane typecheck passed.
  • Existing queue, manager preparation and conversation binding regressions: 149 passed; final error classification/model adoption regressions: 28 passed. Final-head premerge: 14 checks passed. The runtime error classification was simplified; the reviewed module ceiling grows by two lines in the same diff.
  • The same functional recovery oracle reproduces the unanswered request at immutable base 62e234c and passes at this head. Mirrored RFC documentation describes the bounded migration.

The implementation reuses the existing request journal, queue, account provider, source verification and reply worker. It adds no model runner, account policy, service consumer, Goal or authorization grant. Live message completion remains a separate post-upgrade acceptance check.

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
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 | OpenAI | self_reported

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

动机 / Motivation

原私聊项目助手和 Codex 管家用户在账户传输准备中断后,仍需要原消息得到处理和回复。

额度续办尚未启动模型便失败时,旧版本只留下失败通知;新版本在原来源和连接恢复后,由原 worker 按剩余次数接续并原路回传。

已验证原消息、Session、原失败和失败通知保持不变,恢复仅生成一个关联续办,并由原 Bot 发送可独立读回的答案。

不处理未知执行效果,不新增账户策略、服务消费者、Goal、权限或模型 runner。

真实在线消息的升级采用和最终回传仍需独立验收;本 PR 的合并不等于所有历史欠答已关闭。

改动思路 / Approach

资格判断属于现有 TypeScript conversation binding owner;Python 只读取完整 canonical 事实、账户传输和执行既有队列,Lark 继续拥有冻结的回复送达。

本 PR 闭合账户准备失败到原来源续办的路径,保留所有原失败及三次上限;线上采用与历史业务完成由原服务独立验收。

单纯重连账户只能修复后续连接,不能让已经失败的原请求自行恢复;Root 手动重交又会绕开原来源与旧预算。因此选择复用原 request journal、Session queue 和 Lark reply worker,在同一 typed owner 内补上精确的本地准备分支。quota-1 后的准备失败只能进入 preparation-2,再到 preparation-3;原失败、旧送达记录和退避时钟继续保存。没有新进程、第二消息消费者、账户政策或 feature toggle。

触发 旧路径 当前路径
原消息本地账户准备失败 失败通知后永久搁置 原连接与来源恢复后按剩余次数续办
已启动、未知效果、stop、重交 保留 继续保留,无新执行
入队后丢失 ACK 原有 queue correlation 认领相同 client identity,不能再派发

具体改动 / Changes

审查范围为 62e234c → 9eba1bd,10 文件,307+/11-;其中测试179行,双语说明19行。参考已接受规范 docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md,固定版本 62e234c939996ad42f2b1168451cc9a656dce11d:original-source(每次准入重新核验来源及 grant)、bounded-recovery(跨重启不重置次数或重开失败 Turn)、failure-provenance(原失败与通知不变)均在本次源到回复测试中落实。新增双语段明确账户准备这一有界扩展,没有改写既有未知效果禁令来适配测试。

关键代码讲解

  • planRuntimePreparationRecovery 要求完整的 queued/failed 两事件,持久化 started_at、first_event_at 仍为空,无 native result、response、delta、附件且输入/origin一致。旧 resume_failed 也必须满足同样证明;缺失字段不能冒充空检查点。原 quota/routing/preparation lineage 的计数继续单调增加,上限为三。
  • _context_recovery_plan 从完整 canonical 记录派生证明。发现只是提示,受理前还要重新读取原 source/grant 和既有 account transport;项目助手验证其原 project grant,不借用管家的 portfolio。
  • _ensure_adapter_locked 统一保留账户准备错误和原设置分支的 unsupported_configuration;其他恢复异常仍按原规则处理。没有改动模型派发点,原 started_at 检查点仍先于任何模型工作。
  • reconcile_request 沿用原 Bot 及冻结 presentation journal 返回结果。项目助手的失败通知也说明有条件接续,成功答案的正文和发送者须独立读回,旧失败通知不被覆盖。

对主干的风险 / Risks

最强反例是把已执行业务误认成本地准备失败,或在 quota 失败后换族重置预算。本次 TS 反例覆盖已开始/已有 native result、额外事件、错误来源、修改的 client ID、stop、后续重交和计数耗尽;源到 Core 到 Lark 的用例还覆盖 route-unavailable 与入队后崩溃。缺证据继续保守保留,没有把缺少答案当成无执行证明。

PASS:新增回复闭环13例;conversation binding TypeScript 57例;既有队列、上下文准备和绑定149例;最终错误分类/model adoption 28例;control-plane typecheck;最终 head 的 premerge 14项全部通过。基线62e234c在同一功能 oracle 下仍停在原 failed Turn(预期失败),head 实际生成一次续办并回传,比较只排除了两端相同的通知措辞断言,没有归一化执行、来源或预算。

语义与 CI 对齐

新增的是现有 preparation 观测的派生变体,决策仍由同一 TypeScript owner 持有。原运行文件增长先被维护性检查拒绝;合并重复错误分类后只剩必要两行,预算2417→2419与被资格化的代码同一 diff 提交,Any预算及其余扫描不变。此前检查与文档编辑并发造成的 tracked-side-effect 失败已保留;最终在静止、干净的精确 head 上完整通过,未放宽检查。按此 Goal 的当前 review policy 不获取或等待远程 CI。模型和飞书 IO 使用合成 provider,生产账户只做了无模型请求的会话恢复观察,不能据此声称真实欠答已完成。

我的整体评价 / Verdict

未发现阻塞性问题,结论为 APPROVE,交付判定 justified_increment。long_horizon 与 user_experience 均改善:减少人工重交并保持原来源、失败历史和有界预算;这属于现有 owner 的必要补齐,不是新增平行控制面。资格判断属于现有 TypeScript conversation binding owner;Python 只读取完整 canonical 事实、账户传输和执行既有队列,Lark 继续拥有冻结的回复送达。 本 PR 闭合账户准备失败到原来源续办的路径,保留所有原失败及三次上限;线上采用与历史业务完成由原服务独立验收。

检查 manager_failure_reply 与既有 post 消息路径:只改变纯文本诊断,没有布局、折叠、卡片或响应式实现变更;消息正文和发送者通过 provider 读回验证。 视觉未验证范围:飞书客户端视觉表现及真实业务回传不由本次合成用例认证。真实在线消息的升级采用和最终回传仍需独立验收;本 PR 的合并不等于所有历史欠答已关闭。

English verdict: APPROVE 9eba1bd; exact pre-dispatch recovery and original-source reply are verified, while unknown effects, stops and retry-budget limits remain protected. Live adoption and pending-message completion remain separate acceptance.

@loopx-agent
loopx-agent merged commit df97c78 into main Nov 6, 2026
24 of 30 checks passed
@loopx-agent
loopx-agent deleted the codex/account-preparation-recovery-20261106 branch November 6, 2026 13:55
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