Workflow Syntax¶
Workflows define the lifecycle for issues. Each workflow file describes states, transitions, hooks, and actions.
Minimal Workflow¶
model_version: 1.0
workflow:
id: bugfix
name: Bugfix Workflow
version: 1.0.0
states:
backlog:
type: initial
in_progress:
type: active
review:
type: active
done:
type: final
transitions:
- from: backlog
to: in_progress
- from: in_progress
to: review
- from: review
to: done
Workflow Metadata¶
The workflow block contains metadata about the workflow:
workflow:
id: my-workflow # Unique identifier (lowercase, alphanumeric, hyphens/underscores)
name: My Workflow # Display name
version: 1.0.0 # Semantic version
description: | # Optional description
A workflow for tracking work items
override: false # Set to true to override inherited workflows
| Field | Required | Description |
|---|---|---|
id |
Recommended | Unique identifier for multi-workflow support |
name |
Yes | Display name for the workflow |
version |
No | Semantic version (default: 1.0.0) |
description |
No | Human-readable description |
override |
No | Set to true to override inherited workflows |
Note: The id field is required for multi-workflow support. See Issue Types for mapping issue types to specific workflows.
Multi-Workflow Support¶
A project can have multiple workflows, with different issue types using different workflows. This is useful when:
- Bugs need a different lifecycle than features
- Incidents require a specialized response workflow
- Support tickets have different states than development tasks
Setting Up Multiple Workflows¶
- Create workflow files in
.kiket/workflows/: .kiket/workflows/bug.yaml(id:bug).kiket/workflows/incident.yaml(id:incident)-
.kiket/workflows/main.yaml(id:main) -
Map issue types to workflows in
.kiket/issue_types.yaml: -
Each workflow operates independently with its own states and transitions.
See Issue Types for complete documentation on issue type configuration.
States¶
States can be defined as scalars (- backlog) or objects for advanced options:
states:
- backlog:
wip_limit: 999
description: "Unprioritized work"
- in_progress:
wip_limit: 4
auto_assign: true
- review:
require_approval: 1
- done:
on_enter:
- run: close_issue
Supported state attributes:
- wip_limit
- auto_assign
- require_approval
- on_enter / on_exit (array of action references)
- policies (custom key/value pairs consumed by extensions)
Transitions¶
transitions:
- from: backlog
to: in_progress
when:
- field: assignee
operator: present
- from: in_progress
to: review
when:
- field: pull_request.status
operator: equals
value: "open"
on_success:
- run: notify_slack
on_failure:
- run: reopen_issue
when accepts condition arrays (see Language Reference).
- on_success / on_failure run action references.
- auto transitions set auto: true and optional delay: 2h to move items automatically.
Actions & Hooks¶
actions:
notify_slack:
kind: http
url: https://hooks.slack.com/services/...
method: POST
body:
text: "Issue {{ issue.key }} moved to review"
hooks:
on_created:
- run: notify_slack
on_transition:
review:
- run: trigger_ci
Hooks available: on_created, on_updated, on_transition, on_enter_state, on_exit_state, on_due, on_sla_breach.
Workflow Orchestration (workflow_call)¶
The workflow_call action allows one workflow to invoke another as part of a dependency chain. This enables powerful orchestration patterns like: release workflow → deployment workflow → monitoring workflow.
Basic Example: Same Issue Mode¶
Transition the current issue through a different workflow:
transitions:
- from: approved
to: deploying
after:
- type: workflow_call
target_workflow: deployment
target_state: pending
mode: async
input:
approved_by: "${context.user.email}"
release_version: "${issue.custom_fields.version}"
Create Issue Mode¶
Spawn a new issue in another project/workflow:
transitions:
- from: approved
to: deploying
after:
- type: workflow_call
target_workflow: deployment
target_project: INFRA
create_issue: true
issue_template:
title: "Deploy: ${issue.title}"
description: "Deployment triggered from ${issue.key}"
priority: "${issue.priority}"
custom_fields:
source_issue_id: "${issue.id}"
link_type: triggers
mode: async
on_success:
transition_to: deployed
on_failure:
action: notify
recipients: ["ops-team@example.com"]
level: critical
Configuration Reference¶
| Parameter | Required | Description |
|---|---|---|
target_workflow |
Yes | The workflow key to invoke |
target_project |
No | Project key for cross-project calls (default: same project) |
target_state |
No | State to transition to in target workflow |
mode |
No | sync or async (default: async) |
create_issue |
No | Create a new issue instead of transitioning source (default: false) |
issue_template |
If create_issue: true |
Template for creating the new issue |
link_type |
No | Issue link type: parent, child, triggers, blocks, relates |
timeout |
No | Timeout for sync mode (e.g., 30s, 2m) |
max_depth |
No | Override max call chain depth (default: 10) |
input |
No | Data to pass to the target workflow |
on_success |
No | Callback when workflow call succeeds |
on_failure |
No | Callback when workflow call fails |
Variable Interpolation¶
Use ${...} syntax to interpolate values from the source issue and context:
${issue.id}– Issue ID${issue.key}– Issue key (e.g.,PROJ-123)${issue.title}– Issue title${issue.status}– Current status${issue.priority}– Priority level${issue.assignee}– Assignee email${issue.custom_fields.field_name}– Custom field value${context.user.email}– Current user's email${workflow.key}– Source workflow key
Circular Dependency Protection¶
Kiket automatically detects and prevents circular workflow calls. The call chain is tracked and validated before each invocation. If a cycle is detected (e.g., A → B → C → A), the call fails with a descriptive error.
Call Depth Limits¶
By default, workflows can be nested up to 10 levels deep. This prevents runaway chains and ensures predictable behavior. Override with max_depth if needed:
Error Handling¶
Configure callbacks for success and failure scenarios:
- type: workflow_call
target_workflow: deployment
on_success:
transition_to: deployed # Transition source issue on success
on_failure:
action: notify # Send notification on failure
recipients: ["ops-team@example.com"]
level: critical
State Checklists¶
States can define checklists that must be completed before transitioning. By default, checklists block transitions until required items are complete.
states:
in_review:
type: active
checklist:
title: Review Checklist
required: all # all | any | threshold
threshold: 3 # only if required: threshold
items:
# MANUAL: User must explicitly check this
- id: code_reviewed
label: Code has been reviewed
check: manual
assignee_role: team_lead
required: true
# AUTO-CHECK via CONDITION: Checked when condition met
- id: tests_pass
label: All tests passing
check: auto
condition:
field: ci_status
operator: equals
value: passed
# AUTO-CHECK via EVENT: Checked when event received
- id: docs_updated
label: Documentation updated
check: event
event: github.push
event_filter:
ref: refs/heads/main
# AUTO-CHECK via WEBHOOK: External system marks complete
- id: security_scan
label: Security scan passed
check: webhook
webhook_token: ${secrets.SECURITY_SCAN_TOKEN}
on_checklist_complete:
- action: notify
recipients: [${issue.assignee}]
message: "All checklist items complete for ${issue.key}"
Checklist Configuration¶
| Parameter | Required | Description |
|---|---|---|
title |
No | Display title for the checklist |
required |
No | Completion mode: all, any, or threshold (default: all) |
threshold |
If required: threshold |
Minimum number of items required |
blocking |
No | Whether to block transitions (default: true) |
items |
Yes | Array of checklist item definitions |
Checklist Item Types¶
| Check Type | Description |
|---|---|
manual |
User must explicitly check via UI |
auto |
System evaluates condition periodically |
event |
Checked when matching event is received |
webhook |
External system calls webhook endpoint |
Conditional Approval Routing¶
States with approvals can route to different approval chains based on issue field values:
states:
pending_approval:
type: approval
approval_routing:
- name: high_value
condition:
field: custom_fields.estimated_cost
operator: gte
value: 10000
chain:
- level: 1
approvers:
- type: role
role: finance_manager
required: all
- level: 2
approvers:
- type: role
role: cfo
required: all
- name: medium_value
condition:
all:
- field: custom_fields.estimated_cost
operator: gte
value: 1000
- field: custom_fields.estimated_cost
operator: lt
value: 10000
chain:
- level: 1
approvers:
- type: role
role: team_lead
required: all
- name: low_value
condition:
field: custom_fields.estimated_cost
operator: lt
value: 1000
chain:
- level: 1
approvers:
- type: dynamic
identifier: ${issue.reporter.manager}
required: any
default_chain:
- level: 1
approvers:
- type: role
role: admin
required: all
Routes are evaluated in order. The first matching condition's chain is used. If no conditions match, default_chain is used.
Note: If routing-relevant fields change mid-approval, the change is logged but the original chain continues (no re-routing occurs).
Blockchain Anchoring (anchor_data)¶
The anchor_data action records custom data to the blockchain audit trail for compliance purposes.
Requirements:
- Professional+ subscription
- Available only in state hooks (on_enter / on_exit)
states:
approved:
type: final
on_enter:
# Anchor approval decision data
- action: anchor_data
data:
type: approval_decision
issue_key: ${issue.key}
approved_by: ${approval.approvers}
approved_at: ${approval.completed_at}
approval_route: ${approval.route_name}
custom_fields:
deal_value: ${issue.custom_fields.deal_value}
contract_id: ${issue.custom_fields.contract_id}
tags:
- approval
- ${issue.project.key}
# Anchor external compliance data
- action: anchor_data
data:
type: compliance_attestation
standard: SOC2
control: CC6.1
evidence_url: ${webhook.payload.evidence_url}
attested_by: ${webhook.payload.auditor}
attested_at: ${webhook.payload.timestamp}
condition:
field: labels
includes: compliance-critical
Configuration Reference¶
| Parameter | Required | Description |
|---|---|---|
data |
Yes | Custom data payload to anchor (supports interpolation) |
tags |
No | Array of tags for filtering/searching anchored data |
condition |
No | Only anchor if condition is met |
Use Cases¶
- Approval Decisions: Record approval chain decisions with approver signatures
- Compliance Attestations: Record regulatory compliance checkpoints on-chain
- External System Snapshots: Anchor data received from external systems
- Contract Milestones: Immutably record project milestone completions
- Audit Trail Events: Anchor critical workflow state changes
Guards & Policies¶
- Use
guardsblock to centralize transition rules reused across multiple transitions. - Reference feature flags using
when: feature.enabled('beta_approvals').
Namespacing¶
Place workflows in subdirectories to group them (.kiket/workflows/support/triage.yaml). Use the workflow key to set the canonical identifier.
Workflows are version-controlled assets. Update them through pull requests, validate via CI, and let Kiket sync them into the runtime.