v3 是当前唯一可执行的 Workflow 引擎:LLM 驱动的有界 DAG,跑完即散。packages/workflow-core/ 是从 src/workflows/v3/ 生成的发布包(index.ts/schema.ts/engine.ts 均为一行 re-export),保证外部运行时与 botmux 内部不会分叉出两套 DAG 语义。v2(src/workflows/definition.ts)已冻结,只留给 migration/ 做离线迁移;仓库根 workflows/*.workflow.json 是 v2 时代示例。

DAG 定义格式(dag.ts)

V3Dag = { runId, nodes[] },runId 与 nodeId 都是路径安全段([A-Za-z0-9._-]),因为它们直接做 runDir 的路径段。三种节点(V3NodeType):

  • goal — LLM 节点,由 botmux-goal skill 驱动,一个临时 worker 跑一个目标;goal 字段是单句目标。
  • host — 确定性副作用节点,不经 LLM,调注册在 hostExecutors/registry.ts 的执行器:feishu-send / feishu-reply / botmux-schedule。
  • loop — 有界子流水线(结构化返工,如 code→test 直到 test 通过);外层 DAG 保持无环,返工只存在于显式 loop 体内。

节点字段要点(V3Node):

  • depends:入边,可写字符串或 {from, when?};when 是对源节点 resultSchema 结构化结果的谓词(equals/notEquals/gt… 单算子),校验时即与源 schema 的 enum 交叉检查,运行时只读一次 result.json 并记 edgeResolved。
  • triggerRule:入边汇合语义,all_success(默认)/ one_success / {quorum: n},所有入边 settle 后一次性求值。
  • inputs:{from, select?} 把上游节点的 manifest 产物喂进本节点 inputs.json,from 必须 ⊆ depends。
  • timeoutSec:默认 1800s,上限 14400s(防架构节点幻觉出失控预算)。
  • humanGate:创作期冻结的人工审批门(prompt/options/approvers),运行时不允许增删。
  • resultSchema:刻意极小的 JSON-Schema 子集(平铺对象、原始类型、≤32 属性 / ≤4KB),节点须写 result.json,违反会 block(非 fail)。
  • revisitTo:跨节点回溯白名单,只允许回溯祖先;预算 per-pair 默认 1、per-run 默认 8,耗尽后 block 等人工 +1。
  • bot / override:每节点可指定 bot 与能力覆盖(仅 model、systemPromptAppend,权限不可覆盖)——混合后端 DAG 是非破坏性扩展。
  • loop 专属:maxIterations(硬上限 20)、body(仅 goal 节点、不可嵌套)、exit.when、feedback(上轮产物穿线)、output.from(对外产物投影)。

validateDag 是纯函数,一次抛出全部问题(DagValidationError.problems[]);环检测委托 topologicalOrder(含条件边)。

决策与执行分层

  • orchestrator.ts 是纯决策层:decideNext(runState, dag) → 动作描述列表。节点状态机:pending / gateWaiting / running / done / skipped / cancelled / blocked / superseded / failed。
  • runtime.ts 拥有全部副作用:journal/STATE 写入、worker 派发、humanGate 卡片投递、并发上限。
  • ephemeral-pool.ts:一次 runNode fork 一个用完即弃的 worker,以 goal-mode 初始化(GOAL_COMMAND = '/goal'),不解析不信任模型最终文本——节点成败由校验 BOTMUX_GOAL_MANIFEST_PATH 指向的 manifest 决定;worker-fence.ts 做 attempt 围栏。
  • host 节点走 host-execution.ts:冻结输入 → 人工门批准 → 执行器调用,带幂等键与对账(reconciler)。

状态真相:journal + STATE 两层

  • journal.ts:journal.ndjson append-only 审计真相(带跨进程锁与断尾修复);
  • state.ts:materialize(events) 把 journal 折叠成 V3RunSnapshot(runStatus: running / cancelling / cancelled / succeeded / failed / blocked),STATE 文件只是可随时重放的检查点——daemon 重启后靠重放 journal 恢复。

与飞书话题 / 多 bot 的结合

  • RunChatBinding(grill-state.ts)在 run 出生时从 grill worker 注入的环境捕获 larkAppId / chatId / rootMessageId / sessionId 并持久化:daemon 重启后 cold-attach 凭它知道把 humanGate 审批卡片重新发到哪个话题(见 cards)。
  • chatBinding 同时钉进不可变的 run.json,是 dashboard 路由取消等变更到 owner daemon 的依据(见 dashboard)。
  • host 执行器 feishu-send / feishu-reply 把结果发回飞书会话,botmux-schedule 建定时任务(见 schedule);host 节点强制携带 humanGate。
  • 每节点 bot 字段由 bot-resolve.ts 解析成 BotSnapshot,支持一个 DAG 混合多个机器人/CLI(见 multi-bot)。

run 生命周期

  1. grill 前置阶段(grill.state.json):grilling → spec_ready → spec_approved → architect_running → dag_ready → dag_approved;两个人工门(gate-1 确认需求、gate-2 确认 DAG)。
  2. spec.ts 从 spec.md 唯一的 ```json 块抽出 canonical Spec;architect.ts 起一个自主 goal-worker 把 spec 编译成 dag.json。
  3. run-envelope.ts:run.json 是不可变的授权/身份边界,create-once;所有产物(dag.json、spec.json、bots.snapshot.json 等)按 SHA-256 钉死,防止”批一个 DAG、跑另一个”。来源四种:ad_hoc / saved_definition / manual_cli / legacy_v3。
  4. daemon-run.ts 的 driveV3Run 驱动执行;requestV3RunCancel / requestV3Retry / requestRevisitGrant / requestV3LoopGrant / resolveV3GateClick 是 CLI 与卡片回调共用的变更入口。
  5. CLI 面:botmux workflow new/spec-finalize/approve-spec/architect/approve-dag/start(即兴流程)、save/run/list/show(Saved Workflow)、cancel/retry/grant(受阻处理);botmux goal run(goal-cli.ts)是不经 daemon 的单 goal 本地入口,复用同一套 envelope/journal/manifest 校验。

存储位置

  • run 目录:~/.botmux/v3-runs/<runId>/(cli-run.ts defaultBaseDir),内含 run.json、dag.json、spec.json、grill.state.json、journal.ndjson、STATE、各节点 manifest 与 pty-log。
  • Saved Workflow 库:<dataDir>/workflow-library/<workflowId>/(library-store.ts,dataDir 默认 ~/.botmux,可经 SESSION_DATA_DIR 覆盖,见 env):
    • metadata.json — 可变小索引:displayName/aliases/owner(openId+larkAppId)/scope(chat|global)/status(draft|active|archived)/latestRevision/publishedRevision;写更新加锁+原子。
    • revisions/rev_*.json — 不可变、内容寻址(sha256),payload 含 inputs 参数定义、contextRefs、specTemplate、dagTemplate、safety(gateDigest 防审批门被静默削弱 + sideEffects 清单)。
    • id 形如 wf_<32hex> / rev_<64hex>(library-schema.ts);store 从不回退 HOME/cwd 旧搜索路径,与 v2 的 ~/.botmux/workflows/*.workflow.json 彻底隔离。

相关页面:workflow、architecture-overview、daemon-worker、skills(botmux-goal skill 注入)。