Back to Browse

Ddflow MCP Server

by Delian
Developer ToolsLow Risk10.0MCP RegistryLocal
Free

Server data from the Official MCP Registry

Work-queue kernel for AI coding agents: dependencies, worktree isolation, quality gates, recovery

About

Work-queue kernel for AI coding agents: dependencies, worktree isolation, quality gates, recovery

Security Report

10.0
Low Risk10.0Low Risk

Valid MCP server (1 strong, 1 medium validity signals). No known CVEs in dependencies. Package registry verified. Imported from the Official MCP Registry.

3 files analyzed · 1 issue found

Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.

What You'll Need

Set these up before or after installing:

Repository root ddflow manages. Defaults to the client's working directory, resolved to the primary checkout even when called from inside a git worktree.Optional

Environment variable: DDFLOW_REPO

Stable identity for this agent. Shards the event log so concurrent agents never write the same file. Defaults to host plus the git worktree's name, so every process in one worktree agrees and two parallel agents differ. A harness running SEVERAL agents inside one worktree must set this, or their work merges into a single identity.Optional

Environment variable: DDFLOW_AGENT

How to Install

Add this to your MCP configuration file:

{
  "mcpServers": {
    "io-github-delian-ddflow-mcp": {
      "env": {
        "DDFLOW_REPO": "your-ddflow-repo-here",
        "DDFLOW_AGENT": "your-ddflow-agent-here"
      },
      "args": [
        "ddflow-mcp"
      ],
      "command": "uvx"
    }
  }
}

Documentation

View on GitHub

From the project's GitHub README.

ddflow

A portable, agent-agnostic work-queue kernel for AI coding agents.

You keep a queue of phases and tasks with declared dependencies. You say "implement phase P2". Independent tasks fan out to parallel agents in isolated git worktrees; dependent ones wait. Every task passes a quality pipeline whose gates cannot be passed by assertion. If an agent crashes, its work is found rather than lost. If everything except the log is destroyed, the project's decision history rebuilds from the log alone.

Two dependencies beyond python3 and git (Jinja2, for the prompt templates, see Extending it by writing text, not code; and tomlkit, which edits .ddflow/config.toml without losing its comments). Everything else is an optional extra, none needed for the core: ddflow[search] (rapidfuzz) and ddflow[rag] (model2vec) are in use, with BM25 and difflib as the fallback; sqlite-vec (also in ddflow[rag]), ddflow[watch] (watchfiles) and ddflow[mcp-sdk] (the MCP SDK, for a future network transport) are declared and not yet used. A check that needs an absent extra is recorded unavailable, never passed. Works with Claude Code, Gemini CLI, Codex, Copilot, Cursor, Kimi, opencode, Aider, a CI job, a Makefile, or a human at a terminal — over a CLI and an MCP server that are the same implementation.


Instruction for an agent reader

If you are an AI agent and were asked to read this README, this section is your shorthand. Everything below it is detail.

What ddflow is. A work queue with rules the tools enforce, for projects that agents build. Work is phases and tasks with dependencies and declared file globs. Each task gets a lease and its own git worktree, then passes a gate pipeline: a check that could not run is unavailable, never passed; one reviewer must be from another model family; a bug closes only with a regression test that failed first. Everything is recorded in an append-only log in .ddflow/events/, committed with the code. ddflow writes none of your project's code — you do; it adds only its own config, a rules block and git hooks. Every operation is both a shell command (ddflow …) and an MCP tool (ddflow_…).

If the project already uses it (.ddflow/ exists): call ddflow_brief (or run ddflow brief) first and follow it. It replaces reading the project's rule and lesson files. Then: ddflow_next → ddflow_claim → work only in the worktree it returns → ddflow_gate_status, satisfy each gate → ddflow_merge → ddflow_complete. The full driver is docs/ddflow/drivers/implement-phase.md in that project.

