Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions .specgit.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
version: 1
delivery: end-structured-output
delivery: reduce-dag-auto
context:
kind: branch
branch: fix/386-end-structured-output
branch: refactor/392-reduce-dag-auto
issues:
- 386
- 387
- 388
pr: 390
- 392
pr: 393
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ This repository owns the DAG schema, compiler, validator, runtime, and release i

## DAG command family

- Built-in commands ship compiled into the binary: `/dag-flow` (resident orchestration router), `/dag-init` (platform handshake → writes `.opencode/dag-init.json`), `/dag-auto` (six-block ultra-flow driver), `/dag-template-update` (template refresh without git). User command files shadow built-ins by name; register new built-ins through `packages/core/src/plugin/command.ts` + `packages/opencode/src/command/index.ts` (`Default` registry).
- Built-in commands ship compiled into the binary: `/dag-auto` (requirement → workflow routing: classify, match a saved DAG route, retarget, validate, start). Platform delivery (issues, PRs, CI, merge, release) is specgit's job — never part of `/dag-*`. User command files shadow built-ins by name; register new built-ins through `packages/core/src/plugin/command.ts` + `packages/opencode/src/command/index.ts` (`Default` registry).
- Templates come from `opencode-dag-config`: 7 domains × `full`/`lite` plus cross-domain routes (`ultra-flow-route`, `release-route`). Precedence: project `.opencode/workflows/` > global config dir > builtin snapshot (the release pipeline compiles the config repo into the binary via `DAG_TEMPLATES_DIR`).
- `dag.jsonc` supplies DAG node model tiers: `advanced` for `required: true` and review nodes, `standard` otherwise. Never pin `model` inside saved workflow specs.

Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Three terms worth knowing:

- Composable blocks (`explore`, `plan`, `prototype`, `debug`, `coding`, `verify`, `review`, `synthesize`) compile into the node graph; low-level node fields remain available for anything blocks cannot express.
- `workflow(action="draft")` renders a structured graph through the tool schema into a validated YAML spec — field-name mistakes are rejected by the provider, not discovered at validation time.
- Saved workflow libraries at three scopes (project / global / builtin), startable by name; the `/dag-flow` command picks a curated reference topology and retargets it to the task at hand.
- Saved workflow libraries at three scopes (project / global / builtin), startable by name; the `/dag-auto` command routes a requirement to a curated reference topology and retargets it to the task at hand.
- Model tiers in `dag.jsonc` separate decisions from volume: critical nodes on the `advanced` model, fan-out work on `standard`.

**Reliability**
Expand All @@ -67,7 +67,7 @@ Three terms worth knowing:
## Using workflows

Nothing has to be configured to try it: ask for work that has stages, parallel
parts, or a review gate in the middle (`/dag-flow <task>`), and the agent
parts, or a review gate in the middle (`/dag-auto <task>`), and the agent
designs a graph and runs it. Three things turn that into a repeatable setup of
your own.

