Skip to content

feat(operations): separate source context from admitted managed execution - #5327

Open
huangruiteng wants to merge 12 commits into
mainfrom
codex/confirmed-agent-handoff-0930
Open

huangruiteng wants to merge 12 commits into
mainfrom
codex/confirmed-agent-handoff-0930

Conversation

@huangruiteng

@huangruiteng huangruiteng commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Summary / 摘要

Separate source conversation from admitted executor. A registered conversation remains context/return routing; an explicitly opted-in managed delegation / turn run-once can own a native app-server connection and consume exact human authorization once. Codex Desktop native integration is no longer a prerequisite for this new execution kind, and an attached Desktop session is never silently resumed or impersonated.

将来源会话与准入执行者分开:来源会话保留上下文与回传关联,显式启用的 managed delegation / Turn 通过自己持有的 native app-server 连接接手精确批准。不再把 Desktop 原生接入当作新执行路线的前置条件,也不冒充或导入来源会话。

This remains an opt-in, uninstalled protocol delivery, not a completed financial minimum loop. Genuine human approval, domain execution and original-group result readback are still unqualified. Core maintainer review is required; no self-merge or global installation has occurred.

当前仍是显式启用、未安装的协议交付,不宣称真实投研闭环完成。真人精确批准、领域执行和原群结果读回仍待验收,Core PR 留给维护者审核,未自合并或安装本机运行时。

Architecture / 架构

  • One TypeScript owner validates immutable operation terms, managed Goal/Agent/Todo/session/profile bindings, one-shot consumption, evidence-only replacement recovery and append-only unknown-result reconciliation. Python owns existing storage locks, subprocess/native wire IO and Lark transport; it is not another decision source.
  • New managed-turn-handoff-v0 and app-server-operation-tools-v0 are explicit opt-in via --codex-operation-tools, with pinned model/reasoning effort and a restricted sandbox. Default plain Codex execution and extension/simulator behavior remain unchanged. Unsupported hosts, profile drift, unpinned configuration and plain-CLI resume of an operation-equipped session fail closed.
  • The existing Turn session owner persists transport/profile metadata; there is no second scheduler, credential directory, approval store or runtime discovery source. Native tool identity comes from the owned connection's active thread/Turn dispatch metadata, never model arguments, environment IDs or CLI route flags. Dynamic actions are context, pending, prepare, inspect, consume and report.
  • The public attached-session inspect/consume/report-operation path remains blocked with operation_host_authentication_unavailable. Old agent-session-handoff-v0 approvals do not migrate into the managed kind; changing execution kind/profile requires explicit configuration and a fresh exact approval.
  • Existing Goal-lifetime → registry → deterministically ordered original/recovery session owners → action-store locks cover binding validation and canonical commit. Locks do not span venue effects. Only the first committed consumption returns execution permission; lost responses, retries, replacement sessions and unknown outcomes never re-grant it.
  • Native and manager Inbox discovery use the same canonical operation projection and lifecycle owner: bounded recovery-first pages, independent scoped cursors and explicit overflow. Native discovery also checks current Agent registration and exact Goal-instance scope; stopping execution preserves historical reconciliation visibility, without allowing new consumption.
  • Lark callbacks only authenticate exact human confirmation and claim the canonical request; they do not launch a host or perform a financial effect. Initial outcome and later reconciliation have distinct result-card delivery stages, so old delivery cannot certify a new result.
  • Shared Dashboard details distinguish confirmed / consumption pending, consumed / outcome pending, unknown, and reconciled. The existing Team execution preflight displays transport configuration readback, runtime-unqualified status and exact-confirmation/first-consumption requirements. It does not create a configuration owner or approval button; host arguments stay in the original private delegation binding file.
  • Bilingual RFC/roadmap now define source-context versus execution lineage, owned-native qualification, evidence-only recovery, partial maturity and remaining real-world acceptance. Immediate notification remains separate: host_delivery: not_attempted is not relabeled as successful delivery.

中文要点:保留唯一 TS 权威、原 Turn session / Inbox / typed-action 存储;新路线需要显式配置与新批准,不偷换旧批准。确认、首次消费、真实执行、结果证据和消息投递分别记账。UI 复用原共享投影,展示“配置有效不等于运行已验收、确认不等于已执行”,不另造配置源。

Validation / 验证

  • Rebased onto current main (3ec049e): 285 Python tests passed, 1 intentionally skipped live qualifier. This includes operation/Lark/host, delegation, managed binding, Inbox pagination/receipt recovery and independent delegation validation. After the final native-discovery repair, 43 targeted Python tests passed, 1 intentional live skip; the new regression covers valid non-empty pending discovery, stopped historical visibility, exact-instance isolation and registration withdrawal.
  • 39 TypeScript tests passed, including shared operation admission/projection, action-review rendering, delegation and the current Inbox receipt owner. Control-plane typecheck, changed-Python Ruff, syntax/diff checks and the original registry-I/O manifest check (260 sites) passed.
  • The separately enabled real, non-financial Codex app-server qualification passed: native context returned on the owned connection, and resume kept the same thread with a distinct active Turn; both final responses passed the existing typed Turn-result validator. This did not create an operation/card, consume a real human approval, send a message or perform a domain effect. Fake-process CLI qualification additionally proves turn run-once dry-run has no session effect and execution cannot fall back to plain Codex CLI; process descendants are reaped on success and timeout.
  • Standard premerge canary at final head 0de8e96d55e11cd94491a1a6b63d26ed17b4938c: 19/19 checks and all 5 direct checks passed, including the formerly timing-out vocabulary check. No timeout, output/assertion ceiling or required evidence label was relaxed; the earlier failing head's receipts are not reused as this result.
  • Packaged frontend build passed (existing large-chunk advisory retained). Backend-generated canonical synthetic states passed 16 Chinese/English × desktop/mobile operation readback cases; there are no fabricated live channels or frontend approval controls. The existing packaged delegation-preflight browser smoke also passed Chinese/English desktop/mobile checks against the shared transport/preflight projection. Changed screens were visually inspected.
  • Whole-branch privacy/DCO/author+committer inspection uses the verified GitHub noreply identity. Local registries, logs, screenshots, account material and private state remain excluded. Review follows the Goal's wait_for_ci=false; no remote CI fetch/poll/wait is used.

Remaining gates / 剩余门禁

  1. Not the real financial loop yet. After maintainer review/merge, the original configuration owner must explicitly adopt the new managed route and read back its pinned runtime/profile. A real exact approval must then be consumed on that connection, with independently verified domain outcome and original-group result readback. Synthetic approval fixtures and a native context call cannot substitute for these steps.
  2. Existing attached Desktop execution remains unavailable unless that host separately integrates its trusted native connection; this does not block the new explicitly selected managed route. No cross-home rollout/SQLite copying, self-signing proof or ambient identity fallback is introduced.
  3. Immediate host wakeup, automatic source-conversation delivery and any domain adapter access retain their existing owners and separate authorization. This PR does not grant orders, signatures, transfers, account reads or new external messaging authority.
  4. Lifecycle-only source_session_v1 still does not prepare business operations. No registry bypass or fabricated acceptance is added. Core self-merge/install is not authorized by finance-repository standing permission.

中文剩余事项:维护者审核合入后,再由原配置 owner 接入并真实读回;随后完成真人批准 → 首次消费 → 领域证据 → 原群结果的逐段验收。仍未合并、安装或证明收益闭环,不以协议/页面测试代替业务证据。

@huangruiteng huangruiteng 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.

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

评审提交:520c683b60f9dafd6bae98afe04ae5d1392d12c0。以下问题基于原始注册表和动作存储的隔离合成实例复现;未向真实群或外部执行端发起操作。

  1. [P1] 消费者身份由调用者自报,无法保证授权只交给原 Agent 会话。 run_goal_channel_operation 把命令行传入的 Goal、Agent、host、thread 原样构成 actor;后续只比较这些字段与提案及注册表。一个没有原会话证明的独立本地进程,填入原路由字段后,实际收到了 execution_allowed: true 和新的消费 ID。这是已确认请求的一次性执行权,其他能访问该本地 CLI 和运行时的进程可以抢先消费,原 Agent 随后只能看到已消费。请让受信任的宿主/会话边界提供不可由命令参数伪造的调用者身份,并在授予执行权前核验;增加“另一会话填入原路由字段被拒、原会话成功”的真实 CLI 反例。
  2. [P1] 绑定撤销与消费提交之间存在检查时序窗口。 agent_operation_action 先将 _binding() 读到的布尔值传入动作存储,再由另一把锁提交消费;线程绑定变更使用注册表事务,不受这一快照保护。隔离测试在两步之间解除原线程绑定后,消费仍返回 execution_allowed: true,提交后的注册表已显示 missing。请将绑定核验和一次性消费置于协调的原子边界,或使撤销与消费持有同一生命周期锁;用确定性交错测试证明撤销先完成时不能再授予执行权,同时保留过期/解绑后只读对账。
  3. [P2] 超过 20 条时,后续未完成操作仍可能失去可发现入口。 projectAgentOperationInbox 只给前 20 条、总数和第 21 条 ID;manager-inbox 的 next_cursor 仅分页普通 items,不移动 operation_handoffs。若前 20 条长期处于未知结果,至少第 22 条既不在页内也没有可传给 inspect-operation 的 ID。请为操作列表提供独立游标或可完整枚举的稳定定位页;测试超过 21 条且前 20 条不终结时,逐页找回每一条。

