Skip to content

fix(chat): preserve steward input during bounded transport recovery - #6257

Merged
huangruiteng merged 1 commit into
mainfrom
codex/chat-steward-retry-input-20261011
Oct 11, 2026
Merged

huangruiteng merged 1 commit into
mainfrom
codex/chat-steward-retry-input-20261011

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

A steward request that encountered an effect-free transport failure collected a new manager snapshot on retry. Its regenerated snapshot ID and timestamp changed the complete model input, even though the original user message and session were unchanged.

Preserve the original serialized evidence text in the existing per-request retry binding. Each attempt still rechecks the current authority, audience, configuration and stop fences, and the next user request collects fresh evidence. The module line ceiling moves from 2,128 to 2,130; Any and dict[Any] counts do not increase.

Validation:

  • 160 related tests passed across turn steering, Lark private conversations, native steward runtime/privacy and manager team guidance. The new cases cover both steward profiles, exact retry input equality, fresh context on the next request, and grant/scope changes stopping recovery.
  • Native premerge validation passed: 5 direct checks and 13 selected checks. Ruff, diff hygiene and the semantic advisory passed.
  • Four additional cases passed using a real Codex app-server and an installed Python 3.12 wheel: ordinary assistant and trusted owner steward, each recovering from a synthetic 503 or exhausting its bounded retry. Native turn/start parameters remain identical and no second user request is admitted.

The provider and message transport in the native probe are synthetic. This is package/runtime qualification; the daily services have not adopted this revision, and no failed live request was replayed.

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=xhigh

Approval conclusion (author-owned PR; GitHub blocks formal self-approval): APPROVE, recorded as COMMENTED. 精确 head e8964ca9b2c6ad629c0eaa88582537112fcbbd98。

动机

使用本地助手聊天、遇到一次可恢复传输故障的用户。

用户发出一个请求后,上游连接中断;旧版重试重新收集助手上下文,时间和快照标识变化使同一请求的模型输入也变化。修复后,同一请求的安全重试使用首次输入,下一条新请求重新读取证据,用户无需重复输入。

独立真实聊天运行时及隔离安装包均保持两次尝试的完整 turn/start 参数一致;下一请求读取新上下文。重试耗尽、已有工具活动、授权或范围变化、停止都按原边界终止,不重复执行。

本批完成现有 Codex 传输恢复中的请求输入稳定性;不新增重试次数、后台执行或授权,也不声称在线模型理解、生产采用或整条助手路线图已经验收。

改动思路

复用现有每请求 retry_binding,缓存首次序列化输入,同时每次继续新鲜的范围和权限检查,是最小完整修复。只放松身份校验会掩盖输入变化;持久化第二份上下文或另建重试框架会增加状态与回放成本。

当前 PR 一起交付首次输入缓存、首次 sha256 尚未建立时的正确分支、下一请求刷新和授权变化反例,保留原有单次恢复及持久事件 owner。

具体改动

spec_ref:docs/reference/protocols/manager-evidence-and-continuity-v0.md;spec_revision:c51ec1a60671edb8ef536ef0651836b9d7642878。同时采用变更前 accepted app-conversation recovery 合同;首次证据来源新鲜不代表重试可以改写原请求身份。

  • same-request-stable-input:implemented;A safe retry of one accepted request preserves the original user and evidence payload.
  • live-authority-before-dispatch:implemented;Fresh authorization, coverage and stop checks precede every provider dispatch; changed grants/scope reject recovery.
  • bounded-no-duplicate-effects:implemented;Only complete text-only eligible failure can retry once; tool activity, unknown outcomes or exhausted recovery stop.
  • new-request-fresh-evidence:implemented;A later user request collects new authorized Core evidence rather than replaying the previous cache.

