Flow Steps Format
You write a flow as a YAML list of steps, and kapi compiles the list to the internal graph of nodes and edges.
Format Detection
The flow parser auto-detects the format:
spec.stepspresent -> steps format, compiled viaStepsToGraph()spec.nodespresent -> graph format, used directly- Both enveloped (
apiVersion: v1) and bare YAML are supported
Steps Format Spec
type FlowStep struct {
Tool string `yaml:"tool,omitempty"` // tool name
Config map[string]any `yaml:"config,omitempty"` // tool parameters
Label string `yaml:"label,omitempty"` // display label
Parallel []FlowStep `yaml:"parallel,omitempty"` // branches (definition model only)
}
Transformers as ordered steps
Tools that rewrite the source/model (redaction, a simplifier, normalization)
are ordinary entries in steps:; there is no separate structural stage
(E-03). A flow that declares the
removed source_transforms: field is rejected by StepsToGraph with a
migration error pointing at E-03 and directing the author to list the
transformers as ordered steps.
steps:
- tool: redact # applied inline; later steps see the redacted source
- tool: translate
- tool: qa
Transformer ordering is validated by the placement pass
(core/flow/placement.go), which runs beside data-flow validation at every
flow build/load gate and emits these diagnostics:
| Rule id | Severity | Trigger |
|---|---|---|
transformer-after-target | error | a transformer follows a step that produces a committed target; exempt when the transformer produces the target port itself (e.g. unredact) |
transformer-after-remote-egress | error | a recoverable transformer (redact) follows a step with the remote-source-egress or process-exec side effect; exempt for the step(s) producing an input the transformer's config-resolved contract requires |
transformer-late-placement | warning | a transformer sits later than its earliest valid slot (after its last required input), forcing avoidable overlay rebasing |
Compilation
StepsToGraph(spec) generates:
- Tool nodes from
steps, chained sequentially - For a
parallel:block, one node per branch at the same X position, each with an edge from the previous step's node, and an edge from every branch to the next step's node
Auto-assigned IDs follow tool-N pattern. Positions auto-layout left-to-right.
The graph is tool nodes only; the flow's source and sink are bindings resolved
at run time (E-04), not nodes.
A parallel: block exists in the definition model only. Every host runs a flow
as an ordered tool chain
(E-01):
the project flow runner builds one tool per step and fails on a parallel:
step.
Write a flow meant to run as ordered steps.
Examples
Linear pipeline
steps:
- tool: recycle
config: { fuzzyThreshold: 75 }
- tool: translate
- tool: qa
Script step
steps:
- tool: script
label: Filter long segments
config:
code: |
if (part.type === "block") {
if (part.block.source[0].content.text.length > 200) emit(part);
else skip();
} else emit(part);