# `Nous.Workflow.Compiler`
[🔗](https://github.com/nyo16/nous/blob/v0.17.1/lib/nous/workflow/compiler.ex#L1)

Validates and compiles workflow graphs for execution.

Uses Kahn's algorithm for topological sort, which gives three things
in a single O(V+E) pass:

1. **Topological order** — valid execution sequence
2. **Cycle detection** — remaining nodes after sort form cycle(s)
3. **Parallel levels** — nodes in the same round are independent

## Compilation Result

Returns a `{:ok, compiled}` map with:

- `:graph` — the validated graph
- `:topo_order` — topological ordering of node IDs
- `:levels` — list of lists, each level can execute in parallel
- `:terminal_nodes` — nodes with no outgoing edges
- `:fan_in_nodes` — nodes with multiple incoming edges

## Examples

    {:ok, compiled} = Nous.Workflow.Compiler.compile(graph)
    compiled.topo_order
    #=> ["plan", "search", "synthesize", "report"]

# `compiled`

```elixir
@type compiled() :: %{
  graph: Nous.Workflow.Graph.t(),
  topo_order: [Nous.Workflow.Graph.node_id()],
  levels: [[Nous.Workflow.Graph.node_id()]],
  terminal_nodes: [Nous.Workflow.Graph.node_id()],
  fan_in_nodes: [Nous.Workflow.Graph.node_id()],
  cycle_nodes: MapSet.t()
}
```

# `compile`

```elixir
@spec compile(Nous.Workflow.Graph.t()) :: {:ok, compiled()} | {:error, [term()]}
```

Compile and validate a workflow graph.

Returns `{:ok, compiled}` or `{:error, errors}` where errors is a list
of validation error tuples.

# `topological_sort`

```elixir
@spec topological_sort(Nous.Workflow.Graph.t()) ::
  {:ok, [Nous.Workflow.Graph.node_id()], [[Nous.Workflow.Graph.node_id()]]}
  | {:ok, [Nous.Workflow.Graph.node_id()], [[Nous.Workflow.Graph.node_id()]],
     map()}
  | {:error, [term()]}
```

Perform topological sort using Kahn's algorithm.

Returns `{:ok, topo_order, levels}` where `levels` is a list of lists —
each level contains nodes that can execute in parallel.

Returns `{:error, [{:cycle_detected, message}]}` if cycles are found
and the graph does not allow them.

# `validate`

```elixir
@spec validate(Nous.Workflow.Graph.t()) :: :ok | {:error, [term()]}
```

Validate a graph without computing topological sort.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
