Skip to content

v0.18.14

Choose a tag to compare

@github-actions github-actions released this 26 Aug 23:44
· 2396 commits to main since this release

Agent Workflow v0.18.14

本版本交付三条线:任务执行的持久化所有权(RFC-328 把「谁可以继续驱动一个任务」从三套进程内约定变成数据库里唯一、可 fencing、可恢复的事实);MCP 人工门完整面(RFC-329 修掉五条死路径、补 23 个具名工具让 list_pending_gates 名副其实,并给全部路由装上「路由⟷工具」全域守卫);数字员工域的授权面(RFC-330 把工具 / 岗位模版立为行级 ACL 资源、补齐员工定义的前端授权面、给案例加上与编排任务同形的成员制)。另含任务列表「一直在闪」的修复、Windows 上受管进程弹控制台窗口的修复,以及 RFC-319 用户面 e2e 覆盖收口(gap 归零)。

本版本含 2 个数据库迁移与若干行为收紧(工具 / 模版 / 案例的写权与可见性按归属判定;升级后的数据库不能再用旧二进制跑任务执行),升级前请务必备份数据库并阅读文末「升级说明」。

主要更新

持久化任务执行所有权与 fencing(RFC-328)

  • 一个任务任一时刻至多一个 current (owner, epoch)。此前 execution ownership 由 InMemoryTaskDriverSupervisor、driverLease 与 task status CAS 三套互不线性化的机制共同维持:daemon 重启后 handle 全部丢失;人工 resume / retry 不 acquire lease、又会在新 driver attach 前执行 reap / Git rollback / placeholder mint;PID 回执写库失败只告警不阻断。现在以 owners / intents / effects / effect_attempts / effect_fences / maintenance_claims / maintenance_members / lineage_operation_records 八张表建立唯一 durable authority。
  • 四条 kick(start / resume / retry-prep / retry-node)与 auto / recovery 统一先写 continuation intent,worker claim 后才取得不可外造、单调 epoch 的 OwnershipToken;execution-plane 的每一笔 DB mutation 在同一事务内用 exact token fence——旧 epoch 的迟到 output / event / terminal receipt 零落库,日志记 stale code 但不会把已发生的外部动作伪造成已结算。
  • 同一任务的并发重复命令只允许一个 continuation:REST / MCP / 网页 / auto 同时操作同一 task 时,loser 得到 409 或读到 winner,不再靠时序偶然执行一半。
  • 无法证明旧进程已停止时,人工 resume / retry 不再「试着继续」,而是返回 execution-recovery-required,直到 recovery probe 拿到确定证据;terminal maintenance(archive / delete / retention / workspace GC)与 continuation 互斥,谁先取得 durable claim 谁赢。
  • 功能优先、不加笼统封禁:现有 custom transport 重试、built-in 正常成功 / 429 重试、manual node / parent retry、child 删除后的 parent 重跑、wrapper continue 与同任务 agent / script / fan-out 并行全部保留。非幂等 outbound 结果未知时只暂停无 actor 的自动重发,任务以 execution-effect-outcome-unknown 失败并在 failure detail 给出「远端结果未知,继续可能重复动作」的提示;用户随后的人工 retry / resume / sync 即视为显式重新授权。
  • 进程超时改从目标进程就绪时起算;source-terminal 的节点状态投影改为原子;free-collab 规划保持并行但 batch 阶段等到每份初始计划都持久化后才开始。
  • 零 Task / NodeRun wire 变化,创建 / 取消 / 恢复 / 重试的既有 URL 与权限不变。

MCP 人工门完整面、死路径修复与全域「路由⟷工具」守卫(RFC-329)

  • 起于用户问「API 和 MCP 有没有回答完反问提交反问的能力,含提交并继续 / 提交并停止」——REST 完整,MCP 只有整轮快通道。随后动态跑出全量路由 × 工具实际 dispatch 路径的双向 diff:工具只够得着 77 条路由,313 条 PAT 可达路由没有工具。
  • 五条死路径修复:resource_read(kind=repos, method=get) 指向一条从未注册的路由、每次调用恒 404 而 describe_resource 还照表宣称支持(已从表中删除);repair_alert / list_repair_options 需要的 alertId 在 MCP 上根本拿不到(新增 list_task_alerts);launch_task 的 ref 无从解析(新增 list_repo_refs,按 cachedRepoId 内部两跳);answer_clarify 描述写 412 实为 409。
  • 三个人工门补齐 21 个具名工具,MCP 工具 29 → 52:反问门 9 个工具 + answer_clarify 扩 defer / questionIds / resubmitQuestionIds(快通道 body 逐字不变);工作组任务门 7 个工具 + 新增 GET /api/workgroup-tasks/pending(pendingCount 内部早已算出完整候选行却只返回三个数字,重构为 pendingRows 唯一实现);fusion 审批门 5 个工具(status 用枚举收口——路由对未知值静默退化成「无过滤」,模型拼错一次就会把全量当待批)。
  • list_pending_gates 四路 + 分路失败:每路先 unwrap 再 settle,返回 {ok, data | error} + complete——此前一路 500 会表现为「这个门是空的」,而「没有东西等你」正是模型据以走开的答案。
  • 全域守卫:分母取运行期 allRouteMeta()(不硬编码),四向判定 uncovered / staleExemptions / unroutedTools / 权限精确等价;每条豁免是一条独立叶子(不按域分组塞子数组,否则高水位对「往已有组加一条」纹丝不动),接进 ledger-baselines.json 高水位只降不升——资源域运维面与六个新产品域的缺口从「无人看管」变成账本里可见且不可无声增长。
  • reassign 路由的 tokenAccess 由 never 改为 allow(它只改 targetNodeId,不碰 owner / grants / visibility)。

