flow-domain and flow-dsl
flow-domain
Section titled “flow-domain”Pure data types with no I/O. Everything the engine schedules is built from these.
pub struct FlowGraph { pub id: String, pub name: String, pub version: String, pub description: Option<String>, pub nodes: Vec<FlowNode>, pub edges: Vec<FlowEdge>, pub subflows: Vec<FlowGraph>,}
pub struct FlowNode { pub id: String, pub node_type: String, // "action" | "ai" | "agentic" | "utility" | "service" pub position: Position, pub data: serde_json::Value, // scalar-only body; adapter/action fields live here}Edges carry an optional outcome (pass / fail / omitted = always), an
optional label, and an optional when <expr> condition.
The AI node contract (flow_domain::contract)
Section titled “The AI node contract (flow_domain::contract)”Contract-bound ai nodes opt into engine-enforced governance:
pub struct AiNodeContract { // contract, autoApproveAbove, reviewLow/reviewHigh, suppressBelow, // confidenceType, maxInferenceMs, contractVersion - scalar node fields}pub struct RoutingThresholds { /* route(confidence) -> RouteDecision */ }pub enum RouteDecision { AutoApprove, HumanReview, Suppress }pub struct AiOutputEnvelope { /* primary_output, confidence, escalate, reasoning */ }The engine applies the thresholds, never the model. escalate can force a
human gate, but it can never bypass one. Schema violations are node failures,
not degraded-trust results.
flow-dsl
Section titled “flow-dsl”A pure parser and serializer for the textual flow representation.
pub fn parse(src: &str) -> Result<FlowGraph, ParseError>; // path:line:col errorspub fn serialize(graph: &FlowGraph) -> String;pub fn slugify(name: &str) -> String;The key invariant is that serialize(parse(s)) is a canonical-form fixed
point. Round-tripping any valid document yields the canonical form, and
canonical documents survive unchanged. Both flow fmt and version control diffs
depend on this. Preserve this invariant in any grammar change.
The DSL has exactly five node types with scalar-only bodies. The grammar and
authoring rules live in the DSL reference. The
compiled spec (crates/flow-application/spec/spec_compiled.md in the repo) is
generated at build time and embedded as the generation system prompt.