Workflow JSON Format
GenieBuilder workflows can be exported as JSON files and imported into any GenieBuilder instance. This page documents the transfer format so you can create workflows programmatically, share them across teams, or have an AI agent generate them for you.
Have an agent point at this schema and ask it to create anything you want. Then import the JSON into GenieBuilder for agentic execution.
Top-Level Wrapper
Every workflow JSON file uses this envelope:
{
"format": "genie-builder.workflow",
"version": 1,
"exportedAt": "2026-03-27T12:00:00.000Z",
"workflow": { ... }
}
| Field | Type | Required | Description |
|---|---|---|---|
format | string | Yes | Must be "genie-builder.workflow" (the legacy "devoxx-genie.workflow" is also accepted on import) |
version | number | Yes | Must be 1 (current version) |
exportedAt | string | Yes | ISO 8601 timestamp of when the file was created |
workflow | object | Yes | The workflow definition (see below) |
Workflow Object
The workflow object contains the full definition:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name of the workflow |
description | string | Yes | Short description of what the workflow does |
nodes | array | Yes | Array of node objects |
edges | array | Yes | Array of edge objects |
branchTemplate | string | Yes | Git branch name template (supports template variables) |
commitTemplate | string | Yes | Commit message template |
prTemplate | string | Yes | Pull request body template |
createGitBranch | boolean | No | Whether to create a feature branch per run (default: true) |
edgeType | string | No | Visual edge routing style: "default", "straight", "step", or "smoothstep" |
Nodes
Every node shares these base fields:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier within the workflow |
type | string | Yes | One of "start", "step", "decision", "end" |
label | string | Yes | Display label shown in the editor |
position | object | Yes | { "x": number, "y": number } — canvas coordinates |
Start Node
Every workflow must have exactly one start node. It configures iteration limits and optional task/branch bindings.
{
"id": "start",
"type": "start",
"label": "Start",
"position": { "x": 0, "y": 0 },
"config": {
"maxIterations": 3,
"taskId": "task-123",
"baseBranch": "main"
}
}
| Config Field | Type | Required | Description |
|---|---|---|---|
maxIterations | number | No | Maximum retry iterations (default: 3) |
taskId | string | No | Pre-bound task ID (usually left empty so the user picks one at run time) |
baseBranch | string | No | Base branch for PRs (usually left empty to use the current branch) |
Step Node
Steps are the workhorses of a workflow — each one sends a prompt to an LLM executor.
{
"id": "implement",
"type": "step",
"label": "Implement Changes",
"position": { "x": 0, "y": 200 },
"executor": {
"type": "cli-runner",
"id": "claude-code"
},
"toolSet": {
"git": true,
"backlog": true,
"shell": false
},
"promptTemplate": "Implement the task:\n\nTitle: {{task.title}}\nDescription: {{task.description}}",
"expectsVerdict": false,
"includeHistory": true,
"timeoutMs": 300000
}
| Field | Type | Required | Description |
|---|---|---|---|
executor | object | Yes | Executor — see below |
toolSet | object | No | Tool permissions (defaults to all false) |
promptTemplate | string | No | Prompt sent to the executor (supports template variables) |
expectsVerdict | boolean | No | When true, the step must produce a structured verdict for decision routing |
includeHistory | boolean | No | When true (default), the executor receives conversation history from prior steps |
timeoutMs | number | No | Step timeout in milliseconds |
Executor
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | "cli-runner" or "chat-provider" |
id | string | Yes | Identifier of the runner or provider (e.g. "claude-code", "codex") |
model | string | Conditional | Required when type is "chat-provider"; the model to use |
Tool Set
| Field | Type | Default | Description |
|---|---|---|---|
git | boolean | false | Read/write git operations |
backlog | boolean | false | Task management access |
shell | boolean | false | Execute shell commands |
Decision Node
Decision nodes route execution based on conditions attached to their outgoing edges. They have no extra fields beyond the base.
{
"id": "review-gate",
"type": "decision",
"label": "Review Passed?",
"position": { "x": 0, "y": 400 }
}
End Node
End nodes terminate the workflow with a status.
{
"id": "done",
"type": "end",
"label": "Completed",
"position": { "x": 0, "y": 600 },
"status": "completed"
}
| Field | Type | Required | Values |
|---|---|---|---|
status | string | Yes | "completed", "failed", or "cancelled" |
Edges
Edges connect nodes and optionally carry conditions for decision routing.
{
"id": "edge-review-to-gate",
"source": "review",
"target": "review-gate",
"label": "Pass",
"condition": {
"and": [
{ "field": "verdict", "op": "eq", "value": "pass" }
]
}
}
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique edge identifier |
source | string | Yes | ID of the source node |
target | string | Yes | ID of the target node |
sourceHandle | string | No | Source port identifier |
targetHandle | string | No | Target port identifier |
label | string | No | Display label on the edge |
condition | object | No | Condition that must be satisfied for the edge to be followed |
Edge Conditions
Conditions use an and array of clauses — all must be true for the edge to activate.
{
"and": [
{ "field": "verdict", "op": "eq", "value": "fail" },
{ "field": "canRetry", "op": "eq", "value": true }
]
}
Each clause has:
| Field | Type | Description |
|---|---|---|
field | string | Context field to evaluate (e.g. "verdict", "canRetry", "iterationsExhausted") |
op | string | Operator: "eq", "neq", "gt", "lt", "gte", "lte" |
value | string | number | boolean | Value to compare against |
On decision nodes, one outgoing edge may omit the condition to act as the default (fallback) path.
Template Variables
Templates in branchTemplate, commitTemplate, prTemplate, and step promptTemplate fields support {{variable}} substitution:
| Variable | Description |
|---|---|
{{task.id}} | Task identifier (e.g. "TASK-123") |
{{task.title}} | Task title |
{{task.description}} | Task description |
{{task.slug}} | URL-friendly task title |
{{run.id}} | Unique workflow run ID |
{{run.iteration}} | Current iteration number |
{{run.maxIterations}} | Maximum allowed iterations |
{{run.branchName}} | Generated git branch name |
{{workspace.projectPath}} | Absolute path to the project root |
{{git.baseBranch}} | Base branch for PRs |
{{workflow.commitMessage}} | Generated commit message |
{{workflow.prBody}} | Generated PR description |
{{steps.<step-id>.summary}} | Summary output from a previous step |
{{steps.<step-id>.findings}} | Structured findings from a verdict step |
Workflows that reference {{task.*}} variables will prompt the user to select a task before starting a run.
Validation Rules
When a JSON file is imported, GenieBuilder validates the graph structure. Import is rejected if any of these rules fail:
| Rule | Description |
|---|---|
| Non-empty graph | The workflow must contain at least one node |
| Exactly one start node | There must be exactly one node with type: "start" |
| At least one end node | There must be at least one node with type: "end" |
| No incoming edges on start | The start node must have no incoming edges |
| One outgoing edge from start | The start node must have exactly one outgoing edge |
| No outgoing edges from end | End nodes must have no outgoing edges |
| Decision fan-out | Decision nodes must have at least 2 outgoing edges |
| Single default edge | Decision nodes may have at most one unconditional (default) edge |
| Valid edge references | Every edge source and target must reference an existing node ID |
| All nodes reachable | Every node must be reachable from the start node via BFS traversal |
| chat-provider needs model | Steps using executor type "chat-provider" must specify a model |
Complete Example
Below is a full, importable workflow that implements a task and then reviews the result with a feedback loop. Copy this JSON, save it as a .json file, and import it via the workflow editor toolbar.
{
"format": "genie-builder.workflow",
"version": 1,
"exportedAt": "2026-03-27T12:00:00.000Z",
"workflow": {
"name": "Implement & Review Loop",
"description": "A two-agent workflow: one implements a task, another reviews it, with a retry loop on failure.",
"branchTemplate": "feature/{{task.slug}}",
"commitTemplate": "feat: {{task.title}}",
"prTemplate": "## Summary\nImplements {{task.id}} — {{task.title}}\n\n## Description\n{{task.description}}",
"createGitBranch": true,
"edgeType": "smoothstep",
"nodes": [
{
"id": "start",
"type": "start",
"label": "Start",
"position": { "x": 300, "y": 0 },
"config": {
"maxIterations": 3
}
},
{
"id": "implement",
"type": "step",
"label": "Implement",
"position": { "x": 300, "y": 150 },
"executor": {
"type": "cli-runner",
"id": "claude-code"
},
"toolSet": {
"git": true,
"backlog": true,
"shell": true
},
"promptTemplate": "You are working on: {{task.title}}\n\n{{task.description}}\n\nImplement the changes in the project at {{workspace.projectPath}}. Follow existing code conventions.",
"expectsVerdict": false,
"includeHistory": true
},
{
"id": "review",
"type": "step",
"label": "Review",
"position": { "x": 300, "y": 300 },
"executor": {
"type": "cli-runner",
"id": "claude-code"
},
"toolSet": {
"git": true,
"backlog": false,
"shell": false
},
"promptTemplate": "Review the changes made for: {{task.title}}\n\nCheck for correctness, code quality, and test coverage. Output a structured verdict.",
"expectsVerdict": true,
"includeHistory": false
},
{
"id": "review-gate",
"type": "decision",
"label": "Review Passed?",
"position": { "x": 300, "y": 450 }
},
{
"id": "fix",
"type": "step",
"label": "Fix Issues",
"position": { "x": 550, "y": 300 },
"executor": {
"type": "cli-runner",
"id": "claude-code"
},
"toolSet": {
"git": true,
"backlog": false,
"shell": true
},
"promptTemplate": "The reviewer found issues:\n\n{{steps.review.summary}}\n\nFindings:\n{{steps.review.findings}}\n\nFix all reported issues in the project at {{workspace.projectPath}}.",
"expectsVerdict": false,
"includeHistory": true
},
{
"id": "done",
"type": "end",
"label": "Completed",
"position": { "x": 300, "y": 600 },
"status": "completed"
},
{
"id": "failed",
"type": "end",
"label": "Failed",
"position": { "x": 550, "y": 600 },
"status": "failed"
}
],
"edges": [
{
"id": "edge-start-implement",
"source": "start",
"target": "implement"
},
{
"id": "edge-implement-review",
"source": "implement",
"target": "review"
},
{
"id": "edge-review-gate",
"source": "review",
"target": "review-gate"
},
{
"id": "edge-gate-done",
"source": "review-gate",
"target": "done",
"label": "Pass",
"condition": {
"and": [
{ "field": "verdict", "op": "eq", "value": "pass" }
]
}
},
{
"id": "edge-gate-fix",
"source": "review-gate",
"target": "fix",
"label": "Fail + Retry",
"condition": {
"and": [
{ "field": "verdict", "op": "eq", "value": "fail" },
{ "field": "canRetry", "op": "eq", "value": true }
]
}
},
{
"id": "edge-gate-failed",
"source": "review-gate",
"target": "failed",
"label": "Exhausted"
},
{
"id": "edge-fix-review",
"source": "fix",
"target": "review"
}
]
}
}
How this workflow runs
- Start — initializes the run with up to 3 iterations
- Implement — an AI agent writes the code changes using git, backlog, and shell tools
- Review — a separate agent reviews the diff and produces a pass/fail verdict
- Review Passed? — routes based on the verdict:
- Pass — proceeds to Completed
- Fail + can retry — routes to Fix Issues, which loops back to Review
- Iterations exhausted — falls through to Failed (default edge)
- The loop continues until the review passes or iterations run out
Importing and Exporting
- Export: In the workflow editor, click the export button in the toolbar. The JSON file is saved to your downloads folder.
- Import: Click the import button and select a
.jsonfile. If a workflow with the same name already exists, you can choose to create a copy or overwrite it.
BPMN 2.0 notation import and export will be supported in a future release.