Checkpoint Lab — Protected Branches, Repository Rulesets, Push Rules, Required Checks, and Bypass Governance
Build, verify, break, satisfy, and recover a minimal repository policy. Then rehearse an emergency PR-only bypass in a throwaway repository with explicit evidence and immediate recovery so bypass remains exceptional.
Checkpoint outcomes
- Apply a minimal branch ruleset to a disposable default branch after producing a real required check.
- Predict and capture one forbidden direct update without changing the hosted branch.
- Complete the same class of change through a compliant PR and verify the required evidence independently.
- Rehearse a PR-only emergency bypass once, with a failing mock gate, recorded reason, recovery PR, and removal of bypass access.
- Write a short production policy covering normal flow, check ownership, exception triggers, audit evidence, and cleanup.
- Finish with the repository either cleanly archived or restored to an unprotected disposable state.
gh installed. Ruleset creation
and bypass-list changes require repository admin access. No second
identity, paid plan, organization, secret, external CI service, or
self-hosted runner is required.
github-governance-checkpoint. Do not adapt the bypass
rehearsal to a valuable repository. If your current UI does not offer
the documented PR-only bypass mode, use the supplied simulation
instead of broadening privileges.
1. Setup and baseline
\, $(...), printf,
cat <<'EOF', or rm are Git
Bash/Bash/zsh syntax. In PowerShell, keep the same Git/gh
arguments but use the backtick for line continuation and
Set-Content/Add-Content/Remove-Item
for file operations. GitHub ruleset and branch-policy semantics do
not depend on the shell.
gh auth status --active --hostname github.com
gh repo create github-governance-checkpoint --public --add-readme --clone
cd github-governance-checkpoint
gh repo view --json nameWithOwner,visibility,defaultBranchRef,viewerPermission
gh ruleset list --parents
gh ruleset check --default
git status --short --branch
Write down the repository owner/name and default branch. If inherited/parent policy exists, do not stack the checkpoint on top of policy you do not control; recreate the lab under your personal account.
2. Create the evidence producer and observe its real check identity
Create this no-secret workflow before protection:
# .github/workflows/policy-gate.yml
name: policy-gate
on:
pull_request:
permissions:
contents: read
jobs:
policy-gate:
runs-on: ubuntu-latest
steps:
- name: Fail only the named emergency rehearsal
if: ${{ github.event.pull_request.title == 'Emergency bypass rehearsal' }}
run: |
echo "intentional checkpoint failure for bypass rehearsal"
exit 1
- name: Pass normal pull requests
if: ${{ github.event.pull_request.title != 'Emergency bypass rehearsal' }}
run: echo "policy gate passed"
mkdir -p .github/workflows
# Save the workflow above.
git add .github/workflows/policy-gate.yml
git commit -m "ci: add checkpoint policy gate"
git push origin main
git switch -c observe-check
printf 'observe check
' > observe.txt
git add observe.txt
git commit -m "test: observe required check"
git push -u origin observe-check
gh pr create --base main --head observe-check --title "Observe policy gate" --body "Pre-policy check identity run."
gh pr checks --watch
gh pr merge --squash --delete-branch
git switch main && git pull --ff-only
Record the exact passing check name. Prediction 1: after the warm-up
merge, main contains the workflow and
observe.txt, but no ruleset yet constrains future
updates.
3. Stage a minimal branch ruleset
Create checkpoint-main-policy in repository Rulesets
with these properties:
- Target: default branch.
- Enforcement: Disabled while configuring.
- Bypass list: empty initially.
- Rule: require a pull request before merging, zero required approvals for this one-account lab.
- Rule: require the observed
policy-gatecheck. - Keep force pushes blocked and deletion restricted using the normal ruleset defaults where shown.
Verify the object while Disabled, then edit only enforcement to Active.
gh ruleset list -R OWNER/github-governance-checkpoint --parents
gh api -H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2026-03-10" \
repos/OWNER/github-governance-checkpoint/rulesets --paginate \
--jq '.[] | {id,name,enforcement,target}'
# After activation:
gh ruleset check --default -R OWNER/github-governance-checkpoint
Prediction 2: activating the policy changes hosted governance state but does not move any Git ref by itself.
4. Attempt one forbidden direct change and capture rejection evidence
git switch main
git pull --ff-only
BASE_BEFORE=$(git rev-parse origin/main)
printf 'forbidden direct path
' > forbidden.txt
git add forbidden.txt
git commit -m "test: forbidden direct update"
REJECTED_OID=$(git rev-parse HEAD)
git push origin main # expected rejection
git fetch origin
printf 'remote_main=%s
expected_unchanged=%s
' "$(git rev-parse origin/main)" "$BASE_BEFORE"
# Discard only this intentionally rejected disposable local commit.
git reset --hard origin/main
Verification: origin/main must still equal
BASE_BEFORE. Your evidence record should say which rule
blocked the push, not merely “push failed.”
5. Open a compliant PR and satisfy required evidence
git switch -c normal-policy-change
printf 'normal governed change
' > normal.txt
git add normal.txt
git commit -m "docs: normal governed change"
git push -u origin normal-policy-change
gh pr create --base main --head normal-policy-change \
--title "Normal governed change" \
--body "Checkpoint normal path."
gh pr view --json number,baseRefOid,headRefOid,mergeStateStatus,statusCheckRollup
gh pr checks --watch
gh pr merge --squash --delete-branch
git switch main
git pull --ff-only
git log --oneline --decorate -5
Independent verification: query the active branch rules again and
compare the resulting main OID with the PR merge
evidence. The successful merge proves the policy permits compliant
flow; it does not prove bypass is safe.
6. Prepare the emergency-bypass runbook before using bypass
Create a local evidence note outside the repository (or on paper) with:
- Reason:
Chapter 10 isolated bypass rehearsal. - Allowed actor: repository administrator.
- Mode: For pull requests only.
-
Trigger: failing mock
policy-gatecaused solely by the exact disposable PR titleEmergency bypass rehearsal. - Scope: one PR only.
-
Recovery: immediate PR deleting
EMERGENCY_HOLD. - Closure: remove bypass actor and inspect Rule Insights/history if available.
Edit the ruleset bypass list: add Repository administrators and choose For pull requests only. This mode still blocks direct pushes but permits an eligible actor to choose an explicit PR bypass.
7. Rehearse one controlled PR-only bypass
git switch -c emergency-rehearsal
printf 'intentional mock hold
' > EMERGENCY_HOLD
printf 'This is a disposable bypass rehearsal.
' > emergency-note.md
git add EMERGENCY_HOLD emergency-note.md
git commit -m "test: create emergency bypass rehearsal"
git push -u origin emergency-rehearsal
gh pr create --base main --head emergency-rehearsal \
--title "Emergency bypass rehearsal" \
--body "Reason: Chapter 10 isolated bypass rehearsal. Recovery PR will remove EMERGENCY_HOLD."
gh pr checks
Expected: policy-gate fails because the workflow
deliberately recognizes the exact rehearsal PR title. The title is
evaluated by GitHub expression syntax and is not interpolated into a
shell command. Confirm a direct push is still not the bypass path.
In the PR merge box, GitHub should identify that your eligible admin
role can bypass the branch rules through the PR-only exception.
Capture the PR number, failing check, actor, reason, and current
main OID. Then, and only in this disposable lab, execute the
explicit bypass merge action GitHub presents. UI wording can change;
do not search for a hidden API shortcut.
{actor: repository-admin, mode: pull_request, check:
policy-gate=failure, decision: bypass-approved-for-lab, expected
audit: bypass event}. Then remove the marker from the branch, let the check pass, and
merge normally. Never widen bypass just to complete the exercise.
8. Recover immediately through the normal path
After a live bypass, main now contains the harmless
EMERGENCY_HOLD marker, but the mock gate fails only for
the exact rehearsal PR title. Recovery is deliberately a normal
compliant PR, not a second bypass, and removes the marker to restore
the repository state.
git switch main
git pull --ff-only
git switch -c emergency-recovery
git rm EMERGENCY_HOLD
printf '
Recovered through normal governed PR.
' >> emergency-note.md
git add emergency-note.md
git commit -m "recovery: remove emergency hold"
git push -u origin emergency-recovery
gh pr create --base main --head emergency-recovery \
--title "Recover after bypass rehearsal" \
--body "Removes the intentional checkpoint hold and returns to normal policy."
gh pr checks --watch
gh pr merge --squash --delete-branch
Now remove the Repository administrators bypass entry from
checkpoint-main-policy. Verify the normal policy
remains active and direct bypass authority is no longer configured.
9. Verify policy, bypass evidence, and cleanup
git switch main
git pull --ff-only
git status --short --branch
gh ruleset check --default -R OWNER/github-governance-checkpoint
gh ruleset list -R OWNER/github-governance-checkpoint --parents
gh api -H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2026-03-10" \
repos/OWNER/github-governance-checkpoint/rulesets --paginate \
--jq '.[] | {id,name,enforcement,target}'
Where the current ruleset UI exposes Rule Insights, inspect the failed direct action and bypass event. The exercise is incomplete if the technical change succeeded but no one can explain who bypassed what and why.
10. Write the operating policy
Your checkpoint deliverable should be a short policy with these headings:
| Policy element | Minimum statement |
|---|---|
| Protected scope | Default/release branches governed by named ruleset(s); test patterns before rollout |
| Normal change path | PR required; exact CI checks/reviews must pass |
| Check ownership | Each required name/source has an owning team and rename/change procedure |
| Bypass trigger | Only declared production emergency or policy-system outage |
| Bypass actor/mode | Minimum actor set; prefer PR-only for humans |
| Evidence | Incident/PR, actor, reason, blocked gate, before/after SHA, rule insight/audit record |
| Recovery | Return through normal PR path and remove temporary bypass access |
| Review | Retrospective asks why normal path failed and whether policy/evidence producer needs repair |
11. Final cleanup / rollback
Remove the checkpoint ruleset after evidence collection, or disable it if you want to inspect it briefly. Confirm no bypass actor remains. Then archive the disposable repository:
gh ruleset check --default -R OWNER/github-governance-checkpoint
# After deleting/disabling the lab ruleset, verify again.
gh ruleset list -R OWNER/github-governance-checkpoint --parents
gh repo archive OWNER/github-governance-checkpoint
Permanent repository deletion is not required. Archiving is reversible and keeps the lab evidence available for later study.
12. Checkpoint verification
- You predicted that activation changes policy, not a Git ref, and verified it.
-
You predicted that the direct push would fail and verified that
hosted
maindid not move. - You completed a normal PR whose required check passed.
- You configured bypass as PR-only, not unrestricted direct-push permission.
- Any live bypass was one harmless disposable PR with explicit reason.
- You recovered with a normal passing PR and removed bypass authority.
-
You can identify the active policy through both
gh rulesetand versioned REST inspection. - You produced an operating policy suitable for adapting to a real protected branch.
Knowledge check
Why was the bypass actor added only after the normal compliant path was proven?
So normal policy is tested independently and bypass cannot accidentally mask a broken baseline configuration.
The emergency PR has a failing mock check. What evidence must be captured before bypass?
At minimum the PR/actor, target/head SHA, failing requirement, emergency reason, current base SHA, approved exception scope, and recovery plan.
Why is the recovery PR required to pass the normal gate?
Recovery should demonstrate that the repository has returned to the ordinary governed path instead of chaining exceptions.
If PR-only bypass is unavailable, should you switch to “always allow” to finish the lab?
No. Use the supplied simulation and keep privileges narrow; do not weaken policy merely to reproduce a UI feature.
A check is renamed next month. What production process prevents a delivery outage?
Treat required-check identity as a governed contract: coordinate workflow and ruleset changes, test the new check, update policy deliberately, and verify before removing the old producer.
What does Chapter 10 add to the production GitHub operating model?
An explicit, observable change-control layer that binds pull requests and automated evidence to protected refs while governing exceptions and recovery.
13. Production handoff and bridge to Chapter 11
You can now explain not only how a PR merges, but why a protected release branch accepted or rejected a change and how an emergency exception is governed. Chapter 11 moves from protected integration state to tags and releases: immutable-ish names, release notes, assets, changelogs, and release governance. The same principle continues—identify the exact Git ref/object, hosted metadata, policy owner, and evidence before publishing something users may treat as a release.
Authoritative references
Creating rulesets for a repository
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.