Skip to content

feat(agent): add deliverable batch orchestration - #112

Merged
Qiyuanqiii merged 1 commit into
mainfrom
codex/issue-103-batch-delivery
Aug 19, 2026
Merged

Qiyuanqiii merged 1 commit into
mainfrom
codex/issue-103-batch-delivery

Conversation

@Qiyuanqiii

@Qiyuanqiii Qiyuanqiii commented Aug 19, 2026 •

Copy link
Copy Markdown
Member

摘要

  • 新增严格版本化的 batch-delivery.v1:将已经审批并 admission 的核心 child DAG 物化为最多两个可并行交付的 child,每个 child 使用独立 Git worktree、branch、generation lease、一次性 owner token 与缩小工具 profile。
  • 新增持久邮箱与完整状态流:dispatch、ack、progress、question、evidence、ready-for-review、changes-requested、accepted 与 aborted;operation digest、generation fence 和 SQLite 事务保证重启恢复、幂等回放与重复消息 exactly-once。
  • child 交付收据绑定 base/head commit、完整 merge-base diff、function-context call-chain digest、diffstat、changed files、测试/evidence、已知限制和 exact clean state;dirty/uncommitted 或验证后 Git 漂移不能伪装完成。
  • 新增独立 Reviewer 与有序本地 merge queue:从最新显式确认 base 在独立 integration worktree 中逐项合并,检测所有权重叠、base/state drift、文本/语义冲突及测试漂移,并在每一步累积重跑已合并前缀的全部验证。
  • 新增 schema v118、认证 HTTP/OpenAPI、Desktop/React 批次投影与显式控制能力,补齐启动 reconciliation、取消扇出、generation 重试、orphan 保留/清理及中英文文档与 ADR 0119。

Closes #103.

协议、DAG 与缩权 child

batch-delivery.v1 只消费现有协调器已经审批并 admission 的 core child proposal;Prepare 会重新加载并精确绑定同一 Run、Workspace、root Agent、proposal、DAG、预算和 expected artifacts,拒绝自环、循环、未知依赖、重复 task、超过两个 child、预算漂移和不规范所有权声明。

每个 task 声明:

  • stable ordinal、目标/交付合同、依赖和预算;
  • 文件或目录级 ownership hint;
  • git_diff_check、go_test、npm_test 中的显式验证集合;
  • 最大变更文件数、diff bytes、证据和限制上限。

每个 child 获得独立 branch/worktree、base/head、随机 owner token、正数 generation、有限 lease 和 batch-delivery-workspace-tools.v1。明文 token 只在首次 Prepare 或 CAS rotation 响应中返回一次,SQLite 仅保存 digest;丢失 token 必须通过 expected-generation CAS 轮换,旧 generation 立即失效。

工具矩阵固定为 owned Scope 内的:

  • 有界 list、read、glob、grep;
  • 基于 source hash 与 occurrence binding 的 create|patch proposal,以及复用 FileEdit 精确 hash/approval/apply 路径的写入;
  • 固定 Git status、完整 diff inspection 和只暂存 owned changed paths 的 commit。

delete、rename/copy、Shell、任意 argv/process、network、credential、Debug、approval grant、远端 Git、PR 操作和继续派生 child 均不可用。原有 SpecialistRunner 仍保持 no-tool;本协议不会让任意 Specialist 隐式继承 root authority。

Worktree、Git 与提交收据

Prepare 只接受 clean、已提交、未漂移的 source base,并由 Go 创建和回读独立 worktree/branch。root、child 与 integration 必须属于同一个 canonical common Git directory;symlink、junction/reparse、大小写别名和跨仓库 worktree 均 fail closed。

Git 调用使用字面 argv、固定 author/email/message、关闭 hooks 与 attributes 外部路径,并拒绝本地 executable clean/smudge/process/diff/textconv/merge driver。commit 前先写入 durable intent;崩溃恢复只接受 prior HEAD 的一个直属、非 merge 提交,并重新证明 branch、parent、author、message、owned paths、无 delete/rename/copy 与 clean state,多提交或外部漂移保留现场并进入显式恢复路径。

