Your First Workflow¶
A workflow is a directed acyclic graph (DAG) of steps, where each step delegates a task to an agent. Workflows let you compose agents into multi-step pipelines with dependency ordering, conditional branching, and data passing between steps.
This tutorial creates a two-agent analysis pipeline that demonstrates the core workflow primitives: sequential steps, dependsOn, and inputFrom.
Prerequisites¶
- Purko installed and the operator running (Installation)
kubectlandpurkoctlconfigured- Port-forward running:
kubectl port-forward -n purko-system deploy/purko-operator 8082:8082
Step 1 — Create the agents¶
Workflows reference existing agents by name. Create two agents first:
# agents.yaml
apiVersion: purko.io/v1alpha1
kind: Agent
metadata:
name: analyzer
namespace: ai-agents
spec:
model:
provider: anthropic
name: claude-sonnet-4-20250514
role: "code-analyzer"
autonomyLevel: supervised
---
apiVersion: purko.io/v1alpha1
kind: Agent
metadata:
name: reporter
namespace: ai-agents
spec:
model:
provider: openai
name: gpt-4o-mini
role: "report-writer"
autonomyLevel: supervised
Verify both are Ready before proceeding:
Step 2 — Create the workflow¶
# analysis-pipeline.yaml
apiVersion: purko.io/v1alpha1
kind: Workflow
metadata:
name: analysis-pipeline
namespace: ai-agents
spec:
description: "Analyze code, then generate a report"
steps:
- name: analyze
agentRef:
name: analyzer
description: "Run code analysis"
output:
key: analysis_results
retryPolicy:
maxRetries: 2
backoff: "10s"
- name: report
agentRef:
name: reporter
description: "Generate report from analysis"
dependsOn:
- analyze
inputFrom:
- step: analyze
outputKey: analysis_results
failureStrategy: failFast
parallelism: 1
Field-by-field explanation¶
spec.description¶
Human-readable description displayed in the dashboard and in purkoctl workflow list.
spec.steps¶
The ordered list of steps. Each step is one node in the DAG. Steps run in dependency order; steps without dependsOn can run immediately.
steps[].agentRef¶
Points to an existing Agent CR in the same namespace. The workflow controller verifies the agent exists and is Ready before dispatching the step.
To reference an agent in a different namespace:
steps[].output¶
The key under which the step's output is stored. Subsequent steps reference this key via inputFrom. Supported formats: json (default), text, binary.
steps[].retryPolicy¶
If the step fails, the controller retries up to maxRetries times, waiting backoff between attempts. Set maxRetries: 0 to disable retries.
steps[].dependsOn¶
Lists steps that must complete successfully before this step begins. The controller builds a dependency graph from these declarations — cycles are rejected at admission time by the validating webhook.
steps[].inputFrom¶
Passes the output of a previous step as input to this step. The executor resolves analysis_results from the analyze step's output and makes it available to the reporter agent.
spec.failureStrategy¶
What to do when a step fails:
| Value | Behavior |
|---|---|
failFast |
Cancel remaining steps, mark workflow Failed |
continueOnError |
Continue remaining steps, mark workflow Failed at the end |
rollback |
Cancel remaining steps, run rollback hooks |
spec.parallelism¶
Maximum number of steps to run concurrently. Set to a higher number to allow independent steps (those without a shared dependsOn path) to run in parallel.
Trigger the workflow¶
Apply the YAML to create (and queue) the workflow:
If the workflow is already created and you want to trigger a new run:
To pass parameters at trigger time:
purkoctl workflow trigger analysis-pipeline \
--namespace ai-agents \
--param repository=myorg/myrepo \
--param branch=main
Monitor execution¶
Watch workflow status:
Name: analysis-pipeline
Namespace: ai-agents
Phase: Running
Steps: 2 total, 1 completed, 0 failed
Started: 2026-04-23T09:05:00Z
Steps:
analyze Succeeded started 09:05:01 completed 09:06:00
report Running started 09:06:01
Using kubectl directly:
Wait for completion:
Check per-step status with JSONPath:
kubectl get wf analysis-pipeline -n ai-agents \
-o jsonpath='{range .status.stepStatuses[*]}{.name}: {.phase} (retries: {.retryCount}){"\n"}{end}'
View step outputs¶
This streams the output produced by the analyze step — the text the analyzer agent returned, which was passed as input to the report step.
Raw JSON output
For programmatic use, get step outputs as JSON:
A more realistic example — SDLC pipeline¶
The example at examples/workflows/sdlc/01-feature-development.yaml shows a production workflow with six steps, parameter templates, conditional execution, and step timeouts:
apiVersion: purko.io/v1alpha1
kind: Workflow
metadata:
name: sdlc-feature-development
namespace: ai-agents
labels:
app.kubernetes.io/component: sdlc
purko.io/workflow-type: development
spec:
description: "Full SDLC feature development: requirements → design → implement → test → review → deploy"
parallelism: 2
failureStrategy: failFast
parameters:
repository: "CHANGE_ME/repo-name"
branch: "main"
featureTicket: "PROJ-001"
featureBranch: "feature/PROJ-001"
objective: "Describe the feature to implement"
steps:
- name: analyze-requirements
agentRef:
name: requirements-analyst
input:
raw: '{"task": "Analyze the feature request: ${parameters.objective}. Repository: ${parameters.repository}, branch: ${parameters.branch}. Identify acceptance criteria, dependencies, complexity, and risks. Produce a structured requirements brief.", "repository": "${parameters.repository}", "ticket": "${parameters.featureTicket}"}'
timeout:
timeoutSeconds: 600
- name: design-solution
agentRef:
name: architecture-designer
dependsOn: [analyze-requirements]
condition: 'steps.analyze-requirements.output.feasibility != rejected'
input:
raw: '{"task": "Design the technical solution for: ${parameters.objective}. Repository: ${parameters.repository}. Use the requirements brief from the previous step. Produce component design, API changes, data model updates, and an implementation plan with file paths.", "repository": "${parameters.repository}"}'
timeout:
timeoutSeconds: 900
- name: implement-feature
agentRef:
name: code-generator
dependsOn: [design-solution]
input:
raw: '{"task": "Implement the feature in repository ${parameters.repository}. Create branch ${parameters.featureBranch} from ${parameters.branch}. Follow the architecture design from the previous step. Write clean code following project conventions.", "repository": "${parameters.repository}", "branch": "${parameters.branch}", "featureBranch": "${parameters.featureBranch}"}'
timeout:
timeoutSeconds: 1800
- name: run-tests
agentRef:
name: test-engineer
dependsOn: [implement-feature]
input:
raw: '{"task": "Write and execute tests for the feature implemented in ${parameters.repository} on branch ${parameters.featureBranch}. Validate against acceptance criteria. Report coverage on new code.", "repository": "${parameters.repository}", "branch": "${parameters.featureBranch}"}'
timeout:
timeoutSeconds: 1200
- name: security-scan
agentRef:
name: security-scanner
dependsOn: [implement-feature]
input:
raw: '{"task": "Scan the code changes in ${parameters.repository} on branch ${parameters.featureBranch} for security vulnerabilities, dependency issues, and anti-patterns.", "repository": "${parameters.repository}", "branch": "${parameters.featureBranch}"}'
timeout:
timeoutSeconds: 600
- name: code-review
agentRef:
name: sdlc-code-reviewer
dependsOn: [run-tests, security-scan]
input:
raw: '{"task": "Review the code changes in ${parameters.repository} on branch ${parameters.featureBranch}. Consider test results and security scan findings from previous steps. Evaluate for correctness, quality, and adherence to project standards.", "repository": "${parameters.repository}", "branch": "${parameters.featureBranch}"}'
timeout:
timeoutSeconds: 600
- name: chain-pr-review
agentRef:
name: sdlc-router
dependsOn: [code-review]
condition: 'steps.code-review.output.verdict != request_changes'
input:
raw: '{"task": "Code review passed. Chain to the next SDLC phase by triggering the PR Review pipeline. Use the trigger-workflow tool with workflow=sdlc-pr-review and payload containing repository=${parameters.repository} and branch=${parameters.featureBranch}."}'
timeout:
timeoutSeconds: 60
Key patterns in this example:
spec.parameters— named variables substituted intoinput.rawusing${parameters.name}syntaxparallelism: 2—run-testsandsecurity-scanboth depend onimplement-featureand run in parallelcondition—design-solutionis skipped if requirements analysis returnsfeasibility: rejected;chain-pr-reviewonly runs if code review passestimeout.timeoutSeconds— per-step hard timeout (independent ofretryPolicy)
Trigger rules and webhooks¶
Workflows can be triggered by external events. Add a trigger rule to route GitHub push events to this workflow:
Add:
{"name": "github-push", "source": "github", "match": {"action": "push"}, "workflow": "analysis-pipeline"}
Trigger via webhook:
curl -X POST http://localhost:8082/api/trigger/ai-agents \
-H "Content-Type: application/json" \
-d '{"source": "github", "action": "push", "repository": "myorg/myrepo"}'
Clean up¶
Next steps¶
- Connect MCP Servers — give agents real tools (GitHub, PagerDuty, cluster monitoring)
- Workflows concept page — full API reference including edges, concurrency policies, and schedule triggers
- SDLC Automation guide — the complete SDLC pipeline walkthrough