关键代码讲解

  • _run_turn 的局部 retry_binding 原本已绑定一次请求;现在缓存首次 context 序列化结果,不增加磁盘字段或跨请求缓存。
  • _run_started_turn 仍先调用 prepare_turn_context、校验当前授权和停止状态,再向原请求消息附加首次证据。sha256 的判断改为检查该 key 是否存在,避免首次只含 context 时错误索引。
  • _transport_retry_binding 继续绑定 session、模型、权限 profile、管理范围、资源分配和 grants;_prepare_transport_retry 仍要求完整终态、无工具活动、原 claim 有效,预留一次恢复并在等待后再检查。
  • 新回归覆盖 restricted/trusted-owner 的完整输入相等、下一请求刷新及 grant/scope 变化;独立反例另覆盖耗尽、工具活动、stop 和普通项目。
  • 模块行数预算从 2128 调到 2130,Any 计数仍为 36,dict[Any] 仍为 0。增加的两行保存不可从新快照重新推导的原请求输入;删除这个信息会丢失验收不变量。维护预算和质量测试 16 项通过,未修改硬限额或实验标准。

对主干的风险

62 项聊天、普通项目、私有助手及运行时 pytest、16 项维护预算/质量检查、公共 chat-runtime smoke、Ruff、diff、语义与 IO manifest 检查通过。冻结独立 oracle:base 5 通过、4 个输入稳定性用例失败;exact head 与隔离 wheel 各 9/9 通过。

本评审使用真实 Core、磁盘聊天状态、HTTP/stdio 边界及可控失败的合成上游;未调用付费模型。DeepSeek harness 公共 smoke 因 SDK 未安装而跳过,不能计为通过;该 prompt-only 分支未改变且不进入本次 Codex 自动重试。前端没有视觉修改,验证现有请求、停止及结果事件路径,未新增 UI 截图或生产安装。

正常构建前端 chat assets 后打包,安装到隔离环境,在 checkout 外用 python -I 验证模块来源和实际调用;未绕过包装要求。语义 advisory 未检测到支持的新词汇载体;完整语义 smoke 通过但45个 unresolved producer sites仍保留,不能宣称全树语义已证明。IO manifest291站点检查通过。相邻 #6254 的当前公开代码范围是浏览器 steering envelope;此次复核了共享请求身份与 stop 边界,没有借用其结论。 作者声明与本评审独立证据分开,CI未查询、轮询或等待。

我的整体评价

未发现这一有界修复的阻塞问题。复用现有每请求 retry_binding,缓存首次序列化输入,同时每次继续新鲜的范围和权限检查,是最小完整修复。只放松身份校验会掩盖输入变化;持久化第二份上下文或另建重试框架会增加状态与回放成本。 当前 PR 一起交付首次输入缓存、首次 sha256 尚未建立时的正确分支、下一请求刷新和授权变化反例,保留原有单次恢复及持久事件 owner。 未来维护整理已检查:缓存与 hash 沿用同一局部绑定,无需新持久字段、serializer 或另一重试 owner。 用户的现有操作路径没有增加输入、确认或授权步骤,失败与下一次工作仍能诚实回读。阶段恢复经验仅作提示,不继承历史 approval,不宣布母路线图完成、生产采用或合并就绪。

English verdict: APPROVE - exact head e8964ca. Original steward retry input stays stable while live authority fences and later-request freshness remain.

@loopx-agent

Copy link
Copy Markdown
Collaborator Author

Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=xhigh

English verdict: APPROVE - exact head e8964ca. Original steward retry input stays stable while live authority fences and later-request freshness remain.

Motivation

A local steward user submits a request and encounters one eligible upstream transport failure. The old recovery recollects Core context and changes timestamp/snapshot data in the native input for that same request. The candidate preserves the first authorized serialized input, then refreshes evidence for the next distinct request. The user need not repeat the message. Restricted and trusted-owner steward requests fail once with complete native terminal readback, recover with identical whole turn/start params, then a new request collects different fresh evidence. Ordinary-project actual HTTP recovery remains isolated from portfolio collection. The scope is this existing bounded repair; it does not certify parent roadmap completion, production adoption or new authority.

Approach and ownership

