CI/CD / Integrity, coordination, and improvement / Lesson 16
Policy, approvals, and controlled exceptions
Make release decisions reviewable without creating meaningless approval queues.
On this page
Lesson goals
- Connect each control to a named risk and authoritative evidence.
- Design an exception with scope, ownership, and expiry.
A control should change a decision
A release policy translates organizational constraints into checks and decisions. Parcel may require reviewed source, a verified candidate, compatibility evidence, and an environment owner’s decision for a sensitive change. Adding a manual approval after every harmless edit can create delay without improving judgment if approvers cannot see relevant evidence. Ask which risk each control addresses and what information would cause rejection. A control that nobody can explain or that everyone automatically bypasses is a process defect to investigate, not a maturity badge.
Separate evidence from authority
Automated checks report observations; authorized people or policy engines decide whether those observations satisfy release conditions. The approver should see candidate identity, target, configuration, failed or excluded checks, and relevant compatibility limits. Avoid approvals detached from immutable inputs. Protect the policy definition and its evaluation path from the same untrusted change it is meant to constrain. A contributor-controlled field saying approved cannot establish approval. Repository and environment permissions determine who can change or bypass controls and need explicit review.
Bound the exceptional decision
An exception should name the exact candidate, target, waived condition, reason, accountable owner, compensating evidence, and expiry. It should not disable every gate for all future releases. Emergency work can require a faster decision path, but speed does not eliminate the need to record what happened. The following conceptual record illustrates a narrow waiver for an unavailable noncritical report; it does not authorize skipping a security or compatibility requirement and is not an operational approval.
{"candidate":"candidate-r8","target":"production-lab","waived_condition":"optional-report-publication","owner":"release-role","expires":"end-of-lab-window","decision":"review-required"}
All values are synthetic. A real exception needs authenticated authority, an actual expiry, an explicit risk assessment, and preserved evidence. This record grants no access and triggers no release.
Make absence fail closed where required
The complete model below requires all mandatory evidence and rejects an unknown key in a waiver request. This teaches narrow scope, not a complete policy language. In real systems, waiver authority, expiry, candidate binding, and signature or access controls also matter. Prefer a small understandable policy over an elaborate expression nobody can safely change. Test rejection paths as carefully as acceptance: missing reports, old approval, wrong target, unauthorized waiver, and changed candidate should produce clear reasons.
required = {"source-review", "candidate-verified"}
def evaluate(evidence, waivers):
allowed_waivers = {"optional-report"}
return required <= evidence and waivers <= allowed_waivers
print(evaluate({"source-review", "candidate-verified"}, {"optional-report"}))
print(evaluate({"source-review"}, {"candidate-verified"}))
True
False
The second request cannot waive a mandatory verification requirement. This in-memory set calculation does not authenticate reviewers or implement a real waiver service.
Retain the decision, then improve the system
A useful release record explains what was adopted, why it was allowed, which policy version applied, and what happened afterward. It should not become a warehouse of secrets or personal data. Review exception frequency and approval wait time to find recurring infrastructure or policy problems. If a report frequently fails, fix the publishing path or reconsider its role instead of normalizing permanent waiver use. After an emergency, reconcile the record and follow through on the underlying defect while the evidence is still available.
Common errors and fixes
An approval remains valid after the candidate changes.
- Why it happens
- The decision is attached to a job name rather than immutable inputs.
- How to fix it
- Bind decisions to candidate, configuration, target, and defined freshness.
- Prevent it next time
- Invalidate material changes and test stale-approval rejection.
An emergency waiver disables all future controls.
- Why it happens
- The exception lacks scope and expiry.
- How to fix it
- Restore controls and record a narrowly bounded authorized decision.
- Prevent it next time
- Require owner, condition, candidate, target, and expiry for exceptions.
The proposed change can edit its own mandatory gate.
- Why it happens
- Policy authority shares the untrusted execution boundary.
- How to fix it
- Protect policy evaluation and require appropriate independent review.
- Prevent it next time
- Review bypass and policy-edit permissions alongside release permissions.
Check your understanding
1. Approvers always click yes because they only see a green icon. What should change?
Show worked solution
Expose candidate, target, meaningful evidence, exclusions, and the decision’s risk. Remove or redesign controls that require no informed judgment. Measure whether the approval can reject a realistic unsafe case, rather than simply adding more approvers.
2. A report upload is broken for three weeks and every release uses a waiver. What is the systemic issue?
Show worked solution
The exception has become the normal path. Assign an owner to repair the report channel or review whether it should gate release. Retain narrow decisions meanwhile and avoid silently lowering unrelated requirements.
Key takeaways
- Controls need evidence, authority, and an actionable decision.
- Exceptions should be narrow, attributable, and temporary.