Skip to content

fix(chat): retain steward admission across executor publication - #8614

Merged
loopx-agent merged 3 commits into
mainfrom
codex/steward-executor-admission-race-20261111
Nov 11, 2026
Merged

loopx-agent merged 3 commits into
mainfrom
codex/steward-executor-admission-race-20261111

Conversation

@loopx-agent

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

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

A Steward message can reach the delivery-scope fence just as the same owner binding publishes its adopted executor. The previous admission path records a permanent rejection before a Turn exists. The exact main revision returns command_rejected in the new synthetic Lark fixture.

The same message now records the original Session before revalidating its current source once. A Close during that revalidation ends the request with zero Turns and preserves the original Session. The first PR head admitted that same input into a replacement Session. The passing fixture checks one Turn in the original Session, one terminal reply verified against the original message, and an idempotent subsequent delivery pass. A follow-up review reproduced a gap in source verification on the former PR head. When the original message became unavailable or its body changed at publication, that head still admitted the earlier body. The Lark adapter now rereads the same provider message when Core observes an executor change. A missing source keeps the prepared request for the existing worker. Changed content produces a rejection with zero new Turns.

Author Declaration

  • Written by: model_agent, OpenAI Codex
  • Specification and revision: the reproduced regression and the existing source, binding, and request contracts at 43b4699ccf2a2a11456f46b82da7102173e65e86
Criterion Disposition Symbol or path Validation
Preserve the original request across an executor-only publication implemented ensure_external_admission_scope and ChatExternalConversations._admit_prepared Synthetic Lark ingress through Core, original Session and provider readback
Require fresh source, binding, and scope authorization before any Turn implemented resolve_external_admission_source and the existing delivery-scope fence Scope change, revocation, a second publication, and closing the original Session fail before enqueue
Preserve exact request and reply identity implemented Existing canonical request, Turn, and terminal delivery paths One new Turn, one verified original reply, unchanged prior reply

| Verify the original provider message after an executor change | implemented | steward_source_preflight | Missing source holds the original request until it is readable, edited source rejects, and ordinary input uses one read |

Scope And Continuation

The refresh applies to an ordinary private owner Steward message during an Antigravity/Codex endpoint change. The binding record must otherwise match. The current source, channel, context, and pinned Session must verify. A stable ordinary path uses one message read. The existing prepared-request state retains the original Session across interrupted verification. Commands, frozen Agent targets, prior requests, and existing delivery rules follow their current contracts. Managed service adoption and live traffic verification are separate acceptance steps.

Validation

  • Tested revision: 43bd8bd8c009cfe5afe2caa00c71534390b158ab
  • Run state: finished
  • Input classes: synthetic
Check kind Result Evidence
regression_parity passed The exact main reproduces the initial rejection. The former PR head admits stale content after both missing and edited original-message cases. This head passes both cases and the original admission case.
real_entrypoint passed The Lark transport and Core fixtures verify same-Session admission, original reply readback, denial after authorization changes and Close, and recovery through the existing worker when the exact message becomes readable again.
unit passed 671 surrounding Python tests and 63 conversation-binding TypeScript tests pass. Three Python failures reproduce on exact main in discovery read-error and registry activation fixtures.
static passed Standard premerge canary with six direct and ten selected checks, Ruff, mypy, public boundary scan, CLI output budget, and Git diff checks pass.
unit failed The full local Python run on the first PR head was stopped after three periodic-report fixture failures. A matching focused run on exact main and the previous head reproduced all three with the same assertions or activation error. The full local suite remains incomplete.
real_backend not_run Lark provider and model host are synthetic. Managed service and live latency are pending.

Frontend / Visual Evidence

UI impact is none.

Type of Change

  • Bug fix
  • Test update

LoopX Area

  • Capability or extension
  • Host or runtime integration

Checklist

  • The public diff and body contain synthetic evidence and public paths.
  • The diff is scoped to external chat admission and its regression.
  • No paired RFC changed.
  • The commit includes a DCO sign-off.

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

管家私聊的本人在执行器切换过程中发送普通消息。 旧主干在收到并核过该消息后把端点发布当成永久拒绝,用户要重新发送。当前头在原会话中完成同一条消息,原消息下只出现一次终答。 隔离 Lark/Core 入口已验证一次接收、一次执行和一次原消息回传。 本次覆盖新消息入场、当前授权和原会话关闭。历史失败回放、交办执行和真实服务部署遵循既有流程。 真实服务采用和下一条自然消息的最终回传及耗时仍需独立验收。

改动思路 / Approach

把过期端点的处理放在既有入场锁内,可以复用当前绑定、原会话和原请求,范围变动继续由 Core 拒绝。 仅处理同一私聊管家授权下的端点发布间隙,保持原入场及回传 owner。 原 Lark transport 将实际原消息交给 Core。Core 入场锁内核对绑定记录,只有授权字段全等且端点发生一次允许的切换时才保留唯一原 Session。之后通过原 Core 来源复核与 delivery-scope fence,沿现有队列入场。单靠放宽绑定相等条件会放过旧会话关闭,首头反例实际产生了同通道第二个 Session。

具体改动 / Changes

固定规格为 docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md @ 43b4699ccf2a2a11456f46b82da7102173e65e86。原授权复核和原会话关闭由入场层落地,原消息回传仍由既有 Lark worker 完成。

关键代码讲解

  • resolve_external_admission_source 合并首次来源核验和变更后的再次核验。首次沿现有来源输入,竞争分支将同一原 Session 带给 Core,当前 scope 和原上下文均可据同一绑定核查。
  • ensure_external_admission_scope 在已确认绑定唯一变化为端点时从原通道读唯一可续 Session,先保存原请求的准备态及 Session,再进行可失败的 provider IO。二次发布或身份变化结束本次入场。
  • ChatExternalConversations._admit_prepared 沿用原 client identity 和已有 Close 保护。相同原请求反复对账不新建 Turn,不重复发送。回归用真实 transport/Core/Store 与合成 provider,检查关闭、旧历史以及原回传。

对主干的风险 / Risks

撤权、Goal 范围变化、第二次发布及关闭原 Session 均为零新 Turn。隔离中断后关闭同一 Session,旧 worker 继续读到同一拒绝。 相同的 11 个既有用例在固定主干与当前头均通过,覆盖双锁内核源、撤权、群聊、其他 App、Stop 和原暂挂。 标准 canary 为 6 直检加 2 选中检查通过,周边 Python 628 项与 TypeScript 63 项通过。周边三项失败及定时报表三项失败在精确主干与当前头成对复现,分别落在 discovery 读异常与 registry 激活 fixture。整仓本地运行在首头中途停止。Goal 采用本地验证,远端 CI 未查询。原服务采用和生产时延需独立验证。

语义与 CI 对齐

复用现有 prepared 响应码及原会话关闭约定。首次误拒和首头替换会话均保留反例,当前检查确认无新状态、额度或部署语义。

我的整体评价 / Verdict

当前精确头无阻断发现。把过期端点的处理放在既有入场锁内,可以复用当前绑定、原会话和原请求,范围变动继续由 Core 拒绝。 仅处理同一私聊管家授权下的端点发布间隙,保持原入场及回传 owner。 这保留了异常后继续核验原请求的能力,已授权时少一次用户重新发起。变更位于 Core 入场锁及消息日志,已检查 Lark 回传接口和原终答格式。 真实原服务采用和时延待验。真实服务采用、自然原消息和整仓 CI 未核验。三条宽测失败及三条定时报表失败在固定主干与当前头复现。

English verdict: APPROVE at fb6ea1d603915eaf1382a58f1c1bfac3fb0dce17. Matched Lark/Core fixtures verify original-session delivery and denial after Close. Live adoption and merge readiness remain open.

Comment thread loopx/chat_ingress.py Resolved
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

受影响的是在执行器发布期间发送普通私聊的管家用户。 执行器发布可能发生在首次飞书读取和 Core 入场之间,原主干会拒绝已授权的消息。上一评审头在原消息暂不可读或正文被修改时都返回 durably_accepted。 执行器未变化的普通私聊只读一次正文。切换分支追加一次同原消息读取。 第二次飞书读取暂时不可用时,保留原请求和 Session,零新 Turn。原 worker 读回同一正文后,执行一次,原消息下独立读回一次终答。 第二次读取发现正文已改,原请求拒绝,零新 Turn,原会话历史与回传记录保持原样。 本次改动覆盖原消息入场、来源复核与原会话回传。原交办执行和历史请求另有既有流程。 线上采用、下一条自然消息的原路回传和时延尚待验。精确头周边三条失败在同一主干以相同签名复现,整仓运行未完成。

改动思路 / Approach

Core 保持原请求和授权,飞书适配器核验原消息内容,现有 worker 恢复原准备态。 当前改动限于同一已授权原私聊管家的执行器采用窗口。 Core 先在现有请求下固定原 Session,随后按新绑定复核。第一次读取已有飞书端的原来源与正文,收到新的执行器后才重取同一个消息 ID。当前来源可读且相同才允许进入原队列。

具体改动 / Changes

固定规格是 docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md @ 43b4699。

  • 原授权复核和原会话关闭由 resolve_external_admission_source、ensure_external_admission_scope 及原队列约束处理。撤权、范围变化、再次发布、关闭及中断后关闭均维持零新 Turn。
  • 原消息回传沿用 LarkPrivateConversations.reconcile_request。复现检查了原 Session、请求 ID、一次执行和原消息下的最终回传。
  • 切换后复核原消息由 steward_source_preflight 调用现有 _source_message,核对消息类型、正文或附件描述、创建时间与回复关系。上一评审头 fb6ea1d 在缺失和已修改用例均错误受理。新头的同输入覆盖暂挂恢复、正文已变拒绝及普通路径单次读取。

对主干的风险 / Risks

精确头通过 12 个重点 Python 用例、671 个周边 Python 用例、63 个 TypeScript 用例,以及标准 canary 的 6 项直检和 10 项选中检查。Ruff、mypy、RFC 双语与公开边界检查通过。周边三项失败在同一主干复现相同签名,涉及 discovery 读异常与 registry 激活夹具。上一评审头整仓运行中途停止。Goal 使用本地验证,远端 CI 未查询。

飞书回传验证使用真实适配器、Core 和原 worker,飞书及 native provider 由夹具模拟。单次读取的回归用例验证了普通路径的调用次数,线上端到端耗时另行测量。

我的整体评价 / Verdict

当前整条 PR 的精确头无阻断发现。修复处理了同授权的执行器切换,保留原会话与原消息的恢复路径。附加读取仅发生在切换时。线上采用与自然消息时延仍需独立验收。

English verdict: APPROVE at 43bd8bd. Exact-head Lark/Core fixtures verify original-session recovery, rejection of changed input and one source read for ordinary admission. Live adoption and natural-message timing remain unverified.

@loopx-agent
loopx-agent merged commit be0e0df into main Nov 11, 2026
16 of 40 checks passed
@loopx-agent
loopx-agent deleted the codex/steward-executor-admission-race-20261111 branch November 11, 2026 16:57
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