Runbook Spec
The full Runbook file format, the page tree, the panel embed forms, and apply validation.
A Runbook is a resource with three top-level keys, validated on everr apply and again on read.
kind: Runbook
metadata:
name: <slug>
project: <project> # optional
spec:
{ ... }| Key | Type | Notes |
|---|---|---|
kind | "Runbook" | Selects the reconciler. Required. The legacy "Notebook" is accepted as an alias. |
metadata.name | string | The runbook's slug and identity. Required, non-empty. |
metadata.project | string | Optional namespace; defaults to default. Identity and URL are project + slug. |
spec | object | The runbook contents, below. |
spec
| Field | Type | Required | Notes |
|---|---|---|---|
markdown | object | yes | The index page: the front page, and the whole runbook when there are no pages. See below. |
pages | [Page] | no | Child pages; recursive. See below. |
display | object | no | name and/or description, both optional. Human-facing labels. |
variables | [Variable] | no | Dashboard variables, verbatim. $name tokens interpolate into panel queries server-side. |
panels | map | no | Shared dashboard Panels keyed by name, referenced from markdown with ref:. |
duration | string | no | Seeds the time-range picker, same as dashboards (e.g. 6h, 24h). |
refreshInterval | string | no | Seeds auto-refresh (e.g. 1m). |
Unknown keys in spec and in each page are rejected: a misspelled field is an apply error, not silently ignored content.
markdown
markdown:
file: ./high-error-rate.runbook.md| Field | Type | Notes |
|---|---|---|
file | string | Path to a markdown file, resolved relative to the YAML. Must stay inside the apply directory. The CLI inlines the content at apply time; a missing file fails the apply. |
inline | string | Raw markdown content. This is what the server stores; prefer file: in authored YAML and let the CLI inline it. |
Pages
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | yes | The page slug, unique among its siblings. Page names join into the URL: /runbooks/<project>/<slug>/triage/network. |
markdown | object | yes | The page body, same shape as spec.markdown. |
display | object | no | name and/or description. |
pages | [Page] | no | Nested children; pages nest arbitrarily deep. |
Linking between pages
Link by relative markdown path or by page path; the viewer rewrites both into in-app navigation.
See [Triage](./triage/index.runbook.md) first, then [Network](triage/network).Absolute (/...) and external (http(s):, mailto:) URLs are left untouched.
Panel blocks
A fenced panel block embeds a visualization. The body is YAML in one of two forms, discriminated by shape, each with an optional top-level height: in pixels (80 to 2000, default 350).
Inline one-off panel — a full kind: Panel object, defined inline:
```panel
kind: Panel
height: 280
spec:
display: { name: Error rate }
plugin: { kind: TimeSeriesChart, spec: { unit: "%", showLegend: true } }
queries:
- kind: ClickHouseSQL
spec:
plugin:
kind: ClickHouseSQL
spec:
query: |
SELECT toStartOfInterval(Timestamp, INTERVAL {step:UInt32} SECOND) AS ts,
countIf(StatusCode = 'Error') / count() * 100 AS error_pct
FROM traces
WHERE Timestamp >= {from:String} AND Timestamp <= {to:String}
GROUP BY ts ORDER BY ts
```Reference to a shared panel, declared once under spec.panels and reusable from any page:
spec:
panels:
error-rate:
kind: Panel
spec: { ... } # exactly a dashboard Panel spec```panel
ref: error-rate
height: 200
```A panel inside a runbook is a dashboard Panel, byte for byte: same plugins, same ClickHouse SQL, same {from:String}, {to:String}, and {step:UInt32} time parameters, and $name tokens from spec.variables (the dashboard variable schema, verbatim).
Manifest
Runbooks reconcile through the same apply tree as dashboards and alerts:
# everr/everr.yaml
repoid: "2f8e3f90-9d1c-5d5f-a0f9-2d8e7f4a25d1"Declarations sit flat in everr/ as *.runbook.yaml (the legacy *.notebook.yaml suffix is still recognized; apply routes by the kind: field). everr apply ./everr makes the live runbooks for that repoid exactly match the tree, delete-by-default. Use --preview to review first without touching the live state. See the everr apply reference.
Constraints and errors
spec.markdownis required. There is no implicit "first page is the default."- Page
names must be unique among siblings; duplicates fail the apply. - Unknown keys in
specor in a page are rejected. markdown.filemust resolve inside the apply directory; a missing file fails the apply, naming both the YAML and the markdown path.- Malformed
panelfence YAML, aref:to a missing shared panel, and invalid panel or visualization options fail the apply. Panel specs are validated against the visualization registry, exactly like dashboard panels. - An alert's
spec.runbooklink is validated on apply: it must resolve to a runbook in the same apply batch or one already stored. See Link alerts to runbooks.