动机

当前已确认的 operation.execute 由飞书回调处理,原 Agent 没有可消费的规范确认与结果回写链路。此 PR 想把确认留在原动作存储,并经既有 Inbox 让原会话继续其领域工作流;其有用增量是避免回调进程假装执行或重复提交。即时宿主唤醒和真实外部执行验收明确留在后续,因此本次应按“原会话可安全接手的一段协议”判断。现在跨进程冒领和解绑时序反例使“只由原会话接手”尚未成立;20 条后的持续恢复路径也不完整。

改动思路

实现复用既有 operation.execute 提案及 Lark 认证点击:TypeScript 判断不可变请求、确认、claim、路由与消费/对账转换;Python 只负责注册表读取、规范动作存储的加锁提交和 CLI 桥接;Inbox 从同一存储投影,卡片与 Dashboard 从共享操作 frame 展示状态。首次消费先持久化,再返回一次执行许可,丢失响应后的重试只可对账,这是正确的保守方向。agent_handoff 是一次性消费事实,reconciliation 保留原 unknown 结果并追加终态,投递阶段是读回收据。现有 extension 模拟路径保留,不应因 Agent 方案新增第二套审批或领域订单决策源。

具体改动

chat_action_normalization.py 在预览时验证 agent_session 执行器、注册线程和 Goal,并拒绝把真实 handoff 标为模拟;operation_agent_handoff.ts 给出消费、回报、恢复优先级和 20 条注意力页的类型化决定;chat_action_store.py 在文件锁下写入 agent_handoff、原结果及追加对账;operation_handoff.py 接入原注册表和 Inbox。goal_channel_operation.py 新增 inspect/consume/report,非 --execute 路径只读。Lark 回调只留下 claimed 状态并更新原卡,后台结果恢复补送 unknown/终态;action_review_plan.ts、工作区抽屉、双语文案及样式把待原 Agent、已消费、未知和已对账分开显示。两份 RFC 更新了边界,Python/TypeScript/前端测试覆盖正常与若干失败路径。

关键代码讲解

  • planAgentOperationHandoff 比对 payload/projection/confirmation digests、claim、原路由与结果身份,重复消费不再授予执行权;它无法认证传入 actor 的来源。
  • ChatActionStore.consume_agent_operation 在动作文件锁内写入消费事实;传给它的 binding_current 是此前采集的快照。
  • pending_operation_handoffs 从原始提案生成恢复项;projectAgentOperationInbox 排序并截为 20 条,但溢出只提供一个后续 ID。
  • compileOperationReviewFrame 将原始 unknown、追加 reconciliation 和投递阶段投影给 Dashboard/Lark,共享结果语义,仍须以原外部证据判断真实效果。

对主干的风险

最严重的风险不是重复点击,而是一次性的执行许可被错误进程或已经解绑的会话取走;一次消费后不会重新发放,所以错误接手还会让原 Agent 无法继续。当前 52 个 Python 测试、13 个 TypeScript 测试及工作区契约 smoke 在此提交通过,证明已有回调、存储与展示样例可运行,但现有测试把 actor 作为受信输入,也未让解绑和提交交错。另一个长期风险是恢复项积压时第 22 条及以后不可枚举。未独立重跑打包页面的视觉验证,也未做真实群点击或外部执行;这些不能由合成卡片替代。按本 Goal 的 wait_for_ci=false 评审契约,没有查询远端 CI。

语义与 CI 对齐

本次沿用原 typed-action 词汇并新增明确 opt-in 的 agent-session-handoff-v0;默认 extension 执行路径的相关基础测试在 base/head 均通过。但当前 RFC 第 13 节要求“原注册 Agent/会话的一次性消费”和溢出定位,上述三个反例尚未满足。修复后请重跑真实 CLI 身份反例、撤销/消费交错和 22 条不终结恢复项分页,再复跑现有 Python、TypeScript 与打包工作区验证。

我的整体评价

将确认、消费与结果对账归于原动作存储,且区分回调 ACK、卡片读回与外部效果,方向合理;跨 CLI、Lark、Dashboard 和双语文档的范围也与所选交付片段相称。长周期恢复目前会被溢出页阻断,用户路径则可能将确认交给错误会话,故不能把当前精确提交判为可交付。先修复这三处并以同一原始入口重验;即时唤醒和真实外部验收仍按 PR 声明的后续边界处理。

English verdict: REQUEST_CHANGES - 520c683; a separate local process can claim the original session's one-shot execution permission, a concurrent unbind can precede consumption, and overflow cannot enumerate all pending operations. Focused Python/TypeScript/workspace contract tests passed; live execution and packaged visual readback were not independently verified.

@huangruiteng

Copy link
Copy Markdown
Collaborator Author

Revision follow-up / 修复进展(不是评审批准)

Current head: 9a8cc6b5f72aa18f3e2045b5c719d42855d0c889. The REQUEST_CHANGES review at 520c683 remains evidence of that previous head's defects; it is not approval of this revision. Please re-evaluate the changed boundary at this exact head.

  1. CLI identifiers no longer replace the host's ambient thread context. Inspect/consume/report reject absent or foreign context before reading operation parameters or writing consumption; inspect also checks the original route. A real CLI probe with exact route flags and foreign ambient context obtained permission at 520c683, but now exits with operation_handoff_conflict and leaves canonical bytes unchanged. This is a trusted-local-runtime fence, not authentication against hostile same-user processes that can forge environment variables or rewrite canonical files. The bilingual RFC and PR description explicitly retain that limitation; this review must decide whether it is sufficient for the bounded continuation slice. No cryptographic session-isolation claim is made.
  2. Consumption now holds the registry writer's existing lock from activation/registration/binding read through action-store commit. Order is Goal lifetime → registry → action store. The new deterministic interleaving regression uses the real unbind transaction: revocation waits behind an already-locked consumption, and after revocation commits no further permission is granted. This regression fails against the previous source revision and passes here. Evidence-only reconciliation remains possible after unbinding; the lock does not fence later external effects.
  3. Operation attention has an independent scope-bound cursor. manager-inbox read --operation-cursor can enumerate the remaining operations without closing the first 20 unknown results. The regression persists 22 real canonical synthetic proposals/confirmations/unknown outcomes and reads the next page through the real CLI; all 22 are recovered, the canonical store remains unchanged, and foreign-scope cursors are rejected. Restarting without a cursor is still required to discover newly inserted or changed work.

Validation: 195 Python tests across operation/CLI/manager/host plus existing Goal-instance, thread-binding and registry-codec coverage; 14 TypeScript tests; control-plane typecheck; Ruff/diff checks; action-review transport and workspace contract smoke; packaged Chat build. Existing extension-mode public observations match base/head after generated-ID/time normalization. No CI queries were made (wait_for_ci=false). No live group click, browser execution, order/signature/transfer, installation or resident-consumer reload was performed.

中文摘要:本轮修复自报路由可跨会话误用、绑定撤销时序窗口和超容量操作无法完整定位的问题;但宿主环境核对仅限可信本机边界,不能冒充恶意进程隔离。新 head 尚未批准、合并或安装;真实群确认与原 Agent 外部验收仍未发生。待新 head 的身份边界与其余证据获准后,才进入安装及原配置 owner/常驻消费者读回。

@huangruiteng huangruiteng 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.

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

