veritas-kanban/docs/WORKFLOW-GUIDE.md
2026-07-25 04:03:42 -05:00

35 KiB
Raw Blame History

Veritas Kanban Workflow Engine — User Guide

Version: v4.0
Last Updated: 2026-02-09
Status: Production Ready


Table of Contents

  1. Introduction
  2. Quick Start
  3. Workflow YAML Format
  4. Step Configuration
  5. Tool Policies
  6. Session Management
  7. Monitoring & Dashboard
  8. Example Workflows
  9. API Quick Reference
  10. Troubleshooting

Introduction

What is the Workflow Engine?

The Veritas Kanban workflow engine is a deterministic multi-step agent orchestration system that transforms VK from an ad-hoc task board into a repeatable, observable, and reliable agent execution platform.

Think of it as GitHub Actions for AI agents — YAML-defined pipelines that coordinate multiple agents, manage state, handle failures, and provide real-time observability.

Why Use Workflows?

Before workflows:

  • Ad-hoc agent execution with no repeatability
  • No multi-agent coordination
  • Agents repeat the same mistakes
  • No visibility into progress
  • Hard to debug failures

With workflows:

  • Version-controlled YAML pipelines
  • Coordinated agent handoffs with context passing
  • Retry and escalation policies
  • Real-time WebSocket status updates
  • Step-by-step execution logs
  • Reusable workflow library

Key Capabilities

  • Sequential Execution — Steps run in order with context passing
  • Loop Steps — Iterate over collections (stories, subtasks, test cases)
  • Gate Steps — Block execution until conditions are met or approval granted
  • Parallel Steps — Execute multiple sub-steps concurrently
  • Retry Policies — Automatic retries with configurable delays
  • Tool Restrictions — Limit which tools each agent can use
  • Session Isolation — Fresh context per step to prevent context bleed
  • Real-Time Updates — WebSocket broadcasts for live progress
  • Dashboard — Monitor active runs, success rates, and historical trends

Prerequisites

  • Veritas Kanban v4.0+ installed and running
  • OpenClaw configured with agent models
  • Basic understanding of YAML syntax
  • Familiarity with VK task management

Quick Start

Step 1: Create Your First Workflow

Create a file .veritas-kanban/workflows/hello-world.yml:

id: hello-world
name: Hello World Workflow
version: 1
description: A simple 2-step workflow to test the engine.

agents:
  - id: writer
    name: Writer
    role: developer
    model: github-copilot/claude-sonnet-4.5
    description: Writes hello world messages

steps:
  - id: greet
    name: 'Step 1: Greet user'
    type: agent
    agent: writer
    input: |
      Write a friendly hello world message.
      Reply with:
      MESSAGE: <your greeting>
    output:
      file: greeting.md
    acceptance_criteria:
      - 'MESSAGE:'
    on_fail:
      retry: 2
      escalate_to: human

  - id: farewell
    name: 'Step 2: Say goodbye'
    type: agent
    agent: writer
    input: |
      Write a farewell message.
      Previous greeting: {{steps.greet.output}}
      Reply with:
      MESSAGE: <your goodbye>
    output:
      file: farewell.md
    acceptance_criteria:
      - 'MESSAGE:'

Step 2: Run the Workflow via API

# Start a workflow run
curl -X POST http://localhost:3001/api/workflows/hello-world/runs \
  -H "Content-Type: application/json" \
  -d '{}'

# Response:
# {
#   "id": "run_20260209_abc123",
#   "workflowId": "hello-world",
#   "status": "running",
#   "startedAt": "2026-02-09T12:00:00Z",
#   ...
# }

Step 3: View Progress in the UI

  1. Open Veritas Kanban in your browser
  2. Navigate to Workflows tab (header navigation)
  3. Select the workflow name or View details to inspect its definition before execution
  4. Select Start Run, review the optional task association and JSON run context, then confirm the run
  5. Open View workflow runs to see real-time step progress

Browse, Edit, and Duplicate Workflows

