Skip to content

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

  1. Create workflow files in .kiket/workflows/:
  2. .kiket/workflows/bug.yaml (id: bug)
  3. .kiket/workflows/incident.yaml (id: incident)
  4. .kiket/workflows/main.yaml (id: main)

  5. Map issue types to workflows in .kiket/issue_types.yaml:

    issue_types:
      - key: Bug
        workflow: bug        # Uses bug.yaml
      - key: Incident
        workflow: incident   # Uses incident.yaml
      - key: Task
        # No workflow - uses default (main.yaml)
    

  6. 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:

- type: workflow_call
  target_workflow: nested_workflow
  max_depth: 5  # Stricter limit for this call

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 guards block 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.