Runtime · Open Source

FloMorphic

Contract-Driven AI

Today's AI systems are powerful, but difficult to control. They reason, choose tools, and take actions — often hiding critical decisions inside prompts, code, or agent runtimes. FloMorphic introduces a different approach.

Experts define the process, the valid states, the allowed transitions, the policies, and the approvals. AI contributes judgment within those boundaries.

Because intelligence without control is a demo.Operational intelligence requires both.
01 — The inversion

Business processes govern how AI operates

The prevailing model puts an autonomous agent in charge of a business process. FloMorphic inverts it. The process is defined first — its valid states, its allowed transitions, its policies, its approval points — and the model operates inside that definition.

The result is AI that remains visible, controllable, auditable, and adaptable while still benefiting from modern reasoning models. Judgment is what you want from a model. Control is what you want from the system around it.

Agent in charge
        LLM
         │
   ┌─────┴─────┐
   │           │
 tools      decisions
   │           │
   └─────┬─────┘
         │
      outcome

The model owns the process. You see the result, not the path that produced it.

Process in charge
     Process
         │
    ┌────┼────┬────────┐
    │    │    │        │
 policy  LLM  human  tools
    │    │    │        │
    └────┼────┴────────┘
         │
      outcome

The process owns the outcome. The model is one participant, bounded by the contract.

Instead of autonomous agents controlling business processes, business processes govern how AI operates.
02 — The contract

A smart contract for AI-powered systems

The same idea a smart contract applies to value, FloMorphic applies to behavior: the rules are declared up front, they are enforced by the runtime rather than by good intentions, and what happened is inspectable afterwards.

Define what is allowed
──►
Contract nodes + node scopePolicy in JavaScript or Rego decides which transitions may fire; every node's scope declares the slice of context it may read and write. Both are enforced by the runtime.
Define how decisions flow
──►
The graph itselfValid states are nodes, allowed transitions are edges. There is no execution path that is not drawn — including the ones a model is permitted to choose.
Define where humans intervene
──►
Human in the LoopA run parks on a real task, waits for answers, and resumes. Approval is a state of the process, not a notification sent beside it.
Let AI operate within those rules
──►
Virtual functions as portsThe model's tool choices are outbound ports you drew. It selects among them; it cannot invent one. Everything downstream of each choice is already defined.

This is not a metaphor

Contract is one of the six primitives the runtime actually executes. A Rule node compiles to one: its logic — JavaScript or an OPA/Rego policy — runs against the scoped context and returns a set of tags, and the engine follows only the transitions whose tags match. The thing that decides which paths are permitted is named Contract, is deterministic, and is evaluated outside the model.

03 — Core principles

What the design commits to

01

Explicit processes

Over hidden agent behavior. What the system does is composed and readable, not emergent from a prompt.

02

Composable primitives

Over specialized abstractions. Capabilities are compositions of a small closed set, not features the platform grants you.

03

Context as a first-class artifact

Not an implementation detail. The working document of a process is the central object, not state threaded through callbacks.

04

Governance and control

Over blind autonomy. Policy, limits and approval are steps in the process, evaluated outside the model.

05

Human and AI in one workflow

Collaboration inside the same process, not a separate escalation system bolted alongside it.

06

Integration, not replacement

Existing systems are reached and extended. Nothing has to be migrated into the platform to participate.

04 — Definition

Stated plainly

What FloMorphic is

A workflow-centric runtime for building AI-powered systems from explicit primitives.

What FloMorphic is not
  • A no-code automation tool.
  • A collection of pre-built integrations.
  • A black-box agent framework.
05 — The foundation

Six primitives, and nothing reserved

FloMorphic is a product layer on the Inflowenger runtime. Its canvas nodes speak the language of what you are building; the runtime underneath knows only six node types. Every node records which one it lowers to — and that annotation is visible in the product, not buried in a compiler.

Void

void

Structure — start markers, joins, barriers, dead ends.

Code

code

Computation — run JavaScript or OPA/Rego against the scoped context.

Contract

contract

Decision — evaluate a rule, emit tags, fire the matching branches.

Extrinsic

extrinsic

Call a service you own, over one request/reply subject.

Plugin

plugin

A live external process — the open-ended escape hatch. Never compiles away.

GoTo

goto

Composition — jump into another flow and return.

Five of the six are compiled artifacts. Plugin is the exception — it never compiles away, because it is a real external process with its own connections, its own background loops and its own configuration form. That is why a model call, an MCP client and a field-mapper can all be plugin nodes without the runtime knowing what any of them mean.

From canvas to execution

  1. AuthorCompose nodes on the canvas, configure them, connect their handles.
  2. SaveThe raw editor graph is persisted verbatim. No translation happens in the browser.
  3. CompileA per-node hook reads each node's configuration and builds the matching primitive; edges become transitions.
  4. ExecuteA Fractal fetches that node map and walks it, asking the backend for flows and context as it goes.

The hook is the only place product-specific knowledge lives — which is why a different palette on the same primitives requires no runtime change. See the full reduction →

06 — The building blocks

Thirteen nodes, grouped by intent

Each one annotated with the primitive it becomes on compile.

Flow

StartVoid

The entry marker. Exactly one per process.

Wait for AllVoid

A synchronisation barrier — holds until every inbound parallel branch finishes, then merges their results into the shared context.

Continue AfterExtrinsic

Park the run and resume it at a delay or an absolute time.

GotoGoTo

Jump into another flow like a subroutine, and come back.

AI & Logic

LLMPlugin

One turn of a model conversation held on the node's scope, streamed to the canvas. Bound functions become output ports.

MCPPlugin

An MCP client — call a single tool with no model, or drive a model bound to the server's tools.

RuleContract

Evaluate JavaScript or Rego over the scope and route by tag. Branching, policy and validation.

JSCode

A JavaScript step over the scoped context; the result is written to the node's key.

OPACode

A Rego policy over the scope, with condition data available alongside it.

Stores

Doc StoreExtrinsic

Read or write documents in a referenced Document memory store.

Vector StoreExtrinsic

Index or search a referenced Vector store — top-k neighbours, with an optional partition namespace.

Cast / MappingPlugin

Build a value by mapping each key of a store's schema to a static value or a JSONPath resolved at run time.

Human

Human in the LoopExtrinsic

Pause the process for a person. Poses questions, records a task, resumes when the answers arrive.

Three fields on every node

titleThe label.
keyWhere this node's output is written into the context.
scopeThe JSONPath slice of context this node may read and write.

That last pair is context engineering with teeth: what a node — including a model — may see and may write is an explicit contract on the node, enforced by the runtime rather than left to prompt discipline.

07 — Composition

One vocabulary, composed from the same parts

What the field treats as distinct capabilities, and the composition each one is here.

RAG
──►
A Vector Store read nodecomposed into a model node's scope — retrieval as a step in the process, not a subsystem.
Context engineering
──►
scope + key on every nodean explicit contract for what a node may see and write, enforced by the runtime.
Working memory
──►
The run's Context documentone live JSON document the whole process reads and mutates.
Long-term memory
──►
Document and Vector storesfirst-class entities with their own schema and index, resolved server-side.
Tool use
──►
Virtual functions on the model nodea routing tag that fires an outbound port — the tool is whatever you compose after it.
Agent loop
──►
A model node and a Rule node with an edge between themiteration as topology; every pass observable, every exit condition explicit.
Reflection · self-review
──►
A second model node reading the first, gated by a Rulea pattern composed from primitives, not an abstraction the platform provides.
Multi-agent orchestration
──►
Sub-flows via Goto, parallel branches, Wait for Allreal concurrency and barriers in the runtime, not a loop in one process.
MCP
──►
The MCP node — tool-only or model-drivena client node, with the server's tools loaded into the editor.
Guardrails
──►
A Rule node before or after the modeldeterministic policy in JavaScript or Rego, evaluated outside the model.
Human review
──►
The Human in the Loop nodea run that parks on a real task and resumes on the answer.
Observability
──►
The live process event streamevery engine event traced back onto the nodes and edges that produced it.
Scheduling
──►
Continue Afterresumption is an execution primitive, not a queue you operate beside the system.

What is not in that list is a runtime feature invented for any single row. Composable primitives over specialized abstractions is a design commitment, and this is what it buys.

08 — Decisions

The model routes the diagram

The model node's bound functions are outbound ports on the canvas. You declare a function — approve, escalate, search_docs — and it renders as a port you can draw an edge from.

At run time those functions are handed to the model as tools. When the model answers with a tool call, the runtime fires only the matching port. No tool call, and the flow takes its default route.

LLMopenai · anthropic · gemini · openrouter · local
approve──►Rule · policy check
escalate──►Human in the Loop
search_docs──►Vector Store · search
(no tool call)──►default route
The model's decision is a visible edge in the diagram, not a hidden branch inside an agent's control loop.

Every route the model is permitted to take — and everything downstream of each one — is inspectable before it runs. Behavior is bounded by construction rather than by prompt. And the "function" never has to be implemented as a function: it is a routing tag, and its implementation is whatever you compose after it.

09 — Context

Context as a first-class system artifact

Runtime memory

Context

Every run carries a Context: one live JSON document that is the working memory of the process. Nodes read a scope of it, write their result to a key in it, and the engine persists each mutation back through the backend as the run moves.

It is not state threaded through callbacks as an implementation detail. It is the central object — listed, opened, and editable as a tree or as raw JSON.

The model conversation lives here too. The prompt template seeds the messages on the first run; once the scope carries a message array, the template is ignored and the persisted conversation is used as-is. That one rule is what makes iteration work.

Long-term memory

Stores

Contexts are per-run. Memory stores are not. A Document store declares a table and column schema and holds structured documents you can query. A Vector store declares an embedding model, dimensions and a distance metric — and creating one provisions a real vector index sized to it.

The store nodes reference one by id, and the store is resolved server-side, so the request never gets to choose which table it touches.

Retrieval-augmented generation is not a subsystem here. It is a Vector Store read node composed into a model node's scope.

10 — Control

Reasoning that happens outside the model

A Rule node evaluates JavaScript or an OPA/Rego policy against the scoped context and routes by tag. Its rule returns a list of tags; the engine follows only the transitions whose tags match. Three outcomes — accept, retry, reject — is one Rule with three tagged handlers, not three node types.

Place one after a model call and you have deterministic control over what that model produced, before anything downstream observes it. Validation, policy, retry limits, escalation thresholds and cost ceilings become explicit steps — evaluated outside the model, visible on the canvas, and changeable without redeploying the system around them.

Rego is a real policy language·not string matching on model output
11 — Patterns

Patterns, not special-purpose nodes

The behaviors other platforms ship as dedicated features are compositions here. Two examples carry most of the weight.

There is no Loop node

   ┌───────────────────────────────────────────────┐
   │                                        no     │
   ▼                                               │
[ LLM ] ─────► [ Rule: is the task satisfied? ] ───┘
                          │
                          └── yes ──► [ next step ]

The model node appends to the message stack on the context. The Rule node checks whether the task is done. If not, an edge routes back. That cycle is the loop — with every iteration observable, every exit condition explicit, and a human review step insertable anywhere inside it.

There is no Observer node

[ LLM ] draft ──► [ LLM ] observer / critique ──► [ Rule ] accepted?
                                                    │      │
                            ┌── no ──────────────────┘      └── yes ──► [ continue ]
                            ▼
                        back to draft

An observer is a model node reading another node's output against explicit criteria, with a Rule deciding what happens next. It is a pattern composed from primitives, not an abstraction the platform provides — which is precisely why you can change what "acceptable" means without waiting for the platform to support your definition.

Wait for All

When a node fans out, the runtime runs every branch in parallel. This barrier holds until all of them finish, merges their results into the shared context, and continues once.

Continue After

Park the run and resume it later — now + delay, or an absolute time. Long-running work is an execution primitive, not a queue you operate beside it.

Goto

Jump into another flow like a subroutine and come back. Sub-flows are how composition and reuse across processes are expressed.

12 — Integration

Integration with existing systems, not replacement

FloMorphic ships no catalogue of branded connectors, and that is deliberate. A connector catalogue is a maintenance liability whose value decays with every upstream API change. What a process actually needs is a small number of general ways to reach outward.

MCP

client node

The MCP node connects to any MCP server, loads its tools into the editor, and either calls one directly or binds them to a model. The tool ecosystem is maintained by whoever owns the tool — not by this project.

Fits when

The system speaks MCP, or an MCP server can be placed in front of it.

Plugin

process

A standalone process speaking inflowv1, built with the Go or Node/TypeScript SDK — wire-identical, so you pick the language, not a different protocol. It runs where you deploy it and appears as a node with its own configuration form.

Fits when

A REST API, a database, a message bus, a gateway, an internal service. The SDKs' own worked example is an HTTP call node.

Extrinsic

primitive

A request/reply against a NATS subject your own backend registered. Your handler's reply becomes the node's output, and one wildcard registration can serve a whole family of operations.

Fits when

A backend that imports the SDK and exposes its existing domain operations as subjects.

