---
title: Alerting
description: Declare typed alert policy defaults in createSmithers() and override them per workflow.
---

Use `alertPolicy` when you want a workflow to carry operational alert metadata such as ownership, severity, runbooks, labels, and deterministic reactions.

The API is declarative:

- `createSmithers(..., { alertPolicy })` defines module-level defaults.
- `smithers(..., { alertPolicy })` overrides those defaults for one workflow.
- `deliver` uses logical destination names such as `oncall` or `author`; Smithers does not ship a built-in Slack or PagerDuty client.

## Module Defaults

```tsx
import {
  createSmithers,
  type SmithersAlertPolicy,
} from "smithers-orchestrator";
import { z } from "zod";

const platformAlerts: SmithersAlertPolicy = {
  defaults: {
    owner: "platform",
    severity: "warning",
    runbook: "https://internal/runbooks/smithers-workflows",
    labels: {
      service: "deploy-bot",
      env: "prod",
    },
  },
  reactions: {
    "notify-author": { kind: "deliver", destination: "author" },
    "notify-oncall": { kind: "deliver", destination: "oncall" },
  },
};

const { Workflow, Task, smithers, outputs } = createSmithers(
  {
    deployResult: z.object({
      ok: z.boolean(),
      revision: z.string(),
    }),
  },
  {
    alertPolicy: platformAlerts,
  },
);
```

## Workflow Overrides

```tsx
export default smithers(
  () => (
    <Workflow name="deploy">
      <Task id="deploy" output={outputs.deployResult} agent={deployAgent}>
        Deploy the release and report the final revision.
      </Task>
    </Workflow>
  ),
  {
    alertPolicy: {
      rules: {
        runFailed: {
          severity: "critical",
          reaction: "notify-oncall",
        },
        approvalWaitExceeded: {
          afterMs: 86_400_000,
          reaction: "notify-author",
        },
        tokenBudgetExceeded: {
          severity: "warning",
          reaction: { kind: "pause" },
        },
      },
    },
  },
);
```

The merged policy is stored on `workflow.opts.alertPolicy`.

## Merge Semantics

- `defaults` merge shallowly.
- `defaults.labels` merge by key.
- `rules` merge by rule name, and workflow-level fields win when the same rule appears in both places.
- `reactions` merge by reaction name, and workflow-level definitions replace module-level definitions with the same name.

## Reaction Kinds

| Kind | Use for |
| --- | --- |
| `emit-only` | Record the alert without pausing, cancelling, or external delivery. |
| `pause` | Pause the run for operator intervention. |
| `cancel` | Stop the run when continuing would be unsafe. |
| `open-approval` | Escalate into a human approval step. |
| `deliver` | Send the alert to a logical destination handled by your runtime integration. |

You can reference a named reaction from `rules` or inline a reaction object directly.

## Recommended Usage

- Use alert policy for operational conditions such as failed runs, approval timeouts, or budget breaches.
- Keep destinations logical and stable, for example `oncall`, `author`, or `incident-feed`.
- Put transport details in your notifier boundary, not in workflow code.
- Avoid using alert policy for every ordinary business notification.