ready_for_review 收据包含:

  • exact base/head 与 branch;
  • merge-base 完整 diff SHA-256、function-context call-chain SHA-256、diffstat、changed files;
  • 每项验证的 protocol、exit、完整观察流 stdout/stderr digest、byte count、截断证据;
  • evidence refs 和 known limitations。

Submit 在验证前后各做一次完整 inspection,要求 branch/HEAD/diff/changed paths/clean state 完全相同;Store 提交收据时还原子复核当前 generation、未过期 lease、active child 状态和 Run 仍为 running。作者摘要或“完成”声明不构成证据。

邮箱、独立复核与有序合并

schema v118 持久化 plan、child workspace、generation mailbox、receipt、review、merge queue/step 和 operation facts。邮箱消息按 task/generation/sequence 排序,并对 operation digest 做 exactly-once;stale generation、越权 actor、非法前驱和重复 intent 均被 Go 与 SQLite 双重拒绝。

Reviewer 不读取作者摘要作为信任来源,而是从收据 head 重新计算 merge-base 完整 diff、调用链、changed paths 和 tests。接受还要求 Reviewer 分别确认 full diff、call chain 与 test evidence;验证完成后再次证明 exact Git state,任何漂移都返回 changes-requested 或 blocked。

Merge 使用独立 integration worktree/branch:

  1. 要求所有当前 generation 的 deliverable task 都有 accepted review;
  2. 按 DAG 确定稳定顺序,并在开始前检测 changed-file ownership overlap;
  3. 将 source head 作为 no-commit merge 应用,拒绝文本冲突和不确定 index/worktree;
  4. 生成确定性 merge commit,并逐项重跑当前已合并前缀声明过的所有验证;
  5. 验证后重新证明 source、integration、merge parents/tree/author/message、所有 receipt/review 与当前 Run authority;
  6. 只有 integration 状态仍精确匹配当前 step 时才允许回滚失败 step,否则保留现场等待明确恢复。

base 漂移不会自动重放,必须由操作者提供 confirm_replay;文本、语义或测试冲突不会自动选择任一方覆盖。结果仅是本地 integration branch/head,不 push、不创建远端 PR、也不合并远端分支。

取消、失败隔离与启动恢复

  • Cancel 先 fence 所有 active generation,再终止 plan;只删除 exact branch/head/clean/root identity 均匹配的 worktree。
  • dirty、已提交、branch/head 漂移或清理不确定的 child 保留为可审查 orphan,不递归删除不可信路径。
  • 单 child 失败不会污染 sibling worktree;generation retry 轮换 token/lease,并保留上一代 terminal evidence。
  • 启动 reconciliation 收敛 prepared worktree、commit intent、过期 lease、merge intent、缺失 worktree 与 orphan cleanup;不会恢复明文 token、进程、旧 approval 或旧 authority。
  • Run 非 running 时,reconciliation 在任何 filesystem/Git 副作用之前转入 needs_operator_attention;merge queue 每个副作用前和 Store terminal commit 时都重新检查当前 Run。
  • budget reservation/recycle、cancel fan-out、部分成果与 mailbox/review/merge events 均进入既有审计链,不建立第二套无界调度器。

宿主验证与进程边界

默认只允许不会执行仓库代码的 git diff --check。go_test/npm_test 会运行 child-authored code,因此必须同时满足:

  • 当前 Run 仍为 running,并持有当前 full_access(或显式更高的 debug)permission;
  • permission control、danger-full-access 与 --enable-batch-validation-execution 均开启;
  • Desktop batch mutation 另行显式开启 --enable-batch-delivery-control。

验证使用固定宿主可执行文件、Workspace 内 real cwd、去凭据/offline 环境、关闭 stdin;Go 使用 -count=1 禁用 test cache,npm 通过固定 Node + npm-cli.js 启动。Windows 将完整后代绑定 kill-on-close Job Object;Unix 使用 inherited process group 并在所有返回路径回收。输出只以完整观察流 SHA-256、byte count 和有界 prefix digest 持久化,raw stdout/stderr 不进入 SQLite、DTO 或错误消息。

这仍是显式 full_access 宿主执行,不是 OS filesystem/network sandbox。POSIX 进程若主动 daemonize 并脱离 inherited process group,仍可能逃逸;需要可证明隔离时应使用独立容器边界,不能把 offline env 描述为 packet-level containment。