评审提交:9a8cc6b5f72aa18f3e2045b5c719d42855d0c889。这是对整个 PR 的新头复审;上一提交的结论没有沿用。下列反例使用隔离的合成注册表与规范动作存储,没有真实群确认或外部执行。

  1. [P1] CODEX_THREAD_ID 仍可由调用进程自报,不能证明消费方是原 Agent 会话。 新的 deriveAgentOperationActor 比较命令参数与 os.environ,因此缺失或不同的环境线程会被拒,这一点已在真实 CLI 验证。但另一个独立本地进程只需给自己的 CODEX_THREAD_ID 设为原线程 ID,再提交同一组路由参数,就得到 execution_allowed: true 并消费唯一许可;规范存储随之改变。无需改写规范文件。PR 已披露“不隔离恶意同用户进程”,但这也是普通同用户多 Agent 运行时可使用的命令入口;披露不能把自报环境变成宿主认证。请从受信任的宿主调用边界取得不可由该 CLI 进程重设的会话身份,或将协议与交付结论明确降为不保证原会话独占、且不授予其专属执行权的较窄契约,并由所有者接受该取舍。回归应让另一个会话即使设置原路由参数和环境变量也不能消费,而原会话可以。
  2. [P1] 解绑后的恢复义务可见,却无法由接手会话通过公开 CLI 对账。 pending_operation_handoffs 在原绑定失效后仍把 unknown 结果显示给同一 Agent 的 Inbox,这是正确的;但 run_goal_channel_operation 对 inspect/report 也强制环境线程等于原 route,TS 又要求 actor 与原 route 完全相等。隔离的真实 CLI 复现:原会话先消费并报告 submission_unknown,随后注册表改绑新线程;新线程的 manager-inbox read 能看到 binding_current: false 的 unknown 项,但 report 时用原线程参数或新线程参数都返回 operation_handoff_conflict,reconciliation 仍为空。若原线程已经不可用,不能完成 PR/RFC 声称的解绑后对账。请给历史证据建立明确的只读/报告恢复权限与接手 owner,保持 consume 永远不能重新授权;用公开 CLI 测试“新会话可见 → 核对原证据 → 追加 reconciliation → 原卡片读回”,同时拒绝再次提交。

动机

本 PR 要让飞书群里经认证的精确确认回到最初注册的 Agent 工作流,而不是让回调进程运行模拟器或浏览器。这个方向能复用该 Agent 原有的领域验证、外部执行与结果证据,并把确认、消费和对账留在唯一的规范操作记录中。即时宿主唤醒与真实外部验收已明确分期,不要求本 PR 冒充已完成交易。当前新头修复了上一轮的注册表撤销窗口和 20 条注意力页丢失问题,但原会话独占仍靠可重设的环境字段;会话更换后的 unknown 恢复也停在“可见但不可操作”,影响持续推进与用户对状态的理解。

改动思路

operation.execute 保留原 typed-action 存储与 Lark 认证点击;TypeScript 决定不可变绑定、一次消费、结果约束与 Inbox 排序,Python 负责原注册表、动作文件加锁和 CLI/Lark 接线。新提交用 Goal 生命周期锁 → 注册表写锁 → 动作存储锁覆盖绑定读取与消费提交,撤销先提交便阻止消费;独立 operation-cursor 则从同一规范记录逐页定位恢复项。这两处修复是有真实调用者的局部改进。结果回写应与执行许可分开:旧会话失效时,接手者仍须能在明确、受限的证据权限下结清原 unknown,而不能获得第二次执行许可。宿主会话证明也应由宿主提供,不能由命令自身填充。

具体改动

预览时的 chat_action_normalization.py 核对注册路由与非模拟投影;operation_agent_handoff.ts 定义 actor、消费、回报及独立操作游标;chat_action_store.py 在原动作记录里写入一次性 agent_handoff、unknown outcome 与追加 reconciliation。operation_handoff.py 将它们投到 manager Inbox,goal_channel_operation.py 新增 inspect/consume/report 并接入环境线程核对。Lark 回调对 Agent 执行器只确认/认领,不运行外部效果;结果恢复继续更新原卡片。共享 action_review_plan.ts、工作区抽屉、英中文案与样式区分待接手、已消费、结果未知和已对账;双语 RFC 与 Python/TypeScript 测试记录了分期边界。

关键代码讲解

  • deriveAgentOperationActor 阻止参数与当前环境线程不一致,却不能验证这个环境字段确实由原宿主会话提供。
  • collaboration_goal_scope(lock_registry=True) 与 consume_agent_operation 协调绑定与一次性消费;确定性交错测试现已证明撤销不能插入两者之间。
  • projectAgentOperationInbox 为恢复优先的列表生成独立、带范围的游标;真实 22 条规范操作可以分两页全部读出,普通 Inbox 游标不再冒充它。
  • agent_operation_action 对报告保留原 route 身份,即使不要求当前绑定;公开 CLI 的新环境核对使接手会话无法使用这个历史报告能力。
  • compileOperationReviewFrame 和 Lark 原卡共享 unknown/终态及投递阶段,读回仍不能替代真实外部证据。

对主干的风险

最重的风险是一份真人确认的一次性许可被另一个同用户进程拿走,或原 Agent 消失后 unknown 结果长期无法结清。这两种情形不会因重复点击而自愈:前者许可不可重发,后者不得盲目重提。独立验证中,缺失/异会话宿主环境的 CLI 请求都拒绝且存储不变,主动设置原环境 ID 则成功消费;新会话能读到改绑后的 unknown,但两种 report 参数均被拒。此前的撤销窗口已被共享锁关闭,22 条积压可由 --operation-cursor 找全。当前提交的 185 个相关 Python 用例、14 个 TypeScript 用例、工作区契约 smoke 和 diff check 通过;我没有独立完成打包页面视觉复查、真实群点击或外部执行。按评审配置 wait_for_ci=false,未查询远端 CI。

语义与 CI 对齐

本实现明确 opt-in 的 agent-session-handoff-v0,原 extension 模拟路径仍保留,未发现默认开启的权限扩张。新头对撤销与分页的修复符合 RFC 第 13 节;但“原注册会话接手”和“改绑后可对账”的当前义务仍有上述反例。修复后请重跑跨会话真实 CLI 消费测试、改绑后公开 CLI 对账与原卡片读回,并保留现有撤销交错、22 条分页、回调非执行和打包工作区测试。合成 fixture 不能证明真实 Lark 或外部系统执行。

我的整体评价

规范状态单一、回调不代替 Agent 执行、unknown 不重提,以及撤销和溢出页的本轮修复都值得保留,跨 CLI/Lark/Dashboard 的范围也与这一协议切片相称。新头比上一版实质进步,但用户从“确认”到“原会话执行”,以及会话更换后的长期恢复仍未闭合,所以当前精确提交仍需修改。可信本机假设可以作为明示的部署边界;它不能证明一个可由调用进程设置的线程环境就是原会话身份。

English verdict: REQUEST_CHANGES - 9a8cc6b; foreign ambient context is rejected and the revocation/pagination fixes hold, but self-set ambient context still spends the one-shot grant, and a replacement session can see an unknown result but cannot reconcile it through the public CLI. Focused Python/TypeScript/workspace tests passed; packaged visual and live external acceptance remain unverified here.

@huangruiteng

huangruiteng commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator Author

Implementation follow-up at exact head 2004204ff93cdc99a06ba533d1ee0a57c7ceec3c; not an approval or a merge-readiness declaration.

复审的第二项 P1(原会话换绑后历史结果无法对账)已做有界修复:原执行授权仍只允许消费一次;原绑定撤回后,同 Goal/Agent 的当前替代会话只可检查及补交历史证据。TS 拥有权限判断;Python 在原注册表写锁内读回绑定、提交证据。历史结果和消费路由不变,恢复责任人单独记入 outcome_report / reconciliation_report;相同证据重试不改写首次报告人。

P1 #2 (historical reconciliation stranded after session replacement) has a bounded implementation: after the original route is withdrawn, a currently bound replacement for the same Goal/Agent can inspect/report historical evidence only, never consume again. TypeScript owns the access decision; registry validation and evidence commit hold the original writer lock. Original evidence and execution route remain immutable, with separately persisted reporter provenance and idempotent retries.

验证:229 项 Python、15 项 TS;真实 CLI 子进程覆盖换绑 Inbox → inspect → 拒绝再次 consume → 原 unknown digest 精确对账 → 原卡片及共享前端投影读回。包含原绑定仍有效、跨 Goal/Agent、未绑定、未消费路径的拒绝,以及撤回与初次/对账写入的交错回归。没有调用真实 Lark 群或交易场所。

