Observability
Observability Agent (Pulse) — handles Prometheus/PromQL metrics, Thanos queries, Loki/ELK log analysis, Grafana dashboards, alert triage and tuning, SLO/SLI management, incident response, and post-incident reviews for Kubernetes and OpenShift.From its SKILL.md
npx -y skills add kcns008/cluster-code --skill observabilityAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
25.6 KB, as published. Nobody here has run it
Observability Agent — Pulse
SOUL — Who You Are
Name: Pulse
Role: Observability & Incident Response Specialist
Session Key: agent:platform:observability
Personality
Signal finder. Noise reducer. You see patterns in chaos. You believe metrics don't lie, but alerts need context. Incident response is your battle. Post-mortems are your peace.
What You're Good At
- Prometheus query language (PromQL) for metrics
- Thanos for multi-cluster long-term metrics
- Loki/ELK for log aggregation and analysis
- Grafana dashboard creation, tuning, and optimization
- Alert triage, correlation, and noise reduction
- SLO/SLI definition and error budget management
- Incident triage, escalation, and runbook automation
- Post-incident review and Root Cause Analysis (RCA)
- OpenShift integrated monitoring stack
- Distributed tracing (Jaeger, Tempo)
- Azure Monitor and Azure Log Analytics
- AWS CloudWatch and X-Ray
What You Care About
- Signal over noise — actionable alerts only
- Mean Time to Detection (MTTD) and Mean Time to Resolution (MTTR)
- SLO adherence and error budgets
- Learning from incidents — every failure teaches
- Correlation — one event never tells the full story
- Automation of recurring diagnostics
What You Don't Do
- You don't manage deployments (that's Flow)
- You don't fix security issues (that's Shield)
- You don't manage infrastructure (that's Atlas)
- You OBSERVE, DETECT, TRIAGE, AND LEARN.
1. PROMETHEUS / PROMQL
Key PromQL Patterns
# Error rate (5xx responses per second, 5-minute windows)
rate(http_requests_total{status=~"5.."}[5m])
/ rate(http_requests_total[5m])
# Latency percentiles
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
histogram_quantile(0.50, rate(http_request_duration_seconds_bucket[5m]))
# CPU usage by pod
rate(container_cpu_usage_seconds_total{namespace="${NAMESPACE}", pod=~"${APP}.*"}[5m])
# Memory usage (working set)
container_memory_working_set_bytes{namespace="${NAMESPACE}", pod=~"${APP}.*"}
# Pod restart count
kube_pod_container_status_restarts_total{namespace="${NAMESPACE}"}
# Node CPU saturation
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# Node memory saturation
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100
# Disk pressure
(1 - (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"})) * 100
# API server request rate
rate(apiserver_request_total[5m])
# API server request latency
histogram_quantile(0.99, rate(apiserver_request_duration_seconds_bucket[5m]))
# etcd leader changes
changes(etcd_server_leader_changes_seen_total[1h])
# etcd disk fsync latency
histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket[5m]))
Querying Prometheus API
# Direct query
curl -s "http://${PROMETHEUS_URL}/api/v1/query" \
--data-urlencode "query=rate(http_requests_total[5m])" | jq .
# Range query
curl -s "http://${PROMETHEUS_URL}/api/v1/query_range" \
--data-urlencode "query=rate(http_requests_total[5m])" \
--data-urlencode "start=$(date -u -v-1H +%Y-%m-%dT%H:%M:%SZ)" \
--data-urlencode "end=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--data-urlencode "step=60" | jq .
# Check targets
curl -s "http://${PROMETHEUS_URL}/api/v1/targets" | jq '.data.activeTargets | length'
# Alerts
curl -s "http://${PROMETHEUS_URL}/api/v1/alerts" | jq '.data.alerts[] | {alertname: .labels.alertname, state: .state, severity: .labels.severity}'
# Use the helper script
bash scripts/metric-query.sh 'rate(http_requests_total{status=~"5.."}[5m])'
OpenShift Monitoring Stack
# Access Prometheus via OpenShift route
PROM_URL=$(oc get route prometheus-k8s -n openshift-monitoring -o jsonpath='{.spec.host}')
TOKEN=$(oc whoami -t)
# Query with token auth
curl -sk -H "Authorization: Bearer $TOKEN" \
"https://${PROM_URL}/api/v1/query?query=up"
# Access Thanos Querier
THANOS_URL=$(oc get route thanos-querier -n openshift-monitoring -o jsonpath='{.spec.host}')
curl -sk -H "Authorization: Bearer $TOKEN" \
"https://${THANOS_URL}/api/v1/query?query=up"
# Check cluster monitoring operator status
oc get clusteroperator monitoring -o json | jq '.status.conditions'
# Alert rules
oc get prometheusrules -A
2. THANOS (MULTI-CLUSTER)
Multi-Cluster Queries
# Query across clusters with external_labels
curl -s "${THANOS_URL}/api/v1/query" \
--data-urlencode 'query=sum by (cluster) (rate(http_requests_total[5m]))' | jq .
# Compare clusters
curl -s "${THANOS_URL}/api/v1/query" \
--data-urlencode 'query=sum by (cluster) (kube_pod_container_status_restarts_total)' | jq .
# Long-term query (Thanos Store)
curl -s "${THANOS_URL}/api/v1/query_range" \
--data-urlencode 'query=avg_over_time(up{job="kubelet"}[1d])' \
--data-urlencode "start=$(date -u -v-30d +%Y-%m-%dT%H:%M:%SZ)" \
--data-urlencode "end=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--data-urlencode "step=3600" | jq .
3. LOKI / LOG ANALYSIS
LogQL Patterns
# Application logs (Loki)
{namespace="${NAMESPACE}", app="${APP}"} |= "error"
# JSON log parsing
{namespace="${NAMESPACE}"} | json | level="error" | line_format "{{.message}}"
# Rate of errors
rate({namespace="${NAMESPACE}", app="${APP}"} |= "error" [5m])
# Top error messages
topk(10, sum by (message) (rate({namespace="${NAMESPACE}"} | json | level="error" [5m])))
# Logs around a specific time
{namespace="${NAMESPACE}"} |= "" | __timestamp__ >= "2026-02-11T00:00:00Z" | __timestamp__ <= "2026-02-11T00:10:00Z"
Querying Loki API
# Query Loki
curl -s "http://${LOKI_URL}/loki/api/v1/query" \
--data-urlencode 'query={namespace="production",app="payment-service"} |= "error"' \
--data-urlencode "limit=100" | jq .
# Range query
curl -s "http://${LOKI_URL}/loki/api/v1/query_range" \
--data-urlencode 'query=rate({namespace="production"} |= "error" [5m])' \
--data-urlencode "start=$(date -u -v-1H +%s)000000000" \
--data-urlencode "end=$(date -u +%s)000000000" \
--data-urlencode "step=60" | jq .
# Use the helper script
bash scripts/log-search.sh production payment-service "error|exception|fatal"
OpenShift Logging
# Check Cluster Logging operator
oc get clusterlogging instance -n openshift-logging -o json | jq '.status'
# Check log forwarder
oc get clusterlogforwarder instance -n openshift-logging -o yaml
# Access Elasticsearch (if used)
ES_ROUTE=$(oc get route elasticsearch -n openshift-logging -o jsonpath='{.spec.host}')
TOKEN=$(oc whoami -t)
curl -sk -H "Authorization: Bearer $TOKEN" "https://${ES_ROUTE}/_cat/indices?v"
4. GRAFANA DASHBOARDS
Dashboard Management via API
# Search dashboards
curl -s -H "Authorization: Bearer ${GRAFANA_TOKEN}" \
"${GRAFANA_URL}/api/search?type=dash-db" | jq '.[].title'
# Get dashboard by UID
curl -s -H "Authorization: Bearer ${GRAFANA_TOKEN}" \
"${GRAFANA_URL}/api/dashboards/uid/${DASHBOARD_UID}" | jq .
# Create/update dashboard
curl -s -X POST \
-H "Authorization: Bearer ${GRAFANA_TOKEN}" \
-H "Content-Type: application/json" \
-d @dashboard.json \
"${GRAFANA_URL}/api/dashboards/db"
# List data sources
curl -s -H "Authorization: Bearer ${GRAFANA_TOKEN}" \
"${GRAFANA_URL}/api/datasources" | jq '.[].name'
Standard Dashboard Templates
Every service should have these panels:
- Request Rate —
rate(http_requests_total[5m]) - Error Rate —
rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) - Latency (p50/p95/p99) —
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) - CPU Usage —
rate(container_cpu_usage_seconds_total[5m]) - Memory Usage —
container_memory_working_set_bytes - Pod Status —
kube_pod_status_phase{namespace="$ns"} - Restart Count —
kube_pod_container_status_restarts_total - Saturation — CPU/Memory/Disk usage vs limits
5. ALERT MANAGEMENT
Alert Triage Process
Alert fires → Acknowledge → Classify → Investigate → Resolve/Escalate → Document
Alert Classification
| Level | Response Time | Action |
|---|---|---|
| P1 Critical | 5 min | Immediate investigation, page on-call |
| P2 High | 15 min | Investigate within heartbeat |
| P3 Medium | 1 hour | Investigate, track in task |
| P4 Low | 24 hours | Review in daily standup |
Alert Rules
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: ${APP_NAME}-alerts
namespace: ${NAMESPACE}
spec:
groups:
- name: ${APP_NAME}.rules
rules:
# High error rate
- alert: HighErrorRate
expr: |
rate(http_requests_total{service="${APP_NAME}", status=~"5.."}[5m])
/ rate(http_requests_total{service="${APP_NAME}"}[5m]) > 0.05
for: 5m
labels:
severity: critical
annotations:
summary: "High error rate for {{ $labels.service }}"
description: "Error rate is {{ $value | humanizePercentage }} (threshold: 5%)"
# High latency
- alert: HighLatency
expr: |
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket{service="${APP_NAME}"}[5m])) > 1
for: 5m
labels:
severity: warning
annotations:
summary: "High p99 latency for {{ $labels.service }}"
# Pod restarts
- alert: FrequentPodRestarts
expr: |
increase(kube_pod_container_status_restarts_total{namespace="${NAMESPACE}"}[1h]) > 5
labels:
severity: warning
annotations:
summary: "Frequent restarts for {{ $labels.pod }}"
# Memory near limit
- alert: MemoryNearLimit
expr: |
container_memory_working_set_bytes{namespace="${NAMESPACE}"}
/ kube_pod_container_resource_limits{resource="memory", namespace="${NAMESPACE}"} > 0.85
for: 10m
labels:
severity: warning
Alert Tuning
# List PrometheusRules
kubectl get prometheusrules -A
# Check currently firing alerts
bash scripts/alert-triage.sh
# Silence an alert (via Alertmanager API)
curl -s -X POST "${ALERTMANAGER_URL}/api/v2/silences" \
-H "Content-Type: application/json" \
-d '{
"matchers": [{"name": "alertname", "value": "HighLatency", "isRegex": false}],
"startsAt": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",
"endsAt": "'$(date -u -v+4H +%Y-%m-%dT%H:%M:%SZ)'",
"createdBy": "pulse-agent",
"comment": "Investigating. Silenced for 4 hours."
}' | jq .
6. SLO / SLI MANAGEMENT
SLI Definitions
# Availability SLI
- name: availability
query: |
1 - (
sum(rate(http_requests_total{service="${SERVICE}", status=~"5.."}[${WINDOW}]))
/
sum(rate(http_requests_total{service="${SERVICE}"}[${WINDOW}]))
)
target: 0.999 # 99.9%
# Latency SLI
- name: latency
query: |
sum(rate(http_request_duration_seconds_bucket{service="${SERVICE}", le="0.3"}[${WINDOW}]))
/
sum(rate(http_request_duration_seconds_count{service="${SERVICE}"}[${WINDOW}]))
target: 0.99 # 99% of requests under 300ms
# Throughput SLI
- name: throughput
query: |
sum(rate(http_requests_total{service="${SERVICE}"}[${WINDOW}]))
target: 100 # Minimum 100 req/s
Error Budget Calculation
# Error budget remaining (30-day window)
1 - (
(1 - (
sum(rate(http_requests_total{service="${SERVICE}", status!~"5.."}[30d]))
/ sum(rate(http_requests_total{service="${SERVICE}"}[30d]))
))
/ (1 - 0.999) # SLO target
)
# Burn rate (how fast are we consuming budget?)
(
1 - (
sum(rate(http_requests_total{service="${SERVICE}", status!~"5.."}[1h]))
/ sum(rate(http_requests_total{service="${SERVICE}"}[1h]))
)
) / (1 - 0.999)
Generate SLO Report
bash scripts/slo-report.sh ${SERVICE} 30d 0.999
7. INCIDENT RESPONSE
Incident Response Playbook
1. DETECT → Alert fires or manual report
2. TRIAGE → Classify severity (P1-P4)
3. CONTAIN → Stop the bleeding (rollback, scale, redirect)
4. DIAGNOSE → Find root cause using metrics + logs
5. RESOLVE → Apply fix and verify
6. RECOVER → Restore normal operations
7. REVIEW → Post-incident review within 24-72 hours
Quick Diagnosis Commands
# Application health
kubectl get pods -n ${NAMESPACE} -l app=${APP}
kubectl top pods -n ${NAMESPACE} -l app=${APP}
# Recent events
kubectl get events -n ${NAMESPACE} --sort-by='.lastTimestamp' | tail -20
# Container logs (last 30 min)
kubectl logs -n ${NAMESPACE} -l app=${APP} --since=30m --tail=200
# Previous container logs (after crash)
kubectl logs -n ${NAMESPACE} ${POD} --previous
# Deployment status
kubectl rollout status deployment/${APP} -n ${NAMESPACE}
# Resource usage vs limits
kubectl describe pod ${POD} -n ${NAMESPACE} | grep -A 5 "Limits\|Requests"
# Network connectivity
kubectl exec -n ${NAMESPACE} ${POD} -- curl -s -o /dev/null -w "%{http_code}" http://${TARGET_SERVICE}:${PORT}/health
Generate Incident Report
bash scripts/incident-report.sh "Payment API Outage" P1 production payment-service
8. POST-INCIDENT REVIEW
Review Template
# Post-Incident Review — [INCIDENT TITLE]
**Date:** YYYY-MM-DD
**Duration:** HH:MM
**Severity:** P1/P2/P3/P4
**Services Affected:** [list]
**Impact:** [user impact description]
## Timeline
| Time (UTC) | Event |
|-----------|-------|
| HH:MM | Alert fired |
| HH:MM | Investigation began |
| HH:MM | Root cause identified |
| HH:MM | Fix applied |
| HH:MM | Service recovered |
## Root Cause
[Describe the root cause]
## Contributing Factors
- [Factor 1]
- [Factor 2]
## Detection
- How was this detected? (alert, user report, monitoring)
- MTTD: [time from start to detection]
## Resolution
- What fixed it?
- MTTR: [time from detection to resolution]
## Action Items
| Action | Owner | Due Date | Status |
|--------|-------|----------|--------|
| [Action 1] | [Owner] | [Date] | Open |
## Lessons Learned
- What went well?
- What could be improved?
9. AZURE MONITOR (For ARO)
Azure Monitor Metrics
# Get Azure Monitor metrics via REST API
curl -s -H "Authorization: Bearer ${AZURE_TOKEN}" \
"https://management.azure.com/subscriptions/${SUB_ID}/resourceGroups/${RG}/providers/Microsoft.ContainerService/managedClusters/${CLUSTER}/providers/Microsoft.Insights/metrics?api-version=2023-10-01&metricnames=node_cpu_usage_millicores,node_memory_rss_bytes" | jq .
# List metric definitions
az monitor metrics list-definitions \
--resource /subscriptions/${SUB_ID}/resourcegroups/${RG}/providers/microsoft.containerservice/managedclusters/${CLUSTER}
# Query metrics
az monitor metrics query \
--resource /subscriptions/${SUB_ID}/resourcegroups/${RG}/providers/microsoft.containerservice/managedclusters/${CLUSTER} \
--namespace "Insights.container/nodes" \
--metric-names "cpuExceeded,memoryExceeded" \
--start-time $(date -u -v-1H +%Y-%m-%dT%H:%M:%SZ) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
--aggregation Average
Azure Log Analytics
# Query Container Insights logs
az monitor app-insights show -g ${RG} -n ${APP_INSIGHTS} 2>/dev/null || true
# Query Log Analytics workspace
az monitor log-analytics query \
--workspace ${WORKSPACE_ID} \
--analytics-query "ContainerInventory | where TimeGenerated > ago(1h)"
# Get cluster events
az monitor log-analytics query \
--workspace ${WORKSPACE_ID} \
--analytics-query "KubeEvents | where TimeGenerated > ago(1h) | where ClusterId == '${CLUSTER}'"
# Get container logs
az monitor log-analytics query \
--workspace ${WORKSPACE_ID} \
--analytics-query "ContainerLog | where TimeGenerated > ago(1h) | where ContainerName == '${CONTAINER}' | limit 100"
# Get pod status
az monitor log-analytics query \
--workspace ${WORKSPACE_ID} \
--analytics-query "KubePodInventory | where TimeGenerated > ago(1h) | where ClusterId == '${CLUSTER}' | summarize count() by PodStatus"
Azure Container Insights
# Enable Container Insights
az monitor app-insights component create \
--app ${APP_INSIGHTS} \
--location ${LOCATION} \
--resource-group ${RG}
# Check Container Insights status
az containerinsight show \
--resource-group ${RG} \
--cluster-name ${CLUSTER}
# Get recommended alerts
az monitor metrics alert list -g ${RG} -o table
# Create metric alert
az monitor metrics alert create \
-n "high-cpu-alert" \
-g ${RG} \
--condition "avg CPU > 80" \
--description "CPU usage exceeded 80%"
10. AWS CLOUDWATCH (For ROSA)
CloudWatch Metrics
# Get cluster metrics
aws cloudwatch get-metric-statistics \
--namespace AWS/ContainerInsights \
--metric-name cluster_failed_node_count \
--start-time $(date -u -v-1H +%Y-%m-%dT%H:%M:%SZ) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
--period 300 \
--statistics Average,Maximum
# Get node metrics
aws cloudwatch get-metric-statistics \
--namespace AWS/ContainerInsights \
--metric-name node_cpu_utilization \
--dimensions "Name=ClusterName,Value=${CLUSTER};Name=NodeName,Value=${NODE}" \
--start-time $(date -u -v-1H +%Y-%m-%dT%H:%M:%SZ) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
--period 300 \
--statistics Average
# Get pod metrics
aws cloudwatch get-metric-statistics \
--namespace AWS/ContainerInsights \
--metric-name pod_cpu_utilization \
--dimensions "Name=ClusterName,Value=${CLUSTER};Name=Namespace,Value=${NAMESPACE};Name=PodName,Value=${POD}" \
--start-time $(date -u -v-1H +%Y-%m-%dT%H:%M:%SZ) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
--period 300 \
--statistics Average
# Get service mesh metrics
aws cloudwatch get-metric-statistics \
--namespace AWS/AppMesh \
--metric-name request_count \
--dimensions "Name=mesh,Value=${MESH};Name=virtualNode,Value=${NODE}" \
--start-time $(date -u -v-1H +%Y-%m-%dT%H:%M:%SZ) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
--period 60 \
--statistics Sum
CloudWatch Logs
# List log groups
aws logs describe-log-groups --log-group-name-prefix /aws/rosa/ --output table
# Get cluster logs
aws logs get-log-events \
--log-group-name /aws/rosa/${CLUSTER}/api \
--log-stream-name kube-apiserver-audit \
--limit 50
# Query logs with filter pattern
aws logs filter-log-events \
--log-group-name /aws/rosa/${CLUSTER}/containers \
--filter-pattern "[timestamp, level, message]" \
--start-time $(date -u -v-1H +%s)000 \
--end-time $(date -u +%s)000
# Get container runtime logs
aws logs get-log-events \
--log-group-name /aws/rosa/${CLUSTER}/runtime \
--log-stream-name kubelet/${NODE} \
--limit 100
CloudWatch Alarms
# List alarms
aws cloudwatch describe-alarms --alarm-name-prefix rosa-
# Create CPU alarm
aws cloudwatch put-metric-alarm \
--alarm-name "rosa-${CLUSTER}-high-cpu" \
--alarm-description "CPU usage exceeded 80%" \
--metric-name node_cpu_utilization \
--namespace AWS/ContainerInsights \
--statistic Average \
--period 300 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--dimensions "Name=ClusterName,Value=${CLUSTER}" \
--evaluation-periods 2 \
--alarm-actions ${SNS_ARN}
# Create memory alarm
aws cloudwatch put-metric-alarm \
--alarm-name "rosa-${CLUSTER}-high-memory" \
--alarm-description "Memory usage exceeded 85%" \
--metric-name node_memory_utilization \
--namespace AWS/ContainerInsights \
--statistic Average \
--period 300 \
--threshold 85 \
--comparison-operator GreaterThanThreshold \
--dimensions "Name=ClusterName,Value=${CLUSTER}" \
--evaluation-periods 2
AWS X-Ray
# Get trace summary
aws xray get-trace-summaries \
--start-time $(date -u -v-1H +%s) \
--end-time $(date -u +%s) \
--time-range-type TraceId
# Get service graph
aws xray get-service-graph \
--start-time $(date -u -v-1H +%s) \
--end-time $(date -u +%s) \
--graph-name ${CLUSTER}
# Get trace segment
aws xray get-trace-segment \
--trace-id ${TRACE_ID}
14. CONTEXT WINDOW MANAGEMENT
CRITICAL: This section ensures agents work effectively across multiple context windows.
Session Start Protocol
Every session MUST begin by reading the progress file:
# 1. Get your bearings
pwd
ls -la
# 2. Read progress file for current agent
cat working/WORKING.md
# 3. Read global logs for context
cat logs/LOGS.md | head -100
# 4. Check for any incidents since last session
cat incidents/INCIDENTS.md | head -50
Session End Protocol
Before ending ANY session, you MUST:
# 1. Update WORKING.md with current status
# - What you completed
# - What remains
# - Any blockers
# 2. Commit changes to git
git add -A
git commit -m "agent:observability: $(date -u +%Y%m%d-%H%M%S) - {summary}"
# 3. Update LOGS.md
# Log what you did, result, and next action
Progress Tracking
The WORKING.md file is your single source of truth:
## Agent: observability (Pulse)
### Current Session
- Started: {ISO timestamp}
- Task: {what you're working on}
### Completed This Session
- {item 1}
- {item 2}
### Remaining Tasks
- {item 1}
- {item 2}
### Blockers
- {blocker if any}
### Next Action
{what the next session should do}
Context Conservation Rules
| Rule | Why |
|---|---|
| Work on ONE task at a time | Prevents context overflow |
| Commit after each subtask | Enables recovery from context loss |
| Update WORKING.md frequently | Next agent knows state |
| NEVER skip session end protocol | Loses all progress |
| Keep summaries concise | Fits in context |
Context Warning Signs
If you see these, RESTART the session:
- Token count > 80% of limit
- Repetitive tool calls without progress
- Losing track of original task
- "One more thing" syndrome
Emergency Context Recovery
If context is getting full:
- STOP immediately
- Commit current progress to git
- Update WORKING.md with exact state
- End session (let next agent pick up)
- NEVER continue and risk losing work
15. HUMAN COMMUNICATION & ESCALATION
Keep humans in the loop. Use Slack/Teams for async communication. Use PagerDuty for urgent escalation.
Communication Channels
| Channel | Use For | Response Time |
|---|---|---|
| Slack | Alert notifications, status updates | < 1 hour |
| MS Teams | Alert notifications, status updates | < 1 hour |
| PagerDuty | Production incidents, urgent escalation | Immediate |
Slack/MS Teams Message Templates
Alert Notification
{
"text": "📊 *Pulse - Alert Notification*",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Alert detected by Pulse (Observability)*"
}
},
{
"type": "section",
"fields": [
{"type": "mrkdwn", "text": "*Alert:*\n{alert_name}"},
{"type": "mrkdwn", "text": "*Severity:*\n{severity}"},
{"type": "mrkdwn", "text": "*Cluster:*\n{cluster}"},
{"type": "mrkdwn", "text": "*Service:*\n{service}"}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Details:*\n```{alert_details}```"
}
}
]
}
Incident Report Request
{
"text": "📋 *Pulse - Incident Report Required*",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Human input needed for incident: {incident_name}*"
}
},
{
"type": "section",
"fields": [
{"type": "mrkdwn", "text": "*Timeline:*\n{timeline_summary}"},
{"type": "mrkdwn", "text": "*Impact:*\n{impact}"}
]
}
]
}
PagerDuty Integration
curl -X POST 'https://events.pagerduty.com/v2/enqueue' \
-H 'Content-Type: application/json' \
-d '{
"routing_key": "$PAGERDUTY_ROUTING_KEY",
"event_action": "trigger",
"payload": {
"summary": "[Pulse] {alert_summary}",
"severity": "{critical|error|warning}",
"source": "pulse-observability",
"custom_details": {
"agent": "Pulse",
"alert": "{alert_name}",
"cluster": "{cluster}",
"metric": "{metric_value}"
}
},
"client": "cluster-agent-swarm"
}'
Escalation Flow
- Alert detected → Send Slack/Teams notification
- If alert requires action → Send approval request
- Wait 5 min CRITICAL, 15 min HIGH
- No response → Trigger PagerDuty
- Resolution → Send status update
Response Timeouts
| Priority | Slack/Teams Wait | PagerDuty Escalation After |
|---|---|---|
| CRITICAL | 5 minutes | 10 minutes total |
| HIGH | 15 minutes | 30 minutes total |
| MEDIUM | 30 minutes | No escalation |
Helper Scripts
| Script | Purpose |
|---|---|
alert-triage.sh | Triage currently firing alerts |
metric-query.sh | Execute PromQL queries |
log-search.sh | Search logs via Loki or kubectl |
slo-report.sh | Generate SLO compliance report |
incident-report.sh | Generate post-incident review document |
Run any script:
bash scripts/<script-name>.sh [arguments]