The workflow browser separates inspection, authoring, and execution:

  • A workflow name or View details opens a deep-linkable read-only definition at /workflows/:id. The definition shows provenance, variables, agents, ordered steps, phases, gate conditions, loop controls, parallel branches, step inputs, acceptance criteria, and outputs.
  • User-owned workflows with edit permission expose Edit and save through the Author builder at /workflows/:id/edit. The workflow ID remains fixed and the loaded version is sent with the update, so a stale save fails with a conflict instead of overwriting a newer definition. The draft remains in the editor after validation, permission, or conflict errors.
  • Built-in and shared read-only workflows explain why they cannot be edited. Identities with workflow write permission can choose Duplicate to customize, select a new ID and name in Author, and save an independent workflow.
  • Start Run always opens a separate configuration dialog. An optional task ID associates the run with an existing task, while the JSON object supplies initial workflow context.

Browser Back returns from edit or duplicate to the source definition and from the definition to the workflow browser. Direct links use the same safe fallback instead of leaving the application.


Workflow YAML Format

Schema Overview

Every workflow YAML file has this structure:

# ==================== Metadata ====================
id: <unique-workflow-id> # Required: alphanumeric + dashes
name: <human-readable-name> # Required: display name
version: <integer> # Required: starts at 1, auto-incremented on edit
description: | # Required: multi-line description
  What this workflow does and when to use it.

# ==================== Global Configuration ====================
config:
  timeout: 7200 # Max workflow duration (seconds, default: 2 hours)
  fresh_session_default: true # All steps spawn fresh sessions unless overridden
  progress_file: progress.md # Shared progress file (default: progress.md)
  telemetry_tags: ['workflow', 'feature-dev'] # Tags for telemetry events

# ==================== Agent Definitions ====================
agents:
  - id: <agent-id> # Required: unique within workflow
    name: <agent-name> # Required: display name
    role: <role-slug> # Required: maps to tool policy
    model: <model-identifier> # Optional: default model for this agent
    tools: [read, write, exec] # Optional: tool restrictions (overrides role policy)
    description: <agent-purpose> # Required: what this agent does

# ==================== Sequential Steps ====================
steps:
  - id: <step-id> # Required: unique within workflow
    name: <step-name> # Required: display name
    type: agent # Required: agent | loop | gate | parallel
    agent: <agent-id> # Required for agent/loop steps

    # Step execution
    input: | # Template for agent prompt (supports {{variables}})
      Task description here...

    output:
      file: <filename>.md # Output filename (saved in step-outputs/)
      schema: <schema-id> # Optional: JSON schema for validation

    # Validation
    acceptance_criteria:
      - 'Required string in output'
      - '/regex pattern/i'
      - 'json.path == "value"'

    # Error handling
    on_fail:
      retry: 2 # Max retries for this step
      retry_delay_ms: 5000 # Delay between retries (ms)
      retry_step: <other-step-id> # Jump back to another step
      escalate_to: human # human | agent:<id> | skip
      escalate_message: '...' # Message shown on escalation

    # Advanced configuration
    timeout: 600 # Step timeout (seconds, overrides global)
    session: # Session management (see Session Management section)
      mode: fresh
      context: minimal
      cleanup: delete
      timeout: 300

# ==================== Variables (Optional) ====================
variables:
  repo_path: '/path/to/repo'
  base_branch: 'main'

# ==================== Output Schemas (Optional) ====================
schemas:
  plan_output:
    type: object
    required: [stories]
    properties:
      stories:
        type: array

Metadata Fields

Field Type Required Description
id string Unique workflow identifier (alphanumeric + dashes, max 100 chars)
name string Human-readable name (max 200 chars)
version integer Version number (starts at 1, auto-incremented on edit)
description string What the workflow does (max 2000 chars, supports multi-line)

Config Fields

Field Type Default Description
timeout integer 7200 Max workflow duration in seconds (2 hours default)
fresh_session_default boolean true Spawn fresh sessions for all steps unless overridden
progress_file string progress.md Shared progress file name
telemetry_tags array [] Tags for telemetry events (for analytics)

Agent Fields

Field Type Required Description
id string Unique agent ID within workflow
name string Display name for the agent
role string Role slug (maps to tool policy)
model string Default model (e.g., github-copilot/claude-opus-4.6)
tools array Tool restrictions (overrides role policy)
description string What this agent does

Step Types

Agent Step

Run a single AI agent to complete a task.