Validation: 229 Python and 15 TypeScript tests, including the public CLI replacement recovery path, immutable provenance, rejection boundaries, revocation interleavings, original-card readback and the existing shared frontend projection. No live Lark or venue calls were made.

仍阻塞:第一项 P1(同用户进程可伪造环境线程)没有解决。环境变量不是受信宿主身份凭据;本次不缩小“原会话专属执行”要求。标准 canary 第二轮为 17/18,词汇检查仍在原 29 秒上限超时;原生词汇/清单检查通过,但不将其替代成标准门禁通过。未调高上限、未合并、未安装;需要针对新头重新评审,真实原宿主接入及新版打包 UI 视觉复核仍属未完成验收。

Still blocked: P1 #1 (same-user environment forgery) is not fixed, and the original-session-exclusive requirement is not narrowed. The standard canary rerun is 17/18 with a vocabulary-check timeout at the unchanged 29-second limit; the focused same-runner follow-up also timed out at 29.018 seconds. Native vocabulary/manifest checks pass but do not make the standard gate green. No merge or installation. Fresh exact-head review, authenticated original-host adoption and the outstanding packaged-UI visual pass remain required.

@huangruiteng

Copy link
Copy Markdown
Collaborator Author

Implementation-only follow-up at adc9179ef28cd7fe336ed38baecb7f6088a86818; this is not formal approval or merge readiness.

已关闭复审指出的公开 CLI 环境伪造入口:inspect/consume/report-operation 在读取私有条款、结果文件或写回之前均返回 operation_host_authentication_unavailable。完全匹配的 CODEX_THREAD_ID、线程选择器、自报 proof 和旧 effect runtime 的意外成功都不能消费授权。Dashboard、Lark 与 Inbox 现明确展示“用户已确认,但原宿主认证尚未接通”。

Containment fixed; the authenticated positive original-host path is still missing. The bilingual RFC names the necessary Codex Desktop native tool-server producer, owner-controlled issuer enrollment, session-bound/non-exporting tool connection and TypeScript verifier. A LoopX-owned app-server session is not a substitute for the attached original Desktop thread. A bounded companion Todo is recorded in the original Goal and remains blocked; no fixture-generated credential or unused signer was added.

Latest validation: 162 Python tests, 15 TS tests, TS typecheck/Python lint/syntax, native vocabulary/census checks, shared frontend transport/contract checks and packaged Chat build passed. The new real-CLI regression fails on 9a8cc6b (forged exact environment grants execution) and passes on current source for all 9 consume/inspect/report × exact/foreign/missing cases, with byte-identical canonical storage. Positive storage fixtures are now explicitly internal IO tests, not trusted-host qualification.

Retained limits: the standard broad canary's vocabulary check and focused retry timed out at the unchanged 29-second limit; the broad gate is not green. The new authentication-state copy has no new visual browser pass. Genuine native-producer/original-connection positive acceptance and live group/domain/result-card acceptance remain outstanding. No LoopX core self-merge, installation, real finance card, venue action, account read or thread migration was performed.

@huangruiteng
huangruiteng force-pushed the codex/confirmed-agent-handoff-0930 branch from adc9179 to 0de8e96 Compare September 30, 2026 05:43
@huangruiteng huangruiteng changed the title feat(operations): return confirmed execution to the original Agent feat(operations): separate source context from admitted managed execution Sep 30, 2026

@huangruiteng huangruiteng 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.

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

评审提交:0de8e96d55e11cd94491a1a6b63d26ed17b4938c,基线:3ec049e138917a8cce4f84197ba196d26445b2b0。这是整个 PR 的新头评审,不继承旧头的结论。评审范围为显式启用的执行协议及产品读回,不等于真实金融执行已验收,也不构成 Core 合并或安装授权。

动机

旧方案把“最懂问题的来源会话”和“能够安全执行的进程”绑定成一件事:通过普通 CLI 或环境变量证明原会话不可行,而要求 Desktop 先提供专用原生接入又会长期卡住交付。面向长程 Agent,来源应保留上下文和回传关联,执行身份则来自已准入、按任务绑定的 managed Turn。本次按照更新后的 RFC 第 13 节重新实现这一边界,让现有 delegation/Turn 能拥有自己的 native 连接;它不导入、冒充或静默 resume 来源会话。

最小的 fail-closed 修补虽然能堵住冒领,却不能形成可推进的执行路径;反过来开放自报线程 ID 会削弱一次批准只消费一次的安全边界。因此新增受管执行种类是有价值的分期交付,而不是声称整个业务目标已经达成。

改动思路

保留唯一 typed-action 操作存储、原 Turn session owner、Goal 生命周期及 Inbox。TS 判断不可变条款、精确执行 subject、首次消费、历史证据权限和结果转换;Python 负责原有存储事务、子进程、native wire 和 Lark IO,不新增 Python 决策源或第二套凭证/审批/调度器。

managed-turn-handoff-v0 通过 --codex-operation-tools 显式启用,固定 model、effort、受限 sandbox 及执行 profile。私有工具闭包只安装在 LoopX 持有的 app-server 连接,调用者身份取自当前 native thread/Turn 元数据,不从模型参数或环境变量取得。来源路由仅为上下文与返回定位,不是执行身份。

确认、消费、执行证据、对账和卡片投递分别记状态。首次消费先提交事实再返回许可;响应丢失后重试不能再提交业务动作。未知结果保留原件、追加对账;替换会话只在原绑定撤销后取得证据恢复权,永不继承未消费批准。持锁范围覆盖身份核对与提交,不跨越领域外部效果。

具体改动

整个分支覆盖 normalization/action store、原 session owner 和锁序、native host、Turn/CLI/delegation 预检、Inbox/manager hook、Lark callback 与分阶段结果恢复、共享 action-review frame、Dashboard 抽屉及中英文文案、打包 browser smoke,以及双语 RFC/roadmap 和相关测试。默认 extension/simulator 路线保留;公共 attached-session CLI 仍明确拒绝未经认证的消费,不把旧批准转换成 managed 批准。

关键代码讲解

  • planAgentOperationHandoff 是状态转换 owner。它核对 payload/projection/confirmation/claim、精确 session/Todo/profile;只有首次成功提交返回 execution_allowed=true,后续调用及证据恢复一律没有新许可。
  • agent_operation_action 复用 Goal → registry → 有序 session → action-store 锁,在同一边界读当前绑定并提交消费/结果。确定性交错回归覆盖撤销、替换会话和已经消费的未知结果。
  • operation_tool_handler 拒绝 actor/executor 注入,并复用 registered Agent / Goal-instance scope;本轮还修复了非空 pending 的非法 cursor scope。run_codex_operation_host 复用现有 app-server IO、结构化 Turn 结果和进程树清理,profile 漂移或 plain-CLI 降级都拒绝执行。
  • handle_goal_channel_operation_callback 对 managed/attached handoff 只认证确认并留下 canonical claim,不启动 host、不伪造领域结果;原 extension 模拟分支仍执行自己的原协议。

正向路径是:准入 managed Turn → native prepare → 精确 Lark 确认 → 规范 Inbox 定位 → 原 subject 首次消费 → 独立领域证据 report → 原卡片结果读回。工程夹具验证了这些转换;真实 native qualification 则独立验证新建/同线程 resume、不同 Turn 元数据及结构化结果,不把夹具确认当真人批准。

反向路径覆盖:自报环境/route 不能消费;撤销先提交则消费拒绝;换 Todo/profile 不继承批准;已经消费后超时或过期仍可见对账;超过 20 条以独立 scope cursor 完整分页,普通 Inbox 游标不替代操作游标。新 Todo 在同一 Goal 内可以独立 prepare,但必须取得自己的精确批准,不能被上一条操作的门禁全局截住。

对主干的风险

最高风险仍是一次许可误授或在重启后重复外部效果,因此安全结论以真实 caller 边界与确定性交错回归为依据,不以 prose、哈希存在或绿色测试总数代替身份。另一个长期风险是恢复项积压,本次复用 canonical owner,覆盖恢复优先、稳定分页、撤销后 evidence-only 接手、未知原件不覆盖及终态投递重试。

验证结果:重基线后的相关 Python 套件 285 passed / 1 live skip;最终 pending 修复后 43 passed / 1 live skip(与前者重叠,不相加)。独立 opt-in 的真实 native context/resume qualification 通过。39 项 TS 测试及 typecheck、Ruff、registry-IO manifest、标准 premerge 19/19 与 5 项直接检查通过,未放宽时间或输出上限。按当前 wait_for_ci=false 未查询、轮询或等待远端 CI。

默认关闭反例在不可变 main 和 exact head 上使用相同隔离输入,真实普通 turn run-once dry-run/execute,以及安装已 doctor 的原 extension prepare/dry-run/replay/cancel 全部通过;完整归一化输出一致。仅归一化随机 proposal ID、运行时钟和临时结果目录,保留条款、expiry、digests、profile、状态、退出码和副作用。新机制没有给普通 Turn 注入工具/额外操作记录或改变扣额。

打包 frontend 已构建并检查真实共享后端投影:中英文、桌面/窄屏共 16 个 operation 状态用例,以及现有 execution preflight 用例通过,修改页面已视觉检查。UI 明确展示“配置有效但运行未验收、已确认不等于执行”,没有新 Confirm 按钮或第二配置源。native probe 没有卡片、批准、消息或领域效果;live 金融流程和自动宿主唤醒仍未验收。打包器原有大 chunk 提示保留,不伪称无警告。

语义与 CI 对齐

逐项复核 既有评审与恢复框架 和本头 RFC 第 13 节:保留原 attached 路线的 fail-closed 边界,新路线通过明确 executor 种类及新批准成立,而非豁免旧认证;撤销/消费、overflow、替换证据恢复、结果投递分别有回归。相关已合入的 GoalRef Inbox、bound MCP 和 cross-repository delegation validation owner 均复用并纳入本地验收,不另造平行实现。

我的整体评价

本头在长期方向上值得交付:用可替换、精确准入的执行 subject 承接来源上下文,既保住权限,又不将单一 Desktop integration 变成所有 host 的前置依赖。改动较大,但主要增长来自边界/恢复测试与跨入口读回,生产代码复用既有 owner;不是增加另一套 Agent 平台。后续可继续收拢重复夹具,但当前没有需要靠再加一层机制修复的阻塞发现。

结论为协议交付范围内 APPROVE。仍须维护者审核/合入,原配置 owner 显式采用并读回 pinned runtime/profile,随后验证真人批准 → 首次消费 → 领域证据 → 原群结果。未自合并、未全局安装,未将工程成果记为金融收益或最终目标完成。

English verdict: APPROVE - 0de8e96; the opt-in owned managed transport separates source context from authenticated execution, preserves exact one-shot approval and evidence-only recovery, and passes fresh baseline/head default-off parity, native transport, local protocol and packaged UI checks. Genuine human approval, domain execution and original-group readback remain unqualified; maintainer merge and explicit adoption are still required.

@cocolord cocolord left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

评审提交:0de8e96d55e11cd94491a1a6b63d26ed17b4938c。这是对整个 PR 新头的独立复审;旧 head 的结论没有直接沿用。本轮确认此前的环境变量身份、解绑竞态和恢复分页问题已由 owned app-server transport、协调锁、历史证据权限和独立 operation cursor 实质修复,但当前提交仍有两个可复现的合入阻塞项。

动机

这个 PR 要解决的核心问题是:飞书里的真人确认不应由回调进程直接执行,也不能靠调用者自报线程身份交给任意本地进程;确认后的领域操作应回到精确绑定的受管 Codex Turn,一次性消费授权,再把真实外部结果或不确定结果写回原规范动作记录。相比旧 head,当前实现把来源会话只当作上下文/回传路由,把执行身份绑定到 owned app-server 提供的原生 thread/Turn metadata,且为原会话失效后的 replacement session 单独开放“历史证据核对”而不重新授予执行权。这个方向既减少错误代理冒领,也让长期 unknown outcome 能继续收敛。

改动思路

设计继续以原 operation.execute typed action 和 canonical action store 为单一事实源。TypeScript 的 operation_agent_handoff.ts 负责 executor 规范化、当前 binding 判断、一次性 consume、report/reconciliation、恢复排序和 cursor;Python 的 operation_handoff.py 只在 Goal 生命周期锁、registry 锁和 action-store 锁下提供 IO 与桥接。显式 --codex-operation-tools 才启用 codex_operation_host.py 的 owned app-server transport,普通 attached CLI 继续 fail closed。Lark 回调只确认/claim,不代替 Agent 执行;Dashboard/Lark 共用 review frame,把“等待受管 Turn”“已消费待结果”“submission unknown”“已对账但卡片待回读”分开呈现。

正向路径是:用户确认精确 proposal -> Lark 只写 confirmation/claim -> 绑定 Todo、Session、model/effort/profile 的受管 Turn 通过 native loopx_operation tool 消费一次 -> 先持久化 handoff 再允许外部效果 -> report 写入 outcome -> 原卡片读回。负向路径是:错误 Goal/Todo/Session/profile、失效 binding、过期确认或重复 consume 都在 typed owner 中拒绝;原 binding 撤销后,replacement session 只能读取并追加 reconciliation,不能得到第二次执行许可。

具体改动

阻塞问题

  1. [P1] 新 packaged browser 场景依赖测试模块,干净安装环境无法启动。 examples/personal-workspace-browser/confirmed-operation-fixtures.py:11 把 tests/test_chat_operation_actions.py 当作运行时 fixture library 导入,而该测试模块顶层 import pytest。在没有开发依赖的 wheel / browser 环境中,场景在打开页面前即以 ModuleNotFoundError: No module named 'pytest' 退出。exact-head 的 Frontstage Pages、Release Artifacts、chat-bundle-browser 和 dashboard-acceptance 均出现同一调用链;使用干净系统 Python 也独立复现。这使 PR 新增的 EN/ZH、desktop/mobile、read-only UI 验收实际上没有执行,并直接破坏现有 release/frontstage 流程。请把可复用 canonical fixture builder 移到产品或示例可导入的无 pytest helper(或让该示例自包含),不要通过给生产安装补 pytest 来掩盖边界;随后在 wheel-only/clean install 中重跑完整 packaged browser 以及两个 release build。

  2. [P1] 新控制面 owner 重复定义 bare SHA-256 规则,required TypeScript 检查失败。 loopx/control_plane/work_items/operation_agent_handoff.ts:11 定义 /^[a-f0-9]{64}$/,同文件 :234 又以内联正则检查 cursor scope。仓库已有 loopx/control_plane/content_digest.ts 的 BARE_SHA256_PATTERN 作为唯一 owner;required content_digest_single_owner.test.ts 在 exact head 精确报告这两处 offender,导致 typescript-core (1/3) 失败。请复用该共享 typed constant,并重跑 single-owner test 和完整 TypeScript core。否则 digest 词法后续变化需要多处同步,当前 PR 也无法满足既有主干契约。

关键代码讲解

  • normalizeAgentOperationExecutor / managedOperationBindingCurrent 将 managed executor 固定到 Todo、Session、Goal instance、profile digest、model 和 effort;source conversation 不再充当执行身份。
  • run_codex_operation_host 通过受控 app-server 会话注册动态工具,并在每次调用核验 native thread 和 active Turn;chat_agent.py 同时隔离进程树,避免子进程继承受管 transport 凭据。
  • planAgentOperationHandoff 保持 commit-before-effect 和 one-shot consumption。原 outcome 为 submission_unknown 时,只允许引用原 digest 的 append-only reconciliation;replacement owner 只能获得 historical_evidence_only。
  • collaboration_goal_scope(lock_registry=True) 将 Goal 生命周期、registry binding 和 action-store commit 纳入固定锁序;projectAgentOperationInbox 用独立、scope-bound cursor 保持 20 条以后仍可枚举。
  • compileOperationReviewFrame、Lark 卡片和 Personal Workspace 共享 pending/result/delivery 语义;UI 明确说明确认或消费都不等于正在执行。不过新 browser fixture 的依赖错误阻止了这条新增可视化路径的 packaged 验收。
  • CLI、manager inbox、turn selection/registration、delegation preflight、双语 RFC 和 registry manifest 都随 transport/profile/cursor 语义更新;49 个文件属于同一端到端协议切片,没有发现第二套审批存储或 Python 侧重复决策状态机。

对主干的风险

核心权限与状态路径的独立验证是正向的:19 个 focused TypeScript 用例通过;164 个相关 Python 用例通过、1 个跳过,覆盖 native identity、managed binding、撤销/消费锁序、一次性消费、历史 evidence recovery、Lark 回写、cursor 和展示 reducer。当前 GitHub 也显示 base 为最新 main、PR 可内容合并,DCO、dependency review、desktop、PostgreSQL、optional adapter、多数 Python shards 和 focused stage2c 均通过。

但 required CI 仍有两类 PR 自身引入的确定性失败:packaged/release 链路因测试依赖泄漏中断,TypeScript core 因 duplicate digest matcher 中断。前者意味着新增 UI 收益没有在作者声明的 clean installed 边界成立,且扩大到发布产物;后者是已有共享规则 owner 的明确回归,不是可忽略的格式问题。没有做真实群点击或真实领域外部执行,这些仍是该 PR 明示的后续 qualification 边界;本轮也不声称 logged-in Chrome 验证,因为 packaged Chromium 场景在创建页面前已经失败。

语义与 CI 对齐

执行许可、历史 evidence 权限、unknown reconciliation 和 operation cursor 都是 typed fields / exact identity comparisons,没有 substring denylist。通用控制面文案保持 domain-neutral;human_confirmation_required、first_consumption_required、execution_allowed 和 read-only recovery 明确区分 guidance 与机器强制义务。行为变化通过显式 --codex-operation-tools opt-in、双语 RFC、CLI help 和 UI 文案披露;未启用时普通 Codex host 不获得 operation tool,旧 operation-equipped Session 也不能静默降级到普通 transport。唯一 semantic-alignment 违例是 SHA-256 形状绕开现有 typed owner,required test 已精确捕获。

我的整体评价

结论是 REQUEST_CHANGES。这一版对前两轮核心权限问题有实质性修复:原生 host 身份、binding 原子性、replacement reconciliation 和完整分页均比旧 head 更接近可交付契约;整体 architecture 仍把状态与权限决策留在 TypeScript,Python 只做受锁 IO,future-facing pass 不需要再扩一个框架。可惜当前 head 把测试代码依赖带进 packaged browser 运行时,并同时违反 digest 单一 owner,两者都在 required CI 上形成确定性 blocker。完成上述两个局部修复、让 clean install 的完整浏览器/发布链路真正跑完,再基于新 exact head 复审;不需要扩大 PR 的产品范围。

English verdict: REQUEST_CHANGES on exact head 0de8e96d55e11cd94491a1a6b63d26ed17b4938c. The owned native transport, atomic binding/consume boundary, replacement reconciliation, and paginated recovery materially fix the prior blockers, with 19 focused TypeScript tests and 164 Python tests passing. However, the new packaged browser fixture imports a pytest-dependent test module and fails in clean wheel/release environments, while two duplicate SHA-256 regexes violate the repository's single digest owner and fail required TypeScript core. Extract a runtime-safe fixture helper, reuse BARE_SHA256_PATTERN, and rerun packaged/release plus full TypeScript checks.

@huangruiteng

Copy link
Copy Markdown
Collaborator Author

Frame-aligned conclusion / 框架对齐结论

Exact head: 0de8e96d55e11cd94491a1a6b63d26ed17b4938c.

对照原评审与恢复框架,本次不是解除旧 attached-session CLI 的认证拒绝,而是显式增加 managed_turn 执行主体:来源会话只提供上下文与返回定位,执行使用 LoopX 所有的 native app-server 连接及原任务/session/profile 的精确绑定。旧批准不转换、新主体需新批准。首次消费、撤销交错、未知结果的 append-only 对账、替换主体 evidence-only、完整分页和默认关闭对照均已验证;非空 pending 的 cursor/scope 问题也有正反回归。

完整的新头评审为协议范围内 APPROVE。维护者合并、原配置 owner 显式采用、真人精确批准、领域证据与原群读回仍分别验收;旧评审作为旧头证据保留,不能当作新头批准,也不因 native transport 通过而认定金融流程已完成。

English: the previous fail-closed attached route remains closed. The new managed executor satisfies the reviewed protocol and recovery boundaries through an owned native connection, exact subject binding and fresh one-shot consent. The full exact-head review approves this protocol slice only; maintainer merge, explicit adoption and genuine human/domain/result-return qualification remain separate.

@steven-kid steven-kid left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

REQUEST_CHANGES — reviewed head 0de8e96d55e11cd94491a1a6b63d26ed17b4938c, base 3ec049e138917a8cce4f84197ba196d26445b2b0.

本次 fresh audit 独立复现了已有评审指出的两项阻塞,并检查整个 base-to-head 的运行时、CLI、Lark、Inbox、展示和文档改动;没有把作者报告的 canary 作为独立验证。以下不是新增的第三项缺陷,也不重复计算已有问题。

  • [P1] 浏览器验收引入未声明的 pytest 依赖。 examples/personal-workspace-browser/confirmed-operation-fixtures.py:10-11 将 tests 加入路径并导入 test_chat_operation_actions,后者第 9 行导入 pytest。confirmed-operations.mjs:11-13 用 resolveTestPython() 执行该脚本,且主 smoke 无条件注册此场景。独立运行无 pytest 的 Python 立即得到 ModuleNotFoundError: No module named 'pytest';dashboard-acceptance 失败日志给出相同调用链。release-artifacts 工作流用 --no-deps 安装到干净 wheel venv,随后通过 LOOPX_PYTHON_BIN 运行 packaged smoke,因此也会落入这条路径。建议把最小规范状态构造提取为不依赖测试框架的 fixture helper,并让单元测试和浏览器测试共享;不要给零运行时依赖的 wheel 添加 pytest 来掩盖问题。回归须覆盖干净 wheel interpreter 下的 fixture 和 packaged browser scenario。
  • [P1] 新摘要匹配器违反已存在的单一 owner,直接使 TS core 必需测试失败。 loopx/control_plane/work_items/operation_agent_handoff.ts:11 和 :234 分别重新定义整个 bare SHA256 值的正则。base 已有 loopx/control_plane/content_digest.ts 的 BARE_SHA256_PATTERN。独立运行 content_digest_single_owner.test.ts,base 17/17 通过,head 明确列出这两个位置并失败;远端 typescript-core (1/3) 日志一致。最小修复是导入既有 owner 并复用两个验证点,保留复合 cursor 的协议解析。回归应继续运行单一 owner 测试和 operation handoff 测试,不放宽检测规则或新增豁免。

动机

原有 typed operation 把确认、claim、执行结果和原卡读回放在规范 action store 中,但登记来源会话并不能认证真实执行者。简单把环境 thread id 或 CLI route 当作证明会扩大权限;等待 Desktop adapter 则让原本可由自有进程完成的受管工作依赖另一条尚未接通的链路。本 PR 将来源上下文与受管执行身份分开,针对显式配置的 delegation / Turn 提供 native tool 通道。收益是精确批准可以由绑定的受管会话首次消费;目标不是自动获得账号访问、领域交易授权、即时唤醒或完整业务闭环。

不改动可继续保持安全拒绝,但无法提供这条执行路径;只在现有 CLI 加 actor 参数不能建立可信身份。复用既有 app-server adapter、Turn session 和 action store 的方向合理,比新增审批库或调度器更小。然而整体新增 4,622 行、涉及 49 个文件,仍需完整兼容性证据;机制实现和绿灯不能单独证明全部维护成本合理。

改动思路

入口是 turn run-once --codex-operation-tools,也可由既有 delegation 的 host_args 启用。Turn 准入之后启动自有 app-server;CodexChatAgentSession 检查原生 thread/active Turn 元数据,再调用不可由工具参数选择 actor 的闭包。prepare 进入原 ChatActionService.preview;Lark 认证回调只记录确认并 claim,受管 consume 在 Goal → registry → session → action-store 锁内提交单次消费,随后才返回执行许可。

规范确认和消费事实仍在 action store;profile 和 session 复用既有 Turn owner;source_route 从登记关系投影,不是新的身份权威。operation_handoff.py 提供锁和存储 IO,TS planAgentOperationHandoff 决定准入和恢复。manager Inbox 与 native pending 共用规范票据投影和恢复优先排序,分别绑定游标作用域。未知结果保留原 outcome,以精确摘要追加 reconciliation;新的结果投递必须匹配 initial/reconciled 阶段。

对既有 owner 的核查覆盖了 base/head 的 action store、codex_cli session、Lark executor、inbox/peers 和 content_digest。发现明确未复用的是 SHA256 matcher。更全面的默认关闭基线配对、所有保留分支的行为等价与并发 counterfactual 尚未完成,不能标记为已证明。

具体改动

