Skip to content

fix(scheduler): require independent exact-head approval - #828

Draft
seonghobae wants to merge 11 commits into
mainfrom
fix/scheduler-independent-current-head-approval
Draft

fix(scheduler): require independent exact-head approval#828
seonghobae wants to merge 11 commits into
mainfrom
fix/scheduler-independent-current-head-approval

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Safety gap

The organization merge scheduler could previously enter direct-merge/auto-merge paths from a same-head OpenCode APPROVED review even when GitHub still reported reviewDecision: REVIEW_REQUIRED. That lets automation policy run ahead of the repository's independent-review gate and is unsafe if a routine scheduler credential ever acquires a ruleset bypass path.

Test-first repair

Exact RED head c7011f23356eee92c3569709a893790a6b0893c4 added only tests/test_scheduler_independent_approval_gate.py from protected main 1131b1bbafb24e455fc8619cdf316813e8721861.

The production repair now requires, before merge/auto-merge entrypoints:

  • GitHub aggregate reviewDecision == APPROVED;
  • a non-empty pull-request author identity from authoritative GitHub PR metadata;
  • exact-current-head OpenCode approval where configured;
  • an exact-current-head formal APPROVED review from a non-author, non-OpenCode identity; and
  • every pre-existing exact-head Strix/security/check/thread/mergeability/freshness/expected-head gate.

Stale, predecessor-head, dismissed, comment-only, anonymous, author-self, OpenCode-only, status-only, or synthetic-merge evidence remains non-authorizing. No approval is synthesized and no branch/ruleset protection is weakened.

The mature scheduler engine remains in scripts/ci/_pr_review_merge_scheduler_core.py; scripts/ci/pr_review_merge_scheduler.py is the auditable approval-policy facade. This is permanent reviewed source structure, not a temporary repair workflow.

Exact-current-head state

Authoritative head: 8abddc8df9ebddcb14e40e818593e71e1c4ca40a.

Protected base: main at 1131b1bbafb24e455fc8619cdf316813e8721861.

The current head already repaired the stale source-layout contract so test_privileged_review_retries_use_default_branch_repository_dispatch follows the authoritative scheduler core rather than requiring duplicated production literals in the facade.

Current exact-head workflow evidence:

  • Scheduler Independent Approval Quality CI: success;
  • CodeQL PR: success;
  • Python Security: success;
  • Security Scan: success;
  • SAST Semgrep: success;
  • Secret Scan: success;
  • OSV-Scanner PR: success;
  • Scorecard PR: success;
  • SBOM Generation: success;
  • Strix Changed Path Quality CI run 31229459086: failed.

That Strix quality run checked out exact head 8abddc8d... and completed the central suite with 978 passed, 16 subtests passed, 6 failed. All six failures are stale positive merge-path fixtures in tests/test_pr_review_merge_scheduler.py: they still model reviewDecision: REVIEW_REQUIRED and/or OpenCode-only approval while expecting merge/auto-merge behavior.

The remaining test repair must update only those positive fixtures to model the real post-repair authorization state: reviewDecision: APPROVED, authoritative pull-request author identity, exact-head OpenCode approval, and an exact-head formal approval from a different non-OpenCode reviewer. Negative review-policy fixtures must remain fail-closed. Do not weaken production logic or globally inject approvals into the legacy helper merely to make the suite green.

The authoritative legacy test blob observed at this head is 3e421e9039654aa669bf147db3be63fd1386d461. Any head/base/blob movement invalidates this repair plan and requires a fresh read before mutation.

Required next validation

After the six fixtures are corrected, rerun the focused independent-approval regression, complete central suite, Strix quick gate, Python compilation, exact 100% production statement/branch coverage and public-docstring coverage, then regenerate every exact-head security/supply-chain and automated-review surface. Keep Draft until zero valid unresolved findings, qualifying independent non-author approval, repository policy, and branch protection all pass without bypass.

Documentation and governance boundary

docs/doctoring/scheduler-independent-current-head-approval.md and CHANGELOG.md record the incident boundary, exact-head approval semantics, rollback, non-claims, and current GitHub protected-branch/ruleset references. This PR closes #771 only after protected merge; it does not itself solve the organization-wide counted-human-review availability gap tracked separately in #772.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@seonghobae, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2e43cea5-d23d-4806-830e-0da0515febd6

