Repository navigation
Releases: wangbinquan/agent-workflow
Release list
Agent Workflow v0.19.1
Agent Workflow v0.19.1
本版本是 v0.19.0 之后的修订版,累计 93 个提交。主线在长期记忆:补上了「执行结束」这条一直缺失的提炼信号源,并修掉了让记忆蒸馏静默失效一个多月的输出协议问题。
本版本有数据库迁移:SQLite 新增 0227–0229(端点 0226 → 0229);PostgreSQL 新增增量升级边 0003–0005,原地升级,不需要重做 cutover。
注意默认行为变化:新的「任务来源准入门」默认只让手工创建的任务产出候选记忆。定时 / webhook / 事件 / API 启动的任务,即使里面有人审、澄清或留言,默认也不再入队提炼。需要恢复旧行为请在设置页把对应来源勾上——详见文末「升级说明」。
主要更新
执行结束记忆提炼(RFC-366)
此前只有 clarify(澄清答复)、review(人审决定)、feedback(任务留言)三类信号会触发记忆提炼——全部是人类介入点。一个从头到尾没人审、没澄清、没人留言的任务(正是「跑得顺」的那种)在记忆库里等于没发生过,而平台绝大多数产出恰恰来自 agent 自己跑完的那一段。
- 新增两类信号源:
agent-run(每个 agent 节点达终态时各触发一次,loop 每轮、fanout 每分片、每次重试都算)与task-run(任务达终态时触发一次)。只有done/failed会提炼,canceled/interrupted/exhausted/skipped不提炼。 - 喂给蒸馏器的内容按源区分:
agent-run喂会话全文 transcript + 输出端口 + 本次运行已注入的记忆快照;task-run喂任务级摘要(名称 / 状态 / 耗时 / 失败节点 / 错误摘要 / 启动入参 / 各节点终态一览 / 最终输出),不重复搬运 transcript。两者都按字节预算裁剪并标注截断量。 - 任务来源准入门:按任务的启动来源(
launch_origin)白名单决定该任务的事件是否提炼,默认只放行manual。这条门统一管五类源——一个每小时跑一次的定时任务,此前只要中途有人审一次就会照常烧掉一次 LLM 调用,产出的同质候选会淹没人审队列。平台内部任务(数字员工 / 动作执行等用户在任务列表里看不到的执行)一律不提炼。 - 逐源开关:五类源各一个布尔,默认全开,与来源白名单正交——只想要人审沉淀、不想要 agent 过程沉淀时,关掉
agentRun/taskRun即可。 - 成本护栏:
agent-run用 60 秒去抖窗口(其余四类仍是 5 秒),一分钟内陆续结束的多个 agent 合并成一次蒸馏运行。 - 配置全部热读:改完即生效,不需要重启 daemon。设置页「记忆」卡片可配来源白名单、五个源开关与去抖窗口;
/memory的蒸馏任务列表可按agent-run/task-run筛选。 agent-run的候选 scope 收窄到本次结束的那个 agent(外加 workflow / repo / global),不会把一个 agent 的教训记到同任务的其他 agent 头上。
记忆蒸馏输出协议修复(RFC-367)
对本机 daemon 库的实测显示,记忆蒸馏已经静默失效一个多月:memory_distill_jobs 里 176 个 done 有 76 个零候选,有会话捕获的 10 个全部零候选——而这 10 个的捕获里全部含有完整、可用的候选 JSON。最后一条真正落库的候选停在 2026-07-17。
- 根因一:提示词从未给出完整字面语法。蒸馏器的系统提示词里一个尖括号都没有,
<port name="candidates">…</port>与</workflow-output>从未出现在任何提示词中。模型于是写出<wflow-output>/<wf-output>这类残标签,或把 JSON 裹进代码围栏。现在系统提示词内嵌 envelope → port → JSON 的三层嵌套字面示例,用户提示词尾部改用仓内公共协议块(worker 节点一直用的那一个)。 - 根因二:解析失败只 warn,任务照常完成。无 envelope / 无 candidates 端口 / JSON 非法三条失败路径全都是「记一条 warn 然后返回 0 条候选」,结果与「确实没有可蒸馏内容」完全同形:UI 绿、无错误、不退避、不重试。现在这些一律判协议失败——先在同一会话内补问(复用 worker 节点的补问文案与 runtime resume,最多 3 轮),补问预算用尽才让任务
failed并带上失败码与已试轮次,按既有指数退避重试。{"candidates": []}仍然是成功路径,与协议失败严格区分。 - 取数与会话记录同源:候选解析此前读的是子进程 stdout 的末尾 256KB(单行还受 1MiB 截断),而会话页读的是另一条事后走查路径——同一段模型输出有两个互不相同的 reader,历史上已经因此出过一次同型事故。现在蒸馏器迁到仓内的系统代理运行原语,候选解析与会话页渲染同源于一条规范化事件流:页面上能看到 envelope,就不可能解析不出候选。
- 附带收益:claude-code 运行时首次获得蒸馏会话捕获;stderr 行进入会话页。
- 历史数据不回收:此前 76 个零候选的 done 任务保持 done,不重跑、不回填。
记忆蒸馏超时默认值放宽
单次蒸馏的子进程超时默认值从 120 秒提到 1 小时,并在设置页明确标出可调(下限 30 秒、上限 6 小时)。原来的 120 秒对于喂了完整 transcript 的提炼任务经常不够用。
事件自动化目标拆分(RFC-365)
事件中心此前把规则归属、目标、投递 / 订阅和触发上下文一起交给一个启动端口,任务目标与数字员工目标的规则物化、启动和 receipt 归属混在同一个口子里。现在事件中心自己拥有规则选择、模板物化、持久化的来源 / 工作意图与投递结算,任务执行与数字员工各提供一个目标专属适配器、只返回自己的 receipt。
能力零收缩:四种目标、body / 外部 ID 接入、模板插值、现有权限与配置能力全部保留;任务输入不新增数量上限、文本预算不做转换或截断、数字员工的字段引用语法与首次准入时机不变;现有的去重、重试、错误与旧规则失效语义逐条冻结。
其他修复
/memory「按维度」的记忆卡片恢复纵向排列:记忆一多就横向堆积溢出屏幕。根因是分页 footer 的 CSS 规则被插进了一条共享规则的选择器列表中间,选择器列表在第一个{处终止,于是前两个列表被 footer 规则吞走、丢掉flex-direction: column退回横排。同样受影响的还有 agent / workflow / 仓库详情页的「记忆」子页签。
内部架构演进(RFC-360 ~ RFC-364)
这一批不改变用户可见行为,是按目标架构(RFC-294)推进的分层演进:运行时管理的用例迁到公共合同之后、运行时选择在 NodeRun 事务内冻结;执行契约的资源与脚本夹具改为注入;源码控制声明启动合同;MCP 诊断的策略与副作用分离。其中与稳定性相关的一条是 Task 的仓库准备改为先落持久化日志、再做工作区副作用——准备进度、源事实快照与补偿动作都有持久证据,daemon 重启后可以从证据恢复已准备好的 worktree,而不是留下一个说不清状态的中间态。
升级说明
- SQLite 新增迁移
0227–0229:分别是工作区准备日志(RFC-363)、提炼来源值域扩容(RFC-366)、事件自动化工作意图(RFC-365)。升级前建议备份数据库。 - PostgreSQL 新增增量升级边
0003–0005:与上面三条同构,原地应用,不需要重做 cutover(v0.19.0 起 PostgreSQL 已有不可变迁移历史与增量升级链)。 - 记忆提炼的默认覆盖面缩小了(RFC-366 能力影响清单 C1–C7,已确认):升级后,定时 / webhook / 事件 / API 启动的任务,其澄清答复、人审决定、任务留言默认都不再入队提炼——这三类此前是无条件入队的。要恢复旧行为,去设置页「记忆」卡片把对应来源加进任务来源白名单(改完即生效,不需要重启)。另外,定时任务里的留言在被准入门挡下时,接口返回的
distilled为false、distillJobId为null,UI 不再显示「已交付提炼」标记。平台内部任务一律不提炼,且没有开关可以恢复。 - 记忆蒸馏的失败现在是显性的:升级后如果蒸馏模型格式写不对,任务会变成红色的
failed并带上失败原因,而不是一个绿色的「0 条候选」。如果你的/memory → 蒸馏任务里突然出现失败行,说明这些任务此前一直在静默丢弃候选。 - 不要在升级后的数据库上直接回退旧二进制:需要降级时,请停机、换回旧版本,并恢复升级前的备份。
完整变更记录:v0.19.0...v0.19.1
Agent Workflow v0.19.0
Agent Workflow v0.19.0
本版本是 v0.18.19 之后的次版本,累计 548 个提交。主线只有一条:数据库 provider 统一抽象(RFC-359)完工。SQLite 与 PostgreSQL 不再是两份各自演化的实现,而是同一份实现跑在两个引擎上。合一过程中照出并修掉了一批「换个数据库结果就不一样」的用户可见缺陷;在 10 万任务规模的真实语料上,PostgreSQL 的三个重端点已经比 SQLite 更快。
本版本有数据库迁移:SQLite 新增 0224–0226(端点 0223 → 0226);PostgreSQL 基线在 v0.18.19 发布后又重采了一次,已经在 v0.18.19 上完成 cutover 的 PostgreSQL 部署需要再重做一次 cutover。从本版本起,PostgreSQL 有了不可变的迁移历史和增量升级链,后续版本可以原地升级。详见文末「升级说明」。
主要更新
数据库 provider 统一抽象完工(RFC-359)
起因是用户的两条要求:「以后不允许再出现两种数据库一个好一个不好的分支」,以及「postgresql 要做到最高性能表现」。v0.18.19 时这项工作还在进行中,本版本 12 条验收标准全部达成。
- 一份实现:约 150 对按 provider 分开写的孪生适配器,合到只剩 3 对。这 3 对都属于「只有一个引擎才有的资源形态」(SQLite 是一个文件,PostgreSQL 是一台服务器),并且每一对都有两个引擎各跑一遍的对拍测试。数千行 PostgreSQL 副本已经退役。
- 一条启动序列、一个事务原语:PostgreSQL daemon 与 SQLite 入口按同样的顺序执行同一份启动、恢复与播种逻辑;事务统一走一个中立的异步原语,不再有「同步事务只有 SQLite 能用」的分叉。
- 验收证据:收口提交的 CI 46 / 46 个作业全绿。其中后端测试在真 PostgreSQL 上跑 23,018 条、在 SQLite 上跑 16,740 条,全部 0 失败。在 10 万任务语料上做
scale=full性能对比,九个端点全部落在登记值以内,两个引擎返回的数据逐端点一致(itemIds/schemaVersion/nextCursor)。三个重端点 PostgreSQL 显著更快:任务列表首屏的中位数快 77.6ms,运行中任务列表快 37.7ms。 - 防止分叉重新出现:测试默认用
describeEachProvider在两个引擎上各跑一遍,缺少 PostgreSQL 连接时直接判失败而不是跳过;孪生适配器数量、裸事务、裸方言等债务都有只降不升的账本守卫。今后新增的功能会自动在两种数据库上接受验证。
合一过程中修掉的「换个数据库结果就不一样」
这些缺陷此前各自的测试都是绿的,直到同一份行为被放到两个引擎上对拍才暴露出来。多数只在 PostgreSQL 上出现:
- 定时启动:在 PostgreSQL 上,定时启动代理任务或工作组任务会直接返回 HTTP 500。
- 延后仓库准备(远端暂时拉不动时):SQLite 会留下一行可重试的任务;PostgreSQL 返回 400,而且一行任务都不留。这条落在最主要的启动接口
POST /api/tasks上。 - 重试调用节点:在 PostgreSQL 上重试一个「子任务已完成」的调用节点会失败,并让整个任务卡住。
- 数字员工计划的人工评审闸门:在 PostgreSQL 上永远不会进入
waiting。 - 取消:PostgreSQL 上的限额取消失效;取消没有读取评审变更号,可能与评审写入交错落库。
- 同名并发创建:在 PostgreSQL 上返回 500,现已恢复为稳定的 409 冲突。
- 工作组房间的确认预检:在 PostgreSQL 上是空操作。工作树已经不存在时,SQLite 返回 410,PostgreSQL 却返回 200,随后任务搁浅。
- 工作流同步:在 PostgreSQL 上会遇到三个问题:血缘写入死锁、内置工作流处理有误,以及预览结果和实际执行的动作不一致。
- 两个引擎行为不一致、统一取较完整一侧的几处:被取消任务的工作树不回收;工作流被删除后,手动执行在两个引擎上给出不同答案;同步缺少回滚基线的跨行预检;源终止在没有驱动时不同步收尾;恢复管理面两个引擎各有一处弱于对方。
- 任务列表(这次是 SQLite 出问题):并发的列表查询会合并成一次,但合并键漏掉了「启动来源」筛选。同一时刻按不同来源筛选的两个请求会拿到同一批结果,比如查
api来源时收到的是定时任务。合并键现在对完整的筛选条件做规范序列化,以后新增筛选项也不会再漏。
性能
- 认证请求不再每次都写库:此前 PostgreSQL 在每个端点上都比 SQLite 多出 6 条语句,全部来自每次认证请求的两笔记账写。现在 PAT 的
last_used_at也按会话早已采用的时间窗口合并更新。 - 单行写入的围栏检查内联:PostgreSQL 单行 INSERT 的 p95 从 18.11ms 降到 4.96ms。
- 概览与徽标少走往返:概览页的六条资源计数合并成一条
UNION ALL(22 条语句降到 17 条);评审徽标从三次串行往返合并为一次,反问徽标计数也收成一条语句。 - 新增覆盖索引:分别覆盖概览计数、按仓库查任务和任务列表的分面统计(两个引擎都有)。
其他修复
- 删除代理的引用检查恢复完整:此前正在运行任务的代理、被定时任务引用的代理都可以被删除,这会导致任务当场失去定义,或定时任务到点后在无人值守时失败;拒绝理由也不会点名是哪项引用挡住了删除。现在五道引用检查全部恢复,拒绝时会列出具体引用。
- 代理引用了已停用的插件时,保存被拒的报错重新是
plugin-disabled,不再是笼统的agent-resources-invalid,用户能直接看出要去启用哪个插件。 - 设置页「按条件批量归档」对非管理员可用:
POST /api/tasks/archive此前对所有非管理员都返回 404,即使对方已被授予settings:write。 - git 操作不再被环境变量
GIT_DIR劫持:GIT_DIR的优先级高于git -C,如果 daemon 在设置了GIT_DIR的环境里启动,git 操作会不报错地打到另一个仓库。 - 后端新增常设的「丢 Promise」lint 门禁:门禁上线当天就修掉了 15 处真实丢弃的异步写。这类问题的症状通常是「写入好像没生效」,而且集中出现在崩溃恢复和并发分支上。
升级说明
- SQLite 新增迁移
0224–0226:0224退役node_runs的血缘补齐触发器,改为在插入时显式写入(这个触发器只存在于 SQLite,是两个引擎分叉的来源之一);0225/0226只新增索引。升级前仍建议备份数据库。 - PostgreSQL 基线重采(重要):v0.18.19 发布后,基线又重采了一次,补上此前只存在于 SQLite 迁移、没有进入 PostgreSQL 的 schema 保护,例如大小写不敏感的唯一索引,contract digest 因此变化。已经在 v0.18.19 上完成 RFC-349 cutover 的 PostgreSQL 部署,需要再重做一次 cutover。
- PostgreSQL 从本版本起支持增量升级:迁移历史的根固定为本版本的基线,之后的 schema 变更以追加的升级边(
0001、0002…)原地应用,不再需要重做 cutover。 - SQLite 写入改为异步执行 + 进程内单写者串行(RFC-359 能力影响 C-2,已确认):事务语义不变,只是并发写请求改为在应用层排队,不再在 SQLite 层 busy-wait。
- 不要在升级后的数据库上直接回退旧二进制:需要降级时,请停机、换回旧版本,并恢复升级前的备份。
完整变更记录:v0.18.19...v0.19.0
Agent Workflow v0.18.19
Agent Workflow v0.18.19
本版本是 v0.18.18 之后的 patch 版本,主线是修复 Windows 上「杀进程 → 重试建不起来 → 任务停摆」的死链(RFC-356,issue #13)、让意图构建(Intent Builder)看得见完整的工作流图校验(RFC-358),以及任务列表页在两个数据库 provider 上收敛为同一份查询(RFC-357)。同时 PostgreSQL provider 的统一抽象(RFC-359)持续推进,本版本修掉了一批只在 PostgreSQL 上出现的功能缺陷。
本版本不含新的 SQLite 数据库迁移(迁移端点仍为 0223)。PostgreSQL 基线(0000_rfc349_baseline)重采,已经完成 RFC-349 cutover 的 PostgreSQL 部署需要重做 cutover,详见文末「升级说明」。
主要更新
Windows:杀进程后重试建不起来、任务停摆(RFC-356 / issue #13)
用户在 Windows + v0.18.14 上报的三行现场——「超时杀进程 → iso worktree 删除失败(Invalid argument,留待 GC)→ 重试重建 iso worktree 报 already exists」——经源码对账确认是一条必然复现的死链,不是偶发。本版本从三处同时堵上:
- 残留工作树回收阶梯:iso 工作树的丢弃改为「
git worktree remove --force→ 退避重试的目录删除 +git worktree prune→ 报告blocked」三档阶梯,不再是一发git worktree remove失败就只 warn 一句「留待 GC」(而 iso GC 明确跳过活跃 / 非终态任务,那句承诺对活着的任务从不成立)。「丢了注册项的残留目录」(git worktree remove报is not a working tree)现在也能被清掉——这是此前平台完全无法自愈的形态。 - iso 键代际自愈:旧 iso 确实清不掉时,重试自动改用新一代 iso 键(
{原键}-2、-3…)建树并继续,不再以iso-recreate-failed把节点和整条工作流永久钉死。wrapper iso 的 resume 路径同样自愈——此前 Windows 上每次 resume 都撞同一堵墙、永久 wedge,也就是 issue 标题里的「循环调度停摆」。 - Windows 进程树归属真正接线:RFC-254 早已写好的 Job Object 归属代码在生产路径上一次都没有被调用,于是杀树一直落在
taskkill /pid <pid> /T /F这个快照枚举降级档(新 fork 的后代直接逃逸),而isProcessTreeAlive在 Windows 上恒返回null(平台无从知道树是否死透)。本版本把 Job Object 接到 spawn 上:杀树走TerminateJobObject的内核级原子终止,杀树之后仍能查内核确认存活数,并在回收工作树之前于预算内等待树静默。没有 FFI 的 Windows ARM64 保持taskkill降级,降级事实在 daemon 启动时 warn 一次,也会出现在失败诊断里。 - 失败信息会自证:真的清不掉时,
iso-recreate-failed的消息会带上残留路径、最后一次错误与本机 Job Object 可用性,而不是一行光秃秃的错误码。 - 连带修复:
handleTaskIdOf此前用split('/')解析由join()生成的路径,在 Windows 上恒返回'unknown',导致带子模块的仓库其 worktree-scoped 池锚点全部串台、按 taskId 的清理永远匹配不上。
意图构建看得见工作流图校验(RFC-358)
起于用户实证「意图创建的东西过不了校验」。此前意图链路只跑第一层校验(句柄 / 挂载 / 模板语法 / tempRef 环),真正的工作流图校验(端口存在性、wrapper 边界、fanout 结构、clarify 多重性、call 闭环与自调用、模板变量来源、agent 的 skill / MCP / plugin 闭包,共 108 个错误码)从生成到落库一次都不跑——于是意图侧全绿落库,坏在编辑器或启动时才暴露,agent 全程看不见、也无法自愈。
- 变更集里的工作流 op 现在会被解析成可校验候选并跑完整图校验:agent 以变更后形态参与,同批新建的 skill / MCP / plugin 注入闭包,同批新建的被调工作流按名字 + id 双键注入 call 闭包,
currentWorkflow补齐自调用与环判据。 - error 以
<opId>:前缀汇入既有 blocking 列表,draft 期就看得见并禁止提交;warning 单独成段呈现,超出上限时显式标注截断。 - 图修复轮:图校验报 error 时自动接一轮让模型自修(预约与 settle 同事务,无 in-flight 空窗);只有图校验的 error 会触发,第一层报错不再自动重跑。
- copy 操作不再丢 sidecar;提交期补一道二次硬拦。
- 改动 agent 时,其下游影响面会在确认页列出(知情不拦截)。
任务列表页:一份查询,两个 provider(RFC-357)
起于用户反馈「切了 PostgreSQL,任务列表还是卡」。对账结论不是「PostgreSQL 慢」,而是这一页在两个 provider 上是两份实现,PostgreSQL 那份从来没有过 RFC-311 的任何一项优化:三个数据源各发一次 limit: 10_000 的裸查询、把 workflow_snapshot(整份工作流定义 JSON,每行上百 KB)等大列一起搬过来、失败任务再逐行 N+1,然后过滤 / 搜索 / 排序 / 分页 / facets 全在 JS 里做。
- 抽出一份 dialect 参数化的页查询给两个 provider 共用;
services/taskOperations.ts(1,196 行 SQLite 专属裸 SQL)整文件删除并归位。 - 分叉带来的用户可见缺陷一并修掉:页签计数不再随选中的页签变(facets 数改在 view 之前算,前端飞行期沿用旧值);启动来源筛选在 PostgreSQL 上「事件」/「API」不再 400、「定时」不再漏子任务;层级与排序不再写死。
- 前端 WebSocket 失效改为按帧增量:
task.status/task.deleted就地 patch,其余仍走失效 + 30s 低频对账。 - CI 新增一条真 PostgreSQL 窄 lane(假 pool 只断言 SQL 文本,证明不了它在真库上跑不跑得动)。
PostgreSQL provider 统一抽象持续推进(RFC-359,进行中)
RFC-359 的目标是「provider 是一个抽象,而不是一个 if」——不再允许出现两种数据库一好一坏的分支。本版本落地的部分已经修掉一批只在 PostgreSQL 上出现的功能缺陷:
- 评审与澄清可用:评审决定 / 评论增改删 / 文档选择、快速澄清决定、反问下发、延迟提问自动派发全部收敛为一份实现跑在统一事务原语上,PostgreSQL 上「评审无法通过 / 驳回、澄清无法回答」以及路由 500 的问题消失。
- 任务能跑起来:八处 owner 围栏此前把「未显式传执行上下文」当作无主,节点的第一次写就被自己 claimed 的 owner 拒掉(每个任务在铸出 node_run 前必死);effect 账本对冻结 token 做等值判定导致首次心跳后所有 effect 写入被拒。两条都已改成与 SQLite 同规则。
- 启动与恢复对齐:boot 恢复四步(撤销旧 owner / 收割孤儿 run / 修 runtime session lease / 清算 effect)、删除认领崩溃恢复、归档与工作区维护恢复、技能启动屏障、定时载荷治愈、webhook 投递恢复等,PostgreSQL daemon 现在与 SQLite 入口同序执行同一份实现。
- 其他 PostgreSQL 专属修复:坏定义的工作流在 PostgreSQL 上也能删除(并补齐两道此前缺失的删除守卫);
count/sum相关计数、NULL 排序、用户搜索召回等差异随合一消除;PostgreSQL daemon 的系统身份改为正式 admit,四条 daemon 自用路径不再抛foreign-legacy-actor-projection;数据库迁移会话不再继承在线请求超时,验证查询失败不再被记成不变量违规。 - 一份实现:约 150 对孪生适配器已合掉大半(task-execution / resource-catalog / collaboration / identity-access / memory / integration / source-control / event-center / code-capability / digital-employee / development-automation 各批),数千行 PostgreSQL 副本退役;双引擎测试 harness 让每个合一批次在两种数据库上各跑一遍,四个 CI 分片各带真 PostgreSQL。
其他修复
- 数字员工 / 开发任务(mission)停在 working 不动:根因是事实写回被并发挤掉后没有重试,以及悬挂在
prepared的自治 effect 被决策去重吞掉;reconcile 路径上同族的无校验 OCC 写回一次扫干净。 - 终态维护的水位覆盖判据只对最高代际比 digest,冲突归类为 busy(不再误判)。
- 修复重启会杀掉「已回答澄清」续跑的问题(补回 RFC-187 T13 的复活路径)、收尾轮丢派单、系统消息分类判据丢失、流中断的重跑不进账本等一批合一过程中暴露的回归。
- 意图链路:apply 层 changeset 校验收成一份(SQLite 不再裸
JSON.parse);services/intent/5,136 行整目录删除、路由迁入模块并收成 decode-call-map(RFC-355)。
升级说明
- 无新增 SQLite 迁移:迁移端点仍为
0223。仍建议升级前备份数据库。 - PostgreSQL 基线重采(重要):
webhook_deliveries的两条部分唯一索引与user_identities的 provider+subject 唯一索引此前只存在于 SQLite 迁移、没有进入 drizzle 声明,PostgreSQL 侧因此没有去重键。本版本补上声明并重采了 PostgreSQL 基线(contractDigest变更)。已经完成 RFC-349 cutover 的 PostgreSQL 部署需要重做 cutover;PostgreSQL 增量迁移能力仍在 RFC-359 W5 中,尚未提供。 - Windows 行为变更(RFC-356,均为有意变更):
- daemon 进程退出(含崩溃 / 被强杀 / 优雅停机的超预算幸存者)时,在跑的 runtime 子进程会随 Job Object 关闭被内核一并终止——此前它们会留成孤儿、等下次启动收割。
- 正常成功退出的运行,其幸存后代也会在收尾时被终止(它们正是持有工作树句柄的那一批)。
- 被杀掉的运行,其结束时间会晚最多 2s(等待进程树静默);正常退出的运行时序逐字不变。
- 磁盘上可能多出一个暂时清不掉的残留 iso 目录(自愈换新路径的代价),它会在任务终态时由既有 iso GC 一并删除。
- Windows ARM64(无 FFI)保持
taskkill /T /F降级,不新增平台专属杀树路径。
- POSIX 平台行为不变:macOS / Linux 上杀树仍走进程组,时序逐字不变。
- 不要在升级后的数据库上直接回退旧二进制:需要降级时,请停机、换回旧 binary,并恢复升级前备份。
完整变更记录:v0.18.18...v0.18.19
Agent Workflow v0.18.18
Agent Workflow v0.18.18
本版本主线是 PostgreSQL provider 与一键迁移、节点语义统一(包装器可任意深度嵌套)、技能来源追溯:平台新增第二种数据库 provider,管理员提供一个外部 PostgreSQL 后一次点击即可完成检测 / 备份 / 迁移 / 校验 / 切换,且可续跑(RFC-349);工作流的每一种节点收敛为「参数 / 返回值 / 闭包 / 帧」四个概念,loop in loop 等嵌套不再被拒绝(RFC-354);技能版本可追溯到它吃进了哪几条记忆(RFC-353)。同时新增任务不活跃超时收割(RFC-350),并完成 Memory / Knowledge Evolution 两个 bounded context 的合同归位(RFC-352 / RFC-353)。
本版本含 1 个 SQLite 数据库迁移(迁移端点 0222 → 0223),并新增独立的 PostgreSQL migration history;工作流定义 schema 从 v5 升到 v6。升级前请务必备份数据库并阅读文末「升级说明」。
主要更新
PostgreSQL provider 与一键迁移(RFC-349)
- 新增
database.provider:sqlite(缺省,零配置安装完全不变)与postgresql。PostgreSQL server 由管理员、Docker / 编排环境或云厂商在二进制之外提供;单二进制自带 client adapter、连接池、双 dialect migration 与迁移引擎,不内嵌、不安装、不启动数据库 server,也不依赖本机psql/pg_dump。 - 一键迁移:Settings 与 CLI 调同一个 durable operation,自动串起 preflight → 受控维护模式 → SQLite 安全备份 → 目标 schema 初始化 → 分批复制 → 逐表校验 → provider 切换 → 健康检查,全程可查阶段 / 进度 / 错误;中断后从 durable checkpoint 续跑,而不是清库重来。
- 迁移窗口内停止新业务 admission,drain / fence writer、后台 job、outbox 与 apply,并保留独立的迁移状态页与诊断。
- 失败在 cutover horizon 之内自动留在或退回 SQLite;一旦 PostgreSQL 已接收业务新写,旧 SQLite 不再是无损回滚点(须走反向迁移)。
- 新增 canonical schema contract:184 张表逐张归入
KEEP/ARCHIVE_THEN_OMIT/DEFER;首批 6 张已证明零生产消费者的 legacy 表归档为只读 artifact 后不进入 PostgreSQL,其余 legacy 历史表继续在线迁移。 - backup / restore / doctor / readiness 按 provider 各自实现等价能力:SQLite 保留 PRAGMA / WAL / VACUUM 文件备份,新增 provider 中立的版本化逻辑备份(同版 manifest + chunks,可在空 target 完整还原),PostgreSQL 侧另有定时逻辑备份。
- 迁移期间的响应性修复:安全备份的完整性校验挪出主线程(此前会把 daemon 冻住十几秒)、拷贝阶段不再把整张表攒在内存里、块写入路径去掉重复校验(单块写入降 77%)、事件循环停顿超阈值当场记 WARN。
- 双 provider 行为差异修复:PostgreSQL 上 identity 列写不进去、布尔列被赋整数导致定时任务停不掉、
count/sum以字符串返回而静默改写计数与配额、两个 provider 的NULL排序相反导致认领扫描饿死新条目、用户搜索静默少召回,以及常态下的三处 500 与割接窗口的 WS 升级裸奔。 - 取证:1320 万行迁移 errors 0、crash/resume 26/26、三平台单二进制全绿、event-loop 最大停顿 493.6ms / 498.1ms(门槛 500ms,全程未调整)。
节点语义统一:参数 / 返回值 / 闭包 + 帧(RFC-354)
- 每一种节点现在只有四个概念:参数(以它为 target 的边)、返回值(以它为 source 可用的端口)、闭包(体外直连体内的边,容器执行打开时按词法环境绑定)、帧(每次执行一行
node_runs,挂在所属容器执行之下)。 - 包装器嵌套开放到任意深度:
loop in loop、三层以上嵌套均可保存并启动,wrapper-loop-nested禁令退役。node_runs新增帧轴(container_run_id+scope_path),iteration收窄为帧内轮次,嵌套不再碰撞。 - 闭包读点改读容器打开时绑定的环境(沿帧链查找),此前「
iteration ≤当前轮取最高」的数值近似退役——两层 loop 之内的 agent 也能拿到同一份外部值。 - PortRef 字段全部退役、由边表达:
review.inputSource、output.ports[].bind、wrapper-loop.outputBindings/exitCondition.nodeId、wrapper-fanout.inputs[]从定义中删除;loop 的返回值改用wrapper-output边界边(与 fanout 同形),退出条件改为对 loop 自己的返回值端口的谓词。导出的 YAML 更短,手写时只写edges。 - 系统通道注册表折进端口表,clarify 家族改用自己的行表达生命周期:未触发的轮次铸
skipped行,触发的轮次显示问答。 - 任务详情按帧展示:面包屑(如「外 2 › 内 3」)、抽屉帧行、运行历史分帧;崩溃恢复与单节点重试都按帧定位与级联。
- 把 wrapper 拖进 fanout 现在在校验面板立刻报错,而不是启动后才抛
v1-unsupported-inner-kind。
技能来源追溯与 Knowledge Evolution 归位(RFC-353)
- 新增
GET /api/skills/:id/provenance;技能详情页的版本行可展开,直接看这一版融合吃进了哪几条记忆——此前只有一句 changelog。 - 融合(fusion)的编排、状态机、worktree seeding、恢复循环与技能版本回滚整体迁入新的
knowledge-evolutionbounded context;/api/fusions全部端点与skill-catalog.restore-skill-version.v1的路径、入参、响应、错误码与权限逐字不变。 - fusion 持久化不再是跨聚合 god repository;技能回滚的记忆退还(unfuse)改由成员关系协调完成。
任务不活跃超时收割(RFC-350)
- 新增
taskIdleTimeout { enabled, idleHours }:任务树在阈值内没有任何 agent 事件或人类推进动作(评审决策 / 反问答复 / 问题派发决策 / 手动 resume·retry),则先杀 runtime 子进程树、再判canceled,详情页与审计写明静默时长与进程终止结果(含kill-failed/window-expired)。 - 开关默认关闭;开启后出厂阈值 168 小时(7 天),可配 1–8760 小时。收割只负责判终态,出库仍由既有
taskArchive保留期完成,两道开关正交。 - 补齐
interrupted任务树的归档面:daemon 重启翻出来的interrupted此前永远不会被归档删除,现在随既有taskArchive开关一起出库。
结构归位与稳定性
- Memory bounded context 合同归位(RFC-352):注入 / 蒸馏 / 调度 / 源上下文渲染迁进
modules/memory,删掉 8 个兼容 facade;授权谓词从 SQLite adapter 提到 application 层;记忆列表新增可选分页(既有调用者零改动)。用户可见行为、权限档位零变化。 - SQLite 写事务一律预占 writer(RFC-351):37 处绕过
dbTxSync的裸db.transaction收敛到统一原语,修掉「先读后写」升级触发SQLITE_BUSY_SNAPSHOT、在 HTTP 边界被兜成 500internal-error的问题(工具发布接口的偶发 500 即属此类)。 - Resource Catalog 合同 cutover 收口(RFC-345),HTTP 守卫扫描面随路由迁位一并扩到模块 inbound。
- 前端:资源权限保存撞 409 后丢弃本地草稿并刷回服务端权威值,不再让界面停在过期状态。
- CI:
postgresql-evidence周跑从两小时压到半小时,回归 lane 不再串在长 job 之后。
升级说明
- 数据库迁移:新增 SQLite migration
0223(node_runs帧轴)。另新增独立的 PostgreSQL migration history(0000baseline),仅在切换到 PostgreSQL 时使用。升级前务必备份数据库。 - 工作流 schema v5 → v6(重要):已保存的工作流定义读出时透明升级,画布与运行行为一字不差;导入 v4 / v5 YAML 同样自动升级。但 v6 导出的 YAML 无法被升级前的 daemon 导入(向下不兼容)——跨版本共享 YAML 的团队需要同步升级 daemon。
- 默认值不变:不配置
database.provider继续使用 SQLite,零配置安装路径与升级前一致;taskIdleTimeout.enabled默认为false,不会有任务因不活跃被自动终结。 - 切到 PostgreSQL 之后:cutover 后一旦产生业务新写,旧 SQLite 不再是有效回滚点,回退必须走反向迁移;源库、备份与 manifest 在管理员显式 finalize 且保留期满足前不会被删除。V1 有明确维护窗口,不承诺零停机,也不因能连 PostgreSQL 就开放多 daemon 或水平扩容。
- 不要在升级后的数据库上直接回退旧二进制:需要降级时,请停机、换回旧 binary,并恢复升级前备份。
完整变更记录:v0.18.17...v0.18.18
v0.18.17
Agent Workflow v0.18.17
本版本主线是后台维护隔离、人工评审协作与 Intent 能力全景补齐:重维护任务迁入独立 Worker,支持每小时错峰或按 IANA 时区每天定时运行(RFC-338);任务可按具体 review 节点配置只提交意见的评审人(RFC-340);Intent Builder 现在从注册表获得完整能力教学、运行时与平台资源清单,并修复 agent 分支端口在更新时丢失的问题(RFC-348)。同时,任务生命周期与评审 / 反问 / 问题协作切入可重试的已提交事件链(RFC-341),Memory scope move 与 Intent Apply 的恢复一致性得到收口(RFC-342 / RFC-343)。
本版本含 7 个数据库迁移(迁移端点 0215 → 0222),升级前请务必备份数据库并阅读文末「升级说明」。
主要更新
后台维护不再阻塞页面(RFC-338)
- 数据库归档、保留期删除、worktree / 上传目录回收、WAL checkpoint 等同步重维护改由独立 Worker 和独立 SQLite 连接执行,HTTP / WebSocket 主事件循环只做轻量协调。
- 「设置 → 存储与保留」新增后台维护卡:可保留默认的每小时错峰,也可设置每天
HH:MM + IANA timezone启动一次;保存后显示 next / current / last / backlog / error。 - 重维护按可恢复的小切片串行执行;遇到前台写入时快速退让,Worker 崩溃后通过 durable slot / lease / cursor 接续,不重复启动同一 job。
- 正确性与恢复任务保持原有 boot / 周期语义,不会因为选择 daily 而被推迟到夜间。
Intent Builder 获得完整能力全景(RFC-348)
INTENT.md改由闭合注册表派生;新增节点、资源或字段时若没有同步登记教学内容,编译期与架构门会直接报错,避免模型长期看不到平台新能力。- dump 新增运行时清单、agent 输入 / 输出端口名,以及此前缺失的 9 类平台资源真实清单;模型可据此选择现有 runtime、资源和端口并正确接线。
- agent 的
branchPorts现在可创建、读取、更新与清除;更新时省略该字段会保留原值,不再意外清空分支端口。 - remote MCP 可由 Intent 配置 OAuth 客户端信息;
clientSecret继续走 secret 槽位,更新时省略则沿用既有值。 - 教学内容补齐权限、hint、loop / runtime 等现行字段,并移除已退役的
overrides教学,减少无效草稿。
节点级意见型评审人(RFC-340)
- 可按
task + frozen review node配置评审人,而不是把评审人提升为整任务成员。 - 评审人能查看该节点的全部评审文档与意见,并新增、修改或删除自己尚未结算的意见。
- 评审人不能 approve / iterate / reject,也不能替文档做采纳选择;任务 owner / collaborator 继续负责最终决策。
- 新增独立配置页与节点级入口,评审人的任务列表和评审页面只投影被指派节点所需的信息。
已提交事件与崩溃恢复(RFC-341)
- 任务生命周期以及 review / clarify / questions 写操作改为领域状态与 committed event 同事务提交,避免状态已成功但通知 / 后续推进丢失。
- 每个 consumer 独立 claim、retry、dead-letter;一个消费者失败不会让已成功消费者重做,也不会阻塞其他 aggregate。
- 人工门 continuation 统一交给常驻 Worker 消费,HTTP 请求只返回已提交 receipt;请求结束、daemon 重启或短暂故障后仍会继续推进。
- Event Center 现在是 producer event 与 delivery failure 的统一运维入口,可查看 attempt / error / cutover 状态并对失败 delivery 执行精确重试。
Memory 与 Intent 一致性修复(RFC-342 / RFC-343)
- Memory 内容编辑与 scope move 拆成两个命令:普通 PATCH 只改 title / body / tags;candidate memory 通过 versioned Move 更换 scope,并在同一事务写 durable receipt。
- approved / archived memory 的 scope 在界面中明确冻结;candidate move 采用 expected-version CAS,失败 / 回滚不会提前广播
memory.updated。 - Intent Apply 修复 session 锁残留、补偿失败被错误终结、skill version journal 信息不完整以及 committed 后反向补偿等恢复缺口;崩溃后可幂等 roll forward。
Runtime、架构与跨平台修复
- WrapperRuntime 完成 W2-D cutover:loop / git / fanout wrapper、scope / progress 与 merge recovery 进入 task-execution 的单一生产链;现有 wrapper 行为保持不变。
- HTTP 与 MCP 操作统一到 OperationCatalog / 同一 mounted handler chain;System Operations、Identity Access 与 Resource Catalog 的多个聚合完成 typed command / query 和 bootstrap adapter cutover。
- 源码工具链与发布构建升级到 Bun 1.4.0。
- 修复 Windows standalone binary 在 launcher / relay 链路中丢失 stdout / stderr、完成标记与句柄生命周期的问题;发布产物继续覆盖 Windows x86_64、macOS arm64、Linux x86_64 / arm64。
- 任务创建向导的 working branch 配置移到仓库步骤并默认可见,空值仍表示使用仓库默认分支。
升级说明
- 数据库迁移:新增
0216~0222共 7 个 migration。0216增加可恢复维护运行账本;0217增加节点评审人关系;0218~0220建立并切换 task committed-event / delivery 表;0221增加 Memory scope move receipt;0222原子切换 review / clarify / questions delivery。升级前务必备份数据库。 - 维护默认值兼容:升级后仍使用每小时错峰,不会自动改成 daily;管理员可在设置页主动选择每天固定时刻。
- 源码构建要求:从源码运行或构建现在要求 Bun
>=1.4.0;GitHub Release 中的单文件 binary 已自包含运行时。 - 不要在升级后的数据库上直接回退旧二进制:需要降级时,请停机、换回旧 binary,并恢复升级前备份。
完整变更记录:v0.18.16...v0.18.17
v0.18.16
Agent Workflow v0.18.16
本版本主线是数字员工任务的创建与详情两端补齐:创建端补上协作者 / 工作分支 / 最大运行时长 / Token 总量上限四项高级选项(RFC-336),详情端改为「概览 / 详细信息 / 产物 / 执行记录 / 关注与协作」五页签并让 MR 一键直达(RFC-337)。同时 OIDC 的显示用户名与 Git 提交名分离(RFC-335):Provider 可分别指定两个字段,账户页分开编辑,新任务只冻结 Git name。后台目标架构完成 W2-C 一波(RFC-334 NodeExecutorRegistry,零产品行为变化),另修掉多写者任务自动提交推送时的 .git/index.lock 竞态。
本版本含 2 个数据库迁移(迁移端点 0213 → 0215),升级前请务必备份数据库并阅读文末「升级说明」。
主要更新
数字员工任务创建:高级选项补齐(RFC-336)
- 数字员工的「任务内容」步现在与编排任务同形,提供协作者、工作分支、最大运行时长、Token 总量上限四项高级设置;确认步同步展示已选值。四项由同一个按 capability 渲染 / 校验的共享组件承载,不再各来源各写一套。
- 明确不提供「自动提交并推送」开关:数字员工的验证 → commit → CAS push → 创建 / 更新 MR 是平台固定职责,不是可选项。
- 协作者随 Case 原子创建:复用既有 Case 成员关系表,创建事务内直接种下成员行,不再有「创建成功但协作者丢失」的窗口。
- 时长与 Token 是本 Case 的累计上限:跨多轮 Reaction 以 exact-once 的计量回执累计(新增
employee_case_metering_receipts表),内部任务只接收本轮剩余额度,不反过来成为 Case 的配置真相。 - 工作分支真的生效:由员工类型的 capability 声明、冻结进类型 Context,并成为发布链的 source branch。
- 默认行为兼容:四项都不填时与升级前完全一致。
数字员工任务详情:信息架构与交付可见性(RFC-337)
- 运行态只显示一个真实输入:职责图不再把创建任务时的三个入口(正文 / 文件、外部编号、issue 事件)当成运行中操作;只呈现本 Case 实际收到的那个输入(恒为绿色「已接收」),点击在当前页打开完整冻结输入检查器,不再跳去任务创建页或事件中心。
- 五个 URL 页签:概览(输入 / 仓库 / 目标分支 / 当前 MR / 职责图)、详细信息(全部冻结参数与 Context 技术记录)、产物(修改候选 / MR / artifact refs)、执行记录(每轮时间轴、输入输出、Session)、关注与协作(Attention / 事件队列 / 委托)。
- 补齐关键参数:首屏与详情现在显示仓库、目标分支 / 源分支、基线 SHA、执行选项与修改候选——这些事实此前已保存在工作区表与 Context 里,只是页面没读。
- MR 一键直达:MR 创建成功后,页头、职责 2 以及「提交 MR / 关注 MR / 判断可合入」三个工作项和产物页都链接到同一个已保存的 MR
webUrl。 - 零迁移、零执行状态机变化;共享 route / panorama 不硬编码 development / MR 工作项,由类型自有的只读 detail presenter 投影。
OIDC 显示用户名与 Git name 分离(RFC-335)
- Provider 设置:原「用户名字段(Git user.name)」改名为「显示用户名字段」(wire 仍是
usernameClaim,写入产品显示名),旁边新增「Git name 字段」(gitNameClaim,写入新的users.git_name)。两项都支持 1–8 个 claim 按顺序拼接。 - 账户页拆成显示用户名、Git name、Git email 三项分别展示与编辑;产品内列表 / 头像 / 成员选择器仍显示显示用户名,新任务冻结
gitName <email>作为提交身份。 - 每次 OIDC 登录都刷新:existing 登录、首次自动建号、邀请绑定、手工关联四条路径都在创建 session 前按本次 IdP 值对账两个名称;站内手工修改只保留到下一次 OIDC 登录(账户页有明确提示)。
- 显式配置即严格合同:配置了任一 selector 后,若本次 userinfo 缺少全部配置字段或拼接结果为空,本次登录失败并指明是显示用户名还是 Git name 配置有误——不再静默保留旧值。
- 已创建任务的
git_user_name / git_user_email、历史 commit、push 凭据与 RFC-321 publication credential 均不变;users.username登录 handle 也不受 OIDC 刷新影响。
后台目标架构演进:NodeExecutorRegistry(RFC-334,W2-C)
- 建立以 14 个
NodeKind闭合驱动的NodeExecutorRegistry:DAG 节点与工作组 host 都经 task-execution 的单一 node execution gateway 执行;legacyscheduler.runOneNode的长if链与runHostNode复制体已删除,scheduler.ts由 9.3k 行缩到 3.8k 行。新增 kind 若缺 executor 会在装配期被闭合表拒绝,不再等到运行时才以unhandled-node-kind失败。 - RFC-313 的中性 retry cap 算术抽到
platform/contracts,TaskExecution 专属的 followup / restart 状态归回本域。 - 零产品行为变化、零迁移、零新增权限或策略;W2-D WrapperRuntime 尚未启动。
其他修复
- 多写者任务的自动提交推送竞态:本地
git commit现在重新持有任务写锁,不再与同任务并发写者节点的 Git 生命周期争抢.git/index.lock;LLM 生成提交信息与网络 push 仍在锁外执行,不阻塞其他节点。 - CI 时序修正:daemon 就绪等待在高负载 macOS runner 上按既有 10 秒预算完整等待(产品行为与上限不变);工作流启动器 e2e 夹具改用唯一搜索结果选取。
升级说明
- 数据库迁移:新增 2 个(
0214_rfc335_oidc_git_name.sql、0215_rfc336_employee_case_advanced_options.sql),迁移端点由0213前进到0215。升级前务必备份数据库。0214给users增加git_name列并以当前display_name回填(存量用户 Git 提交名不变),给oidc_providers增加git_name_claim(默认空 = 跟随显示用户名)。0215给employee_cases增加max_duration_ms / consumed_duration_ms / max_total_tokens / consumed_total_tokens四列,并新增employee_case_metering_receipts表;纯新增,不改动既有行为。
- 权限目录不变:本版没有权限点增删或改名,也没有能力收缩。
- OIDC 管理员请注意:升级后若希望 Git 提交名与产品显示名取自 IdP 的不同字段,到 Settings → Authentication → OIDC Provider 配置「Git name 字段」;不配置则 Git name 继续跟随显示用户名。一旦显式配置 selector,缺少该 claim 的 IdP 用户会登录失败,请先确认 IdP 对所有用户都返回该字段。
- 仍不能回退运行旧二进制(沿自 v0.18.14 的 RFC-328 能力影响 4):升级后的数据库不能原地跑旧 binary 的任务执行。需要降级时停机并恢复升级前备份(
restore会拒绝比当前二进制更新的备份,务必先换回旧二进制再 restore)。
v0.18.15
Agent Workflow v0.18.15
本版本主线是人工门的原子停驻与持久续跑(RFC-333,收口 RFC-294 P0-C):评审 / 反问 / 提问三类人工门的「打开门」与「提交决定」各自收敛成单个事务,提交后的续跑由唯一的驱动协调器负责唤醒与恢复——提交界面不再出现「决定已提交,但续跑可能失败」这种自相矛盾的回执。另含后台目标架构的两波演进(RFC-331 W2-A 拓扑切分、RFC-332 W2-B TaskEngine 拆分,均零产品行为变化),以及任务推送的代码平台端点解析、Windows 运行时版本探测、首个管理员初始化表单校验、案例成员的任务列表归属等修复。
本版本含 2 个数据库迁移(迁移端点 0211 → 0213),升级前请务必备份数据库并阅读文末「升级说明」。
主要更新
人工门原子停驻与持久续跑(RFC-333)
- 打开门是一个提交:review / clarify / questions 的 gate、round、doc manifest、node 投影、task 状态转移(
awaiting_review/awaiting_human)与 committed event 现在同属一个TaskParkTx。此前是「领域事实先后写入,TaskEngine 稍后再单独停驻任务」,进程在中途中断会留下「有 parked node 却没有完整 gate manifest」「有 gate row 但 task 仍是 running」「已广播但事务组合未完成」这类中间态。 - 提交决定也是一个提交:回答 / 评审决定 / 提问派发与 node 投影、task 回
pending、恰好一条 RFC-328gate-continuationintent 同事务落地;提交之后才由 RFC-332 的唯一TaskDriveCoordinator唤醒或恢复。三条人工门路由里直接调用resumeTask的生产路径归零。 - 不再把内部续跑失败当成决定失败回报:路由返回已提交的决定回执,唤醒失败只进入持久恢复通道由守护进程重试;daemon 重启后能从已提交的决定继续,网页与 MCP 都不再需要各自的补偿逻辑。
- 多文档评审轮次整轮原子可见:此前逐个文档先写文件再插 row,中断会留下不完整的一轮;现在文件等 DB 外产物先进 prepare 日志,最终事务只消费已准备好的引用。
- 收尾阶段咬出并修掉两条真实功能缺口:慢 sibling 的
claimed → pending交接;auto-dispatch 的 deferred question 被初次手工停驻抢先重停,导致已经铸好的前驱重跑执行不了、排队的后续也点不着。 - 既有能力逐项保持:评审的 approve / reject / iterate、评论与选区、rollback、蒸馏;反问的部分 / 完整回答、directive、defer / stop;提问的提问者台账、批量回答、定向重跑;手工提问的可创建范围——输入、顺序、规则与最终结果均不变,REST / MCP / 网页 wire 无破坏性变化。
后台目标架构演进:任务执行的拓扑切分与引擎拆分(RFC-331 / RFC-332)
- RFC-331(W2-A):以实例注入切断 task → scheduler 的四条 drive、scheduler → task 的三条 child-control,以及任务状态发布与调用图查询共六条 exact debt;backend / repo 值级 SCC 由 5/7 降到 4/6,task 的强连通族消失。
- RFC-332(W2-B):initial / resume / retry-prep / retry-node 四路已准入执行汇入唯一
TaskDriveCoordinator;仓库准备成为复用 RFC-328workspace-prepare账本的 phase 0;task 级 hydrate / claim / settle 与 DAG 的 frontier / scope / graph 从scheduler.ts迁入 task-execution 并形成唯一 owner;执行入口收敛为dag | workgroup-turns | dw-generate三路闭集。 - 两波均为零产品行为变化、零迁移、零新增权限或策略,为后续的节点执行器注册表(W2-C)让路。
其他修复
- 任务推送的代码平台端点解析在部分启动路径上丢失(RFC-321 后续):仓库 publication transport 现已贯穿全部任务启动与续跑拓扑,provider 元数据优先,既有管理员 mapping 与 SaaS 约定回退保持不变;并加了覆盖全部生产启动 / 拓扑调用点的架构棘轮防止再次漏接。
- Windows 上运行时版本探测拿不到输出:不再以 detached 方式启动
.cmd探测(Bun 在该形态下丢掉管道输出),同时保留 POSIX 进程组清理与 Windows 进程树 kill 的超时处理;Windows 平台工作流补上真实opencode.cmd回归用例。 - 首个管理员初始化表单:全部校验约束常驻可见,非法提交渲染所有字段错误并聚焦第一条,改用共享 bootstrap schema,单测与 Chromium 覆盖同步扩展。
- 案例成员看不到自己参与的案例(RFC-330 缺口收口):数字员工案例进入统一任务列表的「我的」/「与我共享」两档(我的 = 发起人 ∨ 成员,与我共享 = 成员 ∧ 非发起人,无主案例同样成立),facets 同口径;任务侧「与我共享」对无主任务也成立。
- 清理若干 Windows / macOS 上的运行时与 e2e 时序竞态(已回答反问与随后停驻评审门的先后、冷启动余量、生命周期终态等待)。
升级说明
- 数据库迁移:新增 2 个(
0212_rfc333_human_gate_operations.sql、0213_rfc333_gate_continuation_handoff.sql),迁移端点由0211前进到0213。升级前务必备份数据库。0212新增collaboration_gate_operations与collaboration_gate_artifacts两张表,记录三类人工门命令的 prepare / commit / recovery 状态与 DB 外产物;纯新增,不改动既有表。0213把task_execution_intents的活动索引拆成pending与claimed两条局部唯一索引,使「决定已提交并铸出新 continuation」与「上一任 owner 仍在交接」可以同时成立。
- 权限目录不变:本版没有权限点增删或改名,也没有能力收缩。
- 仍不能回退运行旧二进制(沿自 v0.18.14 的 RFC-328 能力影响 4):升级后的数据库不能原地跑旧 binary 的任务执行,旧 binary 不懂 epoch fence。需要降级时停机并恢复升级前备份(
restore会拒绝比当前二进制更新的备份,务必先换回旧二进制再 restore)。
v0.18.14
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
v0.18.13
Agent Workflow v0.18.13
本版本交付四条线:数字员工的可理解性(RFC-318 把研发链路重做成九个原子业务节点、RFC-323 把 Adapter 从「分类共享工具」搬到「按员工绑定的泳道卡」);身份与凭据(RFC-320 用户档案成为 Git 提交身份的唯一来源、RFC-321 平台发布按归属用户选择个人/公共代码平台 token 并把受管 SSH remote 解析为 HTTP(S));授权与外部接口(RFC-324 资源授权分档为只读 / 可编辑、RFC-326 评审门补齐 MCP/API 完整面、RFC-327 记忆按 scope 与标签检索);稳定性与工程质量(RFC-322 修掉生产上「每隔一段时间全站冻结约 30 秒」、RFC-325 全平台下拉框默认带搜索、RFC-319 用户面 e2e 覆盖加固)。
本版本含 3 个数据库迁移与多处 wire 破坏性变更(任务创建不再接收 gitUserName / gitUserEmail;ACL 与任务成员端点的 userIds 改为带档位的 grants / members),升级前请务必备份数据库并阅读文末「升级说明」。
主要更新
数字员工:原子研发节点与按员工绑定的 Adapter(RFC-318 / RFC-323)
- 九个原子业务节点(
development@9类型包,@1..@8保持不可变):准备外部材料 / 编写实现方案 / 实现变更 / 处理检视意见 / 采集流水线状态 / 分类流水线失败 / 修复流水线失败 / 解决合并冲突 / 编写审批草稿。内部 work item 拓扑不变,development@9把现有九个业务位置绑定到九个 v2 contract。原则只有三条——一个节点只做一个业务动作;tool 只收自己会消费的业务字段、只返回自己负责的业务结果;平台身份、调度、Context、workspace 量测与外部发布状态继续由平台机制负责。使用者看节点卡片即可回答「这个节点做什么 / 本次要输入什么 / 完成后留下什么 / 哪些才需要配置」,不必理解平台 envelope。 - Adapter 按员工绑定:
connectionRef不再挂在分类工具注册上——此前同一个工具一旦绑定 Jenkins,员工 A 与员工 B 想用不同系统就只能复制两份工具注册。现在 Adapter 卡固定显示在声明 slot 的泳道首位,岗位模板给默认值、具体员工可覆盖;创建 / 编辑 / 发布 / 归档 / ACL 全部在就地弹窗完成,员工发布时冻结 exact revision + content digest + 来源,运行时不自动追最新。 - 流水线采集改由平台 Adapter 执行:
collect-pipeline的企业事实取得不再允许自定义工具直接持有连接 / 凭据;Adapter 声明了 secret key 而 daemon 缺值时,由「可能运行后自行失败」改为 spawn 前 fail closed 并给出 typed remediation。 - 旧界面退役:
/code/executors与/code/config/adapters[/<id>](含原始 JSON 编辑器)删除,旧 URL 重定向;历史 Adapter 资源、API、表与 exact revision 一律不删,在途 Case 已冻结的 revision 语义不变。
用户档案驱动的 Git 提交身份(RFC-320)
- 用户档案是 Git 提交身份的唯一来源,任务行是启动时的不可变快照:
user.name = users.display_name、user.email = users.email,任务创建时冻结进tasks.git_user_name/git_user_email,执行期注入GIT_AUTHOR_*/GIT_COMMITTER_*。任务向导不再逐任务填写身份。 - OIDC Provider 配置界面并列提供「用户名字段」(
usernameClaim) 与「邮箱字段」(emailClaim),都可填自定义 userinfo claim;配置后即为严格合同——缺失 / 非法直接拒绝本次登录,不静默回退标准email。每次登录刷新身份快照,并按三方快照语义同步档案(唯一例外:账号邮箱为空时下次拿到合法邮箱立即补齐)。 - 新任务必须有完整显示名与邮箱,邮箱为空即拒绝创建,不退回后台统一身份。
用户级代码平台推送凭据与 SSH→HTTP(S) 传输解析(RFC-321)
- 平台拥有的每一次 Git 发布,都按该工作的归属用户选择「个人代码平台 token → 平台公共 token」,把受管 SSH remote 解析成无凭据的 HTTP(S) endpoint 后,以一次性、目标绑定的 credential lease 完成整笔发布。账号页新增「代码提交与推送」页签自助录入个人 token。
- 失败一律 fail loud:个人 token 失效不会无提示切换为公共身份;私有化部署 SSH/Web 地址不对称而 API 或管理员 mapping 缺失时不猜地址、直接拒绝;受管凭据存在时不再回退 URL 内嵌 token 或 SSH key。
- 父仓 / 子模块改为逐 remote 选择凭据,父仓 token 不再隐式覆盖子模块。agent / runtime 自己执行的
git push继续拿不到平台 token。
资源授权分档:只读 / 可编辑(RFC-324)
resource_grants新增level('read'|'write'),存量行全部回填read——迁移前后对同一账户的可见性 / 可写性判定逐位不变(872 条断言的穷举等价性测试锁死)。判据内核抽成零依赖的resourceAccessPolicy.ts。- 13 类资源的写门分档:只读被授权人对任一写路由得到 403
resource-read-only(不是 404、不是裸 forbidden),前端进入真只读态(画布拖不动、表单禁用、保存不可用),403 文案从「可能已删除」分流为「你对此资源只有只读授权」。 - 任务成员出现「观察者 / 协作者」两档,新加成员默认协作者(与今天同权);定时任务新增两档 + ACL 端点,其可编辑档不含改绑启动目标与改名(定时任务到点以 owner 身份发起,改绑等于借 owner 身份跑任意东西)。
- 降档实时生效:新增
resource-acl.changed控制帧——此前 RFC-212 的连接重扫对降档(仍然看得见)什么都不做,页面不刷新就切不到只读。
评审门的 MCP / API 完整面(RFC-326)
- 本地 AI 客户端通过 MCP 就能走完一整轮评审:找到待审 → 读正文(单 / 多文档、当前 / 历史)→ 逐条提意见 → 逐篇采纳 → 做决策,能力面与网页一致。此前 MCP 只有三个门工具且
submit_review只送决策,iterate 因枚举不一致(iteratevsiterated)根本打不通。 - 提意见只需要正文里逐字出现的一段引文(
quote)+ 可选出现序号 / 章节,完整锚点由服务端按 markdown 源文解析;找不到或歧义时明确报错并列出候选,简化锚点绝不猜。REST 同步接受简化锚点,MCP 仍经 Dispatcher 走/api/reviews/*,不出现第二个更弱的授权面。 - 意见与决策可逐条提交也可一次打包(
comments[]/selections[]),全部评审持久状态在一个数据库事务里落地——任一校验失败零写入,不再有半决策态。 - 网页评审页对任何自洽锚点按源文偏移精确高亮:引文含行内标记、跨段落、锚在含标记的标题上、落在围栏代码块里都在正确位置出现
<mark>,不再有「按序号猜」的全局回退。 - 顺带还掉 RFC-247 门工具零测试的债,并加一条「路由 ⟷ 工具双向完整」的棘轮。
记忆按 scope 与标签检索(RFC-327)
- REST 记忆列表支持多标签过滤,语义可选
any(缺省)/all,保留既有单值tag。 - 新增
GET /api/memories/facets:在调用者可见的记忆上聚合标签与计数,可按 scope 收窄——「有哪些标签可选」此前全仓无处可问,代理写记忆只能凭空造词。 - MCP
resource_read支持query透传与method:'facets',describe_resource报出这套查询契约(模型不用猜参数名再读 422)。本地代理不必再「全量拉回来自己筛」,正是产品立项要避免的上下文膨胀。
全平台下拉框搜索(RFC-325)
- 「要不要搜索」由调用点的自觉改为共享原语的默认行为:153 个
Select调用点里此前有 128 处没有搜索,最痛的是 provider 分组的ModelSelect(opencode models一次可返回上百条,只能滚动找)。现在条目数够多的下拉打开即可打字,新写一个<Select>自动获得搜索;是/否、升序/降序这类小枚举保持现状,不多顶一个搜索框、不丢首字母跳转与空格选中。 - 匹配面统一:主标题、值、描述、分组名都能搜到,中英文 / 全角半角 / 大小写差异不影响命中;键盘全程连贯(打开即打字,↑↓/Home/End/Enter 可用,Esc 一次清词、再一次关闭)。
- 收口时由 WebKit 腿咬出一对相反的 picker 契约,终态是显式
openOnMount:权限面板的加人搜索框不许因拿到焦点而展开(否则盖住弹窗自己的按钮),转让弹窗的 picker 必须一打开就展开(两段式 Escape 依赖它)。
维护节奏错峰与停顿归因(RFC-322)
- 起于生产实况:发布包部署反复出现「每隔一段时间全站冻结约 30 秒、随后自行恢复」,
[db-slow]打出 30 秒级语句;但同库实测该 SQL 走索引 10ms、外部进程 1Hz 连打 14 分钟零次超过 300ms。报出来的 32 秒不是查询代价,是 daemon 线程被占住 32 秒,慢查询日志把整段停顿栽赃给了当时正在执行的那条语句。 - 根因是两个结构性事实叠加:daemon 只有一条 bun:sqlite 同步连接(每条 SQL 同步独占事件循环),而约 12 个 hourly 维护定时器在 boot 的同一秒内装配且零抖动。现在同周期维护任务在周期内均匀铺开,稳态下任一时刻至多一个重维护任务在跑;每个维护任务每拍的实际耗时可观测、超阈值带任务名告警;
[db-slow]能区分「这条 SQL 真的在干活」与「进程被冻住了」。
用户面 e2e 覆盖加固与架构治理(RFC-319 / RFC-294)
- RFC-319 是本版提交量最大的一块(140 笔 test 提交):
e2e/的 spec 文件 62 → 189,能力账本 840 条、剩余 gap 39 条,covered-unverified(审计判定有防护但证据仍是散文)清零——账本的三种状态只减不增,covered的证据必须是{file, test}且守卫每次验证 test 标题逐字存在。 - 写 e2e 的过程本身咬出多个真缺陷并当场修掉,例如:融合节点的结果清单穿不过隔离边界,融合从来就没真正跑通过;人机交互门在「同一节点上还有别人在等」时看不见;一份文档都没有时评审门把人困在门口;首页「等你处理」错了不报错、只让人以为今天没事。
- RFC-294 侧落地 N1 canonical governance(架构账本 provenance 钉死、opaque-type 账本归一、CI 缺口关闭),继续 RFC-317 建立的「只降不升」机器棘轮。
其他修复
- 发行二进制上
backup/migrate/migration-report/package四条命令此前全是死的——一跑就挂,报的还是一句毫不相关的Can't find meta/_journal.json file,backup还会在全新 home 里留下空的db.sqlite+-wal+-shm。根因是这四处直接把源码树路径交给openDb,而单二进制里迁移是嵌进可执行文件的;同一段「先解包到~/.agent-workflow/runtime/migrations」的前置在仓内被抄了五遍、这四处漏抄。现收敛为唯一入口resolveMigrationsFolder(),九个调用点全部改走它。 - 配了
secret.key的部署里,重试仓库准备与 boot 恢复漏传 secretBox——该出口 100% 不可用。 - 内置模板 seeding 改为 create-or-converge,改模板文案不再拖垮 daemon 启动。
/me后台续期不再挂起页面与摘除弹窗;数字员工的内部执行不再刷屏公开任务流;画布校验摘要让开工具条横带(修 Linux 上主操作点不到);转让弹窗 / 权限面板的 picker 展开契约成对锁死。- system-mock 的 SSE 分支
close自我重入(一条走 SSE 的 e2e 刷 152 条栈溢出)已修。
升级说明
- 数据库迁移:新增 3 个(
0207_rfc320_oidc_email_claim.sql、0208_rfc321_repository_transport_credentials.sql、0209_rfc324_grant_levels.sql),迁移端点由0206前进到0209。升级前务必备份数据库。0207从持久化的定时任务 / 事件规则 launch payload 中移除gitUserName/gitUserEmail(存量任务行保留其冻结的身份对)。0208重建code_host_connections(新增连接代次与 typed transport 映射),token 密文逐字节复制、迁移过程从不解封。0209给resource_grants加level列并回填read,行为等价。
- 权限目录不变(仍 113 点),本版没有权限点增删或改名。
- wire 破坏性变更(均为
tokenAccess: 'never'的端点,PAT 本就调不到,影响面是自建脚本与会话 Cookie 调用方):- 任务创建不再接收
gitUserName/gitUserEmail,旧客户端继续发送会明确得到task-git-identity-client-owned,不静默忽略。 PUT /api/{res}/:id/acl的userIds删除,改为grants: [{userId, level}];PUT /api/tasks/:id/members的userIds改为带档位的members;GET /acl响应的users: UserPublic[]改为grants: [{user, level}]并新增canEdit(canManage语义不变)。按「删除优于 deprecate」直接切换,不留兼容字段。
- 任务创建不再接收
- 发布 transport 变化(RFC-321):若工作命中个人或公共受管 token,平台发布改走 HTTP(S)、不再使用 daemon SSH key / deploy key;要继续用 SSH,就不要为该 provider 启用受管 push credential。全局代码平台 token 新增 Git push 用途,必须具备 repository write 权限,权限不足 fail loud 不回退。管理员删除 / 改址代码平台连接会清除该连接下的个人 token 且不可恢复(UI 会显示影响数量并二次确认)。
- 路由退役:
/code/executors、/code/config/adapters[/<id>]删除并重定向;四组执行器清单继续在数字员工分类工具箱、员工页与公开 API 中管理,Adapter 全生命周期移入泳道卡片的次级 Dialog。 - 非 owner 的只读体感变化:打开别人的资源详情页 / 工作流编辑器时界面进入只读态。这不是能力收缩——后端一直拒绝这些写入,此前只是前台在骗人。需要对方能改时,在权限面板显式授「可编辑」档。
- RFC-319 状态如实说明:RFC-319 仍为 In Progress——四层棘轮与账本机制已入网、逐批 spec 持续落主干,剩余 39 条 gap 仍在推进中。
- 可直接替换对应平台二进制。
发布信息
- 源码提交:
b8c24a5c9557810c3b3d790fb8a6cad798b3b94d
v0.18.12
Agent Workflow v0.18.12
本版本交付三件大事:数字员工操作系统(RFC-310 后续批次)把「代码能力」从一条研发流水线升级成可程序化定制员工类型的操作系统,并新增统一事件中心与统一任务创建入口;公共内核架构边界加固(RFC-317)以 18-agent 并行审计的 131 条发现为输入,修掉 52 条 P1/P2(含三条越权 / 数据丢失级 P1)并给公共内核装上「第二实现长不出来」的机器棘轮;统一事件自动化规则权限合同(RFC-315)把 Webhook 私有权限名换成来源中性的事件自动化规则权限。另含 RFC-314 的 node_run_events 三处读写形状修复与 RFC-311 维护循环余项。
本版本含导航结构调整与权限点更名(webhook-triggers:* → event-automation-rules:*,/webhooks → /events,/code → /digital-employees),新增 15 个迁移,升级前请务必备份数据库并阅读文末「升级说明」。
主要更新
数字员工操作系统(RFC-310 后续批次)
- 产品形态变更:上层不再是「一条研发 Mission 长工作流」,而是可程序化定制员工类型的数字员工操作系统。配置层级收敛为「数字员工 → 数字员工分类 → 工作项 → 工具」:分类工具箱直接复用固定的 20 节点全景职责图,点哪个工作项就展示并增加该节点的工具;员工只配置岗位模板、名称启停、范围与节点工具绑定,重试统一收到「设置 → 执行策略」。
- 导航与页面:
/code、/code/executors、/code/assignments三项合并为单页/digital-employees(含分类详情/digital-employees/:typeRef与个案详情/employee-cases/:caseId);/outcomes退出导航。 - 统一事件中心(
/events):Webhook / 轮询降为「观察方式」,公开事件目录只收「已经发生」的稳定业务事实。代码平台统一为code-host.activity@1,11 类公开code-host.*事实可直接建立来源无关的响应规则;自定义来源按事件类型显式配置参数 namespace,机器键与界面显示名分离,完整路径实时显示为trigger.<namespace>.<field>。迁移0199把早期持久化的code-host.webhook@1第二套目录保留为兼容历史但从新创作面隐藏。 - 统一任务创建与任务目录:任务列表只保留一个「新建任务」入口,数字员工成为第四张执行方式卡;选择后继续走「执行方式 → 执行空间 → 任务内容 → 确认」四步 Stepper,最终确认时才调用 Case command。任务目录新增通用
public/internal可见性并沿调用树继承,数字员工的执行宿主标记为 internal——任务列表不再被内部执行刷屏,审计记录一条不删。 - 确定性职责编排:
development@8类型包(@1..@7保持不可变)。检视、流水线、冲突、员工协同与外部审批全部改为可选泳道,未配置不阻断发布 / 执行且不订阅;分类工具注册带有序问题清单,岗位选择工具即自动派生并连接P1..Pn,平台按有序问题种类确定性选择下一把修复工具。 - 双来源入口与人工审核分支:
界面输入与ISSUE是同一来源列中上下并列、无前后顺序的两个入口节点,分别独立汇入「准备工作材料」;关闭审核走「分析并实现」,开启审核走「分析 → 人工审核修复计划 → 实现」,两条路径汇合后回到同一主行。 - 工具契约对齐:分类工具主输入为流水线失败证据与流水线目录,输出显式展示
development.problem-set(逐条问题记录 + 去重后的待处理种类 + 当前头提交);修复工具主输入同步展示问题集、平台分派的问题种类、原始失败证据与流水线目录。中英文文案、示例 JSON、后端 WorkContract 与运行时语义逐项对齐。 - 交互修复:岗位优先级拖拽由稳定泳道容器持有 pointer capture,按冻结槽位边界实时预览、其他泳道以可中断 FLIP 让位;扇出卡改为同一不透明 paint stack,不再与邻卡交错;Select 在焦点交接期间不再逃逸出弹窗。
公共内核架构边界加固(RFC-317)
- 起于 RFC-294 四条判据里从未落地的第四条「存在防止第二实现再长出的棘轮」。18-agent 并行审计产出 131 条经复核发现与 95 条无人看守的违规类别;开工时 116 个架构守卫文件里只有 3 个自带能自证会红的负 fixture。
- 三条 P1 全部修复:①五类数字员工配置资源(动作模板 / 验证档案 / 数字员工 / 自动化策略 / 适配器定义)的写门只校验「能看见」,而 user 预设本就持有这五类的
:update/:archive点 ⇒ 任何登录用户都能改写、发布、归档他人的 public 资源;②归档沿两跳 FK 静默删除review_comments;③employee_definitions的 ACL 三列完全惰性。 - 两条数据正确性修复:
list<markdown>端口值落库前被按行切碎(数据损坏),codec 下沉进 handler;前端五族 class 有调用无定义,直接渲染成裸文本。 - 同批修 52 条 P1/P2、79 条 P3 入账锁死(其中 17 条顺带修掉)、19 条过期断言逐条改对并立成 6 条派生式不变量(判据的一端永远是活的源码:枚举长度 / schema 列 / 真实 import / RFC 索引状态)。
- 机器账本:仓根新增
architecture/{commons-manifest,commons-debt,guard-manifest,ledger-baselines}.json,条目数与源码逐字相等且只降不升——要升须显式allowGrowth并点名 RFC,且在下一笔不涨的提交上被判过期、强制清理。守卫的守卫 manifest 143 条:凡扫语料的守卫必须声明语料下限并两向钉死,凡断言「不存在」的必须配自变异转红的负 fixture。
统一事件自动化规则权限合同(RFC-315)
- 以来源中性的
event-automation-rules:{read,create,update,delete,override-owner}取代 Webhook 私有权限名,同时把来源无关规则从event-sources:update中拆出:默认 user 只读,manager 仅管理本人规则,admin / 显式 override 可跨 owner;创建仍叠加tasks:execute,数字员工目标仍叠加development-missions:launch。 - 迁移
0202保留旧 grant provenance、映射并去重各状态 PAT scope,不映射event-sources:*、不重写 audit。Webhook PAT 通道保持,来源无关规则全路由拒绝 PAT。
node_run_events 三处读写形状修复(RFC-314)
- 起于生产对账:部署 v0.18.11(已含 RFC-311 字节水位)的
node_run_events仍是 78.6 万行 / 1.72GB。三条形状问题与表总行数无关、与单个 run 的事件条数成正比,被归档水位掩着但没消失。 autoKill的max(ts)join 194.9ms → 最慢 0.4ms(改为逐 run「最后 200 行内 max(ts)」的有界窗口——用窗口而非最后一行,因为后果是杀真实进程,要吸收子代理回灌的 ts 乱序);会话树两段窗口的ORDER BY ts造成 TEMP B-TREE,461.5 + 122.0ms → 最慢 48.8ms(窗口按id取、取回后仍按(ts,id)排);事件落库由每行一条 autocommit INSERT 改为单次 chunk 内合并成多行 INSERT。- 零索引新增、零迁移、零 wire 变化:三条真慢语句全部走索引、没有一条
SCAN,慢在行量不在查找;实测加三个索引会让 5000 条 INSERT 的 WAL 页写 ×12.8 且对这三条一条都不起作用。
稳定性、权限与开发工装
- RFC-311 余项:
startEventsArchiver/startTaskArchiveSweeper此前只挂setInterval(1h)、没有 boot 首拍,于是在「重启比一小时更勤」的部署上一次都不执行,两个给库体积封顶的执行者形同虚设;checkpoint 循环读的是 boot 配置快照,改walCheckpointIntervalMs不重启永不生效。两条均已修复。 - 普通用户的语言切换恢复:按 RFC-036 把语言偏好与管理员 daemon 配置权限解耦——无
settings:write的账号只更新浏览器本地语言,不读写/api/config,也不消费前序管理员留下的配置缓存。 - 运行时能力门补齐:runtime 能力门此前只装在注册写路径上,现在在 spawn 前也校验。
- 开发工装(非产品代码):
bun run dev会额外起一个开发用 mock OIDC 身份提供方(http://127.0.0.1:7460),并往当前服务的库里幂等种入admin / manager / user / guest四个角色账号,点一下按钮即可切角色验证权限行为。它整体位于 test-mock 包packages/system-mocks/src/dev-auth/,产品代码零改动,AW_DEV_AUTH=0可关。
升级说明
- 数据库迁移:新增 15 个(
0192_rfc310_digital_employee_os_authoring.sql→0206_rfc310_employee_case_name.sql),迁移端点由0191前进到0206。升级前务必备份数据库。 - 权限目录 109 → 113 点:删除
webhook-triggers:{read,create,update,delete,override-owner},新增event-automation-rules:{read,create,update,delete,override-owner}与event-sources:{read,create,update,archive}。存量 grant 与 PAT scope 由迁移0202同 verb 映射并去重;event-sources:*不由迁移发放。 - 导航与路由变更:
/webhooks→/events(读面权限改为event-sources:read);/code、/code/executors、/code/assignments合并为/digital-employees;/outcomes退出导航。请更新收藏与外部深链。 - 写权收紧(breaking):五类数字员工配置资源的 revise / publish / archive 由「可见即可写」收紧为「owner 才可写」。
resource_grants只进可见性判定、不进 owner 判定,因此被授权的非 owner 写会得到 403;出路是由 owner 操作、授resource-acl:bypass、转移 owner,或自行复制一份。 - 任务列表默认不再显示内部执行:数字员工的执行宿主标记为
internal并沿调用树继承,存量执行树由迁移回填。审计记录未删除,按个案详情仍可追溯。 - RFC-310 状态如实说明:RFC-310 仍为 In Progress——本版交付的 authoring / runtime / case-task 批次已全部落主干,但 RFC-294 的 wave exit 尚未满足(DA public/required SPI、route/bootstrap 与 WorkspaceRef 未全切,
/api/tasks仍未使用 public-only membership)。功能可用,内部架构收口继续。 - 可直接替换对应平台二进制。
发布信息
- 源码提交:
d0aeb3861fff5590c0b95f09704b6d8484463ca0 - 数据库迁移:新增 15 个(
0192→0206) - 变更规模:696 个文件,+108233 / −5923
- 完整变更:v0.18.11...v0.18.12