Repository navigation
v0.18.14
·
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 → 409resource-name-conflict;旧/code/config/employeesplaybook 保存路径改为内容写门,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 的账户不能再改 / 校验 / 发布别人的工具与模版(403resource-read-only);retire收成 owner / bypass(403resource-govern-owner-only);write档不能改名(403resource-rename-owner-only);不可见工具的 authoring body → 404;GET /api/employee-cases/:id对非发起人 / 非成员 / 无tasks:read:all/ 无 bypass → 404,resume / terminate / policy-upgrade 收成发起人 / collaborator / bypass(403employee-case-observer-read-only)。新建工具 / 模版默认 private,其他人在工具箱 / 模版列表看不到,直到 owner 设 public 或逐人授权;已 pin 的员工定义不受影响(引用闭包隐式授权)。 - 成员案例不进统一任务列表的 mine / shared(D22),从案例页直达;此项与任务侧
sharednull-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