--- name: analyze-dag description: > Use ONLY when an Epic is routed to the DAG ticket pipeline (Kind/Epic or Kind/Feature — both resolve to analyze-dag via the routes table directly, [org-internal #3072] phase 3 / [org-internal #3061] Phase 2). The Analyst decomposes the Epic into a single task-DAG artifact — merging roadmap+requirements+design+plan into one graph (nodes = acceptance criteria, edges = contracts, topology = plan). triggers: - analyze-dag - "dag pipeline" - "DAG 管线" - "任务 DAG" - "task DAG" - "DAG decomposition" - "DAG 分解" # `stage` is intentionally omitted: analyze-dag is the DAG route's entry skill, # replacing roadmap+requirements+design+plan — it has no single stage identifier # in the stage registry (see `/workflow-routing.yaml` dag.route and # core/schemas/workflow-routing.schema.json stage enum). Phase-boundary # signalling for the DAG route is the review-dag single gate and verify # milestone, not a StageDone event. role: Producer --- # Analyze DAG — Task-DAG Decomposition (DAG route entry skill) ## Purpose analyze-dag is the **entry skill** of the DAG ticket pipeline (`dag.route.entry.skill`, spec-07 §2). For a DAG-routed Epic (`Kind/Epic`, or `Kind/Feature` — both resolve here via the routes table directly, [org-internal #3072] phase 3 / [org-internal #3061] Phase 2 / TD-388 — including BACKFILL mode for MVP graduates and big-bug relabels), it **replaces** `roadmap` + `requirements-elicitation` + `design` + `plan-iterations` and produces **ONE artifact**: the task DAG, published as wiki page `{epic-slug}/dag` (Tier 2 — human-visible, cross-worktree stable). The task DAG merges three views into a single graph: | View | Where it lives in the DAG | | ---- | ------------------------- | | requirements | node `acceptance_criteria` (each node is its own spec) | | design | edge `contract_ref` (inter-node interface contract) | | plan | topology (edge direction = dependency / execution order) | `{epic-slug}` = the slug of the routed Epic — **not** this design's own slug `dag-pipeline`. ## Agent Role The **Analyst** (Producer) owns and produces the task DAG. The Analyst decomposes the Epic into nodes (acceptance criteria), edges (contracts), and a topological order (the plan), then publishes the single graph. ## Route Disqualifiers — 适用性预检(分解前必查) 分解前,Analyst 必须对照下表预检。任一命中 → **不分解**,将具体未决问题 列回 Epic 并 bounce(在不稳定需求上分解会产出一个即刻腐烂的冻结图; "先出个小 DAG" 不是降级选项——不进管线,先稳定需求): | Disqualifier | 判定 | Bounce 动作 | | --- | --- | --- | | 需求未稳 | scope item 含糊、互相矛盾、或只能以 "视情况" 回答;关键干系人问题仍开放 | 在 Epic 上列出澄清问题清单;问题解决后重入 analyze-dag | | 设计主导 | 主要风险是一个有 ≥2 个可行选项的架构/平台决策,而非任务分解;需要先做一次探索 | 将开放问题转 `prototype`(THROWAWAY spike)或设计探索;决策记录后重入 | | 外部契约未决 | scope 依赖未决的外部契约(第三方 schema、上游 API 未定) | 按 External-System Rule(见下文)解析或围栏;不可拆的残余隔离后再重入 | **反向拦截(Kind/MVP 降级建议,[org-internal #3061])**:一个 `Kind/Feature` 工单在分解预检中 暴露"概念未稳"(scope 仍在探索、成功标准未定、决策日志会推翻节点划分)时, 正确出口不是硬分解,而是建议改标签 `Kind/MVP` 先行交互式验证——概念稳定后 经 backfill 模式(见下文)带着决策日志重入。 ### Phase 0 需求澄清(disqualifier 的结构化扩展,[org-internal #3061]) 预检不止于"能否分解",还须证明"需求已澄清到可分解"。两项强制检查: **1. Scope item 可证伪性预检**:逐条检查 Epic 的 scope item。每条必须能改写为 一个可观察的通过条件(给定输入/操作 → 可观测的结果);写不出来的条目就是 澄清问题,列入 bounce 清单。禁止把不可证伪条目直接塞进 node AC。 **2. 横向完备性三态清单**:对下表每个维度做三态判定——**已覆盖**(scope 有 对应条目)/ **不适用**(一句话理由)/ **待澄清**(列具体问题)。任一维度停在 "待澄清" → bounce(澄清问题清单随 bounce 一起给出,不让用户猜缺什么): | 维度 | 检查 | | --- | --- | | 外部系统 | 沿用 External-System Rule(见下文):每个外部交互有明确协议与失败语义 | | 错误路径 | 关键流程的失败分支有定义(不是只写 happy path) | | 数据生命周期 | 数据的创建/保留/删除策略已明确 | | 权限/安全 | 访问边界与敏感数据处理已明确(或显式声明"无安全面") | | NFR | 性能/容量/兼容性约束已枚举(见下) | | 边界条件 | 值域/并发/时序等边界有约定(或声明"无特殊边界") | **NFR 输入来源明确化**:NFR 不允许"分解时脑补"。Epic 必须自带 NFR 输入—— scope item 中带 `NFR:` 前缀的条目,或一行显式声明"无 NFR 约束"。两者皆缺 → 作为澄清问题 bounce,而不是默认无约束。node schema 的 `NFR:` 条目只能来自 该枚举,不得新增臆造。 ## Node Schema (spec-03 §1) ```yaml node: id: "N-01" # task node N-{nn}; milestone node M-{nn} title: "契约骨架" # one line type: task # task | milestone acceptance_criteria: # "requirements" view — one falsifiable AC per line - "AC-1: <可证伪的验收条件, 映射 test_id>" - "NFR: <产品 NFR 条目>" # NFR:-prefixed entry — enumerated storage, no REQ-F number req_refs: # functional-requirement references - "REQ-F-001" status: pending # pending | ready | in_progress | done | blocked | green(仅里程碑) owner_session: null # assigned session id, null when unassigned size_attrs: # decomposition-time measured attributes (spec-06) cross_session_in: 1 cross_session_out: 1 contract_change: additive # none | additive | breaking (out-edge aggregation) estimated_hours: 8 # task nodes only; milestone nodes omitted estimated_sessions: 1 # task nodes only; milestone nodes omitted ``` Field semantics: - `acceptance_criteria` — the node **is** its spec. Each AC is falsifiable and maps a `test_id` ∈ `{ file-path::test-name | MANUAL | BENCH: