Authoring processes
A process is a JSON document. You can write it by hand, generate it with the Studio Assistant (which loads the learn_process_design skill), or iterate with an LLM in any editor and paste the result. This page covers both paths and the rules a valid definition must satisfy.
The editor in Vertesia Studio
Studio gives you both a visual authoring surface and a code editor for the same definition:
- Statechart / process board. The visual view renders the process as cards and transitions. For larger definitions, use lanes and phases so the graph reads like a business process board instead of a raw dependency graph.
- Inspector. Clicking a node or transition opens the selected definition as YAML, plus readable fields such as type, tool, interaction, writes, phase, lane, and order.
- Explain. The inspector can call
sys:ExplainProcessfor the selected node, guard, or whole process. Use this before changing an unfamiliar definition. - Code tab. The full definition is still editable as JSON/YAML when you need bulk changes, search/replace, or a reviewable diff.
- Live parse. Save is blocked while the document is unparseable.
- Validation. The save path runs the same server-side process-definition validation used by the
validate_processtool. The Studio Assistant calls that tool directly while iterating.
The stored definition contract is explicit about its schema generation: native process definitions carry format_version: 1. Studio can prefill that field for a new draft, but the saved JSON keeps it present so future migrations have a stable boundary.
Authoring with the Studio Assistant
The fastest way to go from "I want a process that does X" to a committed draft is the Studio Assistant. When you ask it to author or change a process, it loads the learn_process_design skill — which unlocks the process tools and grammar before it drafts anything:
learn_process_design— loads the full process grammar and authoring rules before drafting.list_tools,list_interactions,get_interaction— confirm every name it references actually exists.validate_process— validates a draft JSON against the schema. The assistant iterates until clean.create_process/update_process— write or revise a draft in the catalog.publish_process— publishes a draft only after explicit confirmation.start_process_run,get_process_run— run and inspect a draft to test it end to end.LayoutProcessDefinition— improves visual metadata and transition labels without changing runtime behavior.ask_user,plan,update_plan,think— standard authoring scaffolding.
Its iteration loop is:
- Discover — one
ask_userbatch with all open questions. - Load the grammar (
learn_process_design). - Confirm tool / interaction names with the user before referencing them.
- Draft the JSON.
- Validate; fix every error; repeat until clean.
- Create or update a draft. Do not set
statusorversion; the server owns them. - Publish only after explicit confirmation. Include an optional publish comment when one is provided.
- Summarize: node graph, inputs expected per run, outputs written to context, where humans intervene.
Rules a valid definition must satisfy
These are the traps that catch first-time authors. They're codified in the learn_process_design skill and in the server-side validator:
node.inputis a runtime mapping, not a schema. Use a bare template:"invoice": "{{invoice_doc_id}}". Never put a JSON-schema fragment like{ "type": "string", "editor": "document" }insidenode.input— that belongs on the target interaction's input schema.- Document fields in
context.schemamust set bothformatandeditor. Use{ "type": "string", "format": "document", "editor": "document", "description": "…" }. Withouteditor, the Start Run modal falls back to a rawstore:<id>text field. - Agent nodes return structured output, not control-flow tool calls.
Don't prompt worker agents to call process-control tools such as
set_context,transition_to, orskip_node— those belong to the top-level supervisor, not node workers. The engine builds aresult_schemafromnode.writes(plus a_next_nodeenum on multi-transition nodes) and constrains the child's output to match. See Agent nodes. - Agent nodes get only the tools you declare in
node.tools. Skills (learn_*) are available so the agent can self-unlock capabilities. - Agent nodes use
sys:ProcessAgentNodeby default. It injects process orientation automatically. Override withnode.interactiononly when you need a custom interaction with its own input schema. - Every node should have a
human_description. One or two sentences in plain language, distinct from the developer-facingdescription. Surfaces in observability. Undescribed nodes read as noise in the run report. - Template references throw on missing fields. Only reference context fields guaranteed to exist at the node.
- Every
conditionnode must match a branch or havedefault: true. No match and no default = runtime error. - Context is capped at 64 KB serialized. Store large payloads as artifact URIs and reference them.
- Do not overload collection fanout and fixed split/join in your own mental model.
Use
conditionto choose one path,branchto run a fixed set of named branches and join, andforeachto repeat a child body over a collection. - Fanout child bodies do not own routing.
In
foreachandbranch, the child body should betool,interaction,agent, orprocessonly, with no nestedtransitionsorbranches. - Any node that writes context must declare
writes. A non-emptycontext_update, human task answer, interaction result, agent result, collectedforeachoutput, or collectedbranchoutput is rejected unless the parent node declares the target fields inwrites. - Supervisor overrides must be explicit.
transition_tofollows declared exits by default, andskip_noderequiresskippable: true. Usemetadata.supervisor.allow_transition_overrideormetadata.supervisor.allow_skiponly for deliberate break-glass cases. - Large processes need visual metadata.
Set
metadata.phase,metadata.lane, andmetadata.orderon nodes when the graph has more than a straight-line handful of steps. The run UI uses those values for the Process Navigator and stable layout. set_contexttool nodes use anupdatesenvelope. A process tool node that callsset_contextmust pass{ "updates": { ... } }, not raw context fields at the top level. The node still declareswritesfor every updated field.- Use real interaction names.
For open-ended agent behavior, prefer
sys:GeneralAgentor a custom agent interaction. Usesys:ProcessAgentNodefor normal worker-agent nodes unless you have a specific interaction contract to override.
Assignees
Human-task assignee is either a group reference (group:<name>) or a concrete user id. role:<name> is not supported — use group:<name> instead. Leave unset if the task should be available to anyone who can see the inbox.
Process board metadata
The process graph is readable only when authors describe the business structure, not just the transitions. For larger processes, model the visual board deliberately:
metadata.phaseis the stage of work: intake, AI review, approval, fulfillment, closeout.metadata.laneis the responsible actor or system: requester, AI assistant, policy, legal, procurement, outcome.metadata.orderis the stable sort key inside that lane.- Transition and branch
labelvalues are the business names of exits: approved, rejected, needs legal, amount >= 10000.
In the swimlane view, lanes render as vertical responsibility bands and nodes stack top-to-bottom within each lane. The main flow usually moves left-to-right across lanes; alternate paths can loop down or back across lanes. Keep lane names short and consistent.
Add layout metadata to every node in multi-stage processes:
{
"agent2_asset_generation": {
"type": "agent",
"title": "Agent 2 — Campaign Asset Generation",
"metadata": {
"phase": "Gate 2",
"lane": "agent",
"order": 10
},
"writes": ["asset_package"],
"transitions": [
{
"to": "gate2_asset_review",
"label": "Send package to review"
}
]
},
"gate2_asset_review": {
"type": "human_task",
"title": "Gate 2 — Asset Package Review",
"metadata": {
"phase": "Gate 2",
"lane": "review",
"order": 20
}
}
}
Use a small, stable vocabulary for lane: business roles (requester, legal, finance, claims_adjuster) are better than implementation terms when humans need to read the board. Use implementation lanes (ai_assistant, policy, tooling) when ownership is genuinely a system.
Add label to transitions and branches when the guard is not obvious. The graph renders those labels on the edge, and the inspector shows the selected transition / branch as YAML.
Improving layout with the assistant
When a graph becomes hard to read, use the Studio Assistant or the Improve layout action. It calls LayoutProcessDefinition with the current definition and optional notes about the current rendering. The interaction is constrained to visual fields:
- node
title,description, andhuman_description - node
metadata.phase,metadata.lane,metadata.order, and optionalmetadata.position - transition / branch
label
It should not change runtime behavior: no node ids, node types, context schema, inputs, writes, tools, interactions, guards, targets, defaults, or tasks.
Hand-authoring workflow
If you're editing directly in Studio or in a Git checkout:
- Start from the schema: define
context.schemafirst. Every field a node writes must exist here. - Lay out nodes and transitions. Name them for what they do, not how they work (e.g.
legal_review, nothuman_task_1). - Fill each node's
human_description. Ask yourself: what would a reviewer read here during observability? - For
agentnodes, set the minimumwritesscope — the result_schema is derived from it, so tighter writes means stricter agent output. - Add visual metadata and transition labels before the graph gets large. It is much easier to keep the run view readable while authoring than to repair it later.
- Validate. Validation catches unreferenced nodes, branches with no default, and schema mismatches.
- Save the draft. Run it against a known-good input. Iterate. Publish only when it is stable and the publishing user confirms.
Versioning
Process definitions use draft/published versioning:
- New definitions are drafts at
version: 1. - Draft edits mutate the latest draft.
- Published revisions are immutable.
- Editing a published head creates the next draft head instead of changing the published version.
- Listings show only the latest/head revision by default; use the Versions tab or
all_versionsonly when you need history. - Publishing requires explicit confirmation and can include a comment.
- A historical version can be reverted into the current draft from the Versions tab.
Already-running processes continue to execute the definition that was passed into their Temporal workflow at start. Editing or reverting the catalog entry does not change an in-flight run.
Next
- Node types — the reference for each
type. - Observability — how to watch a run and debug what an agent node actually produced.