- id: implement
  name: 'Implement feature'
  type: agent
  agent: developer
  input: |
    Implement {{task.title}}
    Requirements: {{task.description}}
  output:
    file: implementation.md
  acceptance_criteria:
    - 'STATUS: done'
  on_fail:
    retry: 2

Loop Step

Iterate over a collection and execute an action for each item.

- id: process-stories
  name: 'Process each story'
  type: loop
  agent: developer
  loop:
    over: '{{plan.stories}}' # Array to iterate over
    item_var: story # Variable name for current item
    index_var: index # Variable name for loop index
    completion: all_done # all_done | any_done | first_success
    fresh_session_per_iteration: true # New session per iteration
    verify_each: true # Run verify step after each iteration
    verify_step: verify # Step ID to run for verification
    max_iterations: 20 # Safety limit
    continue_on_error: false # If true, skip failed iterations
  input: |
    Implement story {{loop.index + 1}}/{{loop.total}}:
    {{story.title}}

Loop Completion Modes:

  • all_done — All iterations must complete successfully
  • any_done — Stop after first successful iteration
  • first_success — Stop immediately when one succeeds

Gate Step

Block execution until a condition is met or manual approval granted.

- id: quality-gate
  name: 'Quality Check'
  type: gate
  condition: '{{test.status == "passed" and verify.decision == "approved"}}'
  on_false:
    escalate_to: human
    escalate_message: 'Quality gate failed — manual review required'

Condition Syntax:

  • Variable access: {{variable}}
  • Equality: {{a == "value"}}
  • Boolean AND: {{a == "x" and b == "y"}}
  • Boolean OR: {{a == "x" or b == "y"}}

Parallel Step

Execute multiple sub-steps concurrently.

- id: parallel-tests
  name: 'Run all test suites'
  type: parallel
  parallel:
    completion: all # all | any | N (number)
    fail_fast: true # Abort others when one fails
    timeout: 1800 # Max wait time (seconds)
    steps:
      - id: unit
        agent: tester
        input: 'Run unit tests'
      - id: integration
        agent: tester
        input: 'Run integration tests'
      - id: e2e
        agent: tester
        input: 'Run E2E tests'

Step Configuration

Acceptance Criteria

Acceptance criteria validate step outputs before marking the step as complete.

Types of Criteria:

  1. Substring Match (default):

    acceptance_criteria:
      - 'STATUS: done'
      - 'RESULT: success'
    
  2. Regex Pattern:

    acceptance_criteria:
      - '/^STATUS:\s*done$/i'
      - '/ERROR: \d+/'
    
  3. JSON Path Equality:

    acceptance_criteria:
      - 'output.decision == "approved"'
      - 'test.passed > 0'
    

📝 Note: All criteria must pass for the step to succeed. If any criterion fails, the step is marked as failed.

Session Management

Each step can control its OpenClaw session behavior:

session:
  mode: fresh # fresh | reuse
  context: minimal # minimal | full | custom
  cleanup: delete # delete | keep
  timeout: 300 # seconds
  includeOutputsFrom: [step-1, step-2] # for context: custom

Session Modes:

Mode Behavior Use Case
fresh New session per step Prevents context bleed (default)
reuse Continue existing session Multi-turn conversation with same agent

Context Injection:

Mode What's Included Use Case
minimal Task metadata + workflow context Independent steps
full All previous step outputs Steps needing full history
custom Explicit list of step outputs Surgical context control

Cleanup Policies:

Mode Behavior Use Case
delete Terminate session after step Production (saves resources)
keep Leave session running Development/debugging

Example — Fresh Session with Minimal Context:

- id: review
  type: agent
  agent: reviewer
  session:
    mode: fresh
    context: minimal
    cleanup: delete
    timeout: 600
  input: |
    Review this code for security issues.

Example — Reuse Session with Custom Context:

- id: fix
  type: agent
  agent: developer
  session:
    mode: reuse # Continue from previous developer session
    context: custom
    includeOutputsFrom: [plan, test] # Only include plan and test outputs
    cleanup: delete
  input: |
    Fix the issues found in testing.

Error Handling

Configure retry and escalation behavior:

