Graphs that turn questions about building data into small, inspectable, reproducible computations, built the same way by people in a web editor and by AI agents over MCP (Model Context Protocol).

Six graphs over two real buildings

Each graph below reads a public building that BIM Open Data converted from IFC to DuckDB tables, and answers one question with the generic table nodes: duck.table, table.filter, table.join, table.aggregate, table.pivot, table.sort, duck.query, and chart.bar. None of them is a building-specific node.

The graph is the web editor itself. Drag to pan and scroll to zoom; the pane above the graph shows the chart; click a node to show its table there, and hover a port to peek at the rows on its wire.

How the results got here: a test in tests/flow/BimOpenFlow.TableWorkflows.Tests evaluates every graph in samples/buildings with the same packs the host serves, checks the numbers, and writes data/buildings.json with each node's row count and its first rows, which are the rows a table here shows; another test fails when that file no longer matches.

What a graph is

A graph is a JSON document of nodes and wires. Each node is a small function with typed ports and parameters edited on the node itself. A door schedule, rooms per storey, a check that every door leaf is at least 850 mm wide, or a 3D view coloured by category are each a graph of a handful of nodes.

load ──┬─► table.filter ──► table.aggregate ──┬─► chart.bar        (chart)
       │                                      └─► sink.exportCsv  (effect, waits for Run)
       └─► view3d.instances ──► view3d.color ────► 3D pane         (3D view)

Every edit is one of four operations, addNode, connect, setParam, and removeNode, whether it comes from a mouse gesture, the HTTP API, or an MCP tool. A graph an agent builds is one a person could have built.

What travels on a wire

Six kinds of value: Boolean, Integer, Number, Text, Table, and Relation. Almost everything is an immutable Table; a Relation is a query plan and its schema, which becomes rows only when executed. One vocabulary covers loading, SQL, table operations, charts, 3D, and rule checks, so a graph that computes a table can also colour the model.

Nothing writes until Run

Pure nodes only compute, and their results are memoized. Effect nodes write files or IFC property sets, all live in one pack, and stay EffectPending until an explicit Run. Exploring a model, by a person or an agent, never touches a file. Each node reports Ok, Unready, EffectPending, Unavailable, or Error.

Runs are the evidence

A run record pins the graph's hash and every input's content hash beside the outputs, and replays. A number an agent reports comes from a run or a tool result, not from memory. A run can be published as a self-contained HTML report or an evidence package: a zip whose manifest.json lists a SHA-256 per member.

What is in the repository

The engine itself, ara3d-dataflow, is specified separately with its own conformance suite and knows nothing about buildings.

The buildings and their licences

The tables behind these results are converted from openly licensed IFC files. The building data keeps its own licence; this repository's code is MIT licensed.

Full notice, including the MIT licence text (NOTICE.md)
Loading data/NOTICE.md…