Nenjo Docs
Routines

Routines

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

Routines define the execution flow for agent work in Nenjo. Each routine 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 routine 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 routine has exactly one entry point (a step with no incoming edges) and at least one terminal step where execution ends.

Data model

Routine

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

Routine step

FieldTypeDescription
idUUIDUnique identifier
routine_idUUIDParent routine
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

Routine edge

FieldTypeDescription
idUUIDUnique identifier
routine_idUUIDParent routine
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

Routines are activated by a trigger:

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

Execution lifecycle

  1. The routine 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 routines.

Project assignment

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

API

All routine routes are under /api/v1/routines and require authentication.

Routine CRUD

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

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

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

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

# Delete a routine
curl -X DELETE \
  -H "Authorization: Bearer $TOKEN" \
  https://your-instance.com/api/v1/routines/$ROUTINE_ID

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

# Manually trigger a cron routine
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  https://your-instance.com/api/v1/routines/$ROUTINE_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/routines/$ROUTINE_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/routines/$ROUTINE_ID/steps/$STEP_ID

# Delete a step
curl -X DELETE \
  -H "Authorization: Bearer $TOKEN" \
  https://your-instance.com/api/v1/routines/$ROUTINE_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/routines/$ROUTINE_ID/edges

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

Next steps

On this page