To onboard a project, ask the user first: it installs a tool, registers an MCP server and writes files in their repository.

  1. Install: uv tool install git+https://github.com/delian/ddflow-mcp (not on PyPI yet).
  2. In the project root: ddflow adopt --agents claude (your agent's name; see Wiring it into your agent). It writes .ddflow/, the MCP registration, the commit hook and a rules block in AGENTS.md. Restart the agent session so it loads the MCP server.
  3. ddflow import lists the plans, lessons, decisions and unmerged branches the repository already has, and writes nothing. Run ddflow import --apply only once the user agrees with that list.
  4. ddflow config --set gate.unit_tests.command "<their test command>". Then ddflow companions lists the tools the gates expect that are missing: propose them, never install one unasked.
  5. Put the user's plan in the queue (ddflow phase add …, ddflow task add … --globs …) and finish with ddflow doctor.

Exit codes, everywhere: 0 ok · 1 failure · 2 could not run / nothing to do · 3 refused. Never treat 2 as 0.


Everything is yours to change, per project

ddflow ships defaults, never a fixed process. Every part of how it works is a file or a setting in your repository, and each project can differ from the next: the gate pipeline and each gate's command or prompt, which reviewers run, the rules your agents follow, every prompt an agent is handed (including the instructions it receives the moment it connects), the slash-command workflows, your own [[macro]] modes, the export document templates, the branching and release model, parallelism and lease limits, cadences, enforcement strictness, and the per-agent driver docs. Nothing is hard-wired except the four enforced rules at the top of this page, and even those are tuned through documented knobs, never silently bypassed.

Three ways to change anything, all validated before anything is written:

  • Edit the file. It is plain TOML or Markdown under .ddflow/ (committed, shared by every clone) or .ddflow/local/ (git-ignored, yours alone).
  • Use the CLI (ddflow config --set, ddflow workflow …, ddflow prompts eject, ddflow rule …, ddflow export eject).
  • Ask your agent, which has the same operations as MCP tools (ddflow_configure, ddflow_workflow_*, ddflow_rule_*). It changes a project's workflow only with your agreement.

The complete list of what can be changed, and where, is the Customisation reference at the end of this page.


Introduction

The problem it solves

An AI coding agent is good at a task and weak at a project. One agent in one session mostly works. Run it for weeks, or run three at once, and the same failures come back:

  • Work disappears. A session crashes or is closed mid-task, and the half-finished change sits in a directory nobody remembers.
  • Agents collide. Two of them edit the same file, and the second merge quietly undoes the first.
  • Checks that never ran look like checks that passed. The linter was missing, the reviewer endpoint was down, the tests were "run" in a summary. The agent reports done, and nothing on record says otherwise.
  • The project forgets. Last week's hard-won lesson, the reason behind a design choice, the bug that was already fixed once — gone at the next session, or at the next context compaction in this one.
  • Nobody can say what happened. Which instruction led to which change, and which review looked at it, lives in a chat transcript that no longer exists.

ddflow is the layer between you and your agents that makes those failures structurally hard rather than a matter of discipline. It does not write code and it is not an agent. It is a queue, a set of rules the tools enforce, and a log of everything that happened.

What changes for you

Without itWith ddflow
You decide what each agent does next, and keep the plan in your head or a chat.The plan is a queue of phases and tasks with dependencies. ddflow next says what can start now and why everything else is blocked.
Parallel agents step on each other.ddflow claim gives each task a lease and its own git worktree; tasks that declare overlapping files are refused, not merged over.
"Done" means the agent said so.Every task passes a gate pipeline you configure. A gate that could not run is recorded unavailable, never passed; at least one reviewer must come from a different model family than the author; a bug cannot be closed without a regression test that failed first.
A crash loses work.ddflow recover finds orphaned worktrees and reports what each holds. It never deletes work.
Every session starts from zero.Lessons, decisions, research verdicts, bugs and your own prompts are recorded as you go. ddflow brief hands the agent the ones relevant to this task in a bounded amount of context, and ddflow recall searches all of it. The same brief also names the project's own skills, commands and rules files (.claude/skills, .claude/commands, .cursor/rules, .clinerules, AGENTS.md/CLAUDE.md) that bear on the task, by name and path only.
History is a transcript.An append-only event log, committed in git. The board, the index and the reports are rebuilt from it; ddflow replay reconstructs the project's decisions from the log alone.

Who it is for

  • One developer with one agent. A plan that survives the session, a memory that survives compaction, and a record of which checks really ran. The queue is useful even with no parallelism at all.
  • Several agents in parallel — subagents, several terminals, several vendors. The dependency graph says which tasks are independent, worktrees keep them apart, and the merge step lands them without anyone switching the main checkout's branch.
  • A team or a CI pipeline. The log is committed with the code, so a fresh clone knows the queue and its history. Read commands have a machine-readable --json form and every command returns the same four exit codes, so a Makefile or a CI job can drive it exactly as an agent does.

It works with the agent you already use, because everything it does is reachable both ways: as a shell command and as an MCP tool. Use whichever your agent, script or CI job has. Your workflow is text, not code — the gate pipeline, the reviewer instructions and the agent-facing prompts are files in your repository that you can edit.

What it is not

  • Not an agent or a model. Your agent does the work; ddflow decides what may start, checks what was claimed, and remembers.
  • Not a hosted service. Everything is files in your repository and a disposable local cache. No account, no server to run beyond the local MCP process.
  • Not a replacement for your tests or CI. It runs the commands you configure and records their real exit codes and output.

A first run

# ddflow-mcp is not on PyPI yet; until the first release, install from the repository:
uv tool install git+https://github.com/delian/ddflow-mcp   # or: pipx install git+https://github.com/delian/ddflow-mcp
cd /path/to/your/project
ddflow adopt                        # registers the MCP server with your agents, writes .ddflow/ and a block in AGENTS.md
ddflow phase add P1 --title "Password reset"
ddflow task add P1.T1 --phase P1 --title "Reset-token endpoint" --globs 'src/auth/**'
ddflow next                          # what can start now, and why the rest is blocked

adopt registers the server you just installed, by its full path: an install that did not come from a package index (from git, a local directory or an archive) carries a direct_url.json in its metadata (PEP 610), and for one of those adopt writes the ddflow-mcp installed beside its interpreter rather than uvx ddflow-mcp, which would fetch from PyPI. Only an install from an index gets uvx. --launch python still forces the interpreter-plus-PYTHONPATH form.

Then tell your agent "implement phase P1". The driver adopt installed tells it to start with ddflow_brief, claim the task, work in its own worktree, satisfy each gate and land the change. ddflow cannot make an agent follow instructions, but it makes skipping them visible: the commit hook adopt installs flags a commit made without a lease (or refuses it, if you set [enforce].commit_without_lease = "block"), and ddflow complete refuses an item whose gates carry no outcome. Watch it with ddflow board, and ask ddflow doctor at any point whether the project is healthy.


How do I…?

Every row is a command you can run in a terminal and a tool an agent can call over MCP — the same implementation, so neither drifts from the other.

I want to…CLIMCP tool
see what the workflow isddflow workflowddflow_workflow
onboard an existing projectddflow onboard status (standing drift report; also preflight, legacy, memory, test-gate, verify; propose by default, --apply acts, --accept NAME approves one item)ddflow_onboard (stage, apply, accept)
the pre-push checks, on the merge resultddflow ci run (the ci gate; ddflow ci status shows what would run): a scratch worktree of your branch merged with the base, then the project's own pre-commit run --hook-stage pre-push (or [ci].command, run as written; with the default, a language: fail tripwire hook runs on the diff being checked, not over every file); exit 0 passed, 1 failed, 2 could not run (never a pass). After a merge lands, [ci].on_merge (fast default: the pre-commit set without the test hooks; full; off) checks the base, records a ci.result and files a bug and fix task per failing check; the pre-push hook reports with ddflow ci recordddflow_ci (run, status)
check a done task really is doneddflow verify <id> (or --all / --phase P to sweep every done task, worst first, --file-bugs to file what fails; --reopen sends a completion that fails back to the queue with its gates cleared (--reason says why; --force reopens one that holds); --pack prints the evidence pack (requirement fenced as data, what landed, mechanical findings) for an independent verifier and --judge hands it to the cross-family reviewer (gate verify, optional, never part of the default pipeline); on a task that is not done it names work that landed anyway): landed on main, declared files exist, tests exist, no gate failed or skipped without a reason (exit 1 = a claim does not hold)ddflow_verify
what a finished task required and changedddflow show <id> on a done task prints its completion ledger: requirement digest, files and tests the landing changed, skipped gates, forced flag, later amendmentsddflow_show
one-page state of the projectddflow workflow stateddflow_workflow_state
project rulesddflow rule add|edit|list|search|show|removeddflow_rule_add · _edit · _list · _search · _show · _remove
change the workflowddflow workflow pipeline task … · workflow gate <id> … · workflow drop <id>ddflow_workflow_pipeline · _gate · _drop
change any settingddflow config --explain · --set <key> <value>ddflow_configure
add a phase / a taskddflow phase add P1 --title … · ddflow task add P1.T1 --phase P1 --globs 'src/**'ddflow_phase_add · ddflow_task_add
get a plan into the queuesee From plan mode to the queuesame
know what to work onddflow nextddflow_next
start a taskddflow claim <id> → work → ddflow gate … → ddflow merge → ddflow completeddflow_claim, ddflow_gate_*, ddflow_merge, ddflow_complete
see everything about one item or bugddflow show <id> (phase, task or bug id)ddflow_show
see progress / effortddflow progress · ddflow status · ddflow boardddflow_progress · ddflow_status · ddflow_board
find out if we're going in circlesddflow loopsddflow_loops
see which agents are working, and what each needs nextddflow lanes [--watch] · ddflow lanes brief <lane> · ddflow lanes advise (read-only; see Lanes)ddflow_lanes (view, lane)
see where the time went, and when a phase will endddflow metrics · ddflow metrics forecast [--phase P] · ddflow metrics retro <id> · ddflow metrics skips · ddflow metrics lanes (read-only, from the log; a figure under [metrics] min_samples is n/a, never 0)ddflow_metrics (view, item, phase, since, group_by)
record a lesson / decision / research / bugddflow lesson add · decision add · research · bug found|fixedddflow_lesson_add · ddflow_decision_add · ddflow_research_add · ddflow_bug_*
search everything the project remembersddflow recall '<regex>'ddflow_recall
search for people: tasks, bugs, research, decisions, lessons, sessions, prompts, rules, skills, agents, jobs, schedules, logddflow search '<text>' [--exact|--regex] [--kind K] [--source S] [--state S] [--phase P] [--owner A] [--since D] [--limit N] [--json] -- see Searching everythingddflow_list kind=search (query, mode, sources, source)
check a text against what is already filed (read-only)ddflow similar '<text>' [--kind bug,task,...] [--json] -- exit 0 with candidates, 2 with noneddflow_similar
find records filed twiceddflow dupes [--kind bug,task,...] [--open-only] [--floor F] [--limit N] [--json] -- exit 0 with pairs, 2 with noneddflow_dupes
settle a near-duplicate pairddflow link <a> --duplicate-of|--extends|--related|--distinct <b> [--reason ...]ddflow_link
record what happened this sessionddflow session start|prompt|note|endddflow_session_*
list tasks / phases / bugs / researchddflow task|phase|bug|research list [--state S] [--phase P] [--tag T] [--owner A] [--since D] [--limit N] [--offset N] [--json] -- see Listing; bug list shows open bugs unless --allddflow_list (kind, state, phase, tag, owner, since, limit, offset, all)
read the engineering logddflow history [--item X] [--kind K] [--agent A] [--tail N] [--json] -- compact line per event (time, agent, subject, verb, summary); --agent keeps one agent's shard, --tail N the last N oldest-first, --json cuts payload strings over 500 chars and marks the event truncatedddflow_history
check the tooling around the gatesddflow companionsddflow_companions
find which earlier test file makes a test fail only in full-suite orderddflow bisect VICTIM --cmd 'pytest -q {tests}' [--candidates a,b] [--glob G] [--timeout S] [--repeat N] [--max-runs N] -- delta-debugs the files before the victim, running your command many times (exit 0 = found, 2 = nothing to report); see Finding a test polluterddflow_bisect (glob, repeat and max_runs are CLI-only)
check a companion really is an MCP serverddflow companions --verify [--id X] -- launches each registered or installed MCP companion and requires a JSON-RPC answer to initialize (spawns processes; opt-in; exit 1 = not a server, 2 = could not tell)ddflow_companions_verify
find work a crashed agent leftddflow recoverddflow_recover
check the project's integrityddflow doctor · ddflow doctor --accept-lost-events (the operator's word that events a history rewrite took out of a shard are known, see Events that vanished from a shard)ddflow_doctor (--accept-lost-events is CLI-only)
see what upgrading this project to the running ddflow would changeddflow upgrade [--plan] (alias ddflow doctor --upgrade) -- the plan, by category: data repairs, migrations (registered breaking-change migrations and the files each would rewrite), contested records (a decision, lesson or research id two agents defined differently: each is listed with its rivals and the ddflow resolve command; an apply prints it and resolves nothing, the MCP connect proposal and the upgrade notice mention it), config (new knobs, changed defaults; a value anyone set is marked needs operator confirmation), instructions (drifted driver docs and rules, stale after a release or hand-edited), hooks, MCP launch, opt-in features. Writes nothing; exit 0 up to date, 1 while the plan has items. Do it: ddflow upgrade --apply [CATEGORIES] [--snapshot] [--confirm KEY ... --reason WHY]; undo it: ddflow upgrade --restore [NAME] (see "Applying an upgrade")ddflow_upgrade (apply, confirm, reason, snapshot, restore)
rebuild everything from the logddflow replay --verifyddflow_replay
invoke a workflow / a mode of your ownddflow prompts list · prompts get <name> [--arg KEY=VALUE] (rendered, exactly as prompts/get gives it) · prompts show <name> (its source)prompts/list · prompts/get
see what this project left undoneddflow doctor · ddflow statusthe footer on tool results
ask the tool to explain itselfddflow help [topic]ddflow_help