on_fail:
  retry: 3 # Max retries
  retry_delay_ms: 10000 # 10 second delay between retries
  retry_step: implement # Jump back to implement step
  escalate_to: human # human | agent:<id> | skip
  escalate_message: 'Manual intervention required'
  on_exhausted:
    escalate_to: human

Retry Strategies:

  1. Same Step Retry — Re-execute the failed step:

    on_fail:
      retry: 3
      retry_delay_ms: 5000
    
  2. Different Step Retry — Jump back to an earlier step:

    on_fail:
      retry_step: implement
      max_retries: 2
    
  3. Escalation — Delegate to another agent or human:

    on_fail:
      escalate_to: human
      escalate_message: 'Step failed after 3 retries'
    
  4. Skip — Continue with next step:

    on_fail:
      escalate_to: skip
    

Tool Policies

Tool policies define which tools each agent role can access, enabling least-privilege security.

Default Policies

Role Allowed Tools Denied Tools Use Case
planner read, web_search, web_fetch, browser, image, nodes write, edit, exec, message Analysis and planning — read-only
developer * (all tools) none Feature implementation — full access
reviewer read, exec, web_search, web_fetch, browser, image, nodes write, edit, message Code review — can run tests
tester read, exec, browser, web_search, web_fetch, image, nodes write, edit, message Testing — can interact with UIs
deployer * (all tools) none Deployment — full access

Creating Custom Policies

Via API:

curl -X POST http://localhost:3001/api/tool-policies \
  -H "Content-Type: application/json" \
  -d '{
    "role": "auditor",
    "allowed": ["read", "web_search", "web_fetch", "browser"],
    "denied": ["exec", "write", "edit"],
    "description": "Security auditor — read-only with web access"
  }'

Via UI:

  1. Open Settings → Tool Policies tab
  2. Click "New Policy"
  3. Fill in role name, allowed/denied tools, and description
  4. Click "Create"

Assigning Policies to Workflow Steps

Tool policies are assigned via the agent's role field:

agents:
  - id: reviewer
    name: Code Reviewer
    role: reviewer # Maps to reviewer tool policy
    model: github-copilop/claude-opus-4.6
    description: Reviews code for quality and security

steps:
  - id: review
    agent: reviewer # Inherits tool policy from role
    input: |
      Review this pull request.

Override Policy with Explicit Tools:

agents:
  - id: auditor
    name: Security Auditor
    role: reviewer # Base policy
    tools: [read, web_search] # Override: only these tools allowed
    description: Security-focused reviewer

⚠️ Security Note: Denied tools always take precedence over allowed tools. Even if * is allowed, explicitly denied tools are blocked.


Session Management

Why Fresh Sessions Matter

Problem: Context window bloat. When agents reuse the same session across multiple steps, the conversation history grows unbounded, leading to:

  • Slower response times
  • Higher token costs
  • Context window overflow errors
  • Agents confusing outputs from different steps

Solution: Fresh sessions per step. Each step spawns a new isolated session with only the context it needs.

Context Modes

Minimal Context

What's included:

  • Task metadata (title, description, ID)
  • Workflow-level variables
  • Current step configuration

When to use:

  • Independent steps that don't need history
  • Steps early in the workflow (no previous outputs yet)
  • Steps with large inputs (avoid context bloat)

Example:

- id: scan
  session:
    context: minimal
  input: |
    Scan the codebase for security vulnerabilities.

Full Context

What's included:

  • Task metadata
  • Workflow-level variables
  • All previous step outputs
  • Progress file content

When to use:

  • Steps that need comprehensive history
  • Final steps that synthesize all previous work
  • Debugging workflows (see everything)

Example:

- id: summary
  session:
    context: full
  input: |
    Summarize all the work done in this workflow.

Custom Context

What's included:

  • Task metadata
  • Workflow-level variables
  • Explicit list of step outputs

When to use:

  • Surgical context control (only specific previous steps)
  • Balance between minimal and full
  • Avoid including irrelevant step outputs

Example:

- id: deploy
  session:
    context: custom
    includeOutputsFrom: [build, test] # Only build and test outputs
  input: |
    Deploy the application based on build and test results.

Cleanup Policies

Delete (Production)

Session is terminated immediately after step completes.

