Hamburger Cross Icon
On-Call Guardrails - Lunar Policy for Operational Readiness

On-Call Guardrails

✓ Policy Beta Operational Readiness

Enforce on-call operational readiness standards. Verify that services are mapped to an on-call service and have an active schedule, a multi-level escalation policy, and enough rotation participants. Works with any oncall-category collector (PagerDuty, OpsGenie, Datadog On-Call, etc.).

Add oncall to your lunar-config.yml:
uses: github://earthly/lunar-lib/policies/oncall@v1.0.5

Included Guardrails

This policy includes 4 guardrails that enforce standards for your operational readiness.

Guardrail

service-mapped

Verifies the component is mapped to an on-call service. Fails when a collector looked for one and found none (.oncall.service_lookup), naming the places it looked; skips when no collector looked, or a lookup couldn't finish.

oncall service mapping pagerduty backstage service-id
View Guardrail
Guardrail

schedule-configured

Verifies that the service has an active on-call schedule by checking .oncall.schedule.exists is true. Fails if no on-call schedule data is present.

oncall schedule rotation incident response
View Guardrail
Guardrail

escalation-defined

Verifies that an escalation policy is configured for the service by checking .oncall.escalation.exists is true. Fails if no escalation data is present.

escalation incident pagerduty opsgenie datadog response
View Guardrail
Guardrail

min-participants

Ensures the on-call rotation has at least a minimum number of participants to avoid single-person burnout. Checks .oncall.schedule.participants against the configurable min_participants threshold (default: 2).

oncall rotation staffing burnout team size
View Guardrail

How Guardrails Fit into Lunar

Lunar guardrails define your engineering standards as code. They evaluate data collected by integrations and produce pass/fail checks with actionable feedback.

Policies support gradual enforcement—from silent scoring to blocking PRs or deployments—letting you roll out standards at your own pace without disrupting existing workflows.

Learn How Lunar Works →
1
↓ Integrations Gather Data
Collectors extract metadata from code, CI pipelines, tool outputs, and scans
2
{ } Centralized as JSON
All data merged into each component's unified metadata document
3
✓ Guardrails Enforce Standards This Policy
Real-time feedback in PRs and AI workflows

Example Evaluated Data

This policy evaluates structured metadata from the Component JSON. Here's an example of the data it checks:

{ } component.json Example Input
{
  "oncall": {
    "source": {
      "tool": "pagerduty",
      "integration": "api"
    },
    "service": {
      "id": "PXXXXXX",
      "name": "Payment API",
      "status": "active",
      "discovered_via": "system:default/payment-platform"
    },
    "schedule": {
      "exists": true,
      "participants": 4,
      "rotation": "weekly"
    },
    "escalation": {
      "exists": true,
      "levels": 3,
      "policy_name": "Payment API Escalation"
    },
    "summary": {
      "has_oncall": true,
      "has_escalation": true,
      "min_participants": 4
    }
  }
}

Configuration

Configure this policy in your lunar-config.yml.

Inputs

Input Required Default Description
min_participants Optional 2 Minimum number of on-call rotation participants required

Documentation

View on GitHub

On-Call Guardrails

Enforce on-call schedule, escalation, and staffing standards for production services.

Overview

This policy validates that services have proper on-call operational readiness: a mapping to an on-call service, an active schedule, a configured escalation policy, and enough rotation participants to avoid burnout. It reads from the tool-agnostic .oncall category, so the same guardrails work whether the data comes from PagerDuty, OpsGenie, Datadog On-Call, or another incident management tool.

Policies

This plugin provides the following policies (use include to select a subset):

Policy Description
service-mapped Verifies the component is mapped to an on-call service
schedule-configured Verifies an on-call schedule exists for the service
escalation-defined Verifies an escalation policy is configured
min-participants Ensures the rotation has enough participants (default: 2)

Required Data

This policy reads from the following Component JSON paths:

Path Type Provided By
.oncall.service.id string pagerduty, opsgenie, or datadog collector (or any oncall-category collector)
.oncall.service_lookup object pagerduty collector, when it looked for a service and found none
.oncall.schedule.exists boolean pagerduty, opsgenie, or datadog collector (or any oncall-category collector)
.oncall.schedule.participants number pagerduty, opsgenie, or datadog collector
.oncall.escalation.exists boolean pagerduty, opsgenie, or datadog collector

Note: Ensure a collector that writes to the .oncall category is configured before enabling this policy.

Installation

Add to your lunar-config.yml:

policies:
  - uses: github://earthly/lunar-lib/policies/oncall@v1.0.0
    on: ["domain:your-domain"]
    enforcement: report-pr
    include:
      - service-mapped
      - schedule-configured
      - escalation-defined
      - min-participants
    # with:
    #   min_participants: "3"

Examples

Passing Example

{
  "oncall": {
    "schedule": { "exists": true, "participants": 4, "rotation": "weekly" },
    "escalation": { "exists": true, "levels": 3 }
  }
}

Failing Example

{
  "oncall": {
    "schedule": { "exists": false },
    "escalation": { "exists": true, "levels": 1 }
  }
}

Failure message: "Service has no on-call schedule configured. Set up a schedule in your on-call tool (PagerDuty, OpsGenie, Datadog On-Call, etc.) and attach it to the service's escalation policy."

Unmapped Example

{
  "oncall": {
    "source": { "tool": "pagerduty", "integration": "api" },
    "service_lookup": {
      "searched": ["meta:pagerduty/service-id", "input:service_id", "file:catalog-info.yaml", "component:default/checkout", "system:default/payment-platform"]
    }
  }
}

Failure message (service-mapped): "No PagerDuty service is mapped to this component (looked in: meta:pagerduty/service-id, input:service_id, file:catalog-info.yaml, component:default/checkout, system:default/payment-platform). Annotate its Backstage Component, System or Domain with pagerduty.com/service-id, or set the pagerduty/service-id meta or the collector's service_id input."

service-mapped passes whenever a collector wrote .oncall.service.id, even next to a .oncall.service_lookup another one wrote. It skips when no collector looked for a service, and when .oncall.service_lookup.errors says a lookup couldn't complete (e.g. Backstage was unreachable). The other checks still fail on the missing data.

Remediation

When this policy fails, you can resolve it by:

  1. service-mapped: Map the component to its service: a pagerduty.com/service-id annotation on its Backstage Component (or its System or Domain, with the pagerduty collector's from-backstage-collector sub-collector and the backstage collector's backstage_url), the pagerduty/service-id component meta, or the collector's service_id input
  2. schedule-configured: Create an on-call schedule in your incident-management tool (PagerDuty, OpsGenie, Datadog On-Call, etc.) for the service and assign team members
  3. escalation-defined: Create an escalation policy in your incident-management tool with at least one level
  4. min-participants: Add more team members to the on-call rotation (default minimum is 2)

Open Source

This policy is open source and available on GitHub. Contribute improvements, report issues, or fork it for your own use.

View Repository

Common Use Cases

Explore how individual guardrails work with specific integrations.

Ready to Automate Your Standards?

See how Lunar can turn your AGENTS.md, engineering wiki, compliance docs, or postmortem action items into automated guardrails with our 300+ built-in guardrails.

Works with any process
check AI agent rules & prompt files
check Post-mortem action items
check Security & compliance policies
check Testing & quality requirements
Auto-ID My Guardrails
Paste your AGENTS.md or manual process doc and get guardrails in minutes
Book a Demo