Skip to main content

Loop Configuration

Loop configs are YAML files that define how a loop runs. They live in .dmx/loops/{name}.yaml in your repository.

Where configs live

dmx resolves loop configs in this order:

  1. App repo: .dmx/loops/{name}.yaml in your repository
  2. Bundled defaults: the five default loops shipped with dmx

The repo always wins. A file at .dmx/loops/dev.yaml overrides the bundled Dev Loop entirely.

To customise a loop, copy the bundled default into .dmx/loops/ and modify it. To create a new loop, create a new file. The filename stem becomes the loop name.

Full YAML schema

# Required — must match the filename stem
name: dev

# Required — ordered list of skill names to execute
skills:
- implement-next-phase
- commit

# Trigger — how the loop starts
trigger:
type: manual # manual | on_complete

# Goal state — plain-English description of success
goal_state: "All phases implemented and committed, no unchecked tasks remaining"

# Repeat until — condition to evaluate before running validators
# Currently supported: all_phases_complete
# Omit if the loop should run once only
repeat_until: all_phases_complete

# Validators — run after all skills complete (and repeat_until is met)
validators:
- tool: run_tests # validator script name
checks:
- name: tests_pass
required: true # required: true | false
- name: coverage_threshold
required: false

- tool: spec_adherence
checks:
- name: scope_matches_spec
required: true
- name: edge_cases_addressed
required: false

# What to do when an optional check fails
on_optional_failure: warn # warn | ignore

# What to do when a required check fails
failure_handling: pause # pause | fail

# Whether to pause at each skill boundary for human review
human_gate: true

# What to do when the loop completes
on_complete:
on_success:
trigger_loop: validate # loop name to start, or null
on_failure:
trigger_loop: null
on_warning:
trigger_loop: null

Field reference

name

Required. The loop name. Must match the filename stem. Used in trigger_loop references and in /dmx/run-loop name.

skills

Required. Ordered list of skill names to execute. Skills run in order. The loop pauses between skills when human_gate: true.

Skill names correspond to the name field in skill .md files. Available skills are listed in Command Reference.

trigger

How the loop starts.

TypeWhen to use
manualThe developer invokes /dmx/run-loop explicitly
on_completeThe loop fires when the previous loop's on_success.trigger_loop names this loop

goal_state

Plain-English description of what the loop is trying to achieve. Passed to validators as context (goal_state in the input contract).

repeat_until

If set, the skill sequence repeats until the condition is met. Currently supported:

  • all_phases_complete: repeats until all - [ ] items in tasks.md are checked off

Omit for loops that should run once.

validators

List of validators to run after all skills complete (and after repeat_until is satisfied). Each validator:

  • tool: the validator script to run (looked up in validators/{tool}.py, repo first, then bundled)
  • checks: named checks, each with required: true | false

Multiple validators run in order. All required checks across all validators must pass.

on_optional_failure

What happens when an optional check fails:

  • warn: warning is emitted, loop advances
  • ignore: failure is silently ignored

Default: warn.

failure_handling

What happens when a required check fails:

  • pause: loop pauses, you fix and continue
  • fail: loop terminates

Default: pause.

human_gate

When true, the loop pauses after each skill completes and waits for /dmx/loop-continue before proceeding. When false, skills run back-to-back automatically.

Default: true.

on_complete

What to do when the loop finishes:

  • on_success.trigger_loop: loop name to start automatically when all validators pass
  • on_failure.trigger_loop: loop name to start when required validators fail (uncommon)
  • on_warning.trigger_loop: loop name to start when optional validators fail (uncommon)

Set to null to terminate without starting another loop.

Example: custom documentation loop

name: docs
skills:
- docs
trigger:
type: manual
goal_state: "Public API documented, docstrings complete, README updated"
validators:
- tool: lint_check
checks:
- name: no_lint_errors
required: false
on_optional_failure: warn
failure_handling: pause
human_gate: true
on_complete:
on_success:
trigger_loop: null

Example: hotfix loop (faster path)

name: hotfix
skills:
- implement-next-phase
- commit
- validate
- create-pr
trigger:
type: manual
goal_state: "Fix implemented, validated, PR opened against production branch"
validators:
- tool: run_tests
checks:
- name: tests_pass
required: true
on_optional_failure: warn
failure_handling: pause
human_gate: true
on_complete:
on_success:
trigger_loop: null

Tips

Keep loop configs in version control. .dmx/loops/ should be committed to your repo. Loop configs are reviewed in PRs like any other code change.

Start from the bundled defaults. Copy the relevant YAML from The Default Loops and modify it. The defaults are designed to be good starting points, not constraints.

One loop, one responsibility. Avoid creating loops that try to do too many things. A loop that's too long is hard to review and hard to debug when validators fail.