Skip to content

Promote the agent git-bypass guard and Copilot poll-backoff to main (#449, #450) - #451

Merged
ptr727 merged 2 commits into
mainfrom
develop
Jul 26, 2026
Merged

Promote the agent git-bypass guard and Copilot poll-backoff to main (#449, #450)#451
ptr727 merged 2 commits into
mainfrom
develop

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Promotes two develop PRs to main:

  • Guard against agent git operations that require a branch-rule bypass #449 - Rule 4 in gh-write-guard.py: deny any agent git operation that would only land by bypassing an active branch rule (direct push to a PR-gated branch, force where history is protected, delete where deletion is blocked, and the explicit-bypass flags gh pr merge --admin / git commit|push --no-verify). Judged against the branch's live rules, so a code-style develop denies and a config-style develop allows with no hardcoded list. 71 self-test cases; 18 Copilot findings resolved across the review.
  • Poll a slow Copilot with backoff instead of escalating on a timeout #450 - Copilot Review Runbook: a slow/throttled Copilot review is pending, not missing - poll with backoff and report "still pending" rather than escalating on a timeout.

Carried-file/spec changes, so downstream repos re-vendor .github/copilot-instructions.md; the guard lives under host-setup/ (hub tooling). Docs/tooling only - no release.

Deploy of the guard to ~/.claude/hooks/ is held until this promotion passes review; the idempotent host installer + per-machine refresh tracking (#365) follow separately.

🤖 Generated with Claude Code

ptr727and others added 2 commits July 25, 2026 17:16
…449)
Extends the `gh-write-guard` PreToolUse hook with **Rule 4**: deny any
git operation that would only succeed by bypassing an active branch rule
- the gap behind the direct-push-to-develop incident this session, where
an admin-bypass identity makes a plain `git push origin develop`
silently land on a PR-gated branch.
## What it denies
- **Direct update** to a branch whose live rules require a pull request
(every `main`; code-style `develop`). A config-style `develop` has no
such rule and stays allowed - decided by the live rules, no hardcoded
repo list.
- **Force** where `non_fast_forward`/`required_linear_history` is
active.
- **Delete** where `deletion` is active.
- **Explicit-bypass flags**: `gh pr merge --admin`, `git commit/push
--no-verify`.
## Behavior
- The branch's rules come from
`repos/{owner}/{repo}/rules/branches/{branch}` (visible even to a bypass
actor).
- **Fail-closed** on `main`/`master`/`develop` when the rules cannot be
read; fail-open elsewhere (feature branches).
- Each denial names the bypassed rule, the protocol path, and hands the
exact command to the maintainer to run.
- Injectable `rules_lookup`/`current_branch` keep `--selftest`
deterministic and offline.
## Verification
- `--selftest`: 44/44 (existing 21 write-footgun cases + 22 new Rule-4
cases: code/config develop, main, feature, HEAD/sha/bare/+refspec/delete
refspecs, fail-closed vs fail-open, the explicit flags).
- Live end-to-end against real branch rules: `develop`/`main` deny, this
feature branch allow, `--admin`/`--no-verify` deny.
Docs/tooling only - no release. Deploy to `~/.claude/hooks/` is held
until this and the develop->main promotion both pass review.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…450)
Adds one paragraph to the GitHub Copilot Review Runbook's Bounded Retry
Workflow.
## Why
While driving #449 through 13 review rounds in an hour, Copilot
throttled and posted its final re-review ~36 minutes after the request -
beyond a 15-minute poll window. The poll timed out, and the Bounded
Retry Workflow treated that as a *genuinely missing* review and
escalated. It was not missing, only pending.
## Change
Clarify that a slow review is **pending, not missing**: a poll timeout
is evidence only that the review has not landed yet, so report `review
still pending`, poll on a widening interval, and enter escalation only
when the `requestReviews` mutation no-ops/errors or after a genuinely
long confirmed-accepted wait - never on one fixed poll window elapsing.
This complements the #444 head-coverage gate (which prevents concluding
*clean* too early) by preventing the opposite error - concluding
*unresponsive/blocked* too early.
Docs only - no release.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
CopilotAI review requested due to automatic review settings July 26, 2026 00:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Promotes two develop changes to main: a new Rule 4 in gh-write-guard.py that blocks git operations which would only succeed by bypassing active branch rules (plus explicit bypass flags), and a documentation update to the Copilot Review Runbook clarifying that slow reviews should be treated as pending with backoff polling.

Changes:

  • Add Rule 4 branch-rule-bypass detection to host-setup/agent-safety/gh-write-guard.py, including live branch-rules lookup and expanded deterministic self-tests.
  • Extend .github/copilot-instructions.md to advise poll-with-backoff behavior when Copilot reviews are slow/throttled.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

FileDescription
host-setup/agent-safety/gh-write-guard.pyAdds branch-rule-bypass protection (Rule 4) and expands parsing/self-test coverage for git push / bypass flags.
.github/copilot-instructions.mdDocuments backoff polling guidance for slow Copilot reviews to avoid premature escalation.

Comment threadhost-setup/agent-safety/gh-write-guard.py
@ptr727
ptr727 merged commit 059d749 into mainJul 26, 2026
7 checks passed
ptr727 added a commit that referenced this pull request Jul 26, 2026
Promotes #452 - the agent write-safety kit README updated to document
Rule 4 (branch-rule bypass + the unconditionally-denied
verification-skipping flags), the fail-closed behavior on the
protected-default branches, and an explicit Refreshing After an Upstream
Change section (re-run the installer = the refresh mechanism #365
tracks).
Docs only - no release. Restores develop==main after the guard/runbook
promotion (#451).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for freeto 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.

2 participants

@ptr727