Pros:

  • Saves resources (memory, token costs)
  • Prevents orphaned sessions
  • Production-ready default

Cons:

  • Can't inspect session after step completes
session:
  cleanup: delete

Keep (Development)

Session remains open after step completes for manual inspection.

Pros:

  • Useful for debugging
  • Can inspect agent's conversation history
  • Can manually continue the session

Cons:

  • Wastes resources if sessions accumulate
  • Requires manual cleanup
session:
  cleanup: keep

💡 Tip: Use cleanup: delete in production workflows, cleanup: keep only during development.

Timeout Configuration

Each step can override the global session timeout:

config:
  timeout: 7200 # Global: 2 hours

steps:
  - id: quick-task
    session:
      timeout: 300 # Override: 5 minutes for this step

Monitoring & Dashboard

Accessing the Dashboard

  1. Navigate to Workflows tab (header navigation)
  2. Click Dashboard button

Summary Cards

The dashboard displays six key metrics:

Metric Description
Total Workflows Number of workflow definitions
Active Runs Currently executing workflow runs
Completed Runs Successfully finished runs (filterable by period: 24h/7d/30d)
Failed Runs Failed runs (filterable by period)
Avg Duration Average workflow run time
Success Rate Completed / (Completed + Failed) × 100%

Active Runs Table

Real-time list of currently executing workflow runs:

  • Workflow ID — Which workflow is running
  • Status Badge — Running (blue)
  • Started — When the run started
  • Duration — Elapsed time (live updating)
  • Current Step — Which step is executing
  • Progress — Step X/Y with visual progress bar

Click any run to open detailed WorkflowRunView.

Recent Runs History

Last 50 workflow runs with filters:

  • All — Show all runs
  • Completed — Only successful runs
  • Failed — Only failed runs
  • Blocked — Runs awaiting approval
  • Pending — Runs not started yet

Per-Workflow Health Metrics

Success rate and average duration for each workflow:

Workflow Runs Completed Failed Success Rate Avg Duration
feature-dev 25 20 5 80% 30m
security-audit 10 9 1 90% 15m

Visual Indicators:

  • 🟢 Green: Success rate ≥ 80%
  • 🟡 Yellow: Success rate 50-79%
  • 🔴 Red: Success rate < 50%

Real-Time Updates

The dashboard receives live updates via WebSocket:

  • New runs appear instantly when started
  • Step progress updates in real-time
  • Summary metrics refresh on run completion
  • Active runs table updates every 30 seconds

Example Workflows

Feature Development

Complete feature development pipeline: plan → implement → test → review → deploy.

id: feature-dev
name: Feature Development Workflow
version: 1
description: End-to-end feature development pipeline.

config:
  timeout: 7200
  telemetry_tags: ['workflow', 'feature-dev']

agents:
  - id: planner
    name: Planner
    role: planner
    model: github-copilot/claude-opus-4.6
    description: Decomposes tasks into user stories

  - id: developer
    name: Developer
    role: developer
    model: github-copilot/claude-sonnet-4.5
    description: Implements features

  - id: tester
    name: Tester
    role: tester
    model: github-copilot/claude-sonnet-4.5
    description: Validates implementation

variables:
  repo_path: '{{task.git.worktreePath}}'
  base_branch: '{{task.git.baseBranch}}'
  test_command: 'npm test'