数字员工域授权面补齐:工具 / 岗位模版行级 ACL、员工定义前端授权面、案例成员制(RFC-330)

  • 起于用户问「现在数字员工的权限控制点是什么,工具、模版、数字员工有权限归属吗,有 edit 权限控制吗」。源码对账:工具 / 岗位模版只有一列 owner_user_id 做记录、不参与任何判定——持 digital-employees:update(普通 user 基线)即可改 / 发布 / 退休任何人的工具与模版,也不存在私有工具;员工定义的授权面板与只读态前端没跟上(RFC-324 X9);案例读 / 恢复 / 终止全是权限点级、无成员制。
  • 工具与岗位模版成为第 14 / 15 类 ACL 资源:owner + visibility + 只读 / 可编辑分档,GET/PUT …/acl 与其余 13 类同 wire;新建 private,存量回填 public(每个读者看到的行与今天逐位相同)。三类列表按可见性过滤并带 visibility / access / ownerUserId;三类卡片按档位收敛控件(read 档无编辑 / 发布 / 退休,write 档无退休 / 改名)并新增「权限」入口,降档后不刷新页面即收敛。
  • 案例与编排任务完整同形的归属模型:成员制 observer / collaborator + owner 转移(GET/PUT /api/employee-cases/:id/members,WS 帧 employee-case.members.changed),与任务侧共用同一套成员替换 / 用户有效性校验;可见 = 发起人 ∪ 成员 ∪ tasks:read:all ∪ bypass,操作(resume / terminate / policy-upgrade)= 发起人 ∪ collaborator ∪ bypass。转移后运行中案例从下一次执行起以新 owner 为发布主体,代码托管凭据缺则推送显式失败、不静默沿用旧人身份。
  • 岗位模版名字唯一域从「类型版本内全局」放宽为「类型版本内 × owner」:不同 owner 可在同一类型版本下有同名模版(今天 409),同 owner 语义不变、存量不改名;kernel 的 owner-name 唯一表长出分区列声明。类型包自动升级产生的 successor 工具 / 模版继承 source 的 owner + visibility(grants 不继承,需在新版本重新授权)。
  • 两处顺手修:employee_definition 转移撞名 500 → 409 resource-name-conflict;旧 /code/config/employees playbook 保存路径改为内容写门,write 授权者可以保存(今天 403)。前端错误域新增 digitalEmployee,全部 employee-* 码从 misc 兜底改为该域标题。

用户面 e2e 覆盖收口(RFC-319 → Done)

  • 上版如实标注为 In Progress 的 RFC-319 本版收口:能力账本 840 条全部 covered、gap 归零,证据均为 {file, test} 且标题逐字可达;R1 端点未覆盖 271 → 96、R2 前端路由 18 → 4;四层棘轮全部入网 ledger-baselines.json,每条自带负 fixture。
  • 收口批次咬出并修掉的真缺陷:DE-16b 把「请求已发出」当成「写入已完成」(Windows 分片实测红两次);stop 停不下来时的非零退出码此前没有任何用例真跑过;ssh:// 仓库接入第一次被真的跑过;遗留任务的运维面(排干路径)第一次被真的跑过。

