# Leader DAG 化实施计划 本文档定义当前 `inbox v2` 从“leader 输出 chain/task 并即时执行”升级到“更稳定的 DAG planning / gating / replan”模型的落地方案。 目标不是照搬 Astro,而是吸收其中最有价值的五个机制,并严格适配我们现有架构: - `leader` 运行在宿主机,内嵌于 `inbox server` - `worker` 运行在 per-chain 容器中 - `topic / chain / task / dependency / workflow_run / message` 是现有运行时主模型 - 不引入多机器调度,不引入 hosted control plane,不引入新的外部依赖 ## 背景 最近几轮真实回归暴露出两个核心问题: 1. `leader` 的规划产物还不够稳定,更多是“即时创建 chain/task”,而不是明确的计划对象。 2. `worker` 失败后的 replan 缺少约束,导致同一个 topic 里反复新建 chain,造成 worktree / container 增生。 这说明当前系统已经具备“可执行”的基本能力,但还缺少“可控规划”的中间层。 本计划把这层能力拆成五个阶段,按顺序落地。 ## 总目标 实施完成后,系统应具备以下能力: - `leader` 输出稳定的 planning schema,而不是松散文本 - topic 在执行前先经过 gating,而不是盲目并发起 worker - 任务优先按 deliverable 和 batch 拆分,而不是隐式退化成角色链 - `replan` 只能 patch 现有图,不能无限增生 chain - milestone 成为图中的一等节点,用于收口多分支结果 ## 非目标 本计划不包含以下内容: - 多机器 / 多 runner 调度 - 容器资源感知调度 - hosted dashboard / cloud relay - 通用 workflow DSL - 兼容旧 pool / discovery / fixed-role 路径 --- ## 阶段 1:规划产物标准化 ### 目标 让 `leader` 的输出从“只够当前 applyLeaderOutput 消费的最小 JSON”升级为稳定的 planning schema。 ### 要解决的问题 - 当前 `leader` 输出主要服务于即时建链,不利于回放、对比、重规划 - `reply_markdown`、`chains`、`tasks` 混在一起,缺少 plan 元信息 - 缺少 task 的输入、产物、验证、批次、replan 策略等显式字段 ### 产出 新增一个面向 `leader` 的 planning schema,建议至少包含: - `plan_version` - `plan_summary_markdown` - `execution_mode` - `clarify` - `plan_only` - `plan_and_start` - `chains[]` - `key` - `name` - `purpose` - `reuse_strategy` - `tasks[]` - `key` - `chain_key` - `title` - `body_markdown` - `acceptance_markdown` - `deliverables[]` - `depends_on[]` - `verification` - `batch_key` - `replan_policy` - `milestones[]` - `start_nodes[]` - `leader_reply` ### 实现范围 - `inbox/internal/app/leaderloop/service.go` - 扩展 `leaderOutput` 结构 - 更新 `leaderOutputSchema()` - 拆出 `plan` 相关校验函数 - 如有必要,新增: - `inbox/internal/domain/plan/` - 或 `inbox/internal/domain/workflowplan/` ### 设计要求 - schema 必须可序列化进 `workflow_runs.config_snapshot_json` 或 `command_json` - `leader` 返回的 plan 必须可重放 - plan 必须允许“仅规划不启动” ### 验收标准 - `leader` 输出可以表达: - 只澄清 - 只规划 - 规划并启动 - 单元测试覆盖: - 完整 plan decode - 缺字段失败 - 非法 dependency 失败 - 非法 `start_nodes` 失败 ### 风险 - 一次把字段做太多,导致 prompt 不稳定 - schema 改动过大,影响现有 `taskexec` 和 dashboard 显示 ### 收口策略 - 先新增字段,不立刻让 dashboard 全部消费 - `leaderloop` 内部先把 schema 校验稳定,再逐步外显 --- ## 阶段 2:前置 Gating 节点 ### 目标 在真正启动 worker 之前,先通过一组 gating task 判断“是否具备执行条件”。 ### 要解决的问题 - 当前 leader 规划后容易直接启动多个 chain - 一些基础条件没满足时,worker 只会重复失败 - 失败后 leader 再次 replan,进一步放大噪音 ### 典型 gating 场景 - 仓库结构是否存在 - 运行时 provider / auth 是否可用 - 基础 contract / API 边界是否已经明确 - 必要目录 / package manager / root script 是否存在 - topic 是否已具备足够信息,不需要继续澄清 ### 产出 在 planning schema 中加入 gating 语义: - `tasks[].kind` - `gate` - `execution` - `verification` - `milestone` - `tasks[].gate_policy` - `hard_stop` - `ask_user` - `leader_replan` ### 实现范围 - `leaderloop` - 在 `start_nodes` 解析时优先启动 gate task 所在 chain - `taskexec` - gate task 失败后,不自动放开后续依赖 - `dashboard` - 在 chain/task board 上明确标记 gate 节点 ### 设计要求 - gate 失败时,后续依赖节点保持 `draft` 或 `blocked` - leader 收到 gate 失败后,应优先 patch 计划,而不是起新图 - gate task 的完成结果必须带结构化 failure reason ### 验收标准 - topic 首轮执行时,能先只启动 1 个 gating chain - gate 失败后,其余 chain 不启动 - leader 能基于 gate failure 回复用户或 patch 任务 ### 风险 - 如果 gating 太多,会让简单需求变慢 ### 收口策略 - 只保留 2-3 类强 gating - 其它检查继续留在 worker 内部做普通失败 --- ## 阶段 3:按 Deliverable 与 Batch 拆分 ### 目标 让 leader 优先按产物边界拆 task,而不是退化成“前端链 / 后端链 / 基础链”这类松散角色链。 ### 要解决的问题 - 当前 chain 名称仍然容易被 prompt 驱动成泛化角色链 - 同一链上 task 颗粒度不稳定 - 缺少批处理并行能力 ### 产出 在 leader prompt 和 schema 中强化以下约束: - task 必须显式描述最终产物 - chain 只是执行容器,不是角色人设 - 可以使用 `batch_key` 做批次并行 建议的拆分优先级: 1. 先按 deliverable 拆 2. deliverable 太大时,再按 batch 拆 3. 最后才落到实现域(frontend/backend/integration) 示例: - `api-contract` - `backend-crud` - `frontend-list-create` - `frontend-edit-filter` - `integration-e2e` 而不是默认: - `backend` - `frontend` - `foundation` ### 实现范围 - `leaderloop/buildLeaderPrompt` - 增加强约束,要求 chain/task 以产物命名 - `leaderOutputSchema` - 增加 `deliverables[]` 和 `batch_key` - `dashboard` - 在 task 卡片中展示 deliverables 与 batch ### 设计要求 - 同一 batch 内的 task 应能独立并行 - `deliverables[]` 应该能支持后续 verification 和 merge summary ### 验收标准 - 相同需求多次规划时,chain/task 命名更稳定 - leader 生成的任务里,至少 80% 有明确 deliverable 字段 - 支持一个 topic 下存在“批量任务 + 聚合 milestone” ### 风险 - prompt 改得太死,影响 leader 灵活性 ### 收口策略 - 不硬编码固定 chain 名称 - 只强制“必须有 deliverable”,不强制唯一命名模板 --- ## 阶段 4:Replan 只允许 Patch,不允许重建图 ### 目标 把 replan 从“再创建一批 chain/task”改成“在同一张图上 patch 现有节点”。 ### 要解决的问题 - 这次已经真实出现过: - worker 失败 - leader 重规划 - 同一 topic 新建 `chain-2`、`chain-3`、`chain-60` - worktree / container 爆炸增长 ### 核心原则 - topic 进入 execution 后,禁止无边界新增 chain - replan 默认只能做: - 更新已有 chain 状态 - 在已有 chain 下补 task - 调整 dependencies - 调整 `start_nodes` - 标记 chain/task 为 superseded / blocked / cancelled 只有在极少数场景下允许新增 chain,例如: - 用户明确要求增加新的独立工作流分支 - 原图中不存在可复用的产物链 - leader 输出显式 `replan_mode = expand_graph` 即使允许扩图,也必须通过严格限制: - topic 级 max chain count - replan iteration limit - leader 必须解释新增原因 ### 产出 新增 replan 策略字段: - `plan_mode` - `initial` - `patch` - `expand_graph` - `replan_reason` - `supersedes[]` 新增 topic 级保护: - `max_chain_count` - `max_replan_count` ### 实现范围 - `leaderloop/applyLeaderOutput` - 默认复用已有 chain - 有 existing chains 时禁止无限新建 - `taskexec` - worker failure 回传更结构化的失败原因 - 可能需要: - `chains` / `tasks` 新状态,例如 `superseded` ### 验收标准 - 同一 topic 上重复 worker 失败后,不再出现 chain 数量线性增长 - topic 执行 5 次失败回执后,chain 总量仍保持稳定 - 集成测试覆盖: - 初始计划 - worker 失败 - leader patch - 继续执行 ### 风险 - patch 逻辑比“直接新增”更复杂 - 旧 topic 的脏数据可能影响验证 ### 收口策略 - 先在 `leaderloop` 内部做强保护 - 旧 topic 不做兼容逻辑,直接清数据 --- ## 阶段 5:Milestone 成为一等节点 ### 目标 把 milestone 从隐式概念提升为图中的正式节点,用来汇聚多分支结果并决定下一步推进。 ### 要解决的问题 - 当前多分支的收口主要靠 leader 自己看消息判断 - 缺少“某几个 task 都完成后,再开始下一阶段”的正式表达 ### 典型 milestone - `Foundation Ready` - `API Contract Ready` - `Feature Complete` - `Ready for Integration` - `Ready for User Review` ### 产出 在 planning schema 中加入: - `milestones[]` - `key` - `title` - `depends_on[]` - `summary_markdown` - milestone 可被 `start_nodes` 和后续 task 依赖引用 ### 实现范围 - `leaderloop` - 允许创建 milestone 节点 - 在依赖满足时将 milestone 标记为 ready/succeeded - `tasks` 或新表 - 若不新增表,可先将 milestone 作为特殊 task kind 存储 - `dashboard` - graph / board 中区分 milestone 与普通执行 task ### 设计要求 - milestone 不运行容器 - milestone 只负责聚合前置状态 - milestone 可以成为 integration / verification 的 gating 前提 ### 验收标准 - 一条执行链中可见 milestone 节点 - 多分支完成后 milestone 自动推进 - leader 可以基于 milestone 状态决定是否继续启动 integration ### 风险 - 如果把 milestone 单独建表,会扩大 schema 变更面 ### 收口策略 - 第一版先把 milestone 存成 `task.kind = milestone` - schema 稳定后再决定是否单独抽表 --- ## 推荐实施顺序 严格按下面顺序推进,不要并行乱改: 1. 阶段 1:规划产物标准化 2. 阶段 4:Replan 只允许 Patch 3. 阶段 2:前置 Gating 节点 4. 阶段 3:按 Deliverable 与 Batch 拆分 5. 阶段 5:Milestone 一等节点 原因: - 阶段 1 先固定 schema - 阶段 4 先止住增生风险 - 阶段 2 再降低盲目执行 - 阶段 3 再提高任务质量 - 阶段 5 最后做图上的正式汇聚 ## 每阶段的统一交付要求 每个阶段都必须同时完成: - 领域模型改动 - `leaderloop` 应用逻辑改动 - 必要的 HTTP / dashboard 暴露 - 单元测试 - 至少一条真实或半真实回归路径 ## 统一验收门槛 全部五阶段完成后,应满足: - 同一 topic 不再出现失控 chain 增生 - leader 输出稳定 plan schema - 执行前存在明确 gating - task 以 deliverable 为核心组织 - 图中存在正式 milestone 节点 - dashboard 能看出“计划 / 执行 / 收口”的结构 ## 建议的实施文档拆分 后续真正进入实现时,建议在 `.omx/plans/` 或 `docs/` 下继续细分为: - `phase-1-plan-schema.md` - `phase-2-gating.md` - `phase-3-deliverable-batching.md` - `phase-4-replan-patch-only.md` - `phase-5-milestones.md` 本文档作为总计划,不直接承担逐字段设计。