Status: Specification frozen for Phase 1. Engine implementation deferred to v0.5.0.
Design principle: Workflow is an independent concept from Skill. A Workflow can be registered as a Skill by wrapping it with an entry_script that calls
devbase workflow run <id>.
Workflow = DAG of Steps
Step = SkillInvocation | SubWorkflow | ControlFlow
Edge = data dependency + condition
A Workflow defines how multiple Skills compose to achieve a higher-level task. It is NOT a Skill itself, but can be materialized as one.
# workflow.yaml
id: code-review-pipeline
name: Automated Code Review
version: 0.1.0
description: |
Runs lint → test → security-scan → review-summary
Fails fast on lint/test errors.
inputs:
- name: repo_path
type: string
required: true
- name: branch
type: string
default: main
outputs:
- name: review_report
type: json
description: Aggregated review results
steps:
- id: lint
skill: rust-clippy
inputs:
path: "${inputs.repo_path}"
on_error: fail
- id: test
skill: cargo-test
inputs:
path: "${inputs.repo_path}"
on_error: fail
- id: security
skill: cargo-audit
inputs:
path: "${inputs.repo_path}"
on_error: continue # don't block on warnings
- id: summary
skill: text-summarizer
depends_on: [lint, test, security]
inputs:
sources:
- "${steps.lint.outputs.stdout}"
- "${steps.test.outputs.stdout}"
- "${steps.security.outputs.stdout}"
on_error: fail
output_mapping:
review_report: "${steps.summary.outputs.result}"| Type | Syntax | Description |
|---|---|---|
skill |
skill: <skill_id> |
Invoke a registered Skill |
subworkflow |
workflow: <workflow_id> |
Embed another Workflow |
parallel |
parallel: [step_list] |
Execute steps concurrently |
condition |
if: "${expr}" |
Conditional branch |
loop |
for_each: "${expr}"body: [step_list] |
Iterate over collection, executing body steps for each item |
${inputs.<name>} → Workflow input
${steps.<id>.outputs.<name>} → Step output
${env.<NAME>} → Environment variable
${config.<key>} → devbase config value
${loop.item} → Current item in loop iteration
${loop.index} → Zero-based index of current loop iteration
on_error |
Behavior |
|---|---|
fail (default) |
Stop workflow, propagate error |
continue |
Log error, proceed to next step |
retry(n) |
Retry up to n times with backoff |
fallback |
Execute fallback step |
A Workflow can be exposed as a Skill by creating:
workflow-skills/
code-review-pipeline/
SKILL.md # Standard SKILL.md with entry_script: scripts/run.py
workflow.yaml # This DSL file
scripts/
run.py # Wrapper: calls `devbase workflow run code-review-pipeline`
The wrapper script is auto-generated by devbase workflow register <workflow.yaml>.
WorkflowEngine
├── Parser (YAML → AST)
├── Validator (cycle detection, skill resolution)
├── Scheduler (topological sort, parallel dispatch)
├── Executor (SkillRuntime integration)
└── StateStore (checkpoint/resume)
CREATE TABLE workflows (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
version TEXT NOT NULL,
description TEXT,
definition_yaml TEXT NOT NULL,
status TEXT DEFAULT 'draft',
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE workflow_executions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
workflow_id TEXT NOT NULL,
inputs_json TEXT,
status TEXT NOT NULL,
current_step TEXT,
started_at TEXT NOT NULL,
finished_at TEXT,
duration_ms INTEGER
);Tables exist in Schema v16 but are not populated until v0.5.0 Engine implementation.