Every read command takes --json. Every exit code means the same thing everywhere: 0 healthy · 1 real failure · 2 could not run / nothing to do · 3 coordination refused. 2 is never collapsed into 0 — "nothing is ready" and "everything is fine" are different facts, and an agent that cannot tell them apart invents work.

What --json and the MCP tools return has a name. A result that is a JSON object carries a top-level "schema": "<command>@<n>" -- for example "claim@1"; the command is the MCP tool's name without ddflow_, and --json of the CLI command that tool serves says the same. Within a version fields are only ever added; removing or retyping one bumps n. On a refusal the refusal object still leads and the tag follows it. A result that is a bare array (progress, loops, lesson search, ...) keeps its exact shape and has no tag, and text bodies (board, doctor) have none. python -m ddflow.surfaces.tool_table --schemas prints every tool's declared result schema; tests/golden/json/result_schemas.json pins them.


Table of contents


Help: what it can do, and the workflow

$ ddflow help                 # what this is, the loop, every capability grouped
$ ddflow help workflow        # workflow · import · gates · parallel · memory · recovery · config

Reachable as ddflow_help over MCP, and that is the point: an agent connecting had 59 tool descriptions and a state-aware handshake, neither of which answers "what is this, and how am I meant to work here". A tool description explains one tool to someone who already picked it; the handshake describes this repository right now.

