Skip to content

fix(chat): recover original image preflight failures - #8073

Merged
loopx-agent merged 1 commit into
mainfrom
codex/original-image-preparation-recovery-20261105
Nov 4, 2026
Merged

loopx-agent merged 1 commit into
mainfrom
codex/original-image-preparation-recovery-20261105

Conversation

@loopx-agent

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

Copy link
Copy Markdown
Collaborator

Old image requests could fail before any model call when an earlier adapter rejected attachments. Supporting images in the current adapter did not make those original queue entries eligible for recovery, so the user retained only a failure notice.

This change lets the existing reply worker admit one original steward continuation only when canonical Core preparation events, the exact legacy preflight failure, unchanged frozen image payloads and the live original source prove that execution never began. It preserves the original Session, failed Turn and delivery record. A committed admission is correlated after a crash; changed input, revoked authority, stops, native effects and duplicate continuations remain blocked.

Validation: the same new harness reproduces the defect on the immutable base (two original-worker recovery failures and one typed-planner failure, with all six safety negatives still passing). The exact candidate passes 533 related Python tests, 54 conversation-binding tests, control-plane TypeScript checking, Ruff, RFC bilingual checks, and the repository premerge gate (six direct checks and ten selected checks; no failures or advisories). No remote CI was fetched or awaited under the managed review policy. Installed-service recovery and actual original-audience answers remain post-merge acceptance.

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 · OpenAI Codex · OpenAI · self_reported

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

动机 / Motivation

向个人管家发送图文问题、随后只收到失败通知的用户。旧版在模型接收图片之前拒绝输入,升级后原队列仍不接纳这条失败;修复后,原服务核对未执行证明与原消息,再在同一会话接续一次。真实 Core 存储和原回复 worker 的合成端到端测试已证明图片完整入队、答案回到原受众、失败记录不变,入队回执中断也只执行一次。本 PR 不普遍重放失败请求,不为其他会话或项目扩大权限,不新增消费者,也不宣称已清完历史问题。合并后的真实原服务采用、原消息实际补答与更广的历史问题清账,仍须独立核验。

改动思路 / Approach

恢复资格复用现有 TypeScript 决策者,Python 只读取规范事实与核验提供方来源;复用原队列和原收发回执,避免新增任务或权限状态。本次只恢复有完整旧版预发送拒绝证明的 owner-private 管家图文输入;原失败、原图片和原受众保持不变,后续执行仍走既有 Core 授权。最有力的反对理由是“旧错误文字不代表没有执行”;因此这份修复不以错误文字或缺少 upstream id 单独授权,而是同时要求规范事件顺序、零增量、无原生结果、冻结图片一致、原消息和当前授权。直接重发文字会丢图,新建图片重试器会引入第二个执行所有者,均没有采用。

下面是依据代码整理的状态比较,不是运行证据:

原输入状态 原服务的行为
完整旧版预发送拒绝证明,图片和原消息不变 原队列接续一次,并在同一原受众回传
入队成功后返回中断 找回准确已入队 Turn,不再执行一次
有原生执行迹象、正文或图片变更、撤权、停止 保留原失败,禁止接续

具体改动 / Changes

规范依据为 docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md,不可变版本 7f550aef58a80067dd85df0a276b2f6f98be742c。本次未改规范:SAME-QUEUE 对应持久原队列与确定性关联;SOURCE-FENCE 对应每次操作的新鲜来源和权限核验;CANONICAL-MEDIA 对应同一会话的完整图片输入;UNKNOWN-EFFECT 对应不盲目重发效果未知的请求。四项均在本次边界内 implemented;真实安装和模型答案质量仍单独验收,其他异步协作路线没有被宣称完成。

