Skip to main content

Runbook: Sentinel triage (/sentinel-check)

What it is: read-only triage of a production/staging signal that returns a single JSON verdict โ€” verify the signal in Loki, locate the code in GitHub, check the known-issue registry, classify severity, recommend the next step. It runs on your Claude subscription (no API key) and never writes anything.

Who runs it: anyone. Once you have the bewith plugin installed and the Grafana MCP added (below), /sentinel-check "..." works in any Claude Code session โ€” you do not need the bewith-dev/sentinel repo checked out.

Prerequisitesโ€‹

  • Claude Code CLI, logged into a Max/Team subscription.
  • The bewith plugin installed โ€” see install-bewith-plugin.md. That is what ships the /sentinel-check command and the sentinel-triage skill to every session.
  • Read access to the 1Password MCP-Exposed vault (for the Grafana service-account token).
  • GitHub MCP configured (already standard on the team).

Setup โ€” add the Grafana MCP to the CLI (one time)โ€‹

The MCP must live in the CLI, not the Claude Desktop app โ€” a Desktop connector does not reach the CLI where the command runs.

claude mcp add grafana \
-e GRAFANA_URL=https://platformobs.grafana.net \
-e GRAFANA_SERVICE_ACCOUNT_TOKEN="$(op read 'op://MCP-Exposed/Grafana Loki/credential')" \
-- docker run --rm -i -e GRAFANA_URL -e GRAFANA_SERVICE_ACCOUNT_TOKEN grafana/mcp-grafana -t stdio

Then restart the session. Datasource UIDs are public config: Loki grafanacloud-logs, Prometheus grafanacloud-prom, CloudWatch fflqca5egwpa8b (ECS / fr-prod IL), dfn8juqwjz3lsf (EKS us-prod), cfn8j15xcfw1se (EKS ir-staging, eu-west-1).

Usageโ€‹

/sentinel-check "superco-consumer us-prod"
/sentinel-check "payments โ€” customer blocked on checkout, EU"

The command loads the sentinel-triage skill and runs its fixed 7-step order of operations. Example verdict:

{
"is_bug": true,
"severity": "sev-2",
"service": "service-communities",
"env": "eu-central-1",
"customer": "org 19",
"root_cause": "getCommunityHomeUrl(69) returns null unguarded during the 05:00 integrations sync",
"evidence": { "logql": "{aws_region=\"eu-central-1\"} |= \"homeUrl for community: 69\"", "count": 2634, "window": "05:00-06:00Z" },
"code_link": "https://github.com/bewith-dev/backend-services/blob/main/...",
"known_issue": "homeurl-69 (open, chronic)",
"recommended_next_step": "fix -> null-guard getCommunityHomeUrl",
"confidence": "high"
}

The brainโ€‹

The exact order of operations + severity guide live in the sentinel-triage skill (the machine procedure). This runbook is the human how-to; the skill is what the AI executes.

  • Scope resolution: the cluster label is the primary tenant discriminator (ir-staging โ†’ bewith-dev-cluster/eu-west-1; us-prod โ†’ bewith-prod-cluster/us-east-1; fr-prod โ†’ eu-central-1 ECS). eu-west-1 production is clean; there is no ir-prod.
  • Known logging gap (2026-07): the Datadog-EU IL-prod logs arrive with empty env/cluster/host, so IL prod vs staging can only be disambiguated by the coing.co domain in the log body โ€” flag it to the logging owners.

Cross-referencesโ€‹