Expand Down Expand Up @@ -108,8 +108,8 @@ directory and it gains a **name**:
Resolution takes the first match in that order, so a project file shadows a
global one with the same name, and both shadow the builtin tier. The global
scope is maintained by the [`opencode-dag-config`](https://github.com/LeXwDeX/opencode-dag-config)
repository; the `/dag-template-update` command syncs it (preview of
new/changed/unchanged files, backup before overwrite, QA decision gate). A minimal spec:
repository (sync it with a plain `git clone`/`git pull` into your config
dir). A minimal spec:

```yaml
title: Dependency audit
Expand Down
6 changes: 3 additions & 3 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ GraphAgent 是本项目对外的产品名;仓库以 **OpenCode-GraphAgent**

- 可组合块(`explore`、`plan`、`prototype`、`debug`、`coding`、`verify`、`review`、`synthesize`)编译成节点图;块表达不了的还有低级节点字段兜底。
- `workflow(action="draft")` 通过工具参数传结构化图,harness 渲染并校验出 YAML spec——字段写错在 provider 侧就被拒,不用等到校验才发现。
- 三级作用域的工作流库(项目 / 全局 / 内嵌),按名字启动;`/dag-flow` 命令挑选合适的参考拓扑并注入当前任务
- 三级作用域的工作流库(项目 / 全局 / 内嵌),按名字启动;`/dag-auto` 命令把需求路由到合适的参考拓扑并注入当前任务
- `dag.jsonc` 的模型分层把决策和跑量分开:关键节点用 `advanced` 模型,扇出跑量用 `standard`。

**可靠性**
Expand All @@ -60,7 +60,7 @@ GraphAgent 是本项目对外的产品名;仓库以 **OpenCode-GraphAgent**

## 工作流怎么用

不配置也能直接试:给它一件有阶段、有可并行部分、或者中间需要一道审查门禁的活(`/dag-flow <任务>`),智能体自己会建图并跑起来。想把它变成你自己的一套固定流程,有三件事:
不配置也能直接试:给它一件有阶段、有可并行部分、或者中间需要一道审查门禁的活(`/dag-auto <任务>`),智能体自己会建图并跑起来。想把它变成你自己的一套固定流程,有三件事:

### 1. 选定模型分层 —— `.opencode/dag.jsonc`

Expand Down Expand Up @@ -90,7 +90,7 @@ GraphAgent 是本项目对外的产品名;仓库以 **OpenCode-GraphAgent**
| 全局级 | `<opencode 配置目录>/workflows/<name>.yaml` | 本机所有项目 |
| 内嵌级 | 编译进正式版二进制 | 每个正式版安装——兜底解析层 |

解析按此顺序取第一个命中的名字:项目级遮蔽同名的全局级,二者都遮蔽内嵌级。全局作用域由 [`opencode-dag-config`](https://github.com/LeXwDeX/opencode-dag-config) 仓库维护,`/dag-template-update` 命令负责同步(预览新增/变更/不变清单,覆盖前备份,QA 决策门禁)。一个最小的 spec:
解析按此顺序取第一个命中的名字:项目级遮蔽同名的全局级,二者都遮蔽内嵌级。全局作用域由 [`opencode-dag-config`](https://github.com/LeXwDeX/opencode-dag-config) 仓库维护(直接 `git clone`/`git pull` 到配置目录即可同步)。一个最小的 spec:

```yaml
title: Dependency audit
Expand Down
24 changes: 1 addition & 23 deletions packages/core/src/plugin/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,20 @@ import { Effect } from "effect"
import { Location } from "../location"
import PROMPT_INITIALIZE from "./command/initialize.txt"
import PROMPT_REVIEW from "./command/review.txt"
import DAG_FLOW_PROMPT from "./command/dag-flow.txt"
import DAG_TEMPLATE_UPDATE_PROMPT from "./command/dag-template-update.txt"
import DAG_INIT_PROMPT from "./command/dag-init.txt"
import DAG_AUTO_PROMPT from "./command/dag-auto.txt"
import workflowRouting from "./command/workflow-routing.md" with { type: "text" }
import workflowBlocks from "./command/workflow-blocks.md" with { type: "text" }
import workflowContent from "./command/workflow.md" with { type: "text" }
import orchestrationPolicy from "./command/orchestration-policy.md" with { type: "text" }
import orchestrationDomains from "./command/orchestration-domains.md" with { type: "text" }

export const DagFlowDescription = "Start a dependency-graph multi-agent workflow for the supplied task"
export const DagTemplateUpdateDescription = "Update the global DAG reference templates from opencode-dag-config"
export const DagInitDescription =
"Connect this repo to GitHub/GitLab, verify issue/PR permissions, and prepare everything /dag-auto needs"
export const DagAutoDescription =
"Finish it: drive the composed ultra-flow (exploration → design → development → acceptance → release → summary) to completion"
"Route a requirement to a composed DAG workflow: classify, match a saved route, retarget, validate, start"
export const WorkflowFactsContent = workflowContent
export const WorkflowBlocksContent = workflowBlocks
export const OrchestrationPolicyContent = orchestrationPolicy
export const OrchestrationDomainsContent = orchestrationDomains
export const WorkflowContent = workflowRouting
export const DagFlowContent = DAG_FLOW_PROMPT
export const DagTemplateUpdateContent = DAG_TEMPLATE_UPDATE_PROMPT
export const DagInitContent = DAG_INIT_PROMPT
export const DagAutoContent = DAG_AUTO_PROMPT

export const Plugin = define({
Expand All @@ -47,18 +37,6 @@ export const Plugin = define({
command.description = "review changes [commit|branch|pr], defaults to uncommitted"
command.subtask = true
})
draft.update("dag-flow", (command) => {
command.template = DagFlowContent
command.description = DagFlowDescription
})
draft.update("dag-template-update", (command) => {
command.template = DAG_TEMPLATE_UPDATE_PROMPT
command.description = DagTemplateUpdateDescription
})
draft.update("dag-init", (command) => {
command.template = DagInitContent
command.description = DagInitDescription
})
draft.update("dag-auto", (command) => {
command.template = DagAutoContent
command.description = DagAutoDescription
Expand Down
100 changes: 25 additions & 75 deletions packages/core/src/plugin/command/dag-auto.txt
Original file line number Diff line number Diff line change
@@ -1,26 +1,12 @@
You are running `/dag-auto`. Its essence: the user says "finish this thing"
once, and you drive a composed ultra-flow to completion — all the way from
exploration through design, development, test and acceptance, build and
release, to the summary, without the user ever typing "continue". The flow
is audited and debugged BY DESIGN: direction checkpoints run between every
two blocks, repair goes through bounded replan, and delivery counts only
when CI is green and the ordered merge lands.

**The stage classifier is a methodology embedded in this command, not a
skill or external router.** Three disciplines: (1) classify the disposition
of the current state before acting, (2) template-first — match a saved DAG
route before inventing a graph, (3) routing decisions stay in this parent
conversation; children receive concrete work. You apply these yourself at
every boundary wake.
You are running `/dag-auto`: the routing and workflow-composition driver of
the `/dag-*` command family. Its essence: classify the request, match a
saved DAG route, retarget it to the real task, validate, and start it.
Routing decisions stay in this parent conversation; children receive
concrete work. That is ALL this command does — it never touches platform
delivery: no issues, no PRs, no CI watching, no merge or release mechanics.

Arguments: $ARGUMENTS

## Phase 0 — Gate

Read `.opencode/dag-init.json`. Missing → STOP and tell the user to run
`/dag-init` first: auto cannot execute without a verified platform
connection, issue/PR permissions, and template availability.

## Phase 1 — Entry classification

Classify the request; never ask the user to pick a route:
Expand All @@ -31,41 +17,32 @@ Classify the request; never ask the user to pick a route:
`stage-release` (+ its checkpoint) when the project has no release
mechanics, write the retargeted YAML to `.opencode/.dag-specs/<task>.yaml`,
then `workflow(action="validate")` and `workflow(action="start")`.
- **Narrow single-block request** ("review this PR", "grill this plan",
- **Narrow single-block request** ("review this diff", "grill this plan",
"decide X", "只做设计阶段") → run ONLY the matching domain route
(`product-planning`, `technical-design`, `project-development`,
`code-review`, `debug-repair`, `security-audit`, `performance-audit` —
full/lite by risk) or the single ultra-flow stage, and end on its report.

Template-first for every route: `workflow(action="list")` → `read` →
retarget → start; create from scratch only when nothing fits.
retarget → validate → start; create from scratch only when nothing fits.

## Phase 2 — Driving the ultra-flow
## Phase 2 — Driving the graph

**Auto contract.** Drive each stage/checkpoint wake to completion and
advance automatically. Do not pause to ask "shall I continue". The ONLY
interruptions allowed are user-owned decisions: the spec confirmation gate,
a product decision checkpoint, the release human gate, a merge gate the
rulesets reserve for a human, or a cap exceeded (retries / replan loops).
Everything else advances on its own.
interruptions allowed are user-owned decisions (the product decision
checkpoint below) or a cap exceeded (retries / replan loops). Everything
else advances on its own.

**Checkpoint wakes.** Every checkpoint node carries a verdict
`{verdict: continue|replan, findings, target?}` reporting direction
correctness:
- `continue` → do nothing; the graph already advances by itself.
- `replan` → use the findings + target to add correction nodes via
`workflow(action="control", operation="replan")` (never restart the
ultra-flow from scratch). The loop is bounded: at most **3 back-edges**;
on the third, stop and hand the user ONE decision point with the complete
state (findings, attempts, diffs).

**Spec confirmation gate.** Before the design stage creates the platform
issue, present the spec draft (title + body) in chat and wait for ONE
confirmation; create the issue only after it. Spec content = issue body
(label `dag-spec`), the issue IS the atom — no X.Y task fragmentation.
Multiple specs in one plan → one tracking issue listing the spec issues IN
PLAN ORDER (that list is the merge order contract). Skip the gate only when
the user said `full-auto`.
`workflow(action="control", operation="replan")` (never restart the flow
from scratch). The loop is bounded: at most **3 back-edges**; on the
third, stop and hand the user ONE decision point with the complete state
(findings, attempts, diffs).

**Product decision checkpoint.** Force a user decision when the flow hits:
a new external dependency, a breaking change, a public API change, or an
Expand All @@ -74,45 +51,18 @@ materially changes behavior, scope, or acceptance. Present the recommended
answer and wait for one combined confirmation; write the result into the
retargeted objective/instructions, never into child prompts.

## Phase 3 — Platform delivery rules
## Phase 3 — Completion report

1. **Auto CI/CD + TDD watching.** After push, run `gh pr checks <n> --watch
--fail-fast` as a background task so the session wakes when checks
settle. TDD evidence is double: the development stage ran behavior checks
at public seams locally, remote CI re-runs them. CI failure → scoped
repair pass, re-push; cap 3 auto-fix retries, then hand back with failing
checks and logs.
2. **Ordered merge.** Strictly in plan order: PR-N merges only after PR-(N-1)
is confirmed merged. Before each merge gate, rebase the branch on the
advanced base, push, and re-watch CI. Merge acceptance = CI green +
review verdict, never "checkbox done". Respect rulesets from
`/dag-init`; when merge requires a human actor or approval, stop at the
gate and say exactly what to click.
3. **Release human gate.** The release stage defaults to HOLD: execute the
publish only after the user confirms the release brief (mechanism,
version derived from latest tag + commit types, changelog). Argument
`release-auto` overrides.
4. **Monitoring scope.** Nothing watches spec files or task boxes
mid-process. Watched milestones only: issue-closed, PR-merged, CI checks.
5. **Remote truth.** Single source of truth is the platform: every re-entry
reconciles from `gh issue view` / `gh pr list --state all --json` /
`gh pr checks`. Interrupted runs resume by re-querying — the ultra-flow
survives session restarts by finding its stage from remote state plus the
durable workflow graph.

## Phase 4 — Completion report

End with ONE consolidated summary: stages executed (incl. skipped with
reason), checkpoint verdicts and replan passes used, issue number(s), PR
URL(s), CI status, merge position in the plan, release outcome (or
documented skip), and any gate waiting on the human.
End with ONE consolidated summary: the route chosen (saved template name or
task-local graph), stages executed (incl. skipped with reason), checkpoint
verdicts and replan passes used, the exact Workflow ID, and any gate
waiting on the user.

## Rules

- Never create issues/PRs before the `/dag-init` config is verified.
- Never write workflow state to local files; local persistence is only the
retargeted spec YAML under `.opencode/.dag-specs/` and
`.opencode/dag-init.json`.
- Routing decisions live in this conversation; child nodes get concrete
work, not routing questions.
- Supported platforms: GitHub and GitLab (self-hosted included) only.
- Never write workflow state to local files; local persistence is only the
retargeted spec YAML under `.opencode/.dag-specs/`.
- Platform delivery (issues, PRs, CI, merge, release) is out of scope for
this command; if the user asks for it, name the boundary and stop.
32 changes: 0 additions & 32 deletions packages/core/src/plugin/command/dag-flow.txt

This file was deleted.

Loading
Loading