Nenjo Docs
Pipelines

Pipelines

Orchestrate multi-step agent workflows using directed acyclic graphs (DAGs).

Pipelines define the execution flow for agent work in Nenjo. Each pipeline is a directed acyclic graph (DAG) of steps connected by edges, where each step performs a unit of work -- running an agent, evaluating a gate, executing a script, or coordinating a council.

Core concepts

A pipeline consists of three primitives:

  • Steps (nodes) -- Units of work such as agent tasks, quality gates, lambda scripts, cron loops, councils, or terminal states.
  • Edges -- Directed connections between steps that define execution order.
  • Conditions -- Rules on edges that determine which path to follow based on the previous step's result (on_pass, on_fail, etc.).

Every pipeline has exactly one entry point (a step with no incoming edges) and at least one terminal step where execution ends.

Data model

Pipeline

FieldTypeDescription
idUUIDUnique identifier
namestringHuman-readable name
descriptionstring?Optional description
triggerstringWhen to execute: ticket.ready or cron
is_activebooleanWhether the pipeline can be executed
is_defaultbooleanWhether this is the user's default pipeline
max_retriesintegerMaximum retry attempts on failure (default: 3)
metadataJSONArbitrary metadata (e.g., schedule for cron, entry_step_ids for editor)
created_byUUIDOwner user ID

Pipeline step

FieldTypeDescription
idUUIDUnique identifier
pipeline_idUUIDParent pipeline
namestringDisplay name
step_typestringOne of: agent, council, gate, cron, lambda, terminal
agent_idUUID?Agent to run (for agent steps)
council_idUUID?Council to run (for council steps)
role_idUUID?Role to use (resolves to an agent, for agent/cron steps)
lambda_idUUID?Lambda script to run (for lambda/cron steps)
configJSONStep-specific configuration
position_xfloatX coordinate in the visual editor
position_yfloatY coordinate in the visual editor
order_indexintegerOrdering hint for entry-point resolution

Pipeline edge

FieldTypeDescription
idUUIDUnique identifier
pipeline_idUUIDParent pipeline
source_step_idUUIDStep this edge originates from
target_step_idUUIDStep this edge points to
conditionstringWhen to follow: always, on_pass, on_fail, on_review_pass, on_review_fail
metadataJSONOptional edge metadata

Trigger types

Pipelines are activated by a trigger:

  • ticket.ready -- Executes when a ticket transitions to the ready state. This is the default trigger for task-driven pipelines.
  • cron -- Executes on a recurring schedule. See Cron and scheduling for details.

Execution lifecycle

  1. The pipeline is loaded with its steps and edges.
  2. The entry step is identified (the step with no incoming edges, or via metadata.entry_step_ids).
  3. The entry step executes and produces a StepResult with a passed boolean.
  4. The executor evaluates outgoing edges from the current step. The first edge whose condition is satisfied by the step result is followed.
  5. The next step executes, and the process repeats.
  6. Execution ends when a terminal step is reached or no matching outgoing edge is found.

The executor is bounded to steps.len() * 100 iterations to prevent infinite loops on misconfigured pipelines.

Project assignment

Pipelines are assigned to projects. When a ticket in a project becomes ready, the project's assigned pipeline (or the user's default pipeline) is executed. One pipeline can be marked as the default using the set-default endpoint.

API

All pipeline routes are under /api/v1/pipelines and require authentication.

Pipeline CRUD

# List all pipelines
curl -H "Authorization: Bearer $TOKEN" \
  https://your-instance.com/api/v1/pipelines

# Create a pipeline
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Code Review Pipeline",
    "trigger": "ticket.ready",
    "max_retries": 3
  }' \
  https://your-instance.com/api/v1/pipelines

# Get pipeline with steps and edges
curl -H "Authorization: Bearer $TOKEN" \
  https://your-instance.com/api/v1/pipelines/$PIPELINE_ID

# Update a pipeline
curl -X PATCH \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"is_active": false}' \
  https://your-instance.com/api/v1/pipelines/$PIPELINE_ID

# Delete a pipeline
curl -X DELETE \
  -H "Authorization: Bearer $TOKEN" \
  https://your-instance.com/api/v1/pipelines/$PIPELINE_ID

# Set as default pipeline
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  https://your-instance.com/api/v1/pipelines/$PIPELINE_ID/set-default

# Manually trigger a cron pipeline
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  https://your-instance.com/api/v1/pipelines/$PIPELINE_ID/trigger

Steps CRUD

# Add a step
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Developer",
    "step_type": "agent",
    "role_id": "ROLE_UUID"
  }' \
  https://your-instance.com/api/v1/pipelines/$PIPELINE_ID/steps

# Update a step
curl -X PATCH \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Senior Developer"}' \
  https://your-instance.com/api/v1/pipelines/$PIPELINE_ID/steps/$STEP_ID

# Delete a step
curl -X DELETE \
  -H "Authorization: Bearer $TOKEN" \
  https://your-instance.com/api/v1/pipelines/$PIPELINE_ID/steps/$STEP_ID

Edges CRUD

# Add an edge
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "source_step_id": "STEP_A_UUID",
    "target_step_id": "STEP_B_UUID",
    "condition": "on_pass"
  }' \
  https://your-instance.com/api/v1/pipelines/$PIPELINE_ID/edges

# Delete an edge
curl -X DELETE \
  -H "Authorization: Bearer $TOKEN" \
  https://your-instance.com/api/v1/pipelines/$PIPELINE_ID/edges/$EDGE_ID

Next steps

On this page