Skip to content

What a design compiles to

Architect does not invent a format. It authors the configuration files the services were already reading, which is why a hand-written system and a drawn one are the same system.

Architect — what you can place, and what happens to what you build WHAT YOU CAN PLACE — read from the registry, not maintained by hand containerregistryphrame/* images capabilitymanifest(OCI label) catalogvalidate ·group by type paletteinput · processoutput carries read offer WHAT YOU BUILD — a design, compiled into the schemas the services already read canvasplace · wiretyped pins inspectorschema-drivenparameters compilergraph → configsvdi://uuid GitLab commitphrame-config configure compile apply drag a component onto the canvas orchestration — placed onto a node, deployed, running live JPEG thumbnails + stats over MQTT (~1 Hz) come back to the canvas, so a design shows the running system

For the media pipeline the canonical schemas are input-processor.schema.json and output-processor.schema.json (JSON Schema Draft 2020-12). A compiled design populates four arrays:

ArrayContents
inputs[]id, plugin (network, mxl, ndi, …), source, video/audio decode settings, optional DVB tuning
compressors[]id, kind (video, audio, passthrough), codec, bitrate, GOP and so on
outputs[]id, type (file, rtp, srt, rtmp, webrtc, wep, yuv, ndi, vdi, mxl, null), per-type parameters, and streams[]
pipelines[]The wiring: { input_id, compressor_ids[], output_id }

The mapping to the canvas is close to one-to-one. Placing components authors the first three arrays; wiring pins authors the fourth. That correspondence is the reason the canvas is a faithful editor rather than a generator whose output has to be checked — pipelines[] is the set of edges you drew.

Components exchange media over the Phrame bus using addresses of the form:

vdi://<uuid>:<suffix>

where the suffix selects a sub-stream — conventionally :0 for video and :1 for audio. The compiler allocates and tracks these UUIDs, so a wire on the canvas becomes a stable stream identifier that both ends of the connection agree on, and that survives the design being edited.

This is also why a design can be reorganised without breaking a running system: the identity travels with the connection, not with the position of a box.

The media pipeline is only part of what a design describes. The compiler also emits configuration for:

  • vision-mixers — switch, compositor, overlay, scaler and 2D DVE, including screen and tile geometry for multi-output layouts
  • TAMS — server, recorder, player and flow-manager instances, and their connections
  • supporting services — object storage (MinIO) and database (Postgres) instances a system needs to stand on its own
  • egress — HLS, SRT, WebRTC (including WHEP) and NDI outputs
  • automation — Lua automations and role definitions, compiled from the design’s control graph rather than written separately

That last one is worth noting: a design carries a control graph distinct from the media graph. The media graph says which frames go where; the control graph says what drives what. They are edited on the same canvas and compiled together.

The compiler works in both directions. Existing configuration in the repository can be read back onto the canvas, so a system authored by hand — or by an earlier version of Architect — opens as a design rather than being opaque to it.

This matters more than convenience. A one-way generator makes the canvas the only safe place to edit, and anything changed elsewhere becomes a divergence nobody can see. Round-tripping keeps the configuration files honest as the source of truth, with Architect as one of the ways to edit them — alongside the phrame-config editor and, for that matter, a text editor and a commit.

Produced configuration is validated against its JSON Schema before it is committed. Beyond that point the normal path applies: the commit lands in phrame-config, config-sync validates it again on the way to the broker, and a file that fails validation is never published — so the last good configuration stays retained rather than being replaced by a broken one.

The two validations are not redundant. The first tells an author their design is wrong while they are still looking at it; the second protects the running system from anything that reaches the repository by another route.

See also: Configuration & GitOps for what happens to the commit, and the component catalog for where the component definitions come from.