ci(governance): make qa-review + security-review + reserved-path-review merge-blocking (#3141) #3142

Merged
devops-engineer merged 1 commits from ci/required-review-gates-3141 into main 2026-06-22 03:20:42 +00:00
4 changed files with 58 additions and 12 deletions
+30
View File
@@ -21,3 +21,33 @@ E2E Staging SaaS (full lifecycle) / E2E Staging Concierge Creates Workspace
# (pull_request)" to branch_protections/main.status_check_contexts AFTER this PR
# merges (allowlist-superset-of-BP is lint-clean; BP-superset-of-allowlist is not).
E2E Staging SaaS (full lifecycle) / E2E Staging Platform Boot
# #3141 (CTO-authorized): make the three review-team gates TRULY merge-blocking.
# Today they post commit statuses but are NOT in BP, so a PR merges once its 4
# BP-required contexts are green regardless of the review verdicts (proven: #3131
# merged with qa-review red).
#
# MECHANISM — Path B (owner BP flip) is the ONLY option; Path A (sentinel) is
# structurally impossible: `CI / all-required` is a plain `needs:` aggregator
# over CI's OWN jobs (ci.yml). Gitea has no cross-workflow `needs:`, and the
# poll-the-status-API design was deliberately removed (runner-squat RCA
# 2026-06-01). These three contexts are emitted by SEPARATE workflow files on
# pull_request_target / pull_request_review events, so the sentinel cannot gate
# them — which is exactly why ci-required-drift.py F4 enforces cross-workflow
# required contexts in BP directly.
#
# BP variant = (pull_request_target): it fires on every PR open/synchronize and
# starts RED when there is no APPROVE (review-check.sh exits 1 → job conclusion
# publishes `failure`) — fail-closed, no false-green, no deadlock. The
# pull_request_review path explicitly RE-POSTS the (pull_request_target) context
# to flip green on a genuine non-author APPROVE (same shape as sop-checklist).
# Requiring (pull_request_review) instead would deadlock (absent-until-review =
# pending forever).
#
# REMAINING OWNER ACTION: after THIS PR merges, PATCH
# branch_protections/main.status_check_contexts to ADD the three
# `(pull_request_target)` variants of the contexts below (keep the existing 4).
# Allowlist-superset-of-BP is lint-clean; BP-superset-of-allowlist is not — so
# the allowlist (this file) MUST land first, BP flip second. See #3141.
qa-review / approved
security-review / approved
reserved-path-review / reserved-path-review
+9 -1
View File
@@ -113,7 +113,15 @@ permissions:
statuses: write
jobs:
# bp-exempt: PR review bot signal; required merge state is enforced by CI / all-required.
# bp-required: pending #3141 — CTO-authorized: this gate is becoming TRULY
# merge-blocking. NB: `CI / all-required` does NOT enforce this context — it is
# a plain `needs:` aggregator over CI's OWN jobs (ci.yml) and Gitea has no
# cross-workflow `needs:`; the prior poll-the-status-API design was removed
# (runner-squat RCA 2026-06-01). Enforcement requires the BP context
# `qa-review / approved (pull_request_target)` to be in
# branch_protections/main.status_check_contexts (owner action, tracked in
# #3141; allowlist landed in .gitea/required-contexts.txt this PR, BP flip
# follows merge). `pending #NNN` per lint_required_context_exists_in_bp grammar.
approved:
# Gate the job:
# - On pull_request_target events: always run.
+10 -10
View File
@@ -58,16 +58,16 @@ permissions:
jobs:
# IS intended to be branch-protection-enforced (that's its purpose —
# closes cp#673). But main BP currently has 0 status_check_contexts
# (see .gitea/required-contexts.txt, only CI / all-required /
# E2E API Smoke / Handlers PG are pinned) so `bp-required: yes`
# would fail the in-BP verification. `bp-required: pending #673`
# therefore: commit to enforcement, defer the actual
# BP-status-check-add to a separate operator follow-up tracked via
# cp#673. (The actual addition of `reserved-path-review` to main
# BP status_check_contexts is an OPERATOR action — not in scope for
# the lint or this PR.)
# bp-required: pending #673 — the reserved-path-review self-merge guard
# closes cp#673). The BP context add (`reserved-path-review /
# reserved-path-review (pull_request_target)` → main
# status_check_contexts) is an OPERATOR action; it is now CTO-authorized
# and tracked in #3141 alongside qa-review + security-review (the same
# owner BP flip). The allowlist (.gitea/required-contexts.txt) lands this
# PR; the BP flip follows merge (allowlist-superset-of-BP is lint-clean,
# the reverse is not). `bp-required: yes` would fail the in-BP verification
# until BP is flipped, so this stays `pending #NNN` per
# lint_required_context_exists_in_bp grammar.
# bp-required: pending #3141 — the reserved-path-review self-merge guard
reserved-path-review:
runs-on: ubuntu-latest
# Draft PRs can't merge anyway; skip to save a runner. Still runs on
+9 -1
View File
@@ -36,7 +36,15 @@ permissions:
statuses: write
jobs:
# bp-exempt: PR security review bot signal; required merge state is enforced by CI / all-required.
# bp-required: pending #3141 — CTO-authorized: this gate is becoming TRULY
# merge-blocking. NB: `CI / all-required` does NOT enforce this context — it is
# a plain `needs:` aggregator over CI's OWN jobs (ci.yml) and Gitea has no
# cross-workflow `needs:`; the prior poll-the-status-API design was removed
# (runner-squat RCA 2026-06-01). Enforcement requires the BP context
# `security-review / approved (pull_request_target)` to be in
# branch_protections/main.status_check_contexts (owner action, tracked in
# #3141; allowlist landed in .gitea/required-contexts.txt this PR, BP flip
# follows merge). `pending #NNN` per lint_required_context_exists_in_bp grammar.
approved:
# Gate the job:
# - On pull_request_target events: always run.