← Back to blog
Use CasesCI10 min read

September 5, 2026

Stage the CI gate from non-required to required

A required check with a confusing red X loses contributors. Platform may want the gate required on day one. Maintainers who live in contributor Slack want proof it will not punish ordinary PRs. Stage with real traffic before branch protection blocks merges.

Run one week as a non-required job

Evaluate real intents and write audit rows. Do not block merges on the result yet. The step can still fail on deny inside the job; staging lives at the branch-protection layer, not inside @limetry/ci.

The action always records the decision. Whether GitHub treats the job as blocking is a separate, reversible choice.

import { evaluateCiPrivilege } from "@limetry/ci"

const result = await evaluateCiPrivilege({
  apiKey: process.env.LIMETRY_API_KEY!,
  baseUrl: process.env.LIMETRY_BASE_URL,
  policyId: process.env.LIMETRY_CI_POLICY_ID!,
  agentId: "github_actions",
  actionType: "deploy",
  repository: process.env.GITHUB_REPOSITORY!,
  sha: process.env.GITHUB_SHA!,
  eventName: process.env.GITHUB_EVENT_NAME!,
  ref: process.env.GITHUB_REF,
})

process.stdout.write(JSON.stringify({
  action_type: result.intent.action_type,
  trust: result.trust,
  decision: result.evaluation.decision,
  reasons: result.evaluation.reasons ?? [],
  decision_id: result.evaluation.decision_id,
}, null, 2))

Review audit daily for two failure modes: trusted main runs denied, and untrusted PR runs allowed into deploy. Fix contributor-facing annotations before the check becomes required.

Verify classifications before requiring the check

Example after seven days (184 CI evaluations):

ci_privilege on pull_request:        91 allow
deploy on pull_request:              91 deny
deploy on push to main:               2 approval_required
false classifications:                0
median evaluate latency:           142 ms
highest evaluate latency:          611 ms

Update failure text before requiring the check. After evaluate, require_trusted fails closed on untrusted events with a named event and resource:

Refusing privileged CI for untrusted event pull_request on acme/api@f3a91c2

Audit still carries the policy deny, decision_id, receipt digest, reasons, and expiry.

Make the check required

After staging evidence is clean, require the check. Cost: one extra evaluate call per sensitive job. Return: audit across protected workflows and a check GitHub will block on. Environment rules stay. Limetry remains the first question in the job: should this action type run from this event at this SHA?

Origin: Evaluate before CI loads credentials. Incident context: Deny deploy on a Copilot PR burst before production credentials.

Run Limetry on your own stack

Self-host the open source evaluation server, wire evaluate into your agents, and keep privacy-safe audit under your control.