HTTP、OpenAPI 与 Desktop

认证 API 新增:

GET  /api/v1/runs/{run_id}/batch-deliveries
POST /api/v1/runs/{run_id}/batch-deliveries
GET  /api/v1/runs/{run_id}/batch-deliveries/{batch_delivery_id}
POST /api/v1/runs/{run_id}/batch-deliveries/{batch_delivery_id}/children/{ordinal}/review
POST /api/v1/runs/{run_id}/batch-deliveries/{batch_delivery_id}/children/{ordinal}/renew-owner
POST /api/v1/runs/{run_id}/batch-deliveries/{batch_delivery_id}/merge
POST /api/v1/runs/{run_id}/batch-deliveries/{batch_delivery_id}/cancel
POST /api/v1/runs/{run_id}/batch-deliveries/{batch_delivery_id}/reconcile

GET 使用 read bearer;mutation 使用独立 control bearer、严格 JSON、duplicate/unknown-field 拒绝、有界 body 与 Run URL ownership 校验。Prepare/review/merge/cancel 使用 Idempotency-Key;owner renewal 使用 generation CAS;reconcile 本身收敛幂等。普通 DTO 不包含 child/integration root、owner-token digest、tool-profile fingerprint、operation/request fingerprint;raw owner token 只出现在一次性 authority 响应。

Desktop/React 增加 Batch Delivery 投影、child/mailbox/receipt/review/merge 状态、显式 reviewer attestations、base replay 确认、cancel/reconcile 及中英诊断。Bootstrap/runtime capability 严格保持 Go 与前端一致:通用 control token 不会自动开放 Desktop batch control,宿主验证能力也不会仅因 batch control 存在而变 true。

生成后的 OpenAPI 为 124 paths / 138 operations / 325 schemas,TypeScript schema 已确定性重建。

主线兼容性

