> ## Documentation Index
> Fetch the complete documentation index at: https://athanor.alexisbouchez.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Job Dependencies

> Controlling execution order with needs

## The DAG

Jobs in a workflow form a directed acyclic graph (DAG) based on their `needs:` fields.
Athanor uses Kahn's algorithm to topologically sort jobs into levels. Jobs at the same
level run concurrently.

## Simple Chain

```yaml theme={null}
jobs:
  first:
    steps:
      - run: echo "first"
  second:
    needs: first
    steps:
      - run: echo "second"
  third:
    needs: second
    steps:
      - run: echo "third"
```

Execution: `first` → `second` → `third` (sequential).

## Fan-Out / Fan-In

```yaml theme={null}
jobs:
  lint:
    steps:
      - run: echo "lint"
  test:
    needs: lint
    steps:
      - run: echo "test"
  build:
    needs: lint
    steps:
      - run: echo "build"
  deploy:
    needs: [test, build]
    steps:
      - run: echo "deploy"
```

Execution:

```
lint ──┬── test  ──┬── deploy
       └── build ──┘
```

`test` and `build` run in parallel after `lint` completes. `deploy` waits for both.

## Failure Propagation

If a job fails, all jobs that depend on it (directly or transitively) are skipped:

```
lint (fails) ──┬── test  (skipped)
               └── build (skipped) ── deploy (skipped)
```

The workflow finishes with a `failure` status.

## Cycle Detection

Circular dependencies are caught at parse time:

```yaml theme={null}
jobs:
  a:
    needs: b
    steps:
      - run: echo "a"
  b:
    needs: a
    steps:
      - run: echo "b"
```

This produces an error: `cycle detected in job dependencies`.

## No Dependencies

Jobs with no `needs:` field all run in the first level, concurrently:

```yaml theme={null}
jobs:
  lint:
    steps:
      - run: echo "lint"
  test:
    steps:
      - run: echo "test"
  build:
    steps:
      - run: echo "build"
```

All three start at the same time.
