Skip to content

flow-domain and flow-dsl

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.

A pure parser and serializer for the textual flow representation.

pub fn parse(src: &str) -> Result<FlowGraph, ParseError>; // path:line:col errors
pub 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.