Writing rule
When this skill writes a durable artifact, read .claude/rules/writing-standard.md. Use the controlled technical writing profile.
/monitoring-audit — Observability & Incident Readiness
Deep-dive observability analysis. Checks that production issues will be detected, alerted on, and resolvable. Invoke when /launch-check's monitoring row shows WARN or FAIL.
Observability Pillars
| Pillar |
Question |
What to look for |
| Logs |
Can you see what happened? |
Structured logging, log levels, no PII in logs |
| Metrics |
Can you measure what's happening? |
Request counts, latency, error rates, business metrics |
| Traces |
Can you follow a request end-to-end? |
Distributed tracing, correlation IDs |
| Alerts |
Will you know when something breaks? |
Alerting rules, on-call, PagerDuty/OpsGenie |
Process
Step 1: Error tracking
- Grep for error tracking SDK (Sentry, Datadog, Bugsnag, LogRocket, Rollbar)
- Check initialization: is the SDK configured with the correct DSN/API key (env var, not hardcoded)?
- Check error boundaries (React ErrorBoundary, Vue errorHandler, global uncaughtException handler)
- Check if source maps are uploaded to the error tracker for readable stack traces
Step 2: Health endpoints
- Check for a health check route (
/health, /healthz, /api/health, /_health)
- Check what the health endpoint verifies (just "alive"? database connectivity? external service reachability?)
- Check for a readiness probe separate from liveness (Kubernetes-style)
Step 3: Logging
- Check for a logging library (winston, pino, bunyan, python logging, structured logging)
- Check if logs are structured (JSON) or unstructured (console.log with string concatenation)
- Check for appropriate log levels (error, warn, info, debug) — not everything at
console.log
- Check that sensitive data (passwords, tokens, PII) is NOT logged
Step 4: Alerting and incident response
- Check for alerting configuration (CloudWatch Alarms, Datadog monitors, PagerDuty rules)
- Check for a runbook (
docs/runbook.md, docs/incident-response.md, RUNBOOK.md)
- Check for a status page configuration (Statuspage.io, Instatus, or self-hosted)
Step 5: Output
MONITORING AUDIT — <project> @ <sha>
| # | Pillar | Status | Finding |
|----|--------|--------|---------|
| M1 | Error tracking | PASS | Sentry configured in lib/sentry.ts, source maps uploaded |
| M2 | Health endpoint | FAIL | No /health route found |
| M3 | Logging | WARN | Using console.log (unstructured), no log levels |
| M4 | Alerting | WARN | No alerting rules found in code or IaC |
| M5 | Runbook | FAIL | No runbook or incident response doc |
Incident readiness: NOT READY (2 fails — health endpoint and runbook are minimum viable)
Priority fixes:
1. [ ] Add GET /health returning { status: "ok", db: "connected" }
2. [ ] Create docs/runbook.md with deployment, rollback, and common-issue procedures
3. [ ] Replace console.log with structured logger (pino recommended for Node.js)
Persist the run + render trend
After printing the findings table, persist via the shared audit-history lib so the monitoring trend across runs becomes legible. See docs/agdr/AgDR-0019-audit-artefact-persistence.md.
Resolve project name + score + verdict
<project-name> from apexyard.projects.yaml (or basename + /handover reminder if unregistered).
Score: score = max(0, 100 - 25*critical - 10*high - 3*medium - 1*low). Verdict by worst-severity: critical/high → fail, medium → conditional, low/none → pass. Legacy "Incident readiness" two-state: NOT READY → fail, READY → pass.
Persist + render
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-audit-history.sh"
# Lowercase severity in the payload — the lib expects critical/high/medium/low/info.
payload=$(mktemp); cat > "$payload" <<'EOF'
{
"schema_version": 1,
"findings": [
{"id": "M2", "severity": "critical", "status": "open", "summary": "No error tracking SDK detected; uncaught errors are silent"},
{"id": "M3", "severity": "high", "status": "open", "summary": "No /health endpoint; load balancer can't detect hung instance"},
{"id": "M4", "severity": "critical", "status": "open", "summary": "No alerting rules; nothing pages on-call"}
]
}
EOF
# Body: per templates/audits/monitoring-audit.md
body=$(mktemp); cat > "$body" <<'EOF'
... (filled-in body — findings table + Priority fixes) ...
EOF
ts=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
audit_run_persist "<project-name>" "monitoring-audit" "$ts" "fail" 35 "$body" < "$payload"
rm -f "$payload" "$body"
audit_render_trend "<project-name>" "monitoring-audit" 5
Opt-in commit
touch projects/<name>/audits/monitoring-audit/.audit-history-tracked
Rules
- Auto-PASS for projects not yet in production. Pre-launch monitoring gaps are expected — flag them as "set up before first deploy" rather than "FAIL."
- Check IaC too. Alerting rules might be in Terraform, CloudFormation, or CDK files rather than application code.
- Don't require all four pillars. Logs + error tracking + health endpoint is the minimum. Distributed tracing and detailed metrics are "nice to have" for most teams.
- Be specific about what the health endpoint should check — "returns 200" is table stakes; checking database connectivity is the real test.
- Always persist via the lib. The persist step runs regardless of opt-in commit state.
- Severity vocabulary in the JSON is lowercase. The lib expects
critical/high/medium/low/info.
Part of ApexYard — multi-project SDLC framework for Claude Code · MIT.
1---2name: monitoring-audit3description: Observability audit — logging, error tracking, health endpoints, alerting, runbooks. Deep-dive for /launch-check monitoring.4---56## Writing rule78When this skill writes a durable artifact, read .claude/rules/writing-standard.md. Use the controlled technical writing profile.910# /monitoring-audit — Observability & Incident Readiness1112Deep-dive observability analysis. Checks that production issues will be detected, alerted on, and resolvable. Invoke when `/launch-check`'s monitoring row shows WARN or FAIL.1314## Observability Pillars1516| Pillar | Question | What to look for |17|--------|----------|-----------------|18| **Logs** | Can you see what happened? | Structured logging, log levels, no PII in logs |19| **Metrics** | Can you measure what's happening? | Request counts, latency, error rates, business metrics |20| **Traces** | Can you follow a request end-to-end? | Distributed tracing, correlation IDs |21| **Alerts** | Will you know when something breaks? | Alerting rules, on-call, PagerDuty/OpsGenie |2223## Process2425### Step 1: Error tracking2627- Grep for error tracking SDK (Sentry, Datadog, Bugsnag, LogRocket, Rollbar)28- Check initialization: is the SDK configured with the correct DSN/API key (env var, not hardcoded)?29- Check error boundaries (React ErrorBoundary, Vue errorHandler, global uncaughtException handler)30- Check if source maps are uploaded to the error tracker for readable stack traces3132### Step 2: Health endpoints3334- Check for a health check route (`/health`, `/healthz`, `/api/health`, `/_health`)35- Check what the health endpoint verifies (just "alive"? database connectivity? external service reachability?)36- Check for a readiness probe separate from liveness (Kubernetes-style)3738### Step 3: Logging3940- Check for a logging library (winston, pino, bunyan, python logging, structured logging)41- Check if logs are structured (JSON) or unstructured (console.log with string concatenation)42- Check for appropriate log levels (error, warn, info, debug) — not everything at `console.log`43- Check that sensitive data (passwords, tokens, PII) is NOT logged4445### Step 4: Alerting and incident response4647- Check for alerting configuration (CloudWatch Alarms, Datadog monitors, PagerDuty rules)48- Check for a runbook (`docs/runbook.md`, `docs/incident-response.md`, `RUNBOOK.md`)49- Check for a status page configuration (Statuspage.io, Instatus, or self-hosted)5051### Step 5: Output5253```54MONITORING AUDIT — <project> @ <sha>5556| # | Pillar | Status | Finding |57|----|--------|--------|---------|58| M1 | Error tracking | PASS | Sentry configured in lib/sentry.ts, source maps uploaded |59| M2 | Health endpoint | FAIL | No /health route found |60| M3 | Logging | WARN | Using console.log (unstructured), no log levels |61| M4 | Alerting | WARN | No alerting rules found in code or IaC |62| M5 | Runbook | FAIL | No runbook or incident response doc |6364Incident readiness: NOT READY (2 fails — health endpoint and runbook are minimum viable)6566Priority fixes:67 1. [ ] Add GET /health returning { status: "ok", db: "connected" }68 2. [ ] Create docs/runbook.md with deployment, rollback, and common-issue procedures69 3. [ ] Replace console.log with structured logger (pino recommended for Node.js)70```7172## Persist the run + render trend7374After printing the findings table, persist via the shared audit-history lib so the monitoring trend across runs becomes legible. See `docs/agdr/AgDR-0019-audit-artefact-persistence.md`.7576### Resolve project name + score + verdict7778`<project-name>` from `apexyard.projects.yaml` (or basename + `/handover` reminder if unregistered).7980Score: `score = max(0, 100 - 25*critical - 10*high - 3*medium - 1*low)`. Verdict by worst-severity: critical/high → `fail`, medium → `conditional`, low/none → `pass`. Legacy "Incident readiness" two-state: NOT READY → `fail`, READY → `pass`.8182### Persist + render8384```bash85source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-audit-history.sh"8687# Lowercase severity in the payload — the lib expects critical/high/medium/low/info.88payload=$(mktemp); cat > "$payload" <<'EOF'89{90 "schema_version": 1,91 "findings": [92 {"id": "M2", "severity": "critical", "status": "open", "summary": "No error tracking SDK detected; uncaught errors are silent"},93 {"id": "M3", "severity": "high", "status": "open", "summary": "No /health endpoint; load balancer can't detect hung instance"},94 {"id": "M4", "severity": "critical", "status": "open", "summary": "No alerting rules; nothing pages on-call"}95 ]96}97EOF9899# Body: per templates/audits/monitoring-audit.md100body=$(mktemp); cat > "$body" <<'EOF'101... (filled-in body — findings table + Priority fixes) ...102EOF103104ts=$(date -u +"%Y-%m-%dT%H:%M:%SZ")105audit_run_persist "<project-name>" "monitoring-audit" "$ts" "fail" 35 "$body" < "$payload"106rm -f "$payload" "$body"107108audit_render_trend "<project-name>" "monitoring-audit" 5109```110111### Opt-in commit112113```bash114touch projects/<name>/audits/monitoring-audit/.audit-history-tracked115```116117## Rules1181191. **Auto-PASS for projects not yet in production.** Pre-launch monitoring gaps are expected — flag them as "set up before first deploy" rather than "FAIL."1202. **Check IaC too.** Alerting rules might be in Terraform, CloudFormation, or CDK files rather than application code.1213. **Don't require all four pillars.** Logs + error tracking + health endpoint is the minimum. Distributed tracing and detailed metrics are "nice to have" for most teams.1224. **Be specific about what the health endpoint should check** — "returns 200" is table stakes; checking database connectivity is the real test.1235. **Always persist via the lib.** The persist step runs regardless of opt-in commit state.1246. **Severity vocabulary in the JSON is lowercase.** The lib expects `critical`/`high`/`medium`/`low`/`info`.125126---127128*Part of [ApexYard](https://github.com/me2resh/apexyard) — multi-project SDLC framework for Claude Code · MIT.*