Astrixion Docs

Dependencies and data flow

Understand how All and Single dependency rules release downstream workflow work.

A workflow is a directed acyclic graph. Each dependency points from a downstream step to an upstream step and declares exactly how the downstream work is released. Sonar supports two rules: All and Single.

All: wait, then fan in

An All dependency is a barrier. The downstream step becomes ready only when the upstream step is complete: every task is terminal, at least one task completed successfully, and any required result finalization has finished. Sonar then creates the downstream step's normal task set once.

Use All when the downstream command needs a complete stage rather than one upstream task:

subfinder ─┐
assetfinder├── All ──▶ merge and deduplicate
chaos     ─┘

If a step has several All dependencies, every upstream step must satisfy the barrier. All does not automatically concatenate upstream output into one variable; the workflow must give the downstream command the shared files or paths it should read.

Single: stream one task at a time

A Single dependency creates one downstream task for each completed upstream task. It is a streaming fan-out rule: the first downstream task may start while later upstream tasks are still running.

enumerate task A1 ──▶ probe task B1
enumerate task A2 ──▶ probe task B2
enumerate task A3 ──▶ probe task B3

The upstream step must declare one propagation channel:

  • OUTPUT becomes INPUT_UPSTREAM; or
  • OUTPUT_FILE becomes INPUT_FILE_UPSTREAM.

The downstream command reads the corresponding input token. Sonar allows at most one Single dependency on a step, because two independent per-task streams would not define an unambiguous pairing rule.

Combining the rules

A step may have one Single dependency plus one or more All dependencies. In that case, all All barriers must be satisfied before Single fan-out begins. After the barriers open, each eligible completed task from the Single upstream creates one child.

A step using custom SQL input cannot also use Single: both mechanisms would own the task's input.

Parentage, lineage, and repeatability

Every Single child records the source task as ParentTaskId. The reconciler creates a child only when no downstream task already points to that parent, so repeating a reconciliation tick does not repeat the fan-out effect.

LineageId answers a different question: which original input produced this branch? Root work starts a lineage, and descendants carry that identifier across later steps. ParentTaskId traces one edge; LineageId groups the whole branch.

File and line expansion uses the same fields: the generated task points to its expansion parent and keeps the parent's lineage.

Completion behavior

  • A root step with no task is not complete.
  • A step completes only after all of its tasks are terminal, at least one task completed, and required result finalization has settled.
  • If all tasks for a step are terminal and none completed, the scan completes with errors.
  • An expansion that finds no files or lines records a terminal no-work result so descendants do not mistake the placeholder task for real output and the graph does not remain open forever.

On this page