本分支直接基于当前 main 495c27a(包含 PR #111 / schema v117 Workspace Checkpoints),本 PR 顺延为 schema v118 与 ADR 0119,不改写既有迁移历史。

  • v118 从 v117 迁移并新增 batch plan/child/mailbox/receipt/review/merge 表、索引与不可变/状态约束 trigger。
  • v1-v118 全历史 migration/recovery fixture 保持通过。
  • 复用既有 core-child admission、DAG、budget、Run event、FileEdit、typed repository 与 Workspace identity,不建立不兼容调度器。
  • Workspace Checkpoint、command-runtime、agent-code-tools、用户终端、Debug、Docker 与远端 Git/PR 权限继续保持独立能力和审计边界。

验收条件对应

  • Root 可物化两个无依赖 deliverable child;每个 child 使用不同 worktree/branch、独立 generation/lease/token 和缩小工具 profile。
  • owned Scope、link/reparse、root/common-repository identity、network/credential/Debug/delete/派生 child 权限均 fail closed。
  • DAG、邮箱、lease、进度、问题、交付、取消和 operation facts 在重启后恢复且不重复执行。
  • receipt 精确绑定 base/head、完整 diff/call-chain、changed files、tests/evidence/limitations;dirty/uncommitted/state drift 被拒绝。
  • ownership overlap、base drift、文本冲突、语义/测试失败和验证后 Git 漂移都会 block 并保留明确恢复状态。
  • Reviewer 从 merge-base 完整 diff、调用链和 tests 独立复核,不依赖作者摘要。
  • merge queue 按 DAG 逐项应用,累积复验,精确状态下可回滚当前 step,失败不污染 source/sibling worktree。
  • cancel/timeout/crash 后 generation、lease、worktree、进程与 budget 安全收敛,并保留不确定成果。
  • 并发、循环依赖、重复消息、stale generation、orphan cleanup、permission downgrade 和真实 Git worktree/merge 集成测试通过。

本地验证

  • go test -p 2 -count=1 -timeout 30m ./...:全仓通过;internal/application 422.773s、internal/httpapi 138.928s、internal/store 完整 v1-v118 迁移/恢复矩阵 1006.877s。
  • staticcheck 发现并修复 batch tool binding 的 nil 检查顺序;修复后 go test -count=1 -timeout 10m ./internal/application -run '^TestBatchDelivery' 通过(67.525s)。
  • go test -race 定向覆盖 Application 的真实 Git/权限漂移/独立复核/累积验证,以及 Store mailbox exactly-once、generation/lease/Run commit fencing。
  • go test -count=1 -timeout 10m -tags 'desktop,wv2runtime.error' ./cmd/cyberagent-desktop ./internal/desktop ./internal/webui。
  • go vet ./...、go mod verify、go mod tidy -diff。
  • staticcheck -checks='SA*,S1*,QF*' 覆盖全部受影响 Go 包;Desktop 使用完整 desktop,wv2runtime.error 平台标签。
  • npm run check:api,并验证连续生成的 TypeScript schema 无漂移。
  • npm run typecheck、完整 npm test -- --reporter=dot(61 files / 251 tests)、npm run build。
  • npm audit --audit-level=high:0 vulnerabilities。
  • git diff --check、冲突标记、绝对本机路径、凭据形态与构建产物扫描。

额外 govulncheck ./... 如实报告本机 Go 1.26.5 标准库的 5 项可达已知问题(GO-2026-6218、GO-2026-6090、GO-2026-6089、GO-2026-5972、GO-2026-5026,均由 Go 1.26.6 修复);它们不是本次仓库依赖或代码引入,不能把该本机扫描描述为 zero finding。

远端 CI

  • GitHub Actions CI #365 全绿:Go 1.25 当前补丁版下完整测试、module verify/tidy、analyzer compatibility、go vet 与固定版 govulncheck 通过(Go control plane 18m45s);TypeScript 1m13s、Rust 1m03s、Windows Desktop 7m52s、macOS Desktop 2m37s。
  • Desktop release #26 全绿:release dependency/license boundary 1m01s,可复现并验证的 Portable ZIP 8m07s;PR 场景 publish 按预期跳过。

安全审计

提交前安全 diff 扫描发现 1 项 medium 与 6 项 low,均已修复并增加回归:

  • 当前 Run permission 会在 host validation、每个 merge side effect 和 Store terminal commit 重新加载,permission downgrade/Run terminal 立即撤权;
  • Submit/Review/Merge 在验证后重新证明 exact Git state,merge recovery 只接受确定性的 parents/tree/author/message;
  • 非 running Run 的启动 reconciliation 在任何文件/Git 副作用前停止;
  • raw validation output 不持久化,完整观察流 hash 可区分相同 prefix、不同 tail;
  • Git hooks/attributes 与本地 executable filter/diff/merge driver 被关闭或拒绝;
  • Desktop batch mutation 使用独立显式 capability,不从通用 control token 隐式继承;
  • Windows Job 与 Unix process-group 在直接父进程正常退出后仍回收 inherited descendants。

另补强 common Git repository identity、worktree link/reparse、npm scope、累积 validation contract 与 state-drift rollback fencing。没有提交 owner token、credential、原始验证输出、本地数据库、worktree 绝对路径或构建产物。

非目标与仍需人工证据

  • 不允许递归/无界 agent 派生,不让多个 Agent 写同一 worktree/index,不开放 Cyber Specialist。
  • 不自动 push、开 PR 或远端 merge;本 PR 的远端发布是当前操作者明确请求后的普通仓库流程,不属于 batch-delivery.v1 产品能力。
  • 不将 stripped/offline env 或 process group 描述为完整 OS sandbox。

PR 暂保持 Draft。远端 Ubuntu/Windows/macOS/TypeScript/Rust/release 平台证据已闭环;合并前仍建议人工确认 Desktop 的 batch timeline、Reviewer 三项 attestation、base replay/blocked conflict 与 cancel/reconcile 交互。尚未取得的人工交互证据不会写成已完成。

@Qiyuanqiii
Qiyuanqiii marked this pull request as ready for review August 19, 2026 21:46
@Qiyuanqiii
Qiyuanqiii merged commit 9fc824c into main Aug 19, 2026
8 checks passed
@Qiyuanqiii
Qiyuanqiii deleted the codex/issue-103-batch-delivery branch August 19, 2026 21:46
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.

feat(agent): 可交付多代理、Worktree 隔离与合并复核

1 participant