The existing per-request retry_binding is the nearest owner. The new context key is ephemeral original-input information, which a later snapshot cannot reconstruct. Fresh collection still precedes each authority/hash/stop fence. Checking presence of sha256 allows first dispatch when only context has been populated. No extra retry, persisted state, grant or parallel typed decision owner is added. The current PR boundary is original input binding, first hash initialization, next-request freshness and retained live authority with the existing bounded recovery.

Specification and code walkthrough

spec_ref: docs/reference/protocols/manager-evidence-and-continuity-v0.md; spec_revision: c51ec1a60671edb8ef536ef0651836b9d7642878. The accepted pre-change app-conversation and manager continuity contracts require current authority and stable accepted request identity.

  • same-request-stable-input: implemented; A safe retry of one accepted request preserves the original user and evidence payload.
  • live-authority-before-dispatch: implemented; Fresh authorization, coverage and stop checks precede every provider dispatch; changed grants/scope reject recovery.
  • bounded-no-duplicate-effects: implemented; Only complete text-only eligible failure can retry once; tool activity, unknown outcomes or exhausted recovery stop.
  • new-request-fresh-evidence: implemented; A later user request collects new authorized Core evidence rather than replaying the previous cache.

The worker owns one local dict; _run_started_turn binds evidence but continues fresh scoped collection. _transport_retry_binding still includes session, model/profile, manager/allocation/grants. _prepare_transport_retry still requires complete text-only terminal/item readback, a valid claim, one durable reservation and a second fence after backoff. Tests cover both profiles, the next request, changed grant and scope; independent probes also cover exhaustion, tool activity, stop and ordinary-project HTTP recovery.

Positive walkthrough: Restricted and trusted-owner steward requests fail once with complete native terminal readback, recover with identical whole turn/start params, then a new request collects different fresh evidence. Ordinary-project actual HTTP recovery remains isolated from portfolio collection.

Negative walkthrough: Second transport failure ends after two attempts; any commandExecution item prevents retry. Grant/profile or scope changes before recovery prevent a second dispatch. Stop during backoff ends interrupted with one dispatch.

Validation and risks to main

62 focused chat/steward/runtime tests,16 maintainability/quality tests, the public chat-runtime smoke,Ruff,diff checks, semantic smoke and291-site IO manifest passed. A frozen independent oracle checks entire native params, not only message strings: immutable base passes5 controls and fails4 stable-input cases; exact head and separately installed wheel each pass9/9. Future-subject/pagination readback was exercised in the existing150-registration steward test. The2128->2130 module regression budget buys two useful binding lines;Any36 anddict[Any]0 are unchanged, and no hard authority limit was relaxed. Normal chat asset build and ordinary wheel packaging preceded isolated installation. Outside-checkout python -I module provenance was verified; runtime/database/filesystem paths were not success mocks. The semantic advisory found no supported new vocabulary carrier, but45 unresolved producer sites remain after the full passing semantic smoke.

Real Core and disk chat state are exercised through controlled synthetic HTTP/stdio upstream failures. Paid-model comprehension/production adoption are unverified. The optional DeepSeek SDK smoke was skipped because the SDK is absent; this unchanged prompt-only branch does not enter the modified Codex recovery. Existing composer/stop/result consumers were inspected; there is no changed viewport, no new configuration journey and no claimed rendered UI qualification. PR6254 has a separate browser steering envelope boundary; no approval was inherited.

Overall assessment

APPROVE for the exact head, with no identified blocker in this bounded slice. Sustained recovery/next-operation and truthful failure/readback are preserved without extra user input or approval steps. The future-facing pass found the existing per-request dict/hash and typed eligibility owner sufficient; no speculative helper or protocol is needed. Current repository experience was advisory and independently checked, not inherited proof. GitHub blocks formal self-approval on this author-owned PR; the public COMMENTED review records this approval conclusion.

@huangruiteng
huangruiteng merged commit edfe389 into main Oct 11, 2026
4 of 5 checks passed
@huangruiteng
huangruiteng deleted the codex/chat-steward-retry-input-20261011 branch October 11, 2026 19:21
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.

2 participants