Statewright

Create Your Own Workflow

Step-by-step guide to writing a workflow definition from scratch

Create Your Own Workflow

Four states. Guards. An approval gate. A code review workflow, built from scratch.

Step 1: Define the Phases

Think about what your agent should do in order, and what it should NOT be able to do in each phase.

For a code review:

  1. read — understand the PR diff (read-only, no edits)
  2. review — write comments, identify issues (read + limited bash for running linters)
  3. approve — human reviews the agent's findings (approval gate)
  4. complete — done

Step 2: Write the Skeleton

Start with id, initial, and empty states:

{
  "id": "code-review",
  "initial": "read",
  "states": {
    "read": { "on": {} },
    "review": { "on": {} },
    "approve": { "on": {} },
    "complete": { "type": "final" }
  }
}

Step 3: Add Tool Restrictions

Each state gets an allowed_tools list. If omitted, all tools are allowed (no restriction).

{
  "read": {
    "allowed_tools": ["Read", "Grep", "Glob", "Bash"],
    "allowed_commands": ["git diff", "git log", "git show"],
    "max_iterations": 15,
    "instructions": "Read the PR changes. Understand what changed and why. Do not write comments yet.",
    "on": { "UNDERSTOOD": "review" }
  },
  "review": {
    "allowed_tools": ["Read", "Grep", "Bash", "Edit"],
    "allowed_commands": ["eslint", "ruff", "cargo clippy"],
    "max_edit_lines": 50,
    "instructions": "Write review comments. Run linters. Identify bugs, style issues, and potential improvements.",
    "on": { "REVIEWED": "approve" }
  }
}

Step 4: Add an Approval Gate

The requires_approval flag pauses execution and asks a human to confirm before the transition completes.

{
  "approve": {
    "allowed_tools": ["Read"],
    "instructions": "Review is complete. Present findings and wait for human approval.",
    "on": {
      "APPROVED": {
        "target": "complete",
        "requires_approval": true
      },
      "REVISE": "review"
    }
  }
}

Step 5: Add Guards (Optional)

Guards prevent transitions unless conditions are met. The agent passes context data when transitioning, and guards check it.

{
  "review": {
    "on": {
      "REVIEWED": {
        "target": "approve",
        "guard": "has_findings"
      }
    }
  }
}

Define the guard:

{
  "guards": {
    "has_findings": {
      "field": "findings_count",
      "op": "gt",
      "value": 0
    }
  }
}

The agent must pass data: {findings_count: 3} when transitioning. If findings_count is 0, the guard blocks the transition.

Step 6: Deploy

Via the Visual Editor

  1. Go to statewright.ai/workflows
  2. Click "New Workflow"
  3. Paste your JSON definition
  4. Save

Via MCP (from an agent)

statewright_create_workflow(name='code-review', definition={...})

Via the API

curl -X POST https://statewright.ai/api/collections/workflows/records \
  -H "Authorization: Bearer sw_live_..." \
  -H "Content-Type: application/json" \
  -d '{"name": "code-review", "definition": {...}, "active": true}'

Complete Example

{
  "id": "code-review",
  "initial": "read",
  "states": {
    "read": {
      "allowed_tools": ["Read", "Grep", "Glob", "Bash"],
      "allowed_commands": ["git diff", "git log", "git show"],
      "max_iterations": 15,
      "instructions": "Read the PR changes. Do not write comments yet.",
      "on": { "UNDERSTOOD": "review" }
    },
    "review": {
      "allowed_tools": ["Read", "Grep", "Bash", "Edit"],
      "allowed_commands": ["eslint", "ruff", "cargo clippy"],
      "max_edit_lines": 50,
      "on": {
        "REVIEWED": {
          "target": "approve",
          "guard": "has_findings"
        }
      }
    },
    "approve": {
      "allowed_tools": ["Read"],
      "on": {
        "APPROVED": { "target": "complete", "requires_approval": true },
        "REVISE": "review"
      }
    },
    "complete": { "type": "final" }
  },
  "guards": {
    "has_findings": { "field": "findings_count", "op": "gt", "value": 0 }
  }
}

Next Steps

On this page