Skip to main content

dmx

PyPI Test License: AGPL-3.0

The missing orchestrator for AI-native engineering.

Most teams building with AI run into the same problems:

  • Workflow lives in chat history. No process, nothing that persists, nothing you can hand off.
  • Every developer is using AI differently. Different tools, different prompts, different output.
  • Results are unpredictable. Brilliant one session, wrong the next.
  • No shared context. Every session starts from scratch, every developer builds their own mental model.
  • Missing context causes drift. The same problem solved three ways in the same codebase.

The AI SDLC is the framework we built to fix this: start with a spec, build in phases, verify output, keep context in the repo. dmx is the orchestrator that makes the AI SDLC executable.

dmx runs as an MCP server inside Cursor, Claude Code, GitHub Copilot, and Antigravity. It gives you AI skills that govern the full engineering lifecycle — from first spec to production release — as structured loops. Each loop has a skill sequence, a shared memory context, and a validator. A loop without a validator is just a script.

/dmx/create-ticket         # describe the work → spec → branch
/dmx/plan                  # spec → phased task list
/dmx/implement-next-phase  # build next phase, stop, wait for review
/dmx/validate              # quality gate: spec, security, coverage
/dmx/create-pr             # sync memory, draft PR body, open PR
/dmx/create-release        # tag and publish the release

Every command stops and waits. You review, decide, and move forward. Project context lives in .dmx/ — committed to the repo, read by every AI session.

When a skill sequence is trusted, formalize it as a loop — declarative YAML config, automated validators, and persisted state:

/run-loop spec             # start the spec loop (ticket → branch → spec)
/loop-continue             # resume after a human gate

Loop runtime

Loops are declarative configs that run an ordered skill sequence with durable state and automated validation. Default configs ship with dmx; teams override via .dmx/loops/{name}.yaml.

