What Happens After You Choose the Right Tool
Articles
2026-08-288 min read

What Happens After You Choose the Right Tool

We have scoped the job. We have chosen an execution lane and matched tools to the work. That still leaves a system-level decision hiding in plain sight: what genuinely needs what first?

If we do not answer it, the work inherits whatever sequence was easiest to write down. A folder order becomes a process. A checklist becomes a queue. Independent tasks wait because their lines happen to sit beneath one another. The tool may be right and the pace may be deliberate, yet the execution shape is still accidental.

A directed acyclic graph—a DAG—helps us make the distinction visible. It says which units depend on which other units. It does not run them. That second job belongs to a runtime.

Start with the smallest useful shape

The dependency diamond is a better introduction than a page of terminology:

A shared input branches into two independent tasks and joins when both results are required.
Figure 1. Prepare once, expose two independent branches, then join when both results are required.

Once the shared input exists, B and C are eligible together. There is no arrow between them because neither needs the other’s result. D waits because it needs both. This fan-out/fan-in pattern is the canonical small DAG example in Argo Workflows’ documentation, but the reasoning is not specific to Argo.1

Eligibility is not the same as simultaneous execution. A runtime may have one worker, a concurrency cap, a scarce device, a rate limit, or another policy that admits only one branch at a time. Prefect’s documentation makes this distinction in terms of task runners, resources and dependencies; Argo documents concurrency controls separately from graph structure.23 The graph exposes possible concurrency. The runtime decides how much of it becomes real.

That difference matters because it stops us promising that a DAG makes work fast. It may reveal avoidable waiting. It may also reveal that the work is correctly serial.

What the letters commit us to

A graph contains nodes and edges. For a production workflow, a node is a unit of work and a directed edge is a dependency claim: the downstream unit cannot produce its correct result until the upstream requirement has been satisfied. “Acyclic” means those directed edges cannot lead back to where they began.

An arrow is not a reading order, a reporting line, evidence that two people spoke, or a statement that one task usually happens later on the clock. It spends concurrency by imposing a wait. It therefore needs a material reason.

Our working test is simple: could the downstream node still produce a correct result before the upstream node completed? If yes, the edge has not earned its place. If no, write down what the downstream node needs: a file, a decision, a verified fact set, a compiled artifact, a signed-off brief. That answer is more useful than “B comes after A.”

The opposite error is just as serious. Remove a real dependency and the runtime may start a node before its minimum inputs exist. An unnecessary edge creates avoidable sequence; a missing edge creates premature eligibility.4

Four layers, four different questions

We find it useful to separate a production system into four layers. This is a TDA editorial model, grounded in the distinctions made across workflow runtimes rather than a glossary imposed by any one framework.

1. Topology: what depends on what?
The DAG answers this with nodes and directed edges. Some systems ask us to declare those edges. Others can derive some of them from data flow—for example, when a downstream task receives a future representing an upstream result.2

2. Node contract: what counts as done?
A node needs a material output, minimum inputs and completion evidence. “Research complete” is weak. “A source list with each factual claim linked to support” is inspectable. The graph can say that assembly waits for research; the contract says what research must hand over.

3. Runtime: what happens when work becomes eligible?
The runtime schedules and dispatches work, observes state, applies resource and concurrency limits, and handles whatever retry, caching, conditional, persistence and failure rules its implementation supports. Those behaviours vary. In Apache Airflow, for example, the scheduler identifies task instances whose dependencies are complete and sends ready work to an executor; that is Airflow architecture, not a universal law of every DAG system.5

4. Authority: who may permit a consequential transition?
Evidence can establish that checks ran and their conditions passed. It cannot grant its own authority. A person may still own release, publication, spending, deletion or another consequential decision. That gate should be explicit without pretending the human is merely another automated test.

Confusing these layers produces familiar category errors. We blame the graph because retries are poor, although retry policy belongs to the runtime. We draw “approved” after a task without saying who can approve. We call a node complete because a process exited, although its promised artifact is absent. Or we buy an orchestrator to fix a topology that serialises independent work.

A graph for evidence-gated production

Here is a generic production shape:

Reasoning and deterministic work converge into a candidate whose factual support and output quality are checked before a human decision.
Figure 2. Dependency, evidence and authority are related, but they are not interchangeable.

The prepared inputs enable two different kinds of work. Their tools can differ. One branch may need judgement; the other may be deterministic bulk processing. The graph cares that both outputs are required for assembly, not which provider or program produced them.

The candidate then supports two independent checks. Only after both results exist does the human decision become eligible. Even then, eligibility does not force approval. The node contract must say what evidence the decision receives, and the authority rule must say who can act.

