Branch Protection Baseline (GitHub Team — Repository Rulesets)¶
Review-first guide. This document describes the live branch protection configuration on BookingZone repos using GitHub repository rulesets (not classic branch protection). Do not modify rulesets without owner approval.
Last verified: 2026-09-25
Overview¶
BookingZone uses GitHub Team, which supports repository-level rulesets but
not organization-level rulesets (requires GitHub Enterprise). Protection is
applied per-repo via a single ruleset named bz-protect-canonical.
Ruleset: bz-protect-canonical¶
Status: Active on all target repos.
Protected refs by repo¶
| Repo | Refs |
|---|---|
reservation-api-server |
main, develop, release/** |
admin-web-app |
main, develop, release/** |
venuplus-app |
main, develop, release/** |
customer-web-app |
main, develop, release/** |
bz-platform-context |
main |
reservation-browser-tests |
main |
Release ref pattern: Repos currently use
release/YYYY.MM.DD.N(e.g.,release/2026.09.24.1). ADR-0007 prefers semverrelease/x.y.z. The ruleset usesrelease/**to accommodate both patterns — the naming gap should be addressed in a future standardization effort, not silently changed here.
Rules enforced (all repos)¶
| Rule | Setting |
|---|---|
| Deletion | Blocked |
| Non-fast-forward (force push) | Blocked |
| Required linear history | Yes |
| Pull request required | Yes |
| Required approvals | 0 (solo merges allowed; raise later) |
| Dismiss stale reviews | Yes |
| Require conversation resolution | Yes |
| Allowed merge methods | Squash only |
| Bypass actors | RepositoryRole: Admin (actor_id 5, always) |
Required status checks¶
Status checks use strict=false and do_not_enforce_on_create=true.
| Repo | Required checks |
|---|---|
reservation-api-server |
branch-name / check-branch-name, discipline / spec-discipline |
admin-web-app |
branch-name / check-branch-name, discipline / spec-discipline |
customer-web-app |
branch-name / check-branch-name, discipline / spec-discipline |
venuplus-app |
branch-name / check-branch-name, discipline / spec-discipline |
bz-platform-context |
branch-name / check-branch-name |
reservation-browser-tests |
None (no process-guard callers yet) |
Repository merge settings¶
Applied to all six repos:
{
"allow_squash_merge": true,
"allow_merge_commit": false,
"allow_rebase_merge": false,
"delete_branch_on_merge": true,
"allow_auto_merge": true,
"squash_merge_commit_title": "PR_TITLE",
"squash_merge_commit_message": "PR_BODY"
}
Disabled legacy rulesets¶
| Repo | Ruleset name | ID | Status |
|---|---|---|---|
customer-web-app |
Main Branch |
3684145 | Disabled |
reservation-api-server |
develop-rule |
16825918 | Disabled |
What is NOT applied (and why)¶
| Feature | Reason |
|---|---|
| Organization rulesets | Requires GitHub Enterprise + admin:org scope. aerospace-apps is on GitHub Team. |
| Organization required workflows | Requires GitHub Enterprise. |
| 1 required approval | Solo merges are allowed for now; raise approval requirement later when team grows. |
| Required Unit Tests / Ruff / verify checks | Path-skips and currently red tips would lock merges. Add only after green + stable job names. |
Verification commands¶
List all rulesets on a repo¶
Get full ruleset details¶
Check repo merge settings¶
gh api repos/aerospace-apps/<repo> --jq '{
allow_squash_merge,
allow_merge_commit,
allow_rebase_merge,
delete_branch_on_merge,
allow_auto_merge,
squash_merge_commit_title,
squash_merge_commit_message
}'
List required status checks for a ruleset¶
gh api repos/aerospace-apps/<repo>/rulesets/<ruleset_id> \
--jq '.rules[] | select(.type == "required_status_checks") | .parameters.required_status_checks'
Apply / update commands (execute only after approval)¶
Create a new ruleset¶
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
repos/aerospace-apps/<repo>/rulesets \
--input ruleset.json
Update an existing ruleset¶
gh api \
--method PUT \
-H "Accept: application/vnd.github+json" \
repos/aerospace-apps/<repo>/rulesets/<ruleset_id> \
--input ruleset.json
Example ruleset JSON shape (bz-protect-canonical)¶
{
"name": "bz-protect-canonical",
"target": "branch",
"enforcement": "active",
"conditions": {
"ref_name": {
"include": ["refs/heads/main", "refs/heads/develop", "refs/heads/release/**"],
"exclude": []
}
},
"rules": [
{ "type": "deletion" },
{ "type": "non_fast_forward" },
{ "type": "required_linear_history" },
{
"type": "pull_request",
"parameters": {
"required_approving_review_count": 0,
"dismiss_stale_reviews_on_push": true,
"require_last_push_approval": false,
"required_review_thread_resolution": true,
"allowed_merge_methods": ["squash"]
}
},
{
"type": "required_status_checks",
"parameters": {
"strict_required_status_checks_policy": false,
"do_not_enforce_on_create": true,
"required_status_checks": [
{ "context": "branch-name / check-branch-name" },
{ "context": "discipline / spec-discipline" }
]
}
}
],
"bypass_actors": [
{
"actor_id": 5,
"actor_type": "RepositoryRole",
"bypass_mode": "always"
}
]
}
Adjust
conditions.ref_name.includeandrules[].parameters.required_status_checksper repo as shown in the tables above.
Update repo merge settings¶
gh api \
--method PATCH \
-H "Accept: application/vnd.github+json" \
repos/aerospace-apps/<repo> \
-f allow_squash_merge=true \
-f allow_merge_commit=false \
-f allow_rebase_merge=false \
-f delete_branch_on_merge=true \
-f allow_auto_merge=true \
-f squash_merge_commit_title=PR_TITLE \
-f squash_merge_commit_message=PR_BODY
Break-glass policy¶
The bz-protect-canonical ruleset grants Admin bypass (actor_id: 5,
bypass_mode: always). Repository admins can push directly or merge without
passing checks in emergencies.
When to use¶
- Critical production incident requiring immediate hotfix.
- CI infrastructure is down and blocking a time-sensitive deploy.
Procedure¶
- Only repo admins may bypass.
- Post incident note in
#engineeringSlack channel immediately. - Open a follow-up issue within 24 hours explaining why bypass was needed.
- Do not disable the ruleset — use the bypass mechanism.
Rollout checklist¶
When adding a new repo to this protection scheme:
- Verify repo is on GitHub Team (not Free).
- Create
bz-protect-canonicalruleset with appropriate refs. - Configure required status checks (only if CI callers exist and are green).
- Apply repo merge settings (squash-only, delete branch on merge, auto-merge).
- Disable any legacy branch protection rules or rulesets.
- Update this document with the new repo.
- Add the repo to
repo-registry.mdif not already present.
Human + AI git best practices¶
Always¶
- Create short-lived feature branches from
origin/develop(ororigin/mainfor docs repos). - Use PRs for every change.
- Keep PRs small and scoped.
- Use conventional commit style in PR titles (becomes squash message).
- Keep local
main/developfast-forward only.
Never¶
- Never commit directly on protected branches.
- Never push directly to protected branches.
- Never run plain
git pullon protected branches (use--ff-only). - Never force-push to protected branches (ruleset blocks this anyway).
AI-specific guardrails¶
- AI-authored PRs require human reviewer approval (when approvals are raised).
- Use normal branch naming; no special AI prefix required.
- Keep AI provenance in PR description (or co-author trailer).
- Do not allow AI tools to bypass hooks/policies except break-glass.
Local safety defaults (developer machine)¶
Run once per repo:
git config --local pull.ff only
git config --local merge.ff only
git config --local fetch.prune true
Optional shared hooks (.githooks/):
pre-committo block direct commits on protected branches.pre-pushto block direct pushes to protected branches.