Skip to main content

Workflow Composition

Workflows can call other workflows. This lets you build modular, reusable pipelines — a large workflow delegates to smaller, specialized ones.

Calling a sub-workflow

Use a workflow step to invoke another workflow:
- name: validate
  workflow: security-check
  with:
    diff: "{steps.impl.output}"
    agent: "claude-sonnet"
Gump loads the security-check workflow from the playbook, passes the with inputs, and executes it. The sub-workflow runs in the same worktree.

Inputs

A workflow can declare inputs that callers must provide:
# security-check.yaml
name: security-check
inputs:
  diff: { required: true }
  agent: { default: "claude-opus" }

steps:
  - name: review
    agent: "{agent}"
    output: review
    prompt: "Review for security: {diff}"
The with field in the calling step maps values to these inputs. Required inputs without a default must be provided.

Foreach with sub-workflows

A foreach step can use workflow: instead of inline steps::
- name: build
  foreach: decompose
  workflow: tdd
Each item from the decompose step is processed by the full TDD workflow. The item variables ({item.name}, {item.description}, {item.files}) and {spec} are automatically inherited by the sub-workflow. This is how you build recursive decomposition: a high-level workflow decomposes into modules, each module is processed by the TDD workflow, which itself decomposes into sub-items.

State bag grafting

When a sub-workflow completes, its entire state bag is grafted into the parent under the step’s namespace. There’s no explicit return declaration. The parent accesses sub-workflow outputs via the full path:
{steps.validate.steps.review.output}
{steps.validate.run.cost}

Isolation rules

A standalone workflow: step (not in a foreach) inherits {spec} and {run.*} from the parent. It does not inherit {steps.*} from the parent — this is intentional isolation. Pass the data you need via with:. A workflow: in a foreach inherits {item.*} and {spec} automatically. The with: field is optional and adds extra inputs on top.

Example: Modular pipeline

name: modular-tdd
description: Decompose, then apply TDD per item

steps:
  - name: decompose
    agent: claude-opus
    output: plan
    prompt: "Decompose {spec} into independent modules."
    gate: [schema]

  - name: build
    foreach: decompose
    workflow: tdd

  - name: quality
    gate: [compile, lint, test]
Each item is processed by the full built-in TDD workflow (tests → impl → quality). The parent workflow only handles decomposition and the final quality check. The complexity of test-driven development is encapsulated in the reusable tdd workflow.