其他修复

  • 任务列表「每次状态更新整表重建、一直在闪」(用户实报):根因不是渲染性能而是刷新姿势——WS 帧只置脏,再由 15 秒定时器 resetQueries 整表重建,于是每一轮 isLoading 翻 true 整屏换成 LoadingState、VirtualList 卸载重挂、滚动回顶、展开的子分支塌成 spinner。改为就地同步:保留数据的 invalidateQueries,后台重取各页后原子替换,行 DOM 按 key 复用——状态 chip 就地变、滚动位置 / 展开态 / 翻出来的页全留着;新行无需点击自己进列表;「已更新 [刷新]」横幅删除。
  • Windows 上受管目标进程弹出控制台窗口:RFC-328 的 pre-activation launcher 未套用 RFC-254 的宿主平台 spawn 选项;已修,并让 Windows 平台套件在该 launcher 变更时自动触发。
  • 反问 park run 已被 RFC-328 原子取消时,任务 terminal cause 在 post-commit sweep 中丢失——已修并加服务层回归锁。
  • 画布 owner-camera 的 xyflow 尺寸变化生命周期与生产 ResizeObserver 契约对齐。
  • 定时全量 e2e 矩阵(WebKit / macOS nightly / 视觉基线)的多处时序竞态改为可观测状态同步;窄视口下共享 popover 保持在视口内。
  • 员工卡片多了「权限」入口后操作行在 1280 宽溢出 → flex-wrap;onboarding 的 Enter 抢在 <Select> 焦点交接前的 e2e 竞态修复。

升级说明

  • 数据库迁移:新增 2 个(0210_rfc328_task_execution_ownership.sql、0211_rfc330_employee_authoring_acl.sql),迁移端点由 0209 前进到 0211。升级前务必备份数据库。
    • 0210 新增八张 task-execution 表,tasks 加 execution_lineage_id / lineage_slot_path_json,node_runs 加 continuation_slot_key / lineage_slot_path_json / operation_generation / spawn_launch_nonce;存量行只回填 lineage / slot 元数据,不伪造进程身份或 owner,boot recovery 先补偿孤儿状态再由 continuation 开始新一代。
    • 0211 给工具加 name / visibility / acl_revision、模版加 visibility / acl_revision(存量回填 public,读面逐位不变),模版唯一索引放宽为 (owner, type, typeRevision, name),新表 employee_case_members。
  • 不能回退运行旧二进制(RFC-328 能力影响 4):升级后的数据库不能原地跑旧 binary 的 task execution——旧 binary 不懂 epoch fence,允许它继续写会重新打开本版关闭的窗口。需要降级时停机并恢复升级前备份。
  • 权限目录不变(仍 113 点),本版没有权限点增删或改名。
  • 数字员工域写权收紧(breaking,RFC-330 能力影响清单 I1~I9):非 owner、无 write 授权、无 bypass 的账户不能再改 / 校验 / 发布别人的工具与模版(403 resource-read-only);retire 收成 owner / bypass(403 resource-govern-owner-only);write 档不能改名(403 resource-rename-owner-only);不可见工具的 authoring body → 404;GET /api/employee-cases/:id 对非发起人 / 非成员 / 无 tasks:read:all / 无 bypass → 404,resume / terminate / policy-upgrade 收成发起人 / collaborator / bypass(403 employee-case-observer-read-only)。新建工具 / 模版默认 private,其他人在工具箱 / 模版列表看不到,直到 owner 设 public 或逐人授权;已 pin 的员工定义不受影响(引用闭包隐式授权)。
  • 成员案例不进统一任务列表的 mine / shared(D22),从案例页直达;此项与任务侧 shared null-owner 一起记为已知功能缺口(docs/audit-backlog.md)。
  • wire 变化(additive):三类列表 DTO 新增必填 visibility / access / ownerUserId;新增 4 条 …/acl + 2 条 …/members 路由与 employee-case.members.changed 帧;GET /api/workgroup-tasks/pending 新增;answer_clarify 新参数全部可选,省略时 body 逐字不变;resource_read(kind=repos, method=get) 从 MCP 表删除(它从未成功过)。
  • 并发命令语义变化(RFC-328 能力影响 2 / 6):同一任务的重复 resume / retry / 归档 / 删除并发到达时只有一个赢,其余得到 409;unkillable 进程或未知 FS / Git 身份且无确定证据时,维护、删除与磁盘回收可能保持 recovery-required,不再「试着继续」。
  • RFC-328 / RFC-329 状态如实说明:两个 RFC 的代码已全部落主干并经主 CI,但索引仍分别标 Implementation candidate / Draft——RFC-328 的 T34 / T35(远端 exact-SHA 证据回填与文档收口)与 RFC-329 的 T24(索引 / STATE 收口)尚未完成,功能可用,文档收口继续。
  • 可直接替换对应平台二进制。

发布信息

  • 源码提交:a20f83e38aceac9064fe20df3b2ca7183ae6aecb
  • 数据库迁移:新增 2 个(0210 → 0211)
  • 变更规模:275 个文件,+55069 / −4978
  • 完整变更:v0.18.13...v0.18.14