The Extrinsic primitive is how the runtime reaches a service you own: a request/reply against a subject your backend registered, where your handler's response becomes the node's output. It is the mechanism FloMorphic's own storage, approval and scheduling nodes are built on — one wildcard registration can back a whole family of operations.

13 — Beyond the graph

The system around the process

The entities a real deployment needs beside the canvas.

Contexts

The run documents themselves — listed, opened, and edited as a tree or as raw JSON.

Memory

Vector and Document store definitions, and a browser for the data inside them.

Prompts

A reusable prompt-template library with declared variables and placeholder substitution.

Node settings

Named configuration profiles bound to a node kind — one provider profile per environment — referenced by id, so credentials never live on the graph.

Processes

Every run: status, duration, error, and a jump straight to the context it carried.

Human tasks

The queue the review node feeds — open a task, answer it, or close it out.

Extensions

Register a plugin from a Git repository so it joins the ecosystem and contributes nodes to the palette.

14 — Underneath

Four actors, talking over NATS

FloMorphic's backend never executes a flow. It answers the engine's questions — what is this flow, what is this run's context — and runs the domain logic a node calls out to. Fractals do the traversal. Plugins live on their own isolated accounts with narrowly-scoped credentials, able to publish and subscribe only on the subjects they own.

 ┌────────────────────┐   REST: creds, accounts, resources   ┌────────────────────────┐
 │  Infra             │◄────────────────────────────────────►│  FloMorphic API        │
 │  control plane     │                                      │  imports inflow-fusion │
 │  NATS + registry   │   NATS: get flow / get, set context  │  owns the data         │
 └─────────┬──────────┘◄────────────────────────────────────►└───────────┬────────────┘
           │ registered engines                                          │ HTTP + WebSocket
           ▼                                                             ▼
 ┌────────────────────┐   NATS: flow + context, svc.* calls  ┌────────────────────────┐
 │  Fractal (engine)  │─────────────────────────────────────►│  FloMorphic canvas     │
 │  walks the graph   │                                      │  the browser           │
 └─────────┬──────────┘                                      └────────────────────────┘
           │ NATS on an isolated, scoped plugin account
           ▼
 ┌────────────────────────────────────┐
 │  Plugin nodes:  llm  ·  mcp  ·  …  │
 └────────────────────────────────────┘

Every event the engine emits is streamed to the canvas over a WebSocket and traced back onto the nodes and edges that produced it — so a run is observed on the same diagram it was composed on, with its process row recording status, duration and error. Full architecture →

15 — Growth

From a laptop to a cluster

The same artifact runs at every size. Nothing about a process changes as the deployment grows — only how many processors are attached to it.

Standalone

The canvas alone, or canvas + API with the runtime disabled

The web app persists to browser storage with no backend at all; the API runs CRUD-only when no infra is configured. Enough to compose, save and review real processes offline.

Single box

Infra + one Fractal + the API + the canvas

One compose network, and a database that is a file. This is already a complete, executing system — not a demo mode.

Scaled out

Infra + many Fractals

Fractals register themselves with Infra; new processes are load-balanced across the registered pool round-robin. Fractals carry tags, so work can be steered to the right class of processor.

Scaling is adding processors, not re-architecting. The graph, the context model and the node semantics are identical at every stage — so the process you composed on day one is the thing that runs in production, not a sketch of it.
16 — Open

Open source, and open at the seams

Being readable is the easy half. FloMorphic is open where it matters — at the joints you would reach for to build something of your own.

The palette is data plus a hook

Adding a node kind is a catalog entry on the frontend and a case in the compiler — not a runtime change. Fork the palette, keep the runtime.

The model nodes are ordinary plugins

The LLM and MCP nodes are standalone binaries with no privileged access, each pinning its own SDK version. Whatever you build gets exactly the contract they do.

The backend is storage-agnostic

Controllers depend only on repository interfaces. SQLite is one registered driver; another is a new package that registers itself.

Nothing is reserved

FloMorphic uses the same primitives, subjects and credentials any other system on Inflowenger would. It is the proof, not the exception.

Build systems you can understand

As AI becomes part of critical business processes, the challenge is no longer generating intelligent responses. The challenge is understanding, governing, and evolving the systems that produce them. FloMorphic helps you build those systems.

Pre-1.0 and moving. Per-repository licence files are being finalised as the projects are published — until a repository carries a LICENSE, do not assume a permissive licence for that component.