📥 Commits

Reviewing files that changed from the base of the PR and between 1131b1b and c10607a.

📒 Files selected for processing (8)
  • .github/workflows/scheduler-independent-approval-quality-ci.yml
  • CHANGELOG.md
  • docs/doctoring/scheduler-independent-current-head-approval.md
  • scripts/ci/_pr_review_merge_scheduler_core.py
  • scripts/ci/pr_review_merge_scheduler.py
  • tests/test_pr_review_merge_scheduler.py
  • tests/test_required_workflow_queue_contract.py
  • tests/test_scheduler_independent_approval_gate.py

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

Repair only the six stale positive scheduler fixtures on exact current Draft head 8abddc8df9ebddcb14e40e818593e71e1c4ca40a, protected base 1131b1bbafb24e455fc8619cdf316813e8721861. The authoritative tests/test_pr_review_merge_scheduler.py blob is still 3e421e9039654aa669bf147db3be63fd1386d461; abort and re-read if head/base/blob moves.

Production approval policy is already the intended security fix and must not be weakened. Strix Changed Path Quality CI run 31229459086 completed the central suite with 978 passed + 16 subtests and exactly six stale positive-path failures because they still expect merge/auto-merge while modeling reviewDecision: REVIEW_REQUIRED and/or OpenCode-only approval:

  • test_inspect_pr_blocks_and_waits_for_policy_states
  • test_inspect_pr_handles_approved_reviews_and_dispatch
  • test_direct_or_auto_falls_back_to_auto_merge_when_branch_policy_blocks_direct_merge
  • test_direct_or_auto_attempts_direct_merge_when_mergeability_is_blocked
  • test_body_head_sha_approval_prevents_same_run_opencode_rerun
  • test_current_head_approval_cleans_previous_head_change_gate_before_merge

Update only the semantically authorized positive fixtures used by those paths so they model the real post-repair authorization state: reviewDecision: "APPROVED"; authoritative non-empty PR author.login; exact-current-head OpenCode formal approval where configured; and an exact-current-head formal APPROVED review from a different non-author, non-OpenCode identity. Preserve predecessor/stale/self/comment-only/anonymous/REVIEW_REQUIRED negatives as fail-closed.

Do not change the default make_pr() helper to globally inject approval. If repetition warrants it, add a narrow beginner-readable helper such as an explicitly named authorized/mergeable fixture constructor and use it only where the test is supposed to prove an authorized merge path. Preserve explicit caller-provided reviews and derive the review commit from that fixture's current headRefOid rather than hard-coding head when a test overrides the head.

After the test-only repair, rerun the focused independent-approval gate, complete central suite, Strix quick gate, compilation, exact 100% production statement/branch coverage and public-docstring gate, plus all exact-head security/supply-chain checks. Keep Draft; no self-approval, synthetic approval, branch-protection bypass, or temporary/write-capable repair workflow.

Copy link
Copy Markdown
Contributor Author

@opencode-agent Fix only the current exact-head Strix regression on PR #828 at head 8abddc8df9ebddcb14e40e818593e71e1c4ca40a, base 1131b1bbafb24e455fc8619cdf316813e8721861, with tests/test_pr_review_merge_scheduler.py blob 3e421e9039654aa669bf147db3be63fd1386d461. The exact-head Strix job 31229459086 proved 978 passed / 16 subtests passed / 6 failed; all six failures are stale positive merge/auto-merge fixtures, not production defects. Repair those positive fixtures test-first so each merge-authorizing case explicitly models the post-repair authorization state already pinned by tests/test_scheduler_independent_approval_gate.py: reviewDecision="APPROVED", a non-empty PR author.login (e.g. pull-request-author), the existing exact-head OpenCode APPROVED review, and an exact-head formal APPROVED review from a different non-OpenCode/non-author identity (e.g. cwl-noema-review). Do not change the default make_pr() to approved, do not globally inject approval, do not weaken production scheduler logic, and do not alter negative/fail-closed review-policy fixtures.

