// docs / sop authoring

SOP Authoring

A Standard Operating Procedure (SOP) is a YAML file that tells adoe how to respond to a class of alerts. The AI decision engine matches incoming alerts to SOPs, checks their preconditions, and — when confidence is high — executes the actions automatically.

← back to docs

Anatomy of an SOP

SOPs live as YAML files in the sops/ directory and are loaded at startup. Here's a complete example:

name: cpu_high
description: Handle high CPU alerts
alert_types:               # Signals this SOP handles
  - cpu_high
  - cpu_spike
preconditions:             # All must match for this SOP to apply
  - field: env
    operator: in
    value: [prod, staging]
actions:                   # Executed in order
  - type: github_action
    repo: infra
    workflow: restart-service.yml
    inputs:
      service: "{{ service }}"
      env: "{{ env }}"
    timeout: 300
validation:                # Confirm remediation worked
  check_type: metric
  metric: cpu_percent
  condition: "< 80"
  timeout: 180
rollback:
  notify_human: true
  pagerduty_escalate: true
confidence_threshold: 0.85
auto_execute: true         # false = recommend only

Field reference

FieldPurpose
nameUnique SOP identifier.
descriptionHuman-readable summary (also fed to the AI when selecting between SOPs).
alert_typesList of alert signals this SOP handles (matched against alert.signal).
preconditionsConditions that must all match for the SOP to apply.
actionsOrdered list of remediation steps.
validationPost-execution check that confirms the fix worked.
rollbackWhat to do if validation fails (notify / escalate).
confidence_thresholdMinimum AI confidence required to act on this SOP.
auto_executetrue runs actions automatically; false only recommends them.

Preconditions

Each precondition is a field / operator / value triple. Supported operators:

OperatorMeaning
eqfield equals value
nefield does not equal value
infield is one of a list of values
not_infield is not in a list of values
regexfield matches a regular expression

Common fields are service, env, severity, and signal.

Action types

adoe ships four executors. The type field selects which one runs each action.

GitHub Actions

- type: github_action
  repo: org/repo
  workflow: workflow.yml
  inputs:
    key: value

AWS SSM

- type: ssm
  document: AWS-RunShellScript
  parameters:
    commands:
      - "systemctl restart myservice"

Shell

- type: shell
  command: "kubectl rollout restart deployment/{{ service }}"
Safety: the shell executor refuses a configurable set of blocked commands. Prefer scoped, idempotent commands and lean on DRY_RUN=true while iterating.

SSH

- type: ssh
  host: "{{ host }}"
  command: "sudo systemctl restart {{ service }}"

The SSH executor supports direct connections and bastion-host hops.

Templating

Action fields support Jinja2 templating against the normalized alert, so a single SOP can serve many services. Available variables include {{ service }}, {{ env }}, {{ signal }}, {{ severity }}, and others from the alert payload.

Validation & rollback

After actions run, the agent validates the outcome. check_type may be:

If validation fails, the rollback block decides what happens — typically notify_human: true and pagerduty_escalate: true.

Auto-discovery from GitHub & Confluence

Rather than hand-writing every SOP, adoe can read your existing runbooks and generate SOPs with AI. The onboarding wizard offers this as a step, or you can call the API directly:

# Discover from GitHub repos (scans runbook/sop/playbook markdown)
curl -X POST "http://localhost:8000/sops/discover/github?repos=myorg/runbooks&repos=myorg/infra-docs"

# Discover from Confluence spaces (optionally filter by labels)
curl -X POST "http://localhost:8000/sops/discover/confluence?spaces=OPS&labels=runbook"

Discovered SOPs are saved inactive for safety. Review and activate them before they can run:

# List SOPs, review one, then activate it
curl http://localhost:8000/sops
curl http://localhost:8000/sops/{sop_id}/content
curl -X POST http://localhost:8000/sops/{sop_id}/activate
After editing SOP files on disk, reload them without a restart: curl -X POST http://localhost:8000/sops/reload.