35 KiB
Veritas Kanban Workflow Engine — User Guide
Version: v4.0
Last Updated: 2026-02-09
Status: Production Ready
Table of Contents
- Introduction
- Quick Start
- Workflow YAML Format
- Step Configuration
- Tool Policies
- Session Management
- Monitoring & Dashboard
- Example Workflows
- API Quick Reference
- 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
- Open Veritas Kanban in your browser
- Navigate to Workflows tab (header navigation)
- Select the workflow name or View details to inspect its definition before execution
- Select Start Run, review the optional task association and JSON run context, then confirm the run
- 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 successfullyany_done— Stop after first successful iterationfirst_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:
-
Substring Match (default):
acceptance_criteria: - 'STATUS: done' - 'RESULT: success' -
Regex Pattern:
acceptance_criteria: - '/^STATUS:\s*done$/i' - '/ERROR: \d+/' -
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:
-
Same Step Retry — Re-execute the failed step:
on_fail: retry: 3 retry_delay_ms: 5000 -
Different Step Retry — Jump back to an earlier step:
on_fail: retry_step: implement max_retries: 2 -
Escalation — Delegate to another agent or human:
on_fail: escalate_to: human escalate_message: 'Step failed after 3 retries' -
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:
- Open Settings → Tool Policies tab
- Click "New Policy"
- Fill in role name, allowed/denied tools, and description
- 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: deletein production workflows,cleanup: keeponly 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
- Navigate to Workflows tab (header navigation)
- 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:
-
Find orphaned runs:
ls -la .veritas-kanban/workflow-runs/ # Look for runs with status "running" -
Inspect run state:
cat .veritas-kanban/workflow-runs/run_XYZ/run.json -
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:
- Use
session.context: minimalfor independent steps - Limit
includeOutputsFromto only necessary steps - Check OpenClaw server health
High token costs
Possible causes:
- Using
session.context: fullon all steps - Reusing sessions across many steps (context bloat)
Solutions:
- Use
session.mode: fresh(default) - Use
session.context: minimalorcustom - Monitor token usage in dashboard
Getting Help
- GitHub Issues: github.com/BradGroux/veritas-kanban/issues
- Documentation: Check other docs in
/docs/directory - Examples: See
.veritas-kanban/workflows/for working examples
End of User Guide