The six observed failures to repair are:

  1. test_body_head_sha_approval_prevents_same_run_opencode_rerun
  2. test_current_head_approval_cleans_previous_head_change_gate_before_merge
  3. the rest_clean positive case inside test_inspect_pr_blocks_and_waits_for_policy_states
  4. merge-authorizing positive cases inside test_inspect_pr_handles_approved_reviews_and_dispatch (update every positive path that must now satisfy the gate, not just the first assertion; preserve negative cases)
  5. test_direct_or_auto_falls_back_to_auto_merge_when_branch_policy_blocks_direct_merge
  6. test_direct_or_auto_attempts_direct_merge_when_mergeability_is_blocked

Use an explicit small positive-fixture helper only if it makes the intent clearer; it must not affect default/negative fixtures. Before pushing, re-read the live PR head and target blob and abort/re-plan if either moved. Validate the focused independent-approval regression, all affected legacy scheduler tests, full suite, exact 100% production statement/branch coverage and public-docstring gate, Strix quick gate, compilation/syntax, and clean diff. Keep the PR Draft and do not merge or synthesize approval.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review
@opencode-agent review
@cwl-noema-review review

Review-only on exact current head c10607aec1f1f23f2125422310101e03de9bd86d. Do not mutate the branch, approve from the author identity, merge, release, or create repair automation. Verify that the scheduler facade still delegates to the authoritative core without duplicating privileged implementation, that the independent exact-current-head approval gate remains fail-closed (reviewDecision == APPROVED, non-empty PR author, exact-head OpenCode approval where configured, and a distinct exact-head non-author/non-OpenCode formal approval), and that positive scheduler fixtures do not weaken negative stale/self/comment-only/anonymous/review-required cases. Treat all predecessor-head checks and reviews as stale. Report only exact-head actionable findings or an exact-head no-finding verdict.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected_head='c10607aec1f1f23f2125422310101e03de9bd86d'
repo='ContextualWisdomLab/.github'
pr='828'

echo '== Live PR metadata =='
gh pr view "$pr" --repo "$repo" --json number,isDraft,headRefOid,baseRefOid,url \
  --jq '{number, isDraft, headRefOid, baseRefOid, url}'

echo '== Checked-out commit =='
git rev-parse HEAD
git status --short

echo '== Exact-head commit verification =='
test "$(git rev-parse HEAD)" = "$expected_head"
test "$(gh pr view "$pr" --repo "$repo" --json headRefOid --jq .headRefOid)" = "$expected_head"
echo 'exact-head verified'

echo '== Changed files at exact head relative to merge base =='
base="$(git merge-base HEAD origin/main)"
git diff --name-status "$base"...HEAD

echo '== Relevant source/test file locations =='
fd -t f -a '(^|/)(pr_review_merge_scheduler|_pr_review_merge_scheduler_core|test_scheduler_independent_approval_gate|test_pr_review_merge_scheduler)\.py$' .

echo '== Python structure maps =='
ast-grep outline scripts/ci/pr_review_merge_scheduler.py --items all || true
ast-grep outline scripts/ci/_pr_review_merge_scheduler_core.py --items all || true
ast-grep outline tests/test_scheduler_independent_approval_gate.py --items all || true
ast-grep outline tests/test_pr_review_merge_scheduler.py --items all || true

echo '== Policy identifiers with context =='
rg -n -C 5 --type py \
  'reviewDecision|headRefOid|author|OpenCode|APPROVED|independent|formal.*review|reviews' \
  scripts/ci/pr_review_merge_scheduler.py \
  scripts/ci/_pr_review_merge_scheduler_core.py \
  tests/test_scheduler_independent_approval_gate.py \
  tests/test_pr_review_merge_scheduler.py

echo '== Exact-head diff for relevant files =='
git diff --unified=80 "$base"...HEAD -- \
  scripts/ci/pr_review_merge_scheduler.py \
  scripts/ci/_pr_review_merge_scheduler_core.py \
  tests/test_scheduler_independent_approval_gate.py \
  tests/test_pr_review_merge_scheduler.py

Length of output: 101369


🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected_head='c10607aec1f1f23f2125422310101e03de9bd86d'
test "$(git rev-parse HEAD)" = "$expected_head"