关键代码讲解

  1. _preparation_image_identity 从既有规范图片推导完整有序字节与元数据的 hash/count。没有新增需要人工同步的资格字段,图片内容也不传到 TypeScript 进程。
  2. _context_recovery_plan 读取准确原请求、失败或已入队 Turn 和完整规范事件,提供派生图片事实与原生结果是否存在。它不在 Python 中复制业务资格判断。
  3. planPreparationRecovery 只给准确旧版拒绝一种迁移机会;已入队的 continuation 必须匹配同一原图片。后来的失败不能切换成新图片重试预算。
  4. planRoutingRecovery 复用当前准备阶段的时钟、预算和请求身份。三事件历史格式仅在该准确图片拒绝中接受;普通授权准备失败仍要求原四事件格式,任何原生事件或不完整证明都不能授权。
  5. _recovery_source_observation 在原提供方重新核对冻结的图片 key 和 caption,再检查已存图片与规范请求一致。它不重新下载图片,也不会把图文问题替换为纯文字。原回复 worker、队列与终态回执继续处理实际执行和回传。

全量 diff 为五个文件 +239/-19,其中生产代码 +80/-19,另外159行扩展既有测试。没有新 CLI、消费者、账户策略或授权记录。

对主干的风险 / Risks

主要风险是把“没有答案”误判成“没有执行”,或者在入队回执丢失后再次执行。完整 Core 证明、原来源和图片身份、现有 source fence、确定性 client id,以及新的 crash 反例共同约束这两种风险。受影响的只是 owner-private 管家历史准备失败;普通项目、群、attached host、效果未知失败和接续后再次失败不获得此迁移资格。

PASS:同一套新 harness 在不可变 base 上复现两项原 worker 正例失败、六项拒绝反例通过,以及 typed planner 53/54;候选原 worker 八项全过,typed54项全过。PASS:相关 Python 完整回归 533 项,TypeScript typecheck、Ruff、RFC 双语 diff 与 Git diff 检查。PASS:仓库 premerge 六项 direct checks、十项选定检查,零失败和 advisory。Goal 的 change-quality receipt 策略为 disabled,没有将其冒称为已生成的质量凭据。CI policy 为 wait_for_ci=false,本次未获取、轮询或等待远端 CI。

早期本地试验暴露过 discovery backoff 和缺失 native-result 以空对象表示的读取差异;原失败日志保留,最终测试使用准确缺失语义并覆盖入队中断。没有删除反例、放宽权限或以绿色汇总掩盖当前失败。提供方与模型协议在隔离测试中为合成;已安装原服务、真实消息读回及真实回答内容尚未作为本次源码验证的既成事实。

语义与 CI 对齐

本次复用 preparation recovery,并为有证据的旧版 attachment preparation 扩展一种瞬时观测,不建立第二份 authority。旧错误文字只按完整相等解码历史格式,并与规范事件和图片证明同时成立;不是字符串子串 denylist。无 Agent 指令或强制调度义务变更,也无 default-off 声明。现有来源、停止、撤权和不重复执行规则保持在原所有者,相关语义与架构 gate 均通过。

我的整体评价 / Verdict

没有发现阻塞问题。long_horizon=improved:旧承诺能够回到已有队列,崩溃不会打开无限新预算;user_experience=improved:用户不用复制图片、另开会话或重复确认。此次为 justified_increment,实际原服务采用和历史问题清账仍保留。没有渲染布局变更,已检查原 post/回复路径,visual_review=not_applicable;本次未新增页面截图验收,也不把合成 provider 的正文断言当作真实用户已经收到答案。源码边界已可独立回滚,正常升级后还必须检查原服务自行补办与原受众独立读回。

English verdict: APPROVE — exact head 86ba27db35c4668266055fc5ab2e592c78982021; bounded original image-preflight recovery, current-source and duplicate-execution guards validated; installed delivery remains separate acceptance.

@loopx-agent
loopx-agent merged commit 9c4826d into main Nov 4, 2026
22 of 29 checks passed
@loopx-agent
loopx-agent deleted the codex/original-image-preparation-recovery-20261105 branch November 4, 2026 23:12
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