This page documents the 11 built-in step types provided by the Spec Kit Workflow System. Workflows are multi-step, resumable automation pipelines defined in YAML. The workflow engine loads a definition, resolves inputs, and dispatches steps through a centralized STEP_REGISTRY mapping type_key strings to StepBase implementations src/specify_cli/workflows/engine.py113-121
Each step implements an execute() method that receives a StepContext containing workflow inputs and results from previous steps src/specify_cli/workflows/base.py112-127 Results are returned as a StepResult object which can include status, output data, and nested steps for control flow src/specify_cli/workflows/base.py79-92
The following diagram bridges high-level workflow concepts to the specific Python classes and methods that handle them.
Workflow Execution Bridge
Sources: src/specify_cli/workflows/base.py40-129 src/specify_cli/workflows/engine.py37-97 src/specify_cli/workflows/expressions.py126-146 workflows/ARCHITECTURE.md11-46
Invokes an installed Spec Kit command (e.g., speckit.specify) via an integration CLI. This is the primary step type for SDD automation workflows/README.md83-94 It resolves the integration and model from the context if not explicitly provided.
YAML Syntax:
Technical Detail: The step ensures the integration CLI is dispatched via the integration's execution logic. It is registered in the STEP_REGISTRY with the key command tests/test_workflows.py105-109
Sends an arbitrary natural language prompt to the integration CLI without needing a pre-defined command file workflows/README.md96-105
YAML Syntax:
Executes a system shell command and captures output, including exit code, stdout, and stderr. It supports an opt-in output_format: json to parse stdout into structured data workflows/README.md107-115
YAML Syntax:
An interactive human review point. In a TTY environment, it prompts the user; in non-interactive environments (CI), it returns StepStatus.PAUSED so it can be resumed later src/specify_cli/workflows/steps/gate/__init__.py23-30
YAML Syntax:
Technical Detail: The on_reject field controls the workflow's reaction to a negative user response. abort results in StepStatus.FAILED, while retry returns StepStatus.PAUSED to allow re-execution src/specify_cli/workflows/steps/gate/__init__.py76-90 It can also display file contents via show_file src/specify_cli/workflows/steps/gate/__init__.py46-54
Provides conditional branching based on an expression. It evaluates a condition and returns either the then or else branch as next_steps workflows/README.md147-163
YAML Syntax:
Multi-branch dispatch based on an expression value workflows/README.md165-185
YAML Syntax:
Repeats nested steps while a condition is truthy, evaluating the condition before each iteration src/specify_cli/workflows/steps/while_loop/__init__.py12-17 Supports a max_iterations safety cap (defaults to 10) src/specify_cli/workflows/steps/while_loop/__init__.py23-26
YAML Syntax:
Similar to while, but executes the body at least once before checking the condition src/specify_cli/workflows/steps/do_while/__init__.py11-19
Dispatches a step template for every item in a collection src/specify_cli/workflows/steps/fan_out/__init__.py12-18 It sets context.item for each iteration src/specify_cli/workflows/base.py56-57
YAML Syntax:
Sources: src/specify_cli/workflows/steps/fan_out/__init__.py11-55 workflows/README.md215-227
Aggregates results from a preceding fan-out step workflows/README.md229-238 It receives the fan_in data in its context src/specify_cli/workflows/base.py59-60
Bootstraps a project equivalent to running specify init. It scaffolds templates, scripts, and agent integrations workflows/README.md117-133
YAML Syntax:
Spec Kit uses a custom expression evaluator for workflow templates, providing a safe Jinja2-like subset for dynamic configuration src/specify_cli/workflows/expressions.py1-6
The evaluator builds a namespace from the StepContext, allowing steps to access inputs, previous step results, and loop items src/specify_cli/workflows/expressions.py126-146
Data Flow: Expression Namespace
Sources: src/specify_cli/workflows/expressions.py126-146 src/specify_cli/workflows/base.py40-75
| Feature | Syntax | Example |
|---|---|---|
| Variable access | {{ inputs.name }} | Dot-path traversal |
| Step outputs | {{ steps.id.output.key }} | Access results from id |
| Context variables | {{ context.run_id }} | Global run identifier src/specify_cli/workflows/expressions.py144-145 |
| Comparisons | ==, !=, >, <, in | {{ status == 'active' }} |
| Filters | | | {{ list | join(', ') }} |
Built-in Filters:
default(value, default_val): Returns default_val if value is None or empty string src/specify_cli/workflows/expressions.py30-34join(list, sep): Joins a list into a string src/specify_cli/workflows/expressions.py37-41map(list, attr): Maps a list of dicts to a specific attribute, supporting dot notation src/specify_cli/workflows/expressions.py44-63contains(value, sub): Checks for existence in string or list src/specify_cli/workflows/expressions.py66-72from_json: Parses a JSON string into a typed value; raises ValueError on failure src/specify_cli/workflows/expressions.py75-89Sources: src/specify_cli/workflows/expressions.py19-89 src/specify_cli/workflows/expressions.py97-123 src/specify_cli/workflows/expressions.py149-183
Refresh this wiki