Skip to content

The Spec Builder ​

The Spec Builder is the interface where you compose a processor's spec. It's a full-page, three-panel app modelled on no-code function-stack builders like Xano and Make.

You reach it from Providers → Processors → (a processor) → Edit spec.

Layout ​

The page is split into three columns.

The Spec Builder with a real processor open: source model and enrichments in the left panel, the instruction stack in the centre, and the inspector for the selected instruction on the right.

Left panel — Spec configuration ​

Top-level fields on the spec, in this order:

  • Source model — the source model this processor operates on, and the variable name you'll use to reference it inside the spec.
  • Constants — named values the spec can reference anywhere. Their actual values are set on each source-to-processor link, not on the spec itself. This is how one processor can be reused across multiple sources or providers.
  • Enrichments — related-data fetches you add to the spec. Each added enrichment appears as a nested field on its parent (the source model, or another enrichment if nested).

Changes to the left panel reshape what the rest of the spec is allowed to reference. Removing a constant or an enrichment that's still in use will produce a validation error on save.

Center panel — The instruction stack ​

The body of the spec: a vertical list of instructions, executed top to bottom. Every instruction is either an operation (does something — upsert_activity, define_variable, …) or a block (contains other instructions — if_else, for_each).

  • Each instruction shows a one-line read-only summary of what it does, derived from its schema and the values it currently holds.
  • Blocks render their child instructions as indented sub-lists below themselves (if_else shows the then and else lists; for_each shows its body).
  • Drag any instruction to reorder it within its list, or to move it into or out of a block.
  • Click an instruction to select it and edit its fields in the right panel.
  • Click the + button at the end of any list to add a new instruction.

Example

The tiny processor from the Architecture page renders here as a single instruction in the center panel: one upsert_agent_external_identity with a one-line summary. Clicking it selects the instruction and opens its fields in the inspector on the right.

Right panel — Inspector ​

The editing form for the currently selected instruction.

The first field is the instruction type selector — change the instruction's type (e.g. from upsert_activity to if_else) without re-adding it from scratch. Below it, the schema-driven form for that instruction's fields: literal text inputs, variable pickers, expression builders, sub-expression lists. Both operations and blocks have fields edited here; a block's child instructions live in the center panel.

Variable pickers and expression-builder fields are aware of the current variable scope at this point in the spec. Autocomplete suggests only what's actually available — including any variables introduced by earlier operations with a return_as field (define_variable, upsert_*, etc.), and the item variable inside a for_each body.

Argument help while you type ​

Expression fields are written as formulas, and a formula gives you no clue which argument goes where — string_replace takes three, but which one is the text and which is the thing being replaced?

Put the caret between an expression's parentheses and the editor shows its signature, with the argument you are currently filling in highlighted:

string_replace(subject, "search", "replace"?)

Read it as follows:

  • Plain names — subject — take an expression: a variable, a literal, or another expression nested inside.
  • Quoted names — "search" — take a literal value only. A variable or a nested expression in that position is rejected when you save.
  • Braced names — {item_as} — take a variable name.
  • A trailing … — arguments… — means the argument repeats: concat takes as many as you give it.
  • A trailing ? — "replace"? — means the argument is optional.

Below the signature is a line describing the highlighted argument — whether it is a literal or an expression, which type it expects, and whether it is required — and a link to that expression's entry in the Expressions reference.

The same signature appears in the autocomplete list as you type a function's name, so you can see what a function takes before you pick it.

Variable scope ​

The scope panel lists every variable available at the currently selected step, with each entry showing its inferred type (string, integer, datetime, agent_external_identity, …). See Variables and types for the full picture of what's in scope where and how the type system works.

Typing into a variable picker filters the dropdown to matching paths. Each suggestion shows its type alongside.

When viewing a previously-run execution in the trace viewer, or when a historic run is selected in edit mode, the scope panel additionally shows the actual value each variable held at that step — useful for understanding why a condition went the way it did.

Saving and validation ​

Saves are explicit:

  • Ctrl+S (Cmd+S on macOS), or the Save button in the topbar.
  • The browser will warn you if you try to leave with unsaved changes.

Every save runs the full spec validator before writing. If the spec is invalid, the save is rejected and the errors appear inline:

  • Missing required fields
  • Type mismatches (e.g. passing a string into a field that expects agent_external_identity)
  • References to variables that don't exist or aren't in scope at that point
  • References to fields flagged as containing end-customer personal data

Successful saves that change the spec create a new immutable spec version. You can re-run a previous execution against the current saved spec from the trace viewer — useful for verifying that a fix actually changes the outcome before enabling the processor.

Going back to an earlier version ​

Versions in the topbar lists every version of this processor's spec, newest first. Open one and the canvas shows it read-only, so you can read what the processor used to do before deciding anything. The version currently running is marked current and cannot be opened — it is already what you are looking at.

From there, Restore this version puts that spec back. Restoring is an ordinary save: it is validated like any other, and it writes a new version rather than deleting anything, so the spec you restored from is still in the list. Cancel returns you to the current spec and changes nothing.

Two things worth knowing before you rely on it:

  • A version is written only when a save actually changes the spec. Saving the same spec twice gives you one version, not two, and renaming a processor gives you none.
  • A very old version can fail validation when you restore it, because an instruction it uses may have been changed or removed since. You get the same inline errors as any other rejected save, and the processor keeps running what it was already running.

What this section covers next ​

Now that you know where to click, the rest of this section is reference material for what to put in those clicks: