## ADDED Requirements

### Requirement: DAG topological execution
The engine SHALL execute workflow nodes in topological order determined by `depends_on` edges using Kahn's algorithm.

#### Scenario: Independent nodes run concurrently
- **WHEN** a workflow has nodes A and B with no `depends_on`
- **THEN** both A and B SHALL execute in the same topological layer, concurrently

#### Scenario: Dependent nodes run sequentially
- **WHEN** node B lists `depends_on: [A]`
- **THEN** A SHALL complete before B begins

#### Scenario: Cycle detection
- **WHEN** nodes form a cycle (A → B → C → A)
- **THEN** the loader SHALL reject the workflow with a cycle detection error

### Requirement: Trigger rules
The engine SHALL support 4 trigger rules for join semantics.

#### Scenario: all_success (default)
- **WHEN** a node has multiple upstream dependencies and no explicit `trigger_rule`
- **THEN** it SHALL only run if ALL upstream nodes completed successfully
- **THEN** it SHALL be skipped if any upstream node failed

#### Scenario: one_success
- **WHEN** a node sets `trigger_rule: one_success`
- **THEN** it SHALL run if at least one upstream node completed successfully

#### Scenario: all_done
- **WHEN** a node sets `trigger_rule: all_done`
- **THEN** it SHALL run when all upstream nodes have finished (any status), regardless of success/failure

#### Scenario: none_failed_min_one_success
- **WHEN** a node sets `trigger_rule: none_failed_min_one_success`
- **THEN** it SHALL run only if no upstream node failed AND at least one succeeded

### Requirement: when conditions
Nodes SHALL support a `when:` string that evaluates to a boolean condition.

#### Scenario: when condition prevents execution
- **WHEN** a node has `when: "false"` or any expression that evaluates falsy
- **THEN** the node SHALL be skipped as if its trigger_rule prevented execution

### Requirement: Node retry with configurable policy
Nodes SHALL support a `retry` config with `max_attempts`, `delay_ms`, and `on_error` (transient|all).

#### Scenario: retry on transient error
- **WHEN** a node with `retry: { max_attempts: 3 }` fails with a transient error
- **THEN** it SHALL retry up to 3 times with configured delay between attempts

#### Scenario: retry exhausted
- **WHEN** all retry attempts fail
- **THEN** the node SHALL be marked as failed and trigger_rule evaluation proceeds
