Skip to main content
This cookbook shows the complete flow of an incident on the ChatCLI AIOps platform — from automatic detection to the post-mortem with lessons learned. Names, timestamps and values below are illustrative; the object names follow the patterns the operator actually uses.
The walkthrough assumes an operator installed with the Helm chart in chatcli-system, one ready Instance with the watcher enabled (the AIOps pipeline talks to the first ready Instance in the cluster, so run one per cluster), an ApprovalPolicy that requires approval for this change, and a NotificationPolicy that routes the Issue to Slack. Anomalies, Issues, AIInsights, RemediationPlans, ApprovalRequests and PostMortems are created in the workload’s namespace (production here), not in the operator namespace.

Anatomy of an Incident

Scenario: OOMKill in Production

1. Automatic Detection

The Watcher detects that payment-service pods are being OOMKilled:

2. Issue Created

The CorrelationEngine groups the uncorrelated anomalies of the same resource from the last 10 minutes into one Issue. The risk score is the sum of the signal weights (oom_kill 40 + memory_high 15 = 55), and an Issue opened by an oom_kill anomaly is always critical:
The incident ID INC-YYYYMMDD-NNN is a label (a per-namespace, per-day sequence); the Issue name is <resource>-<signal>-<unix time>.

3. Notification Sent

The NotificationReconciler matches the Issue against your NotificationPolicies and sends it to their channels (Slack, PagerDuty, Opsgenie, email, webhook or Teams). Channels, routing, throttling and escalation are covered in Notifications. Without a NotificationPolicy nothing is sent.

4. AI Analyzes the Problem

The IssueReconciler turns the suggested actions into a Runbook (auto-oom-kill-critical-deployment-<hash>) unless a matching Runbook already exists, and creates the RemediationPlan payment-service-oom-kill-1773933601-plan-1.

5. Approval Required

Before executing, the RemediationReconciler checks the ApprovalPolicies. Here a policy requires approval for resource changes in production, so the plan waits in WaitingApproval:
With no ApprovalPolicy matching, the plan could still be parked: by the cluster tier (when CHATCLI_OPERATOR_CLUSTER_NAME points at a ClusterRegistration whose tier requires it) or by the opt-in decision engine, which never runs a critical Issue unattended. Those requests use the synthetic policies cluster-tier and decision-engine: one approver, 30-minute timeout.
Option A — Approve via kubectl:
The value is approver:reason. The operator appends it to status.decisions and removes the annotation; a quorum rule needs one annotation per approver until requiredApprovers is reached. Use platform.chatcli.io/reject to reject. Option B — Approve via Web Dashboard: Port-forward the operator Service (kubectl -n chatcli-system port-forward svc/chatcli-operator 8090:8090), open http://localhost:8090, enter an API key with the operator role, then Approvals, type your name, and Approve. Option C — Approve via REST API:
All three options record a decision in status.decisions; the operator then applies the rule (quorum, change window) and moves the request to Approved or Rejected. The dashboard and REST calls store the approver as <name> (api-key: <identity>) and count each API key once toward a quorum, so each approver needs their own key. A request that is no longer pending, or that the same key already decided, answers 409.

6. Remediation Executed

After approval, the RemediationReconciler executes:
The controller does:
  1. Captures a structured ResourceSnapshot (replicas, images, CPU/memory requests+limits, HPA min/max)
  2. Creates an ActionCheckpoint before each action
  3. Applies AdjustResources (memory 512Mi -> 1Gi)
  4. Verifies deployment health for up to 90s
  5. Healthy (readyReplicas >= desired) -> Completed
Automatic protection: If the action fails (e.g., invalid memory_limit), the operator automatically restores the resource to the snapshot state (replicas, images, resources). The plan transitions to RolledBack instead of Failed. If the verification expires (90s without health), the rollback is also executed. The postFailureHealthy field confirms whether the resource returned to normal. A failed or rolled-back plan sends the Issue back to AI re-analysis with the failure evidence, until maxRemediationAttempts is reached and the Issue escalates.

7. Issue Resolved

  • The NotificationPolicy sends the resolution to Slack
  • The Pattern Store (ConfigMap chatcli-pattern-store in production) records a success for oom_kill + Deployment + critical
  • The watcher dedup entries for the resource are cleared, and new anomalies on the same resource are suppressed for the resolution cooldown (10 minutes by default, Instance spec.aiops.resolutionCooldownMinutes; 0 turns it off)

8. Automatic PostMortem

Every completed plan produces a PostMortem named pm-<issue>:
The timeline opens with a detected event (the Issue description), has one event per plan action, action_executed when it succeeded and action_failed when it failed (for agentic plans, a step whose observation failed) and closes with resolved (the plan result).

9. Review and Close

Both endpoints need the operator role; the body (reviewer, notes) is optional. Pass the namespace: without ?namespace= these PostMortem endpoints look in default.
If the remediation only contained the problem (Issue Contained, PostMortem requiresHumanAction: true), acknowledge the follow-up first with POST /api/v1/postmortems/{name}/ack-human-action: a PostMortem closed without that acknowledgement is reverted to Open.

Day-to-Day Operations

Monitor via CLI

Monitor via API

The REST API allows 600 requests per minute per valid API key (30 per minute per client host without one); scripts that poll should stay under that.

Custom Runbooks

Runbooks match on severity + resource kind (and signal type, preferred when it matches). The operator searches Runbooks in every namespace, so a Runbook applies to matching Issues cluster-wide.

Important Metrics

Configure alerts in Prometheus/Grafana for these metrics. The dashboard JSON files in deploy/grafana/ include panels for them; the dashboards-configmap.yaml there holds only the ServiceMonitors, and its header comment has the exact commands that build the ConfigMap from the four files (one --from-file per JSON file, then the grafana_dashboard=1 label), or import the JSON files manually.