Two halves, deliberately:

  • The narrative is a template under ddflow/templates/prompts/help/, so ddflow prompts eject-style overriding applies — put your own .ddflow/prompts/help/workflow.md in place and the tool teaches your workflow.
  • The capability inventory is generated from the live tool table. A hand-kept command list in a second place is the documentation-drift class, and this project has paid for it twice.

Three ratchets keep the prose honest, because a page recommending a flag that was renamed is worse than no page — whoever finds nothing reads the code, and whoever finds a wrong answer trusts it. Every command a page names must exist as a CLI leaf or an MCP tool; every topic the index offers must resolve; and every tool must fall into a group, so a new capability has to be classified rather than quietly dropped from an inventory that claims to be complete.


The default workflow at a glance

Three pictures of what ships by default. Every step is configurable (see The workflow, and changing it); ddflow workflow prints what this project actually runs.

The agent's loop. One item at a time: pick it, lease it, clear its gates, land it. Each arrow labelled with an exit code is what the tool says, not a convention — 2 means nothing to do, 3 means refused, and neither is ever read as success.

flowchart TD
    S["Session start<br/>ddflow brief · recover"] --> R{"Crashed agent's<br/>work left over?"}
    R -- yes --> SV["Inspect the worktree, salvage,<br/>ddflow release"] --> N
    R -- no --> N["ddflow next"]
    N -- "exit 2: nothing ready" --> W["ddflow wait<br/>sleeps until a holder lets go"] --> N
    N -- "exit 0: items ready" --> C["ddflow claim<br/>lease + isolated git worktree"]
    C -- "exit 3: refused<br/>(lease or file-glob conflict)" --> N
    C --> P["Task pipeline<br/>satisfy every gate in order"]
    P --> M["ddflow merge<br/>lands the branch from the primary checkout"]
    M --> D["ddflow complete<br/>checks every gate has an outcome<br/>+ a different-family review"]
    D -- "exit 3: refused" --> P
    D -- done --> N