steps:
  - id: plan
    name: 'Plan: Decompose into stories'
    type: agent
    agent: planner
    input: |
      Decompose this task into 5-10 implementable user stories.

      TASK: {{task.title}}
      {{task.description}}

      Output YAML format:
      ```yaml
      stories:
        - id: story-1
          title: "..."
          acceptance_criteria: [...]
      ```
    output:
      file: plan.yml
    acceptance_criteria:
      - 'stories:'
      - 'acceptance_criteria'
    on_fail:
      retry: 2
      escalate_to: human
    timeout: 600

  - id: implement
    name: 'Implement: Execute stories'
    type: loop
    agent: developer
    loop:
      over: '{{plan.stories}}'
      item_var: story
      completion: all_done
      fresh_session_per_iteration: true
      max_iterations: 20
    input: |
      Implement this user story.

      STORY {{loop.index + 1}}/{{loop.total}}: {{story.title}}
      {{story.description}}

      ACCEPTANCE CRITERIA:
      {{story.acceptance_criteria}}

      REPO: {{repo_path}}
      TEST_CMD: {{test_command}}

      Instructions:
      1. Implement the feature
      2. Write tests
      3. Run {{test_command}} — tests must pass
      4. Commit changes

      Reply with:
      STATUS: done
      CHANGES: <what was implemented>
    output:
      file: 'implement-{{loop.index}}.md'
    acceptance_criteria:
      - 'STATUS: done'
    on_fail:
      retry: 2
    timeout: 1200

  - id: test
    name: 'Test: Integration validation'
    type: agent
    agent: tester
    input: |
      Run integration tests on the complete feature.

      REPO: {{repo_path}}
      TEST_CMD: {{test_command}}

      Instructions:
      1. Run full test suite
      2. Check for integration issues
      3. Verify end-to-end functionality

      Reply with:
      STATUS: done
      RESULTS: <test outcomes>
      ISSUES: <any bugs, or "none">
    output:
      file: test-results.md
    acceptance_criteria:
      - 'STATUS: done'
    on_fail:
      retry_step: implement
      max_retries: 2

  - id: gate
    name: 'Gate: Quality Check'
    type: gate
    condition: '{{test.status == "completed"}}'
    on_false:
      escalate_to: human
      escalate_message: 'Quality gate failed'

Security Audit

Loop through security findings and fix each issue.

id: security-audit
name: Security Audit & Remediation
version: 1
description: Scan for vulnerabilities, prioritize, and fix issues.

agents:
  - id: scanner
    name: Scanner
    role: planner
    description: Finds security vulnerabilities

  - id: fixer
    name: Fixer
    role: developer
    description: Fixes security issues

  - id: verifier
    name: Verifier
    role: tester
    description: Validates fixes

steps:
  - id: scan
    name: 'Scan: Find vulnerabilities'
    type: agent
    agent: scanner
    input: |
      Perform comprehensive security audit.

      Scan for:
      - SQL injection
      - XSS
      - CSRF
      - Path traversal
      - Secrets in code

      Output YAML:
      ```yaml
      vulnerabilities:
        - id: vuln-001
          severity: critical
          type: sql-injection
          file: server/routes/users.ts
          description: "..."
      ```
    output:
      file: scan-results.yml

  - id: fix
    name: 'Fix: Patch vulnerabilities'
    type: loop
    agent: fixer
    loop:
      over: '{{scan.vulnerabilities}}'
      item_var: vuln
      completion: all_done
      continue_on_error: false
    input: |
      Fix this vulnerability:

      ID: {{vuln.id}}
      SEVERITY: {{vuln.severity}}
      TYPE: {{vuln.type}}
      FILE: {{vuln.file}}

      Implement the fix and write a regression test.
    output:
      file: 'fix-{{loop.index}}.md'

  - id: verify
    name: 'Verify: Validate fixes'
    type: agent
    agent: verifier
    input: |
      Validate all security fixes are effective.
      Try to bypass each fix (adversarial testing).

Code Review

Parallel multi-model review with gate approval.

id: code-review
name: Multi-Model Code Review
version: 1
description: Get reviews from multiple models concurrently.

agents:
  - id: claude
    name: Claude Reviewer
    role: reviewer
    model: github-copilot/claude-opus-4.6

  - id: gpt
    name: GPT Reviewer
    role: reviewer
    model: github-copilot/gpt-5

  - id: gemini
    name: Gemini Reviewer
    role: reviewer
    model: github-copilot/gemini-2.5-pro

steps:
  - id: review
    name: 'Review: Multi-model analysis'
    type: parallel
    parallel:
      completion: all
      fail_fast: false
      steps:
        - id: claude-review
          agent: claude
          input: 'Review this PR for code quality and bugs'
        - id: gpt-review
          agent: gpt
          input: 'Review this PR for security and performance'
        - id: gemini-review
          agent: gemini
          input: 'Review this PR for architecture and design'

  - id: gate
    name: 'Gate: Approval Decision'
    type: gate
    condition: '{{review.failures == 0}}'
    on_false:
      escalate_to: human
      escalate_message: 'One or more reviews flagged issues'