This drawing is still not an orchestrator. It contains no worker, queue, durable state, admission policy or retry mechanism. It is a declaration that a runtime could execute, once node contracts and system semantics exist.6

Keep revision outside the DAG run

What happens when the human requests changes? The tempting picture adds an arrow from the decision back to reasoning or assembly. That may be a useful workflow flowchart, but it is no longer a DAG: the return path creates a directed cycle.

The cycle is a design signal. It tells us that iterative lifecycle control and acyclic production are different models. We can handle a requested revision as a new run, a revised graph, or a state transition around the run.

A candidate moves through checking and human decision, with failed evidence or requested changes returning it to working before approval.
Figure 3. Revision is allowed to loop in the surrounding lifecycle; the production run remains acyclic.

This preserves an important distinction. The state machine says where the overall item is in its lifecycle. Each DAG run says which production work is eligible within one attempt. A rejection can retain its evidence, open a revision state, and launch a new run without inventing a backward DAG edge.7

The same reasoning in four domains

The following shapes are proposals, not claims that every project in a domain should use the same graph.

Software delivery. A successful build can make unit, integration and security checks eligible together. Packaging waits for the checks it genuinely requires; release remains an authority decision. Some systems already express this directly. GitHub Actions, for example, runs jobs in parallel by default and uses needs to declare that a job must wait for another.8

Data, ML and batch work. Validated inputs may feed independent partitions or feature calculations, followed by a join and evaluation. A graph exposes those branches, while the runtime still owns worker capacity, failure behaviour and resource constraints. If training changes the question that should be asked next, however, that discovery may belong in a lifecycle outside a fixed DAG.

Editorial and research production. A cleared brief can enable source gathering and structural work. A candidate waits for the required inputs; factual and quality checks can then branch before a human publication decision. The contracts matter: a pile of links is not the same output as traceable support for the claims in the draft.

Media production. Approved source material may enable independent transcodes, captions, metadata and derivative preparation. A delivery package waits only for the required variants and checks. Creative exploration that changes the intended artifact is different: it can revise the graph rather than being disguised as a deterministic node.

Across all four, the useful question stays small: what result is required before this next unit can be correct?

When a DAG is the wrong model

Not every collection of work deserves orchestration.

  • Use a function, short script or checklist when the sequence is small, fixed and easy to observe.
  • Use event handling for work that responds continuously to arrivals rather than completing one finite dependency graph.
  • Use a state machine when the important truth is lifecycle—working, checking, awaiting a decision, revising—not dependency within one run.
  • Keep discovery intentionally serial when each result determines what question is sensible next. Parallel branches are not a virtue if they spend effort before the problem is understood.

A DAG is useful when explicit dependencies improve correctness or expose meaningful eligibility. It is not a certification of sophistication, reliability or fitness.9

Lab exercise: draw the first honest graph

Take one current job. Do not begin with software or a favourite framework. Begin with the work.

  1. Name the final material output. What must exist—not merely happen?
  2. List the units of work. Give each one a concrete output and its minimum inputs.
  3. Test every proposed edge. Could the downstream unit still produce a correct result first? Remove layout order and habit masquerading as dependency.
  4. Mark concurrent eligibility. After each completion, which independent units now have all their inputs? Do not promise they will run simultaneously.
  5. Define completion evidence. What artifact, test result or inspection proves each node met its contract?
  6. Mark authority points. Which consequential transitions require a person, and what evidence should that person receive?
  7. Choose the failure action. Does failure mean retry this node under a stated policy, revise the graph because the dependency model was wrong, or move the overall item into a different lifecycle state?

The result is a dependency sketch, not yet a running system. That is enough to reveal where sequence is earned, where it is accidental, and which responsibilities still need contracts, runtime policy or human authority.

The practical sequence now has three parts: scope the job, choose the lane, then design the dependency shape. Only after that should a runtime execute eligible work. A correct tool inside an accidental queue is still the wrong system.

Sources

Footnotes

  1. Argo Workflows, DAG walkthrough.

  2. Prefect, Tasks and Task runners. 2

  3. Argo Workflows, Synchronization.

  4. Supported generalisation across the Airflow, Argo Workflows, GitHub Actions and Prefect documentation summarised in the article’s source research.

  5. Apache Airflow, Architecture Overview and Scheduler.

  6. TDA interpretation of the distinction between a dependency declaration, node contracts, runtime behaviour and human authority.

  7. Directed-acyclic definition, with the state-machine treatment proposed in the article’s public diagram brief.

  8. GitHub Actions, Workflow syntax and Using jobs.

  9. TDA editorial recommendation, bounded by the source research: a DAG does not itself guarantee speed, correctness, cost, auditability or reliability, and not every workflow is best represented as a DAG.

1,903 words · 8 min read