Foreground is running /dmx/* skills manually — you are the orchestrator. Background is the loop runtime: you define the sequence, write validators that encode your judgment, and review the artifact. Trust is earned by validators, not a config flag.

Command What it does
/run-loop Start a loop by name — loads config, writes state, runs the first skill
/loop-continue Resume a paused loop after human review at a gate

Bundled loops for the SDLC pipeline:

Loop Skills Chains to
spec create-ticket plan
plan plan dev
dev implement-next-phase, commit validate
validate validate release
release create-pr —

Each loop config defines a goal state, optional repeat_until condition, validators, human gate policy, and on_complete chaining. Run state is written to .dmx/jobs/{job_id}/{loop_name}-{task_id}.json — there's no separate active-run pointer; the active run is derived by scanning a job's state files for the one non-terminal (pending/running/paused/iterating) entry, keyed off the current branch/ticket. On a feature branch, a release snapshot (complete with outcome still null, written by create-pr before check_pr_ready) is also the active run until that check finishes. This keeps loop state isolated per branch: pausing work on one branch and running a loop on another can't corrupt or lose either one's state.

Validators are plain Python functions at validators/{name}.py in the app repo (bundled fallbacks ship with dmx). The orchestrator invokes them via subprocess after all skills complete — the coding agent runs skills; validators run deterministically. A validator entry can set timeout_seconds. When it is omitted the runner allows 630 seconds, and that limit is passed to the validator as loop_context.timeout_seconds. run_tests stops the test command 30 seconds sooner. A configured timeout_seconds must be at least 60 seconds, so that gap is always there. To raise the limit, set timeout_seconds on this validator in the loop's YAML: your .dmx/loops/{name}.yaml if you have one, otherwise the shared source that provides the loop. If you use the bundled loop, copy it to .dmx/loops/{name}.yaml first; that file replaces it. On timeout, dmx stops that command and the processes it started: SIGTERM, then SIGKILL after 5 seconds. Windows stops the tree with taskkill /T /F. A process that starts its own session, such as some Docker-based test setups, is not stopped.

Status: M1 is complete (#5) — config, state persistence, MCP orchestration (run_loop, loop_advance, loop_continue, loop_status), human-gate sequencing, validator execution, the policy engine, repeat_until iteration, on_complete auto-chaining, and loop-level memory hooks are all implemented and covered by an end-to-end integration test suite that runs the full spec → plan → dev → validate → release pipeline through the real MCP tools.

Loop-level memory hooks: before the first skill runs, the runtime surfaces activeContext.md's Open Learnings / Open Decisions to the agent; when a loop finishes (complete, paused for validator review, or iterating), it appends a one-line breadcrumb to Session Notes. This is a deterministic log entry, not judgment — promoting it into durable knowledge is still /dmx/update-memory's job.

Shared sources

An organization can define loops, skills, and validators once in a dedicated git repo and have every app repo in the org pull from them, instead of copy-pasting the same files into each one and letting them drift. This adds a third resolution tier, in between the app repo and dmx's own bundled defaults:

app repo (.dmx/loops/, .dmx/skills/, validators/)         ← highest precedence
        ↓
.dmx/vendor/{name}/{loops,skills,validators}/               ← declared shared sources,
        ↓                                                      checked in declared order
.dmx/vendor/{name-2}/{loops,skills,validators}/
        ↓
bundled with dmx (src/dmx/{loops,skills,validators}/)      ← lowest precedence

Declare one or more sources in .dmx/shared-sources.yaml, pinned to a tag, branch, or commit SHA (same git::<url>//<subdir>?ref=<ref> addressing Terraform uses for module sources):

shared_sources:
  - name: org-wide
    source: "git::https://github.com/acme/dmx-shared.git//?ref=v1.4.0"
  - name: team-frontend
    source: "git::https://github.com/acme/dmx-frontend-skills.git//?ref=v2.1.0"

Then run /dmx/sync to clone each source at its pinned ref and vendor it into .dmx/vendor/{name}/, committed to the repo like any other .dmx/ state. Re-run it whenever a source's ref changes. /dmx/sync:

  • Is blocked on branch_base — like every other write path in dmx, it produces a commit that belongs on a reviewed branch, not straight on main.
  • Fails clearly (not silently) if a source can't be cloned, its ref doesn't exist, the resolved directory doesn't look like a dmx shared source (no loops/, skills/, or validators/ at the resolved path), or an entry under its skills/ doesn't match either supported shape.
  • Warns — without failing the sync — about same-name collisions across the app repo and every declared source, e.g. two sources both defining spec.yaml, so an unintended shadow never goes unnoticed.

Skills support two shapes, in every tier that resolves them (a project's own .dmx/skills/, a shared source's skills/, and dmx's bundled skills): dmx's own flat {name}.md, or the agentskills.io / Claude Code / Cursor convention of a {name}/SKILL.md folder with optional scripts/, references/, and assets/ — so a shared source (or a project directly) can point straight at an org's existing standards-shaped skills repo with zero dmx-specific restructuring. When a folder-shaped skill resolves, dmx tells the agent its on-disk root path so it can resolve those scripts//references//assets/ paths directly, and surfaces any dependencies: declared in its frontmatter as an explicit note (dmx has no auto-install step of its own).

list_skills lists those local and vendored skills: one line per name, name (source): description, using the name get_skill_definition accepts. It does not list bundled skills. The CLI command dmx list-skills does the opposite and prints bundled skills only. A listed skill whose name matches a bundled command is marked on the line, because loops and get_skill_definition load the override while /dmx/{name} still runs the bundled prompt. A discovery question ("which skills can update helm?") calls list_skills, lists the matches, and runs nothing. A task request with no loop active runs the one clear match through get_skill_definition, and asks which to run when several match.

Because everything is vendored and committed rather than fetched live at resolve time, network and git credentials are only needed at /dmx/sync time — infrequent and human-reviewed — not on every loop run. /dmx/sync shells out to plain git, so it inherits whatever credentials the invoking environment's git already has (SSH agent, gh auth, a CI deploy key or machine-user PAT) — nothing dmx-specific to configure, and it works the same way against GitHub, GitHub Enterprise, GitLab, or any other git host. See #27 for the full design.

Roadmap

  • Full lifecycle workflow — spec, plan, build, validate, release
  • .dmx/ memory bank — shared project context committed to the repo
  • Loop runtime — background execution engine with validators, policy, repeat_until, and autonomous chaining (#5)
  • Org-wide shared sources — vendor shared loops/skills/validators from a central git repo (#27)
  • Team server — hosted MCP endpoint, shared loops and rules across the team
  • Gateway — model governance, cost visibility, autonomous background execution

Get started

{
  "mcpServers": {
    "dmx": {
      "command": "uvx",
      "args": ["--from", "deepmodel-dmx", "dmx", "serve"]
    }
  }
}

Add to your IDE config (Claude Code, Copilot, Antigravity ↓). Then follow Your first project to initialize and run the full loop on a new repo.

Your first project

A brand-new repo, from /dmx/init through the first merged PR. You review at every gate; /dmx/loop-continue is how you move forward.

Before you start

  • A GitHub repo cloned locally with an origin remote. The spec loop creates the feature branch on GitHub from origin/{branch_base} (usually main or master), even if you track work in Jira or use no ticketing system.
  • The dmx MCP server added to your IDE (install guide).
  • The GitHub MCP server (user-github) authenticated. /dmx/init probes it before writing any files.
  • The Atlassian MCP server only if you will choose Jira at init.

1. Initialize

On the integration branch (main or master):

/dmx/init

Choose a workflow — sdlc (this walkthrough) or freestyle (no process enforced) — and a ticketing system: none, github-issues, or jira. Re-run /dmx/init at any time to switch workflow or ticketing; existing memory bank files with content are left intact.

Init writes .dmx/config.md and the memory bank (projectbrief.md, productContext.md, systemPatterns.md, techContext.md, activeContext.md). Open a new chat so the IDE rules take effect.

If you already have a docs/ folder, init reads it when populating the memory bank. Writing the requirement first is slightly better; either order works.

2. Write the product requirement

Create docs/requirements.md at the repo root and put the product or feature description there. You can paste the requirement into chat later instead, but a file is easier to review and reuse.

docs/requirements.md is a convention, not a dmx artifact. The spec loop uses whatever you point it at.

3. Commit and push

The spec loop must start from the configured integration branch, and it creates the remote feature branch from whatever is already on origin. Commit .dmx/, docs/, and any files init wrote, then push:

git add .
git commit -m "chore: initialize dmx and capture product requirements"
git push -u origin HEAD

Stay on main or master.

4. Start the spec loop

In the same message as the command, point at the requirement file or paste it:

/dmx/run-loop spec

See docs/requirements.md

This creates a GitHub issue or Jira ticket (if you configured one), cuts a feature branch from origin/{branch_base}, checks it out, and writes .dmx/spec.md. Then it pauses.

5. Answer the spec

Open .dmx/spec.md. Fill in Technical Approach if it is incomplete, and answer every question. Empty answers or placeholders (TBD, TODO) fail the spec validator.

/dmx/loop-continue

On success the runtime auto-chains to the plan loop.

6. Review the plan

plan writes .dmx/tasks.md with phases and tasks, then pauses. Edit freely — this is the implementation contract.

/dmx/loop-continue

That starts the dev loop.

7. Build phase by phase

Each dev cycle:

  1. Implements the next unchecked phase in tasks.md, then pauses.
  2. Review the diff.
  3. /dmx/loop-continue runs commit only. It does not push.
  4. Review the commit.
  5. /dmx/loop-continue again — validators run, then either the next phase starts or the loop chains to validate.

Repeat until every phase is checked off.

8. Validate and open the PR

After the last phase, validate runs the quality gate and pauses. Review the report, then /dmx/loop-continue. On success the release loop runs create-pr: it pushes the feature branch and opens the pull request.

9. Merge and close

Review the PR and merge it. Then:

/dmx/close-ticket

That closes the ticket, comments the PR link, and deletes the feature branch locally and on origin. /dmx/loop-continue after merge is not a close path — the release loop ends when the PR exists.

You can run the same steps by hand (/dmx/create-ticket, /dmx/plan, /dmx/implement-next-phase, …) instead of loops. See the skill catalog below.

Learn more

Full install guide

Step 1 — Add the MCP server

Add to your Cursor MCP config (~/.cursor/mcp.json) and restart:

{
  "mcpServers": {
    "dmx": {
      "command": "uvx",
      "args": ["--from", "deepmodel-dmx", "dmx", "serve"]
    }
  }
}
Claude Code, Copilot, Antigravity

Claude Code — ~/.claude/claude_desktop_config.json

{
  "mcpServers": {
    "dmx": {
      "command": "uvx",
      "args": ["--from", "deepmodel-dmx", "dmx", "serve"]
    }
  }
}

GitHub Copilot — .vscode/settings.json

{
  "mcp": {
    "servers": {
      "dmx": {
        "command": "uvx",
        "args": ["--from", "deepmodel-dmx", "dmx", "serve"]
      }
    }
  }
}

Antigravity — ~/.gemini/config/mcp_config.json

{
  "mcpServers": {
    "dmx": {
      "command": "uvx",
      "args": ["--from", "deepmodel-dmx", "dmx", "serve"]
    }
  }
}

Step 2 — Run /dmx/init in your IDE

Open any chat and run /dmx/init. It will:

  • Write always-apply engineering rules into your project (.cursor/rules/, CLAUDE.md, etc.)
  • Scaffold the .dmx/ memory bank — durable core files plus an activeContext.md learning inbox
  • Configure your workflow mode (feature branches or trunk) and ticketing system

Safe to re-run. Updates config without overwriting memory bank files that already have content.

After you upgrade the dmx package, run /dmx/upgrade once, then commit the changed rule files. It refreshes the rules copied into the repo and does not change .dmx/config.md, the memory bank, or .dmx/jobs/.

Step 3 — Start your first ticket

On a new repo, follow Your first project (/dmx/run-loop spec through /dmx/close-ticket).

To start a ticket by hand instead:

/dmx/create-ticket

Describe what you want to build. dmx scaffolds the spec, asks clarifying questions, and waits for your answers before writing a line of code.

Full skill catalog

Workflow

Skill What it does
/dmx/init One-time project setup: rules, memory bank, IDE config
/dmx/upgrade Refresh IDE rule files after upgrading the dmx package
/dmx/create-ticket Idea → ticket → branch → spec in one command
/dmx/derive-ticket Uncommitted changes → ticket → branch → derived spec
/dmx/plan Answered spec → phased tasks.md
/dmx/implement-next-phase Execute the next phase in tasks.md, stop
/dmx/implement-next-task Execute the next single task, stop
/dmx/validate Pre-PR quality gate: ticket, code, security
/dmx/create-branch Create a properly named branch, scaffold spec
/dmx/commit Conventional commit from staged diff
/dmx/create-pr Open PR with correct title + description
/dmx/draft-pr-description Generate PR body without opening the PR
/dmx/close-ticket Post-merge: close ticket, delete branch

Release

Skill What it does
/dmx/hotfix Create hotfix branch from production_branch
/dmx/draft-release-note Generate release notes from merged PRs
/dmx/release-merge Open integration → production release gate PR
/dmx/create-release Tag production branch and publish GitHub release

Utilities

Skill What it does
/dmx/status Snapshot of in-progress tickets and open PRs
/dmx/sync-branch Rebase/merge integration branch onto current branch
/dmx/sync Vendor org-wide shared loops/skills/validators into .dmx/vendor/
/dmx/update-memory Deep sync: promote inbox learnings, reconcile contradictions
/dmx/review Code review: clarity, correctness, maintainability
/dmx/test Write tests that enable change
/dmx/docs Write clear, human-first documentation
/dmx/secure Security analysis — thinks like an attacker

Loop

Skill What it does
/run-loop Start a loop by name — reads loop config, initialises state, runs first skill
/loop-continue Resume a paused loop after human review at a gate
Memory bank (.dmx/)

The .dmx/ directory is the project's shared memory — committed to the repo so every developer and every AI session starts from the same understanding.

File Role Lifetime
config.md Project settings — ticketing, integration/production branches, credentials; injected as always-apply rule Updated by /dmx/init
projectbrief.md Goals, scope, non-negotiables Durable — updated rarely
productContext.md User-facing behaviour and flows Durable — updated when features ship
systemPatterns.md Architecture, patterns, component relationships Durable — updated when design changes
techContext.md Stack, dependencies, constraints Durable — updated when tooling changes
activeContext.md Learning inbox: open learnings, decisions, session notes Branch-local — promoted to durable files on commit/PR
spec.md What is being built and why — YAML frontmatter + scope + Q&A Branch-scoped — created by create-ticket, committed with the PR
tasks.md Phased implementation plan Branch-scoped — created by plan, committed with the PR
loops/ Loop config overrides (YAML) Optional — overrides bundled defaults from dmx
jobs/ Per-run loop state (skill progress, validator results); also doubles as the active-run pointer — no separate pointer file exists Branch-scoped — committed with the PR when present

Branch-as-identity model: each branch holds exactly one unit of work. spec.md and tasks.md live directly in .dmx/ on the feature branch. When a PR merges, they go with it — but close-ticket doesn't delete them, so main (and any branch cut from it afterward) keeps the last-merged ticket's spec.md/tasks.md as a stale leftover rather than truly starting fresh. The spec loop guards against this explicitly: it only starts from the configured integration branch and never trusts a pre-existing spec.md for its own job identity, so a leftover file can't get a new ticket's state written into the previous ticket's job folder.

Three-tier memory sync: learnings accumulate in activeContext.md during implementation. /dmx/commit promotes qualifying items (light sync), /dmx/create-pr promotes all remaining items (full sync), and /dmx/update-memory does a deep reconciliation on demand.

Metadata

Release files for deepmodel-dmx 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for deepmodel-dmx 0.5.0
File Size Uploaded
deepmodel_dmx-0.5.0.tar.gz 320.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for deepmodel-dmx 0.5.0
File Interpreter ABI Platform
deepmodel_dmx-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 498.2 kB

Release files / deepmodel_dmx-0.5.0.tar.gz

Download URL deepmodel_dmx-0.5.0.tar.gz
Size 320.6 kB
Tags Source
SHA-256 checksum
How to use checksums
9cfc7f8c3a076bb24ce7bbd88c8302b84d35705d98f61979cf145b290c375166
BLAKE2b-256 checksum
How to use checksums
9dbd353c86ab0162fb78147b2f80a0d5f9761672a1e4a93f32268b6e1fed739a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / deepmodel_dmx-0.5.0-py3-none-any.whl

Download URL deepmodel_dmx-0.5.0-py3-none-any.whl
Size 177.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f1002795cdd7ead0b3a157e1721c007936ea4db8af744fdcc3a7d5b32b76f622
BLAKE2b-256 checksum
How to use checksums
c4d9491c24a1ee1171adfb25ae125eae206de1b21e614e03841f4a5f7fccf93d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.1

2 release files

This release

0.5.0 This release

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page