Workflow Engine
Last updated April 7, 2026
Jobs, steps, triggers, and artifacts.
The workflow engine orchestrates multi-step jobs across plugins. Workflows are declarative, have typed inputs and artifacts, and can run on schedules, webhooks, or be triggered manually. A workflow is the right tool when you need to chain several plugin operations together, run them with dependencies, or run them automatically in response to an event.
This page covers the mental model. For hands-on usage see Guides → Your First Workflow. For the full spec see Workflows → Spec Reference.
What a workflow is
A workflow is a YAML (or JSON) document that describes a graph of jobs, where each job contains an ordered list of steps. Each step calls a plugin handler, an inline shell command, or another workflow.
id: ai-review
name: AI Code Review
version: "1.0.0"
on:
push:
branches: ["main"]
jobs:
review:
steps:
- id: diff
uses: "@kb-labs/commit-plugin/git:diff"
with:
base: ${{ inputs.base }}
- id: analyse
uses: "@kb-labs/ai-review-plugin/review:run"
with:
diff: ${{ steps.diff.outputs.diff }}
- id: comment
uses: "@kb-labs/commit-plugin/github:comment"
with:
body: ${{ steps.analyse.outputs.summary }}A workflow is not a script. You don't write imperative code — you declare what to run, what its inputs are, what its outputs are, and in what order. The workflow daemon resolves the dependency graph and schedules execution.
Workflows vs plugin commands
Both workflows and plugin CLI commands call plugin handler code. The difference is scope and lifecycle:
| Plugin command | Workflow | |
|---|---|---|
| Invocation | pnpm kb <cmd> | kb workflow:run or trigger |
| Coordination | Single handler | Multiple handlers across plugins |
| State | Ephemeral (handler returns) | Persisted (jobs, artifacts, logs) |
| Triggers | Manual only | Manual, push, schedule, webhook |
| Long-running | No (CLI blocks) | Yes (daemon manages lifecycle) |
Use a plugin command for a single-purpose tool. Use a workflow when you need to compose commands, pass artifacts between steps, or run things on a schedule.
Jobs and steps
A workflow contains one or more jobs. Jobs run in parallel by default unless you declare dependencies:
jobs:
build:
steps:
- uses: "@kb-labs/build-plugin/build:run"
test:
needs: [build] # runs after build
steps:
- uses: "@kb-labs/qa-plugin/qa:run"
deploy:
needs: [build, test]
steps:
- uses: "@kb-labs/deploy-plugin/deploy:push"Each step within a job runs sequentially. A step can be:
- Plugin handler —
uses: "@package/group:command"with optionalwith:inputs. - Shell step —
run: |with a multiline shell script (requiresshellpermission). - Workflow call —
uses: "workflow://other-workflow-id"to compose workflows.
Steps can reference outputs from previous steps via ${{ steps.<id>.outputs.<key> }} expressions. The engine evaluates expressions at runtime after the referenced step completes.
Triggers
Workflows can be triggered four ways:
Manual
pnpm kb workflow:run --workflow-id=ai-review --input='{"base":"main"}'Or via the REST API: POST /api/v1/workflows/runs.
Push (git hook)
on:
push:
branches: ["main", "release/*"]
paths: ["src/**"] # optional filterTriggered by the commit plugin's post-commit hook or via a repository webhook routed through the gateway.
Schedule (cron)
on:
schedule:
- cron: "0 9 * * 1-5" # weekdays at 09:00The workflow daemon maintains a cron scheduler. Cron expressions follow standard five-field syntax.
Webhook
on:
webhook:
source: github
events: ["pull_request.opened", "pull_request.synchronize"]Incoming webhooks hit the gateway, which routes them to the REST API's webhook handler. The handler matches the event against registered workflow triggers and enqueues runs.
Artifact passing
Artifacts are structured outputs that steps produce and subsequent steps consume. They're persisted by the workflow daemon so they survive step failures and retries.
steps:
- id: generate
uses: "@kb-labs/mind-plugin/mind:rag-query"
with:
text: "summarize recent changes"
outputs:
summary: ${{ result.answer }}
- id: post
uses: "@kb-labs/notify-plugin/slack:send"
with:
text: ${{ steps.generate.outputs.summary }}Artifacts are stored in the platform's configured storage adapter (IStorage). They're automatically cleaned up after the run retention period (configurable per tenant tier).
Execution targets
By default, workflow steps run using the same execution backend as the invoking host. You can override per-job or per-step:
jobs:
isolated-job:
execution-target:
mode: container # run this job in a Docker container
image: "node:22-slim"
steps:
- uses: "@kb-labs/untrusted-plugin/run:task"This is the same execution model that plugin commands use — in-process, worker-pool, subprocess, or container. Workflows just expose it as a per-job configuration rather than a global platform setting.
See Execution Model for how the backends work.
Running and monitoring
# Start a run
pnpm kb workflow:run --workflow-id=ai-review
# List runs
pnpm kb workflow:list-runs --workflow-id=ai-review
# Tail logs for a run
pnpm kb workflow:logs --run-id=<id> --follow
# Cancel a run
pnpm kb workflow:cancel --run-id=<id>Studio shows all runs in the Workflows section with live step status, artifact contents, and log output.
What to read next
- Guides → Your First Workflow — build and run a real workflow.
- Workflows → Spec Reference — complete YAML schema.
- Workflows → Triggers — detailed trigger configuration.
- Workflows → Artifact Passing — how artifacts are typed, stored, and consumed.
- Execution Model — the backends jobs can run on.