facade='scripts/ci/pr_review_merge_scheduler.py'
core='scripts/ci/_pr_review_merge_scheduler_core.py'
legacy='tests/test_pr_review_merge_scheduler.py'
regression='tests/test_scheduler_independent_approval_gate.py'

echo '== Facade full map and bounded source =='
nl -ba "$facade" | sed -n '1,360p'

echo '== Core approval-related definitions and entrypoint call sites =='
rg -n -C 12 --type py \
  '^(def (pull_request_author_login|has_independent_current_head_approval|merge_approval_block_reason|inspect_pr|enable_auto_merge|merge_pr|fetch_pr|fetch_open_prs)|PULL_REQUEST_FIELDS_FRAGMENT)|\bmerge_approval_block_reason\(|\bhas_independent_current_head_approval\(|Decision\(.*"(merge|auto_merge)"' \
  "$core"

echo '== Core exact source regions around each relevant definition/call =='
for line in $(rg -n --type py \
  '^(def (pull_request_author_login|has_independent_current_head_approval|merge_approval_block_reason|inspect_pr|enable_auto_merge|merge_pr|fetch_pr|fetch_open_prs)|PULL_REQUEST_FIELDS_FRAGMENT)|\bmerge_approval_block_reason\(' \
  "$core" | cut -d: -f1 | sort -nu); do
  start=$(( line > 25 ? line - 25 : 1 ))
  end=$(( line + 100 ))
  echo "--- $core:$start-$end ---"
  nl -ba "$core" | sed -n "${start},${end}p"
done

echo '== Merge and auto-merge return sites, with enclosing context =='
rg -n -C 20 --type py 'Decision\([^)]*"(merge|auto_merge)"|action="(merge|auto_merge)"' "$core"

echo '== Approval regression test, complete =='
nl -ba "$regression" | sed -n '1,280p'

echo '== Legacy fixture definitions and all modified authorized/negative-policy regions =='
rg -n -C 16 --type py \
  '^(def (make_pr|merge_approved_pr|test_body_head_sha_approval_prevents_same_run_opencode_rerun|test_current_head_approval_cleans_previous_head_change_gate_before_merge|test_inspect_pr_blocks_and_waits_for_policy_states|test_inspect_pr_handles_approved_reviews_and_dispatch|test_direct_or_auto_falls_back_to_auto_merge_when_branch_policy_blocks_direct_merge|test_direct_or_auto_attempts_direct_merge_when_mergeability_is_blocked))|reviewDecision|independent-reviewer|pull-request-author|COMMENTED|anonymous|stale|previous-head' \
  "$legacy"

echo '== Test-only diff, minimal context =='
base="$(git merge-base HEAD origin/main)"
git diff --unified=12 "$base"...HEAD -- "$legacy" "$regression"

Length of output: 2832


🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected_head='c10607aec1f1f23f2125422310101e03de9bd86d'
test "$(git rev-parse HEAD)" = "$expected_head"

numbered() { awk '{printf "%6d\t%s\n", NR, $0}' "$1"; }

facade='scripts/ci/pr_review_merge_scheduler.py'
core='scripts/ci/_pr_review_merge_scheduler_core.py'
legacy='tests/test_pr_review_merge_scheduler.py'
regression='tests/test_scheduler_independent_approval_gate.py'

echo '== Facade, complete (expected small policy facade) =='
numbered "$facade"

echo '== Core approval definitions and calls =='
rg -n -C 10 --type py \
  '^(def (pull_request_author_login|has_independent_current_head_approval|merge_approval_block_reason|inspect_pr|enable_auto_merge|merge_pr|fetch_pr|fetch_open_prs)|PULL_REQUEST_FIELDS_FRAGMENT)|\bmerge_approval_block_reason\(|\bhas_independent_current_head_approval\(' \
  "$core"

