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:
- App repo:
.dmx/loops/{name}.yamlin your repository - 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.
| Type | When to use |
|---|---|
manual | The developer invokes /dmx/run-loop explicitly |
on_complete | The 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 intasks.mdare 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 invalidators/{tool}.py, repo first, then bundled)checks: named checks, each withrequired: 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 advancesignore: failure is silently ignored
Default: warn.
failure_handling
What happens when a required check fails:
pause: loop pauses, you fix and continuefail: 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 passon_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.