With [flow].integration = "pr", merge opens a pull request and parks the item in review instead; next completes it when the request merges.

A lease is evidence of intent, not a lock, but a LIVE lease held from another clone is not overwritten by accident: release and gate run|record|skip on it exit 3 naming the holder, unless you pass --force --reason "<why>" (CLI only; recorded as forced on the event). Agents of the same clone, an expired lease and a lease with no recorded clone are unaffected.

The task pipeline. Ten gates, in order. Heavy borders are the gates gates.required names by default (implement, unit_tests, merge); the rest still need some outcome — passed, failed, unavailable, partial, or an explicit skip with a reason — because silence is not a pass.

flowchart LR
    subgraph A["You, the agent"]
        direction TB
        g1["1 · research<br/>falsifiable claim + probe"] --> g2["2 · rules<br/>ddflow brief --item"] --> g3["3 · implement<br/>in the item's worktree"]
    end
    subgraph X["A different model family"]
        direction TB
        g4["4 · rubber_duck<br/>try to refute it"] --> g5["5 · critic<br/>diff vs. stated intent"]
    end
    subgraph T["Tooling"]
        direction TB
        g6["6 · standards<br/>linters, architecture"] --> g7["7 · unit_tests<br/>the suite, executed"]
    end
    subgraph B["You, again"]
        direction TB
        g8["8 · bug_hunt<br/>recurring bug classes"] --> g9["9 · dedupe<br/>already exists?"]
    end
    g10(["10 · merge<br/>ddflow lands it"])
    A --> X --> T --> B --> g10

    classDef req stroke-width:3px
    class g3,g7,g10 req

