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. Tenantadmins can only write to recipes they own (tenant_idmatches their tenant).superadmincan write to anything, including the global catalogue. A tenant admin cannot modify a global recipe —PATCH /recipes/{slug}returns403if the recipe has notenant_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_contentand 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 viaGET /recipes/{slug}/playbookon 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:
- Click Test (dry-run).
- Pick a server from the dropdown (your tenant's servers).
- Click Run --check. The editor calls
POST /recipes/test, which enqueues an ARQ job. - 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:
- 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".
- 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. - A proposed playbook is shown in a teal card beneath the assistant's reply. Two buttons appear: Apply and Discard.
- Apply replaces the editor content with the proposed playbook.
- Discard removes the proposal card without touching the editor.
- 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.
Related routes¶
policies.md— policies wire triggers to recipesincidents.md— recipes are executed against incidentsmaintenances.md— maintenance plans may invoke recipesrecipes/authoring.md— in-depth authoring guide