Skip to content

Authoring Workflows

Lex edited this page Aug 15, 2026 · 1 revision

Authoring Workflows

A workflow spec is a YAML file describing a graph. This page covers the two authoring paths, the file shape, and how to make a spec reusable.

Path 1: let the agent draft it

The fastest route. In a session:

"save a reusable workflow that audits dependencies and proposes an upgrade order"

The agent uses the built-in create-dag-workflow skill: it agrees on phases and gates with you, writes the spec into the scope you pick (project .opencode/workflows/ or the global dir), and proves it by starting it once.

For one-off graphs there is workflow(action="draft"): you describe the graph in structured tool parameters, the harness renders and validates the YAML file, and hands back the spec_path. Field-name mistakes are rejected by the tool schema at the provider boundary — they never reach the file.

Path 2: write the YAML

Minimal complete spec:

title: Dependency audit
config:
  name: dependency-audit
  nodes:
    - id: inventory
      name: inventory
      worker_type: explore
      depends_on: []
      required: true
      prompt_template:
        id: config-explore
        input:
          target: "package.json files and lockfiles"

    - id: report
      name: report
      worker_type: general
      depends_on: [inventory]
      report_to_parent: true
      prompt_template:
        inline: "Flag outdated or duplicated dependencies in {{inventory}} and propose an upgrade order."

Node fields worth knowing beyond the obvious:

Field What it buys you
condition Expression over upstream outputs; false skips the node, pure descendants cascade-skip
input_mapping Renames upstream outputs for the template (count: "node-b.output.count")
output_schema JSON Schema; the child must call submit_result with a matching payload
review Marks a design/diff review node with fingerprint binding to the implementation
timeout_ms Per-node deadline; queue wait counts

Or use blocks, which compile to nodes and handle the review-route contracts for you:

config:
  name: fix-a-defect
  objective: Reproduce, fix, and verify the reported defect.
  blocks:
    - id: reproduce
      kind: debug
      instruction: Build a red test for the reported symptom.
    - id: fix
      kind: coding
      depends_on: [reproduce]
      instruction: Fix the root cause and turn the test green.
    - id: verify
      kind: verify
      depends_on: [fix]
    - id: review
      kind: review
      depends_on: [verify]

Naming it: the three scopes

Scope Path Availability
Project .opencode/workflows/<name>.yaml This repo, committed with it
Global <opencode config dir>/workflows/<name>.yaml Every project on the machine
Builtin Compiled into release binaries Fallback tier

First match wins, project shadows global, both shadow builtin. Once named, "run the dependency-audit workflow" starts it without a path.

Rules a saved spec must respect

  • No pinned models — tiers come from dag.jsonc, never from the spec.
  • worker_type must exist in the agent catalog.
  • Template variables marked required must be supplied (input or input_mapping), or the node fails loudly at spawn — by design.
  • Prefer inline prompts for global workflows, so they don't depend on a repo-local template file.

Report files

A node whose final reply is a single absolute file path gets captured as {content_ref, size, sha256, summary}; workflow(action="result") returns the pointer. Writing reports under .opencode/workflow-reports/ keeps them out of git — an ignore entry is added automatically on first write. Long reports belong in files, not in the transcript.

Clone this wiki locally