-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Summary
Safe admin merge, when performed manually by Copilot CLI, has repeatedly broken branch protection settings on the main branch. This has happened across multiple incidents over the life of the project.
Root cause
The safe admin merge protocol required Copilot CLI to manually disable branch protection via API, merge a PR, then reconstruct the protection settings from memory. Copilot CLI is unreliable at this task — it forgets settings, uses wrong values, and hides mistakes behind summaries instead of showing raw API data.
Incident history
Incident 1: required_conversation_resolution silently disabled
Copilot CLI used the full PUT endpoint (repos/OWNER/REPO/branches/main/protection) to restore settings. The PUT API is a full replacement — omitting required_conversation_resolution from the JSON body silently set it to false. This happened on every admin merge without being detected.
Impact: PRs #172, #189, #193 merged with unresolved review threads.
Incident 2: Wrong required status check name (2026-03-22)
During safe admin merge of PR #245, Copilot CLI reconstructed branch protection with the required status check name set to CI (the workflow name) instead of check (the job name). GitHub matches against job names, not workflow names.
Impact:
- PR test: add direct unit tests for
_infer_model_from_metrics(#238) #246 permanently BLOCKED for 9 hours — theCIcheck never appeared - Orchestrator dispatched quality gate every 5 minutes — 100+ approval reviews accumulated on PR test: add direct unit tests for
_infer_model_from_metrics(#238) #246 - Wasted compute and API calls for 9 hours straight
Incident 3: Review settings left broken (2026-03-22)
When Copilot CLI fixed the status check name (Incident 2), it failed to also fix dismiss_stale_reviews (was false, should be true) and required_approving_review_count (was 0 but dismiss_stale_reviews being wrong meant reviews were not properly managed). It then tested hold/release scripts against live settings while the orchestrator was still running.
Impact: Three PRs (#252, #255, #256) auto-merged without any quality gate review. All three had to be reverted.
Why Copilot CLI cannot be trusted with this
- Reconstructs from memory: Instead of saving settings before and restoring them after, it tries to rebuild the config from what it remembers. It gets it wrong.
- Hides mistakes: Reports summaries of what it did instead of showing raw API responses. When asked to report before/after, it does it for a while then stops.
- Does not verify: Makes changes and moves on without checking the actual state matches what was intended.
- Compounds errors: When fixing one mistake, introduces new ones (fixed check name, broke review settings).
- Tests against live: Ran untested scripts against live branch protection while the orchestrator was actively merging PRs.
Expected behavior
Branch protection settings should never change during a safe admin merge except for the one setting needed to bypass protection temporarily. All other settings must remain untouched.
Current state
- PRs fix: update stale README command examples (#239) #252, Extract
_effective_statsto deduplicate active-vs-totals branching (#242) #255, refactor: consolidate duration formatting into _format_timedelta (#243) #256 reverted (pending push) - Issues [aw][code health] README command examples are stale (missing column, wrong token format) #239, Extract _effective_stats to deduplicate active-vs-totals branching #242, Consolidate duration formatting functions in report.py #243 need to be reopened
- Copilot CLI stripped of permission to modify branch protection directly
- Branch protection currently correct (verified via API)