# How buzz-workflow Enables YAML-as-Code Automation in Buzz

> Learn how buzz-workflow enables YAML-as-code automation in Buzz. Execute YAML workflows as immutable Nostr events with conditional logic and webhooks.

- Repository: [Block Open Source/buzz](https://github.com/block/buzz)
- Tags: how-to-guide
- Published: 2026-08-27

---

**buzz-workflow treats YAML workflow definitions as immutable Nostr events (kind 30620), executing them through the Buzz relay with support for conditional logic, external webhooks, and tracked runs (kind 46020).**

The `block/buzz` repository implements a Nostr-native messaging platform where automation logic lives as first-class events. The **buzz-workflow** crate provides the **YAML-as-code automation** layer, allowing developers to define complex business logic in declarative YAML files while the engine handles execution, state tracking, and conditional branching using the `evalexpr` crate.

## YAML-as-Code Architecture and Event Model

### Workflow Definitions as Nostr Events (Kind 30620)

In [`crates/buzz-workflow/src/lib.rs`](https://github.com/block/buzz/blob/main/crates/buzz-workflow/src/lib.rs), the engine parses YAML workflow definitions into strongly-typed Rust structures. These definitions are stored on the relay as Nostr events of **kind 30620**, created using the `build_workflow_definition` helper found in [`desktop/src-tauri/src/events/workflows.rs`](https://github.com/block/buzz/blob/main/desktop/src-tauri/src/events/workflows.rs). Each workflow event contains:

- A unique identifier in the `d` tag
- A channel reference in the `h` tag
- A YAML-encoded body describing the action sequence

### Transient Run Events (Kind 46020)

When triggered, the relay creates a run event of **kind 46020** that references the parent workflow ID. The `get_workflow_runs` command in [`desktop/src-tauri/src/commands/workflows.rs`](https://github.com/block/buzz/blob/main/desktop/src-tauri/src/commands/workflows.rs) exposes this metadata for UI consumption, enabling real-time monitoring of automation execution.

## Declarative YAML Structure

Workflow files define sequences of actions such as `CallWebhook`, `SendMessage`, and `Delay`. According to the architecture outlined in [`ARCHITECTURE.md`](https://github.com/block/buzz/blob/main/ARCHITECTURE.md), each step supports optional `evalexpr` condition expressions that gate execution based on event fields, secrets, or runtime variables.

## Conditional Execution with evalexpr

The engine evaluates boolean expressions at each step using the **evalexpr** crate. Conditions can reference the triggering event's properties, allowing workflows to branch logic without imperative code. This evaluation happens within [`crates/buzz-workflow/src/lib.rs`](https://github.com/block/buzz/blob/main/crates/buzz-workflow/src/lib.rs) before executing any action.

## Core Actions and Capabilities

The workflow engine supports several action types:

- **CallWebhook**: Invokes external HTTP endpoints with optional secret authentication
- **SendMessage**: Emits new Nostr events into the channel
- **Delay**: Suspends execution for a specified duration

## Relay Integration and Architectural Isolation

The relay integrates the workflow engine through [`crates/buzz-relay/src/handlers/side_effects.rs`](https://github.com/block/buzz/blob/main/crates/buzz-relay/src/handlers/side_effects.rs). Notably, **buzz-workflow** maintains strict architectural isolation—it does not import `buzz-pubsub` or `buzz-search` directly. All coordination flows through the relay, preserving the single source of truth principle documented in [`ARCHITECTURE.md`](https://github.com/block/buzz/blob/main/ARCHITECTURE.md).

## Implementation Examples

```yaml

# examples/workflow.yaml

id: "c1d2e3f4-5678-90ab-cdef-1234567890ab"
channel: "general"
steps:
  - name: "Notify webhook"
    action: CallWebhook
    url: "https://example.com/notify"
    method: POST
    body: |
      {
        "channel": "{{channel}}",
        "message": "A new event arrived"
      }
    condition: "event.kind == 40002"
  - name: "Delay"
    action: Delay
    seconds: 10
  - name: "Post reply"
    action: SendMessage
    content: "Automation completed"
    condition: "event.tags.contains('important')"

```

```rust
// Creating a workflow definition event (Rust)
use buzz_cli::events::workflows::build_workflow_definition;

let yaml = std::fs::read_to_string("examples/workflow.yaml")?;
let event = build_workflow_definition(
    "c1d2e3f4-5678-90ab-cdef-1234567890ab",
    "general",
    &yaml,
    None,          // optional secret for webhook auth
    false,         // not a draft
)?;

```

```rust
// Triggering a workflow run from the client
use buzz_cli::commands::workflows::trigger_workflow;

let run = trigger_workflow("c1d2e3f4-5678-90ab-cdef-1234567890ab").await?;
println!("Run created: {}", run.run_id);

```

## Summary

- **buzz-workflow** implements **YAML-as-code automation** by treating workflow definitions as Nostr events (kind 30620) and runs as kind 46020
- The engine lives in [`crates/buzz-workflow/src/lib.rs`](https://github.com/block/buzz/blob/main/crates/buzz-workflow/src/lib.rs) and evaluates conditions using the `evalexpr` crate
- Actions include webhooks, message sending, and delays, with execution tracked via the relay's side-effects handler
- Workflows are immutable, versioned, and deletable through standard Nostr mechanisms (NIP-09)

## Frequently Asked Questions

### What is buzz-workflow?

**buzz-workflow** is the automation engine in the Buzz platform that enables **YAML-as-code** workflow definitions. It parses YAML files into executable sequences of actions, stores them as Nostr events, and manages their execution lifecycle through the Buzz relay.

### How are workflows triggered in Buzz?

Workflows are triggered by Nostr events that match defined criteria. When triggered, the relay creates a run event (kind 46020) referencing the workflow definition (kind 30620). The `trigger_workflow` function in [`desktop/src-tauri/src/commands/workflows.rs`](https://github.com/block/buzz/blob/main/desktop/src-tauri/src/commands/workflows.rs) initiates this process programmatically.

### What event kinds does buzz-workflow use?

The system uses **kind 30620** for workflow definitions and **kind 46020** for transient run instances. **Kind 5** (NIP-09) handles signed deletions. These conventions allow workflows to benefit from Nostr's existing authenticity and fan-out mechanisms.

### How does conditional execution work?

Each workflow step can include an `evalexpr` boolean expression evaluated at runtime by the engine in [`crates/buzz-workflow/src/lib.rs`](https://github.com/block/buzz/blob/main/crates/buzz-workflow/src/lib.rs). These expressions can reference the triggering event's fields, secrets, and variables, allowing dynamic branching without modifying the core YAML structure.