Skip to content

feat(38-01): review-bot auto-merge mechanism (classifier + workflow)#17

Open
OgeonX-Ai wants to merge 3 commits into
mainfrom
feat/merge-flow-review-bot
Open

feat(38-01): review-bot auto-merge mechanism (classifier + workflow)#17
OgeonX-Ai wants to merge 3 commits into
mainfrom
feat/merge-flow-review-bot

Conversation

@OgeonX-Ai

Copy link
Copy Markdown
Contributor

Summary

Implements the review-bot mechanism for REQ-1.5.1 (Phase 38-01):

  • classify-automerge-eligibility.ps1: fail-closed diff classifier. IN-CLASS iff (dependabot[bot] author AND every changed path is a dependency-manifest file) OR (every changed path matches the docs allowlist). The workflow/executable denylist applies to ALL authors including dependabot -- -SelfTest carries the blocker-docs: establish enterprise organization governance #2 regression fixture (dependabot-with-workflow-file -> OUT-OF-CLASS).
  • auto-merge-eligibility.yml: wires the classifier as the required status check automerge-eligibility on every PR.
  • review-bot.yml: mints a cas-review-bot App installation token, then gates approval on three fail-closed checks in sequence -- classifier IN-CLASS, autogen critic_cli (pinned to origin/main commit b0524b7, PR feat(38-01): review-bot auto-merge mechanism (classifier + workflow) #17 -- never the closed feat/phase-29-peer-critic branch) reporting 0 blocking findings, and green required CI checks. Only then does the App (never GITHUB_TOKEN, never an agent PAT) approve and enable squash auto-merge.

Full design rationale, class boundary, and the honest trust model: docs/merge-flow-policy.md (companion PR on the root repo).

Remaining human step (cannot be automated by an agent)

This PR does not include the GitHub App itself -- App creation requires org owner action:

  1. Create the GitHub App cas-review-bot (Pull requests: Read & Write, Contents: Read & Write, Checks: Read, Metadata: Read) and install it org-wide on Coding-Autopilot-System.
  2. Store REVIEW_BOT_APP_ID / REVIEW_BOT_PRIVATE_KEY as org Actions secrets.
  3. Apply branch protection to one repo first: pwsh -File scripts/apply-branch-protection.ps1 -Repos org-dotgithub (root-repo script, companion PR).
  4. Open a trivial docs-only PR (not authored by the review bot) and confirm: automerge-eligibility goes green, review-bot approves after critic_cli passes, auto-merge lands it with zero manual click. Then confirm a PR touching a .ps1/workflow file is held (OUT-OF-CLASS, not approved).

Branch protection was not applied for real by this PR -- only -DryRun evidence was captured; application is operator-gated.

Test plan

  • pwsh -File .github/scripts/classify-automerge-eligibility.ps1 -SelfTest -- 5/5 fixtures pass, exit 0.
  • YAML syntax validated for both workflows.
  • Zero non-ASCII characters in the new .ps1 file (PS 5.1 hazard guard).
  • Live App-gated auto-merge test (blocked on App creation, see above).

🤖 Generated with Claude Code

- classify-automerge-eligibility.ps1: IN-CLASS iff dependabot-manifest-only
  OR docs-only; workflow/executable denylist applies to ALL authors
  including dependabot (checker blocker #2 regression fixture covered)
- decision derives from gh pr view changed paths + author only, never
  labels/title
- auto-merge-eligibility.yml wires the classifier as a required status
  check (context: automerge-eligibility) on pull_request events
- -SelfTest covers 5 table-driven fixtures: pure-docs, docs+workflow-file,
  dependabot-manifest-only, dependabot+workflow-file (regression), mixed
- pull_request_target trigger; mints a cas-review-bot App installation
  token via actions/create-github-app-token (pinned SHA bcd2ba4, v3.2.0)
- gate 1: eligibility classifier -- OUT-OF-CLASS stops before any approval
- gate 2: checks out autogen at pinned commit b0524b7 (verified on
  origin/main via PR #17; never feat/phase-29-peer-critic) and runs
  critic_cli --severity-gate blocking against the PR diff; non-zero exit
  requests changes instead of approving
- gate 3: gh pr checks --required must be green
- only when all three gates pass: gh pr review --approve as the App token,
  then gh pr merge --auto --squash -- the App is the sole approving
  identity, never GITHUB_TOKEN or an agent PAT
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Comment thread .github/workflows/review-bot.yml Fixed
…d job

CodeQL flagged review-bot.yml (pull_request_target, App token minted) for
checking out untrusted code in a privileged context: the diff step did
`git fetch origin pull/<n>/head:pr-head` then diffed against it, pulling
attacker-controlled ref content into the runner's git state before the
critic gate ran.

Replace with an API-only diff: `gh pr diff <n>` piped directly into
critic_cli over stdin (--diff -). No git fetch/checkout of the PR head
occurs anywhere in the job; the only actions/checkout calls left are the
job's own base-ref self-checkout and a pinned, trusted autogen commit for
critic_cli. Also add fail-closed handling if `gh pr diff` itself errors,
so a failed API call can no longer be misread as "zero findings".

Ref: T-38-SEC-PWN
@OgeonX-Ai

Copy link
Copy Markdown
Contributor Author

T-38-SEC-PWN mitigation applied (commit 548d95f)

CodeQL flagged this workflow (.github/workflows/review-bot.yml, lines ~59-68) for "Checkout of untrusted code in a privileged context" — the pull_request_target job minted an App token and then git fetch'd the PR head ref before diffing it.

Fix: the privileged job is now checkout-free of untrusted refs. The diff is obtained exclusively via gh pr diff <n> (GitHub API, text) and streamed to critic_cli over stdin. The eligibility classifier already consumed gh pr view --json files,author (API only). The only remaining actions/checkout calls are (1) this repo's own base-ref self-checkout (no ref: override, so it can never resolve to the PR head under pull_request_target) and (2) Coding-Autopilot-System/autogen pinned to a fixed, trusted commit SHA for critic_cli. Also added fail-closed handling if gh pr diff itself errors.

Details: docs/security/T-38-SEC-PWN-review-bot-pwn-request-mitigation.md (added in this push).

Note: I could not find a merge-flow threat table on PR #18 — that PR is an unrelated release-engineering fix — so this mitigation record lives here on #17 instead.

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.

3 participants