White paper 03 / Workflow systems
Typed Compilation of Agent Workflows
Turning an authored graph into a checked, revisioned execution plan
Abstract
A workflow draft is a graph for authors. A runtime needs a resolved topology with node semantics, transitions, configuration, contracts, and revision identity. Ground Control compiles a draft against a versioned authoring catalog. The compiler parses the graph, resolves node families, checks catalog and graph constraints, attaches node contracts, and diagnoses executable cycles and other modeled errors. It emits a topology associated with the draft ID and revision, catalog version, and canonical authored-graph hash. A separate content hash identifies the compiled review subject after selected derived projections are excluded. Blocking diagnostics prevent candidate issuance. This is static checking over a defined workflow language. It does not prove arbitrary agent behavior or external tool correctness.
Contribution. The compiler defines a domain-specific intermediate representation and checks graph structure, declared port and artifact contracts, and selected runtime-binding status before it issues a reviewable workflow candidate.
Implemented architecture.
The problem: graph syntax does not define runtime meaning
A diagram can be visually complete and still lack an executable interpretation. An edge can name a nonexistent port. A required input can receive no connection. Two connected ports can declare disjoint data types. A node family can be missing from the active catalog, or a forward-transition cycle can violate the execution model. These faults have different causes, but they share one risk: the scheduler receives a graph whose operational meaning is incomplete or contradictory.
A compiler provides an explicit boundary between the authoring language and an executable representation. In this domain, source is a revisioned workflow draft plus a catalog, tenant capabilities, package-binding checks, schedule-trigger checks, and available agent-binding status. The target is a compiled topology with normalized node families and transitions, carried diagnostics, and identities tied to the source revision. The compiler does not infer unrestricted program meaning. It checks only semantics that the graph model and catalog state define.
Mechanism: parse, resolve, validate, project
The compile function first validates request identity and tenant scope, then parses the draft JSON into a workflow graph. It preserves the authored-node view for diagnostics and indexes catalog node families. Visual-only families such as annotation and grouping are removed from the executable graph, while diagnostics can still refer to authored content. The compiler normalizes supported authoring details, identifies agent nodes, and requests their binding-status rows when a reader is available. A reader error fails compilation; unavailable binding status is represented as a diagnostic state rather than silently treated as accepted.
The compiled topology acts as an intermediate representation. A node carries a node ID, family ID, canonical node kind, definition semantic, title, execution flags, configuration, optional contracts, and package bindings. A transition carries source and destination node IDs, port names, transition kind, and relevant retry, gate, or branch configuration. The topology also records catalog version, workflow identity, draft ID and revision, authored graph hash, and visual layout. These fields make the target useful to publication and runtime consumers without treating the visual editor’s JSON as the runtime contract.
Validation proceeds in layers. Catalog checks detect stale catalog versions, unsupported node types, invalid configuration, unavailable tenant capabilities, missing integration references, and malformed or stale package bindings. Graph checks detect duplicate node IDs, missing required shape, dangling connections, invalid ports, self-connections, incompatible port types, duplicate input connections, missing trigger nodes, and unsupported router semantics. Additional passes check schedule-trigger fields, gate and evidence bindings, unwired triggers, branch settings, and executable forward-transition cycles. Diagnostics carry severity, stable code, message, optional node ID, and a blocking flag. A blocking diagnostic withholds candidate issuance; a warning or informational diagnostic can remain visible without necessarily rejecting a candidate.
Contracts add a declared type layer to node connections. The optional `workflow-node-contracts/v1` envelope can declare input and output ports, each with required status and accepted data types, plus artifact contracts. A transition mapping names the producer output port, successor input port, and artifact IDs. When any compiled node enables contract mode, the compiler validates declared mappings, checks that mapped ports correspond to the transition’s ports, and requires overlap between producer and consumer data-type sets. It also diagnoses missing required input mappings and undeclared mapped artifacts. A graph without declarations stays on its legacy path, including older mappings that lack contract data. The compiler does not infer a conversion between types or validate arbitrary payload values at runtime.
After graph checks, the compiler computes a canonical hash of the authored graph and builds the topology. It then calculates a canonical topology content hash for the candidate. Selected derived projections are excluded from that hash: authored sentences and catalog-derived worker-slot flags are temporarily removed, while other post-hash projections such as branch labels and gate triggers are bound afterward. This rule keeps the review identity tied to the defined authored subject rather than selected derived values. It is a hash boundary, not a correctness proof or a digest of every runtime dependency.
draft revision + catalog + validation context → parse → resolve IR → graph and contract diagnostics → canonical hashes → candidate when no blocking diagnosticWorked trace: port mismatch and a cycle
Consider three nodes: retrieve a dataset, generate a report, and request approval. The dataset node declares a required `dataset` output with type `tabular-data`. The report node declares a required `dataset` input with the same type and a `report` artifact output. An edge maps the producer’s output to the report input, and a second edge maps the report artifact to approval. Compilation resolves all three families, builds node and transition records in the intermediate representation, and checks that the mapped port names match the transition and that the declared data-type sets overlap. If both mappings are declared, the candidate may be issued if no other blocking diagnostic exists.
Now suppose the report input declares `image` while the dataset output remains `tabular-data`. The compiler reports an incompatible-contract diagnostic on the edge, marks it blocking, and returns topology plus diagnostics without issuing a candidate. Suppose instead the author adds a forward edge from report back to dataset retrieval. Cycle analysis considers only forward transitions whose endpoints remain in the compiled executable topology. It finds a directed cycle and returns a stable witness listing its nodes and edges. The author can repair the types or graph and compile a new draft revision. The old source identity and any previously issued candidate remain tied to their earlier revision and hash.
Evaluation scope and limits
A compiler evaluation can generate graphs with known outcomes: valid and invalid ports, disjoint type sets, absent required inputs, missing artifacts, stale catalog versions, duplicate IDs, unwired triggers, invalid branches, absent binding rows, and forward cycles. It should compare emitted codes and blocking decisions with the defined graph properties, then repeat compilation to assess deterministic diagnostics and hashes for the same inputs. A separate user study can measure whether an author can locate and repair a diagnostic from its code, message, and node reference.
No benchmark or deployment result is reported here. The modeled language sets the limit of static checking. A type-compatible edge does not prove that an agent produces the declared data, and a valid configuration does not guarantee that a remote integration responds. An accepted agent binding is an input to workflow governance, while runtime admission and binding revision rules remain separate controls. Hashes identify defined content. Diagnostics expose modeled failures. Neither establishes formal equivalence, safety, or successful execution.
Related work
Compiler construction studies translation from a source representation to a target form with checks at defined stages. Typed intermediate representations make selected structural properties explicit before later processing. Kahn’s algorithm gives a classic method for topological ordering of a directed acyclic graph; cycle detection is a related graph check, although this compiler emits a deterministic cycle witness rather than claiming a scheduling order. The domain-specific contribution is to connect graph compilation with contracts, revision-bound publication, and agent-binding status.
References
- [1]Niklaus Wirth (1996). Compiler Construction. Addison-Wesley.
- [2]Arthur B. Kahn (1962). Topological Sorting of Large Networks. Communications of the ACM, 5(11).