全 PR 为 49 文件 +4,622/-79,包含 24 个 runtime 文件、10 个 app/UI 文件、10 个测试/示例文件、4 个文档及1个 manifest。运行时涵盖 normalization/store、chat native dispatch、CLI 注册与选择、host binding、collaboration scope/inbox/peers、TS effect handlers 和 Lark callback/recovery。展示复用 action review frame,增加双语确认待消费、已消费待结果、unknown 和结果卡读回状态,保留 unknown 在工作区中可见,调整移动端换行;preflight 只显示配置事实且保持 runtime-unqualified。新增/扩展 Python、TS、浏览器验证;registry manifest 只更新行号。双语 RFC 与 roadmap 明确 managed route 和尚未验收的真实链路。

关键代码讲解

  1. codex_operation_host.py:211 run_codex_operation_host:仅接受受限 sandbox、固定 model/effort 与 Todo lineage,计算 profile digest,复用或创建原 session;profile 漂移或错误的 resume/start_new 拒绝。安装工具后使用原 typed Turn result,finally 关闭自有进程树。
  2. codex_operation_host.py:71 operation_tool_handler:限定 context/pending/prepare/inspect/consume/report 参数键;以闭包中的 lineage/session/profile 构造 actor,工具不能注入另一个主体。pending 使用登记 Agent 和 Goal instance scope;错误返回有界拒绝而非私有载荷。
  3. operation_handoff.py:165 agent_operation_action:检查 Goal/Agent、生命周期和恢复资格,在固定顺序锁中读原/接手 session,交给 action store 原子提交。外部领域效果不在锁内发生。
  4. operation_agent_handoff.ts:120 planAgentOperationHandoff:核对不可变条款、确认摘要、claim 和 executor;只有首次消费返回 execution_allowed=true。重复消费不重新授权;替代会话只能在原绑定撤销后回写历史证据,unknown 对账要求绑定原 outcome digest。
  5. goal_channel_operation.py:114 _result_delivery_stage 及 callback/recovery:区分首次结果和对账结果投递;共享 compileOperationReviewFrame 驱动 Lark 与 Dashboard。旧卡片读回不能证明新 reconciliation 已传回。

对主干的风险

正向 fixture 路径覆盖 prepare → 合成的认证确认 → 首次消费 → unknown → 精确摘要对账;负向覆盖伪造 native thread、工具 actor 注入、绑定撤销、过期、重复消费、并发重试和公共 CLI 的宿主认证拒绝。合成确认只证明存储/协议,不证明真实用户点击;fake app-server 只证明 wire/进程处理,不证明真实模型或真实领域执行。

独立验证:所选 TS 文件(handoff、action review、delegation、digest owner)52 测试中 51 通过、1 失败;control-plane typecheck 与 diff whitespace 检查通过。Python 第一轮在允许本地 IPC 后 109 通过、1 live qualifier 跳过,随后 delegation fixture 被本机 Node 25 内置 SQLite 3.51.2 未资格化阻断,不能称整套通过。base 上 prompt-upgrade hook 测试也复现 turn_start_capability_hook_dispatch 差异,因此远端该失败不能据此归因本 PR。远端 dashboard 和 TS 失败则有本地一致复现。

默认关闭的运行时门禁存在,但浏览器验证链已受无条件场景注册影响。原 attached Desktop CLI 明确 fail-closed;不能因为 managed route 不再依赖它而写成 attached 认证已完成。完整 EN/ZH 桌面/移动端浏览器验收、真实 native qualification、人工批准、领域结果与原群 readback 本次未独立完成。

我的整体评价

请求修改。单一审批存储、来源/执行者分离、单次消费和未知结果不重试的方向清楚,相关合成测试提供了有用证据;两项确定的集成回归仍阻止通过。请先去掉浏览器 fixture 对 pytest 测试模块的依赖,并复用摘要 owner,然后在合格运行时重跑受影响的 packaged/browser 与 TS core 验证。

此次没有修复、push、merge、部署或安装运行时,也没有执行真实业务操作。未完成的默认关闭全分支比较、合格 SQLite 下完整 delegation 验证及真实批准/回传验收保留为 unverified;作者此前的 19/19 canary 和直接检查不能替代这些独立观察。真实业务闭环是文档已声明的后续验收范围,不把它虚构为已经复现的代码漏洞。

English verdict: REQUEST_CHANGES at exact head 0de8e96d55e11cd94491a1a6b63d26ed17b4938c. Independently reproduced the existing two P1 findings: the browser fixture imports pytest through a test module, breaking clean interpreter/package acceptance, and duplicate bare-SHA256 matchers fail the existing single-owner TS gate. Selected TS tests: 51 passed, 1 failed; base digest gate: 17 passed. Typecheck and diff checks passed. Python: 109 passed, 1 live test skipped before an unqualified local SQLite runtime blocked delegation setup. Live human approval, domain effects and original-channel readback remain unverified. No merge or deployment performed.

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…ry pages

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…ation

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…ridge

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…owner

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
@huangruiteng
huangruiteng force-pushed the codex/confirmed-agent-handoff-0930 branch from 0de8e96 to bf9edcb Compare September 30, 2026 07:38

@huangruiteng huangruiteng 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.

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

完整复审 head:bf9edcb409021514d69e3922529bc80c7c46fb55;基线:996bcc0274a4d5d838bf5d41a4b73bf13cc68d93。没有剩余阻塞性代码发现;本轮两项 P1 已修复。 以下是整个 51 文件分支的重新评审,不继承旧 head 的 APPROVE。真实用户批准、领域执行与原群回传仍分别验收,协议通过不代表金融闭环已经完成。

动机

本 PR 要解决的不是“注册一个来源线程就能冒充它”,而是把来源上下文与可信执行身份分开,让已准入、按 Todo 绑定的 managed Turn 使用自己持有的 native app-server 连接。来源会话仍提供上下文及返回定位,不导入、不冒充、不静默 resume 原会话;Desktop 专用接入不是该新执行种类的前置依赖。

只继续 fail-closed 可以堵住冒领,却无法产生可用的执行路径;直接接受环境变量或工具自报 actor 又会削弱精确一次批准。因此复用已有 Turn/session/action-store owner 的 native adapter 是合理分期,而不是另建审批库、凭证目录或调度器。反对立即交付的最强理由是分支较大且只验证一种 native host,尚未证明真实领域收益;该问题通过明确协议切片、默认关闭、现有产品入口和独立后续验收来界定,不能用测试数量宣称业务完成。

改动思路

通用权限和状态转换由 TS planAgentOperationHandoff 唯一决定;原 Python 负责锁内存储、已有 session 生命周期、native wire 和 Lark IO。显式 --codex-operation-tools 及原 delegation 的 host_args 控制启用,固定 Goal/Agent/Todo/session/profile、model、effort 和受限 sandbox。调用身份来自当前连接拥有的 native thread/active Turn 元数据,模型不能在工具参数中选择 actor/executor。

确认、首次消费、领域结果、unknown 对账与消息投递是不同事实。消费提交后才返回首次执行许可,响应丢失后的重试没有新许可。unknown 原件保留、对账追加;撤销原绑定后,当前注册的替换主体只有历史证据权限,不继承未消费批准。锁序覆盖 Goal → registry → 有序 session → action store,不跨越外部领域效果。新的独立 Todo 可以 prepare,但仍须自己的精确批准,不被上一条操作的门禁全局截住。

具体改动

完整分支为 51 文件、+4833/-192:normalization/action store、原 session/Goal-instance owner 及锁序;native host、chat-agent 分派与进程树清理;Turn/CLI/delegation binding/preflight;Inbox/manager hook 与恢复分页;Lark callback 和分阶段结果投递;共享 action-review frame、Dashboard 抽屉/移动端文案;打包 browser、TS/Python 回归、registry IO 行号 manifest;双语 RFC 和 roadmap。没有修改全局 capability 配置、skill 或自动加载的 AGENTS 指令。

本轮针对两条旧头评审的修复:

  • 浏览器 fixture 原来经 tests/test_chat_operation_actions.py 隐式导入 pytest,干净解释器复现 ModuleNotFoundError。现在最小规范构造集中在 examples/operation_action_fixtures.py,只使用标准库和已安装的 LoopX,单元测试与浏览器共享它;显式 release interpreter 不再被源码 PYTHONPATH 静默覆盖。新增 python -S 回归,并在真实 --no-deps、没有 pytest 的 wheel venv 跑完浏览器路径。没有给 wheel 增加 pytest 运行依赖。
  • profile digest 与 cursor scope 两处 bare-SHA256 校验改为导入现有 BARE_SHA256_PATTERN。单一 owner 回归把新模块列为 canonical consumer,未增加白名单、删除检查或改变复合 operation cursor 协议。完整 TS core 已通过,而非只跑新增用例。

