checkId: check.release.promotion.gates plugin: stellaops.doctor.release severity: warn tags: [release, promotion, gates, policy, attestation]
Promotion Gate Health
This check reads persisted gate evaluations from pending approvals at GET /api/v1/release-orchestrator/approvals?statuses=pending. There is no global /api/v1/promotion-gates read model.
What it checks
passedand signedexceptionresults are non-blocking.advisoryresults are visible warnings.- the known non-blocking Policy.Engine and reachability
skippedresults are warnings. - denied, failed, blocked, error, and unknown non-passing results are blocking failures.
- a pending approval with no persisted
gateResultsis unevaluated and returnsWarn.
Doctor reports pending approval, total gate, blocking gate, advisory gate, and unevaluated approval counts. Malformed approval envelopes return Warn; they never become a false “no gates configured” pass.
Diagnose
# List pending approvals and their gateResults
curl -s -H "Authorization: Bearer $TOKEN" \
"https://<gateway>/api/release-orchestrator/approvals?statuses=pending"
# Inspect one approval, including gate evidence
curl -s -H "Authorization: Bearer $TOKEN" \
https://<gateway>/api/release-orchestrator/approvals/<approval-id>
Remediate the failing gate’s evidence or policy input. Use the signed gate-exception workflow only when the operator has intentionally accepted the risk; Doctor treats a persisted exception as non-blocking because the Release Orchestrator truth guard does.
Verification
stella doctor run --check check.release.promotion.gates
Related checks
check.release.active– stale pending approvals are also aged by the active-release check.check.release.environment.readiness– target readiness can block a promotion/deployment path.check.release.environment.matches-approved– detects post-deployment digest drift.
