Engine capabilities
Subworkflow Reuse
A Horus showcase of the subworkflow construct. A sub block carries a complete child workflow, and a YAML anchor instantiates the same two-stage body twice under different prefixes.
What this workflow does
This workflow demonstrates the subworkflow construct of horus-runtime. A sub:
block carries a complete child workflow. Horus inlines the child into the parent
graph when the workflow runs.
There is no binding table to keep in sync. Horus derives the ports from the child itself. The in-port is the root artifact that the child reads. The out-port is the task output that nothing inside the child consumes.
The showcase uses that to demonstrate reuse. A two-stage trim -> shout cleaning
pipeline is written once, as a YAML anchor. The workflow instantiates it twice,
as clean_a and clean_b, through a YAML alias. Each instance runs against a
different input.
The problem it solves
A real pipeline repeats the same sequence of stages on different data. A cleaning sequence, a prep sequence, or a scoring sequence appears several times.
If you copy the stages, you own several copies. A fix to one copy misses the others. If you factor the sequence into a helper script, you lose the per-stage graph. The engine sees one opaque stage, so it cannot show you where a run failed.
The subworkflow construct keeps both properties. The body is written once, and
the engine still sees every inner stage. Horus inlines the inner stages at
<subworkflow id>/<inner id>, so clean_a/trim and clean_b/trim never
collide. The same body is reused verbatim, with no id or path conflict.
Reuse happens at the YAML parsing level. The sub: value of clean_a is tagged
&clean_pipeline. The sub: value of clean_b is *clean_pipeline, a plain
YAML alias. The loader sees two independent but identical sub: blocks. This
needs no custom tooling.
Pipeline
split (local) examples/quotes.txt (2 lines) ──► quote_a.txt, quote_b.txt
clean_a (subworkflow) clean_b (subworkflow)
│ trim -> shout │ trim -> shout
│ (same body, inlined │ (same body, inlined
│ as clean_a/trim, │ as clean_b/trim,
│ clean_a/shout) │ clean_b/shout)
──► clean.txt ──► clean.txt
combine (local) clean_a/clean.txt + clean_b/clean.txt ──► results/report.txt
│ concatenates both cleaned quotes
Inputs and outputs
Input
examples/quotes.txt: two lines of text.
Outputs land in horus_workflow_results/:
quote_a.txtandquote_b.txt: the two split lines.clean_a/clean.txtandclean_b/clean.txt: each input line, trimmed and then uppercased. The folder is the inner working directory of the inlined subworkflow.results/report.txt: both cleaned lines, one per line.
Run the workflow
Install uv if you do not have it:
curl -LsSf https://astral.sh/uv/install.sh | sh
Then install the horus-runtime and run the workflow:
cd workflows/engine-showcases/w04-subworkflow-reuse
uv sync
horus run workflow.yaml
You can also install the runtime with pip:
pip install horus-runtime
To use your own text, replace the two lines in examples/quotes.txt. To change
the behavior of both instances at once, edit the clean_pipeline body in
workflow.yaml. Both clean_a and clean_b pick up the change, because they
share the one anchored body.
References
Run this workflow
The workflow is open source. Clone the pantheon repository and run it with the horus-runtime engine. To run it on managed compute without a cluster of your own, join the Temple Compute OS waitlist.