The phase pipeline. A phase wraps its tasks and checks the whole before it lands:

flowchart LR
    p1["research<br/>the phase's open questions"] --> p2["tasks<br/>each runs its own<br/>ten-gate pipeline,<br/>in parallel where<br/>globs allow"]
    p2 --> p3["unit_tests"] --> p4["bug_hunt"] --> p5["dedupe"]
    p5 --> p6["live_test<br/>run the real thing"] --> p7["corrections"] --> p8["docs<br/>README and docs<br/>match the change"] --> p9(["merge"])

Details: The task pipeline · The phase pipeline · Parallelism and coordination · Crash recovery.


Two ways to drive it

The CLI is the whole product. The MCP server is a second surface over the same commands, and tests/test_mcp_parity.py fails if the two diverge — every subcommand has a tool, every flag is reachable, and each exemption carries a written reason.

Standalone: a terminal, a Makefile, CI

$ ddflow init
$ ddflow config --set gate.unit_tests.command "python -m pytest -q"
$ ddflow phase add P1 --title "Billing" --globs "src/billing/**"
$ ddflow task add P1.T1 --phase P1 --title "Tax rules" --globs "src/billing/tax.py"

$ ddflow next                          # exit 2 = nothing actionable; exit 1 = unknown --phase
$ ddflow claim P1.T1                   # exit 3 = refused, with the reason
leased P1.T1 · worktree .ddflow/worktrees/P1.T1 · branch ddflow/P1.T1

$ cd .ddflow/worktrees/P1.T1 && ...   # do the work
$ ddflow gate status P1.T1             # what the pipeline wants next
$ ddflow gate run P1.T1 unit_tests     # runs it; the exit code IS the evidence
$ ddflow gate record P1.T1 implement --outcome passed --evidence "added tax.py"
                                       # failed/unavailable/partial/skipped also need --reason
$ ddflow complete P1.T1                # exit 3 lists whatever is unsatisfied
$ ddflow merge P1.T1

You get everything except the judgement. Command gates run themselves; agent gates wait for a human to record an outcome, and ddflow gate skip <id> <gate> --reason "..." is the escape hatch — recorded as a skip, never as a pass.

Merge queue. Where several agents land work at once, ddflow queue add <id> enqueues an item, ddflow queue run (any agent may) integrates the head of the queue — one entry's ci at a time, --max-batch N entries per run, --unit-tests / --no-unit-tests to run or skip each entry's unit_tests gate on the merged result — ddflow queue status (the default) prints the line, and ddflow queue remove <id> drops an entry. Defaults live in [merge_queue].

Changelog line (optional). ddflow complete P1.T1 --changelog "Added: tax rounding" (and ddflow bug fixed B1 --regression-test ... --changelog "Security: ...", MCP changelog on ddflow_complete / ddflow_bug_fixed) records one line for the project's changelog on the completion event. The category is one of Added, Changed, Deprecated, Removed, Fixed, Security (case-insensitive; anything else is refused with that list); --changelog skip (or internal) marks work that must not appear in the changelog. complete never asks for it and never requires it, and logs without it fold exactly as before.

In CI, the exit codes are the interface:

check:
	ddflow doctor        # 1 = integrity problems, each named
	ddflow workflow      # 1 = the pipeline does not hang together
	ddflow cadence       # 2 = no periodic pass is due

2 is never "no problem". A job that treats it as success reports a green build for a suite that never ran.

Every command

Every top-level command, with the first line of its --help. The list is generated from the command parser (python -m ddflow.surfaces.command_table README.md rewrites it, and ddflow pins regenerate does so after a merge), so a command added on another branch never needs a line written by hand here.

Documentation truncated — see the full README on GitHub.

Reviews

No reviews yet

Be the first to review this server!