API Quick Reference

Method Endpoint Description
GET /api/workflows List all workflows
GET /api/workflows/:id Get workflow definition
POST /api/workflows Create workflow
PUT /api/workflows/:id Update workflow
DELETE /api/workflows/:id Delete workflow
POST /api/workflows/:id/runs Start workflow run
GET /api/workflow-runs List runs (supports filters)
GET /api/workflow-runs/:id Get run details
GET /api/workflow-runs/active Get active runs only
GET /api/workflow-runs/stats Get aggregated stats
POST /api/workflow-runs/:id/resume Resume blocked run
POST /api/workflow-runs/:runId/steps/:stepId/approve Approve gate step
POST /api/workflow-runs/:runId/steps/:stepId/reject Reject gate step
GET /api/workflow-runs/:runId/steps/:stepId/status Get step status
GET /api/tool-policies List tool policies
GET /api/tool-policies/:role Get policy for role
POST /api/tool-policies Create custom policy
PUT /api/tool-policies/:role Update policy
DELETE /api/tool-policies/:role Delete custom policy

Full API documentation: See API-WORKFLOWS.md


Troubleshooting

Common Errors

Error: "Workflow must define at least one agent"

Cause: Missing agents section in YAML.

Fix:

agents:
  - id: developer
    name: Developer
    role: developer
    description: Implements features

Error: "Step references unknown agent"

Cause: Step's agent field references an agent ID that doesn't exist.

Fix: Ensure agent is defined in agents section:

agents:
  - id: developer
    ...

steps:
  - id: implement
    agent: developer  # Must match an agent.id

Error: "retry_step references unknown step"

Cause: on_fail.retry_step references a step ID that doesn't exist.

Fix: Ensure referenced step exists:

steps:
  - id: implement
    ...
  - id: test
    on_fail:
      retry_step: implement  # Must match a step.id

Error: "Run not blocked (current status: running)"

Cause: Attempting to resume a workflow that's not in blocked status.

Fix: Only resume runs with status blocked (workflows waiting for gate approval or human escalation).

Debug Logging

Enable detailed workflow execution logs:

Server logs (stdout):

# Look for workflow-related log entries
tail -f server.log | grep workflow

Run state files:

# View run state
cat .veritas-kanban/workflow-runs/run_20260209_abc123/run.json

# View step outputs
ls -la .veritas-kanban/workflow-runs/run_20260209_abc123/step-outputs/

Progress file:

# View step-by-step progress
cat .veritas-kanban/workflow-runs/run_20260209_abc123/progress.md

Run State Recovery

If the server crashes mid-workflow, runs can be recovered:

  1. Find orphaned runs:

    ls -la .veritas-kanban/workflow-runs/
    # Look for runs with status "running"
    
  2. Inspect run state:

    cat .veritas-kanban/workflow-runs/run_XYZ/run.json
    
  3. Resume manually (if blocked):

    curl -X POST http://localhost:3001/api/workflow-runs/run_XYZ/resume
    

Automatic transient-failure recovery is persisted on the step as runRetry. Scheduled retry and fallback timers are restored after server restart. Cancel an exact pending workflow recovery with:

curl -X POST http://localhost:3001/api/workflows/runs/run_XYZ/recovery/cancel \
  -H 'Content-Type: application/json' \
  -d '{"stepId":"implement","parentRunId":"run_XYZ:implement:0"}'

Only explicitly transient failures retry automatically. Policy and configuration failures do not retry, while fallback agents must pass the same runtime capability and sandbox preflight as a normal workflow launch.

Performance Issues

Slow workflow execution

Possible causes:

  • Large progress files (>10MB)
  • Too many step outputs in context
  • Network issues with OpenClaw API

Solutions:

  1. Use session.context: minimal for independent steps
  2. Limit includeOutputsFrom to only necessary steps
  3. Check OpenClaw server health

High token costs

Possible causes:

  • Using session.context: full on all steps
  • Reusing sessions across many steps (context bloat)

Solutions:

  1. Use session.mode: fresh (default)
  2. Use session.context: minimal or custom
  3. Monitor token usage in dashboard

Getting Help


End of User Guide