> Extracted from verify/SKILL.md (section:dag-branch) — moved verbatim; read > on-demand ONLY when the routed Epic is DAG-shaped (frozen DAG at > `{epic-slug}/dag` and `task_route.keep_gates` includes `verify`). ## DAG branch (milestone + task modes) > This branch OVERRIDES the Preconditions table, Phase 1 read inputs, Phase 5 > report index, Phase 5.5 ACCEPTED_RISK source, Phase 5.6 final sweep, and > Phase 6.5 commit gate for a DAG-ticket-pipeline Epic. It applies when the > routed Epic is DAG-shaped: a frozen DAG copy exists at `{epic-slug}/dag` and > the DAG's `task_route.keep_gates` includes `verify`. Legacy iteration verify > (the sections above) remains authoritative for non-DAG iterations. Spec: > `dag-pipeline/spec-05` §5. commit status stays > `pipeline/verify` in both modes. ### Milestone mode (verify runs on a milestone M when `all_incoming_done_and_green`) A milestone node (`type: milestone`) has no implementation work and no ticket; its verify is the integration verification welded at a DAG convergence point (`cross_session_in ≥ 2`). Trigger: the aggregator agent (main session/Orchestrator) detects `all_incoming_done_and_green` — every fan-in source node at its terminal state (task source `done` / milestone source `green`) — and initiates this verify run; the milestone never self-triggers. **Precondition replacements** (vs legacy iteration verify): | Legacy verify precondition | Milestone-mode replacement | | ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | design-space review converged (`review status --stage design-space` success) | review-dag converged (`review status --stage review-dag` success) | | iteration-plan review converged | REMOVED (DAG has no plan review; the single review-dag gate replaces it) | | legacy iteration plan at `{slug}/04-plan-index` | DAG artifact + milestone fan-in slice (no `04-plan-*` page) | | legacy NFR targets from `{slug}/03-design-06-non-functional-design` | REMOVED (product NFRs live in node AC, handled by per-task review-code) | | upstream roadmap chunk done+verified | all milestone fan-in source nodes at terminal state (task source `done` / milestone source `green`, i.e. `all_incoming_done_and_green`) | | code review converged (`pipeline/review-code` success) | ALL fan-in node tickets review-code PASS + PR merged (implied by `done`) | | code review final report exists | REMOVED (no Epic-level final report; per-node review-code reports live on task tickets) | | carried items from previous iteration closed | REMOVED (vacuous — no iteration) | | `core/checklists/verification.md` accessible | KEEP (unconditional) | | Acceptance criteria exist | from DAG-slice-generated DoD matrix (fan-in node AC + integration/contract-conformance/regression/NFR-coverage items) | | `slug` matches the plan slug | N/A (output naming frozen to `{epic-slug}`) | **Phase 1 read inputs** → the DAG slice: read the milestone's fan-in subgraph (fan-in nodes + their cross-session edges + contracts) from the frozen DAG copy `{epic-slug}/dag`, and generate the DoD matrix from it (integration items, contract-conformance items, regression items, NFR-coverage items) instead of reading `04-plan-*` pages. **Output naming**: `{epic-slug}/05-verify-milestone-{M-id}` (distinct from iteration verify `05-verify-iteration-{N}`). **Phase 5 report index**: append a `VERIFY-M-{M-id}` row to the `## 工件索引` comment with 重读 = `ON-DEMAND` (NOT `ARCHIVE`). The milestone verify does NOT edit the comment directly — it reports the row-payload to the aggregator agent (main session/Orchestrator), which is the SINGLE WRITER appending in place (`工单评论 API(见 TERMINOLOGY)`). `ARCHIVE` is never written by milestone verify (Epic close is the sole archive point). **Phase 5.5 ACCEPTED_RISK source**: fan-in node task-ticket review-code reports (located in each task ticket's review annotations / `## 当前状态` review row), not an Epic-level final report. A missing Epic-level final report does NOT trigger the "code-review final report does not exist" warn (that warn is legacy-iteration-only). tech-debt / baseline-failure / flaky-test registration proceeds as usual, sourced from the milestone DoD matrix's regression / baseline-classification results. **Phase 5.6 milestone mode** (restricted semantics — skip archive-at-close and issue close): 1. **Checklist final sweep** only — object = each fan-in task ticket's row 6 (`verify里程碑`) + the milestone DoD matrix, NOT the Epic body checklist. Verify each fan-in node's row 6 is checked or annotated `_(Pending: M-{M-id} 未 green)_`. Do NOT flip a still-Pending row 6 — that flip belongs to the aggregator agent (main session/Orchestrator), which performs the node-ticket close action. Write the milestone DoD matrix final sweep to `{epic-slug}/05-verify-milestone-{M-id}`. 2. **Do NOT fold/remove any Epic-body `## 当前状态` / `## DAG 状态` section** — milestone verify is read-only on Epic body state. 3. **SKIP archive-at-close** (the `## 工件索引` archive banner + row-level `ARCHIVE`) and **SKIP issue close** — both belong to the aggregator agent at Epic close. 4. **SKIP Tier 1 run archive** (Phase 5.6 step 5, Tier 1 run archive sub-bullet) — the aggregator agent performs it at Epic close. **Milestone verify execution context (pinned)**: run the integration/regression/contract-conformance/NFR suite on a checkout CONTAINING all fan-in nodes' merged code — the aggregator agent syncs main (containing the merged fan-in PRs) into the execution worktree, or builds a temp verify worktree from main HEAD, before triggering; the verify report `{epic-slug}/05-verify-milestone-{M-id}` records the actual execution commit SHA. **M→green status transition**: NOT done by milestone verify (read-only on Epic body). The aggregator agent (main session/Orchestrator) reads the verify report and sets the aggregator table M row 状态 = `green`, 重读 = `ON-DEMAND`, and syncs the frozen DAG copy `{epic-slug}/dag` node `status` to `green`. **Phase 6.5 milestone mode**: vacuous skip — a milestone has no implementation commit. Commit existence is evidenced by the fan-in node verify PASS + PR merged (already implied by `all_incoming_done_and_green`). **Milestone verify FAIL recovery**: FAIL → M `status` = `blocked`. Fix responsibility = the fan-in node owning the failing integration/regression item (the last-done fan-in node's session) or the Epic-level session (DAG author) if un-attributable. Re-run is triggered ONLY by a "fix-landed event" (fix commit merged + CI green, or an explicit re-done report from the owning session) — NOT status polling (done nodes are never reset; `all_incoming_done_and_green` stays true after FAIL). M stays `blocked` until a fix event, then returns to `pending` and verify re-runs. No review-dag re-run unless the fix changes a cross-session contract or the node/edge set. ### Task mode (verify on a task node ticket, because `task_route.keep_gates` includes `verify`) Each task ticket closes only after its own verify run, but legacy verify preconditions do not hold in DAG mode — this node-level branch reuses the `verify` skill with the following node-scoped semantics (so the `verify` gate is not silently downgraded to CI-only). **Verification object**: the node's own `acceptance_criteria` → the `test_id` suite (`file-path::test-name` / `MANUAL` / `BENCH:`) all passing fresh + that node's review-code PASS recorded + CI green. NOT milestone fan-in integration/contract/regression items (those are milestone verify's). Spec authority = the node in the frozen DAG copy `{epic-slug}/dag`. **Precondition replacements** (task mode — mirror the milestone table, scoped to the node): | Legacy verify precondition | Task-mode replacement | | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | | design-space review converged | review-dag converged (this Epic already passed the single gate; do NOT re-run it) | | iteration-plan review converged | REMOVED (DAG has no plan review) | | legacy iteration plan at `{slug}/04-plan-index` | the node in the frozen DAG copy `{epic-slug}/dag` (no `04-plan-*` page) | | legacy NFR targets from `{slug}/03-design-06-non-functional-design` | REMOVED (product NFRs live in node AC, handled by per-task review-code) | | upstream roadmap chunk done+verified | this node's cross-session in-edge source nodes at terminal state (task source `done` / milestone source `green`) | | code review converged (`pipeline/review-code` success) | this node's ticket review-code PASS + PR merged | | code review final report exists | REMOVED (this node's review-code report lives on the task ticket) | | carried items from previous iteration closed | REMOVED (vacuous — no iteration) | | `core/checklists/verification.md` accessible | KEEP | | Acceptance criteria exist | from node AC + `test_id` suite | | `slug` matches the plan slug | N/A (Tier 1 run slug = `{epic-slug}-task-{node-id}` — the same node-task run namespace review-code runs in and this mode's archive bundle uses below; the Phase 2 precondition-gate cache read MUST use this slug. Only the wiki output naming stays Epic-scoped: `{epic-slug}/05-verify-task-{node-id}`) | **Phase 1 read inputs** → the node's AC + `test_id` suite from the frozen DAG copy `{epic-slug}/dag`, generating the DoD matrix. **Output naming**: `{epic-slug}/05-verify-task-{node-id}`. **Phase 5 report index**: append a `VERIFY-TASK-{node-id}` row, 重读 = `ON-DEMAND` (NOT `ARCHIVE`), via the aggregator agent as single writer (task verify does not edit the comment directly). **Phase 5.5 task mode**: ACCEPTED_RISK source = this node's task-ticket review-code report (no Epic-level final report → no "does not exist" warn). tech-debt / baseline-failure / flaky-test registration proceeds as usual. **Phase 5.6 task mode**: only checklist final sweep — object = this ticket's 5-row checklist (NOT row 6 `verify里程碑` — row 6 is flipped ONLY by the aggregator agent). SKIP archive-at-close (`## 工件索引` row-level `ARCHIVE`) and issue close (both belong to the aggregator agent). SKIP Tier 1 run archive — the aggregator agent collects it cross-worktree at task-ticket close (archive to `/archive/{epic-slug}-task-{node-id}.json` and commit to the workflow branch). Do NOT fold Epic body status sections. **Phase 6.5 task mode**: object = this node ticket's commit; semantics = "node implementation commit exists". Baseline = the task worktree's creation-commit SHA (`git log {creation-SHA}..HEAD`), NOT a generic base-branch (post-merge there are no new commits vs base). The task worktree is retained until ticket close (the aggregator agent removes it after collecting task-level Tier 1 archive); the task session must NOT remove its own worktree. **commit status**: still `pipeline/verify` in both modes. ### No-milestone DAG Epic-level verify gate When the routed Epic's DAG has NO milestone (no `cross_session_in ≥ 2` convergence point), the Epic-level `keep_gates: verify` is satisfied AGGREGATELY by all task-ticket verify runs (each with commit status `pipeline/verify` success) — NO independent Epic-level verify run, NO `{epic-slug}/05-verify-milestone-{M-id}` artifact, NO `VERIFY-M-{M-id}` index row. The Epic close condition degenerates to "all task nodes `done`". ---