echo '== Core exact regions =='
for line in $(rg -n --type py \
  '^(def (pull_request_author_login|has_independent_current_head_approval|merge_approval_block_reason|inspect_pr|enable_auto_merge|merge_pr|fetch_pr|fetch_open_prs)|PULL_REQUEST_FIELDS_FRAGMENT)' \
  "$core" | cut -d: -f1 | sort -nu); do
  start=$(( line > 20 ? line - 20 : 1 ))
  end=$(( line + 120 ))
  echo "--- $core:$start-$end ---"
  sed -n "${start},${end}p" "$core" | awk -v n="$start" '{printf "%6d\t%s\n", n++, $0}'
done

echo '== All core merge/auto-merge decision sites =='
rg -n -C 24 --type py 'Decision\([^)]*"(merge|auto_merge)"|action="(merge|auto_merge)"' "$core"

echo '== Independent-gate regression test =='
numbered "$regression"

echo '== Legacy fixture helpers =='
sed -n '1,115p' "$legacy" | awk '{printf "%6d\t%s\n", NR, $0}'

echo '== Legacy tests named in the request, with sufficient bounded context =='
for name in \
  test_body_head_sha_approval_prevents_same_run_opencode_rerun \
  test_current_head_approval_cleans_previous_head_change_gate_before_merge \
  test_inspect_pr_blocks_and_waits_for_policy_states \
  test_inspect_pr_handles_approved_reviews_and_dispatch \
  test_direct_or_auto_falls_back_to_auto_merge_when_branch_policy_blocks_direct_merge \
  test_direct_or_auto_attempts_direct_merge_when_mergeability_is_blocked; do
  line="$(rg -n "^def ${name}\b" "$legacy" | head -1 | cut -d: -f1)"
  echo "--- $legacy:$line ($name) ---"
  sed -n "${line},$((line + 300))p" "$legacy" | awk -v n="$line" '{printf "%6d\t%s\n", n++, $0}' \
    | sed -n '1,/^ *[0-9][0-9]*[[:space:]]def /{ /^ *[0-9][0-9]*[[:space:]]def /!p; }'
done

echo '== Direct negative-policy test cases in legacy suite =='
rg -n -C 8 --type py \
  'REVIEW_REQUIRED|CHANGES_REQUESTED|COMMENTED|author.*login|author.*\{\}|author.*None|commit.*old|previous-head|anonymous|independent' \
  "$legacy"

echo '== Test-only exact-head diff =='
base="$(git merge-base HEAD origin/main)"
git diff --unified=16 "$base"...HEAD -- "$legacy" "$regression"

Length of output: 178950


🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected_head='c10607aec1f1f23f2125422310101e03de9bd86d'
repo='ContextualWisdomLab/.github'
test "$(git rev-parse HEAD)" = "$expected_head"
test "$(gh pr view 828 --repo "$repo" --json headRefOid --jq .headRefOid)" = "$expected_head"

core='scripts/ci/_pr_review_merge_scheduler_core.py'
facade='scripts/ci/pr_review_merge_scheduler.py'

echo '== Exact live head remains verified =='
gh pr view 828 --repo "$repo" --json headRefOid,isDraft --jq '{headRefOid,isDraft}'

echo '== Complete core decision segment =='
sed -n '2340,2650p' "$core" | awk -v n=2340 '{printf "%6d\t%s\n", n++, $0}'

echo '== Production direct-core imports, file execution, and scheduler entrypoints =='
rg -n -C 4 \
  '_pr_review_merge_scheduler_core|pr_review_merge_scheduler(\.py)?|--self-test|inspect_pr\(' \
  --glob '*.py' --glob '*.yml' --glob '*.yaml' --glob '!tests/**' .

echo '== Workflow references to scheduler files =='
rg -n -C 5 \
  'scripts/ci/(pr_review_merge_scheduler|_pr_review_merge_scheduler_core)\.py' \
  .github

echo '== Core module export or runtime alias changes =='
rg -n -C 4 \
  '__all__|sys\.modules|importlib|exec_module|from scripts\.ci\._pr_review_merge_scheduler_core|import scripts\.ci\._pr_review_merge_scheduler_core' \
  scripts tests .github

echo '== Final changed file list and production diff summary =='
base="$(git merge-base HEAD origin/main)"
git diff --stat "$base"...HEAD
git diff --name-status "$base"...HEAD
git diff --check "$base"...HEAD
git diff --unified=8 "$base"...HEAD -- "$facade" "$core"

Length of output: 108137


@seonghobae, no exact-head actionable findings.

I verified live PR #828 head c10607aec1f1f23f2125422310101e03de9bd86d.

The facade delegates scheduler behavior to the authoritative core. It adds the approval boundary without duplicating privileged scheduler implementation.

The merge gate fails closed for:

  • reviewDecision != APPROVED;
  • missing PR author identity;
  • stale reviews;
  • author self-approval;
  • OpenCode-only approval;
  • anonymous reviews; and
  • comment-only reviews.

The positive fixtures use a narrow authorized fixture helper. The default fixture remains REVIEW_REQUIRED with no injected approval. Negative fixtures remain fail-closed.

No branch mutation, approval, merge, release, or repair automation was performed.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

Reconcile this Draft with the exact current protected main before generating any further review evidence. Current PR head is c10607aec1f1f23f2125422310101e03de9bd86d; current protected main is 6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba. The branch is one protected-main commit behind. The only overlapping path from that base movement is CHANGELOG.md: PR blob aa391048c86632aa2010ec249c6980aa8ba26aff, protected-main blob bf30091dd6df4551f211142b4828b5c674362bb8.

Before writing, refetch and require those head/main/blob identities to remain exact. Merge the protected-main tip into the existing branch with a normal non-forced merge. Resolve CHANGELOG.md by preserving both independent [Unreleased] fixes: protected main's bounded Strix timeout-fixture entry and this PR's independent exact-head approval-gate entry. Preserve every other line from both sides. No rebase/force-push, -X ours/-X theirs, temporary/write-capable workflow, global fixture approval injection, reviewer/credential change, or production-policy weakening.

After reconciliation, ensure the effective feature diff remains the scheduler approval-policy facade/core, its permanent quality workflow/tests, doctoring, and changelog only. Rerun Scheduler Independent Approval Quality CI, the complete central suite, Strix Changed Path Quality CI, Python compilation, exact 100% production statement/branch and public-docstring gates, plus security/supply-chain checks. Keep Draft until fresh exact-head automated review, zero valid unresolved findings, qualifying independent non-author approval, and branch protection all pass.

Copy link
Copy Markdown
Contributor Author

@opencode-agent address

Reconcile this scheduler separation-of-duties repair onto current protected main without rewriting history. Exact PR head is c10607aec1f1f23f2125422310101e03de9bd86d; current protected main tip is 6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba. The approval-policy facade blob is 1d6538b306094c09e13928698efbc464f1450943 on the PR head and 75e18c860c30b80055bec18a6c3c456f1d53d195 on current main. Do not write if the head, protected-main tip, or relevant blobs have moved.

Use a trusted checkout and normally merge exact protected main into this existing branch. Preserve all newer main behavior and the narrow authorization invariant already implemented on this branch:

  • direct merge or auto-merge entrypoints require GitHub aggregate reviewDecision == APPROVED;
  • authoritative PR author identity must be non-empty;
  • exact-current-head OpenCode approval remains required where configured;
  • a separate exact-current-head formal APPROVED review must come from a non-author, non-OpenCode identity;
  • all existing exact-head Strix/security/check/thread/mergeability/freshness/expected-head gates remain in force;
  • stale, dismissed, comment-only, anonymous, author-self, OpenCode-only, status-only, predecessor-head, or synthetic evidence remains non-authorizing.

The current branch diff already updates positive scheduler fixtures toward merge_approved_pr/independent-review evidence; do not globally inject approvals into negative fixtures and do not weaken the production facade merely to satisfy legacy tests. Resolve merge conflicts minimally, preserving the mature core plus the auditable approval-policy facade.

Do not force-push, use -X ours/-X theirs, create temporary/self-modifying/write-capable workflows, or change reviewer credentials/branch protection. After reconciliation run the focused independent-approval quality gate, complete central suite and Strix quick gate, exact 100% production statement/branch/public-docstring gates, and all security/supply-chain checks on the resulting exact head. Keep Draft until zero valid findings and current-head automated/independent review are satisfied; do not merge or synthesize approval.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Block scheduler merges without exact-head independent approval

1 participant