Skip to content

Recipes

Catalog of remediation playbooks. Recipes are the atomic units the agent (or a policy) can execute on a server.

RBAC. Read and execute are open to all authenticated roles. Create, update, and delete are admin-or-above. Tenant admins can only write to recipes they own (tenant_id matches their tenant). superadmin can write to anything, including the global catalogue. A tenant admin cannot modify a global recipe — PATCH /recipes/{slug} returns 403 if the recipe has no tenant_id.

Catalog

Route: /recipes Role gating: read for all; write for admin or superadmin.

Card grid with name, description, incident type, risk level (drives the approval gate), category (diagnostic / remediation), proactive flag, and tags.

Filters

  • Category dropdown (All Categories / Diagnostic / Remediation).
  • Proactive-only checkbox.
  • Free-text search on name and description (client-side).

Actions

  • New Recipe (top button) → /recipes/new.
  • Click a card → recipe detail.
  • Hover reveals a delete button. The server enforces RBAC — attempting to delete a global recipe or another tenant's recipe returns 403.

Create

Route: /recipes/new Role gating: admin (creates a recipe scoped to their tenant); superadmin (creates a global recipe, tenant_id = NULL).

Opens the full Recipe Editor — see Editor below.


Detail

Route: /recipes/{slug} Role gating: read for all.

Read-only view: name, version, risk level, trust level, category, proactive badge, description, incident type, playbook path, variables JSON, prerequisites, pre / post-checks, rollback notes, tags.

The Edit and Delete buttons are always rendered. The server enforces RBAC — admin can only edit/delete their own tenant's recipes; global recipes return 403.

The page does not run recipes directly. Recipes are executed via:

  • a Policy wired to a trigger,
  • the Approve button on an incident's pending execution,
  • the maintenance scheduler.

Editor

Routes: /recipes/new · /recipes/{slug}/edit Role gating: admin (own-tenant recipes); superadmin (any). Global recipes render a read-only banner ("Official recipe — read-only").

The editor is a full-width split view:

  • Left column — CodeMirror YAML editor (syntax highlighting, scrollable, 520 px tall). The playbook is stored as inline playbook_content and displayed directly; no file path lookup needed for new recipes. For existing recipes that have no inline content (older file-based recipes), the editor fetches the content via GET /recipes/{slug}/playbook on mount.
  • Right column — AI Assistant chat panel (360 px wide). See AI Assistant below.

Metadata panel

A collapsible section above the editor exposes every recipe field:

Field Notes
Name Human-readable label. Auto-slugifies on the create form.
Slug Editable while creating; locked after first save.
Risk low / medium / high / critical — drives the approval gate.
Incident type Free text: service_down, disk_full, custom, …
Category diagnostic or remediation (free text).
Description Operator-facing summary.
Tags Comma-separated; stored as an array.
Variables JSON object — keys become Ansible extravars available in the playbook.

Live validation

The editor calls POST /recipes/validate 600 ms after each keystroke (debounced). Validation runs a YAML parse followed by ansible-playbook --syntax-check against the draft content. A "Valid" / "Invalid" badge appears in the toolbar; errors are shown in a red strip below the editor. The Save button is disabled until validation passes (ok: true).

Dry-run Test

The Test (dry-run) button opens a panel that lets you run the current draft playbook against a real server with --check before saving it. No changes are applied to the target.

Workflow:

  1. Click Test (dry-run).
  2. Pick a server from the dropdown (your tenant's servers).
  3. Click Run --check. The editor calls POST /recipes/test, which enqueues an ARQ job.
  4. The editor polls GET /recipes/test/{job_id} every 2 seconds (up to 2 minutes). When the job completes the output appears in a code block beneath the server selector.

The test result shows the full Ansible stdout. A green background means ok: true (all tasks passed the check); a red background means ok: false (at least one task would have failed or changed). The test does not block saving — you can save a recipe that failed a dry-run.

Minimum role to use the Test feature: operator.

Save gate

The Save button requires all of:

  • Name is non-empty.
  • Slug is non-empty (create) or already set (edit).
  • Incident type is non-empty.
  • Playbook editor is non-empty.
  • Live validation has returned ok: true.

AI Assistant

The chat panel beside the editor lets you draft and refine the playbook conversationally.

How it works:

  1. Type a message — e.g. "restart nginx if it's down and check it's listening on port 80 afterwards" or "add a rollback task".
  2. The assistant (streaming response via POST /recipes/assist/chat) replies in natural language. If it wants to propose a concrete edit it emits a Proposed playbook block.
  3. A proposed playbook is shown in a teal card beneath the assistant's reply. Two buttons appear: Apply and Discard.
  4. Apply replaces the editor content with the proposed playbook.
  5. Discard removes the proposal card without touching the editor.
  6. Nothing is applied automatically. The assistant never mutates the editor; every change requires an explicit Apply click.

The assistant is a colleague, not an edit bot. If it is unsure what you want, it will ask a clarifying question rather than guess. The assistant sees the current content of the editor at the start of each message so you can ask follow-up questions ("explain what the second task does") without re-pasting the playbook.

Minimum role to use AI Assist: admin.


Tenant recipes vs global catalogue

Global recipe Tenant recipe
tenant_id NULL UUID of owner tenant
Slug uniqueness Unique globally Unique within tenant
Who can create superadmin admin of any tenant
Who can edit/delete superadmin admin of the owning tenant
Visible to All tenants Only the owning tenant
Editor banner "Official recipe — read-only" (for non-superadmin) Editable

The global catalogue ships with OpenRemedy and is seeded at install time. Tenant admins create their own recipes for bespoke remediation or to extend the catalogue for their environment.