关键代码和调用关系:

  • planAgentOperationHandoff:不可变条款、确认/claim 摘要、当前精确绑定及首次消费的 TS owner;重试和历史证据恢复不返回新的 execution_allowed。
  • agent_operation_action:读原绑定与提交消费/报告处于同一固定锁序,覆盖撤销和竞争接手,而非先读快照后无锁授权。
  • operation_tool_handler / run_codex_operation_host:私有工具闭包拒绝 actor 注入,pending 使用 registered Agent 与精确 Goal-instance scope;host 复用原 app-server IO、结构化 Turn validator 和退出时进程树清理,profile 漂移或已装备会话的 plain-CLI 降级被拒绝。
  • handle_goal_channel_operation_callback:managed/attached 分支只认证确认并写 canonical claim,不启动 host、不制造领域结果;原 extension 模拟路径和投递恢复 owner 保留。

正向工程路径是准入 → native prepare → 合成精确确认 → pending 定位 → 首次消费 → unknown report → 绑定原 digest 的追加对账 → 共享读回。反向覆盖伪造 native metadata、actor/executor 注入、撤销先提交、换 Todo/profile、重复消费、消费后过期及替换主体 evidence-only;超过 20 条仍可通过独立 scope cursor 完整枚举。真实 native context/new Turn/同线程 resume 则独立执行,不能把合成的确认或领域结果当成真实授权。

对主干的风险

主要风险是一次许可误授、恢复后重复外部效果以及 unresolved 项积压。当前证据覆盖真实 caller 边界、撤销/消费交错、原件不覆盖、历史恢复、完整分页与未来独立 subject;不以哈希存在、文案或单次成功替代身份。旧 attached CLI 的未经认证路径仍 fail-closed,历史批准没有自动转换为 managed 批准。

本轮 final head 的本地验证:

  • 完整 TS:3539 passed、0 failed;30 项可选 PostgreSQL 测试按原环境条件 skip,本 PR 的 handoff/摘要 owner 测试没有跳过;typecheck 通过。
  • 相关 Python 11 个套件:397 passed、1 个显式 live qualifier skip;该 qualifier 另外启用执行并通过(1 passed),验证真实 native context/resume 与结构化输出。重叠测试不重复计数。
  • 标准 premerge:19/19,另 5 项直接检查通过;Ruff、diff hygiene 和全部 51 个变更路径公开边界扫描通过,未调整 ceiling、时间/输出上限或扫描契约。全仓扫描仍会命中未改动的专门私网地址负例 fixture,未把它改成通过;当前规定的变更范围扫描与风险门禁均真实通过。
  • 构建并用 --no-deps 安装 final wheel,确认该解释器没有 pytest;完整打包 browser 26/26 通过,其中新增操作状态覆盖 EN/ZH、1512/390 宽度共 16 组合。真实规范后端生成状态,浏览器 API 为隔离呈现 fixture;整页视觉检查、reload/读取及无额外持久写入通过,不将 fixture 的新鲜度当作 live 业务证明。既有 execution preflight、共享打包入口、installed Chat HTTP/current & previous assets/PWA 和 release-artifact smoke 通过。保留原打包大 chunk advisory。
  • 不可变 main 与 final head 使用同一物理工作负载,实际普通 turn run-once dry-run/execute 与已 doctor 的原 extension prepare/dry-run/replay/cancel 完整配对输出相等。仅归一化随机 proposal UUID、运行时钟和随机结果目录;保留完整诊断、expiry、digest、profile、Turn identity、退出码、canonical replay/cancel 与无外部效果。Codex 最终回答是 fake,准入/写回/扣额、原 extension 与存储是真实隔离路径。

按 Goal 当前 wait_for_ci=false,本轮没有查询、轮询或等待远端 CI。所有关键新增边界都有当前本地证据,GitHub 的旧头 requests-changes 历史仍保留,不假装已经被评审者撤回。

我的整体评价

对照既有评审/恢复框架和双语 RFC 第 13 节,来源/执行分离、可信 native producer、commit-before-effect、一次消费、撤销交错、unknown append-only 对账、replacement evidence-only、完整分页、独立未来 subject 与默认关闭兼容性均满足协议切片。本轮还删除了 fixture 对测试框架的耦合并复用摘要 owner;不是通过豁免检查修复报告。

结论为 APPROVE。长期收益是受管执行与恢复不再被未实现的 Desktop 认证前置卡住,产品入口能够如实读回确认、消费、结果及投递阶段;没有新增必须重复填写的配置或第二确认 UI。继续沿原配置 owner 进行安装/启用与读回,再分别验证真人批准、领域授权及证据、原群结果回传;这些已在 RFC 中声明,不在此处虚构完成。本次 PR 的人工自合并授权独立于功能权限,仍必须先通过 exact-head merge-readiness;评审本身不授予全局安装或业务动作权限。

English verdict: APPROVE - exact head bf9edcb409021514d69e3922529bc80c7c46fb55, base 996bcc0274a4d5d838bf5d41a4b73bf13cc68d93. Both P1 regressions are fixed without exemptions: runtime-only shared fixtures work in a pytest-free installed wheel, and SHA-256 validation reuses the canonical TS owner. Full TS: 3539 passed; related Python: 397 passed with the skipped live qualifier separately passed; packaged browser: 26/26; premerge: 19/19 plus five direct checks; default-off base/head outputs match. This approves the explicitly opted-in managed protocol and truthful product readback, not genuine human/domain/result-return qualification or global adoption. CI was not consulted under the resolved Goal policy.

@huangruiteng

huangruiteng commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator Author

Frame-aligned repair and merge decision / 框架对齐修复与合并决定

Exact head: bf9edcb409021514d69e3922529bc80c7c46fb55; base: 996bcc0274a4d5d838bf5d41a4b73bf13cc68d93.

对照原评审与恢复框架及双语 RFC 第 13 节,managed 执行仍使用自己持有的 native 连接;旧 attached-session 的未认证消费继续拒绝,来源仅作上下文/返回定位,旧批准不转换。首次消费、撤销交错、unknown 原件与追加对账、replacement evidence-only、完整 scope 分页、独立未来 Todo 和默认关闭的主干配对均已在当前 head 重验。

旧头两项 P1 已修复:浏览器与单元测试复用无 pytest 的 runtime-only fixture;两处 SHA256 matcher 复用 BARE_SHA256_PATTERN,检测规则未豁免。真实 pytest-free wheel 的完整 packaged browser 26/26、installed HTTP、release smoke、3539 项 TS、397 项相关 Python、独立真实 native qualifier、19/19 premerge 与 5 项直接检查通过。按当前 Goal CI policy 没有查询或等待远端 CI。

本次完整新头评审为协议切片 APPROVE,已校验并读回作者 COMMENTED fallback;旧评审不被删除或伪称撤回。Owner 当前针对 #5327 的自合并请求独立于协议权限,仍以此 exact head 的 merge-readiness 为前置,不修改仓库证据门禁。全局安装/原配置 owner 启用、真人批准、领域执行和原群读回仍分阶段验收。

English: both old-head P1 regressions are repaired without test exemptions or a new runtime dependency. The full current-head review approves the owned managed protocol, canonical recovery and truthful packaged readback. Existing attached authentication stays closed; genuine human/domain/result-return acceptance and global adoption remain separate. The explicitly requested self-merge is fenced to this head and requires current merge readiness; historical reviewer requests are retained.

Merge hold / 合并暂缓

本次 exact-head merge-readiness 返回 ready=true;按 Owner 针对 #5327 的明确自合并授权,提交了带 expectedHeadOid 与已核实 noreply authorEmail 的 squash 合并请求。GitHub 返回 UNPROCESSABLE: Invalid email address,独立读回确认 PR 仍为 OPEN、head 未变、mergedAt 为空。代码评审的 APPROVE 不变,但合并、安装和实际采用均不能记为完成。账号级邮箱隐私设置是否变更需 Owner 决定;不回退个人邮箱,不清除历史评审,也不直接推送 main 绕开 exact-head 合并边界。

English: the unchanged head passed merge readiness, but the explicitly authorized, exact-head-fenced squash request was rejected by GitHub's noreply authorEmail validation. Independent readback confirms OPEN and no merge timestamp. The code-review approval remains valid; merge, installation and adoption remain incomplete. Account-wide email privacy changes require the owner's decision. No personal-email fallback, historical-review dismissal or direct main push is used.

This branch has not been deployed

No deployments
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.

3 participants