ci: Gatekeeper App auto-approver bridge + auto-sweep (MCP-1249)#687
Conversation
Bridge that turns a Paperclip Codex review verdict of ACCEPT into a real GitHub approving review posted by the "MCPProxy Gatekeeper" GitHub App, so the required-1-approving-review branch protection is satisfied without an admin override and without the author approving their own PR (author!=approver). Pairs with scripts/arm-auto-merge.sh for full Model B. - Reads verdict of record from the Paperclip review thread (bots don't post to GitHub); only ACCEPT approves, request_changes/unknown are no-ops. - Mints a GitHub App installation token (RS256 JWT via openssl, no extra deps). - Inert until configured (GATEKEEPER_APP_ID / _INSTALLATION_ID / _PRIVATE_KEY, e.g. ~/.mcpproxy-gatekeeper/env) — exits 2 with setup guidance. - --dry-run + --verdict overrides for testing. Validated against live data: reads accept for PR #622, fails safe unconfigured, no-ops on request_changes. App registration + cred wiring is the remaining (owner) step. Related MCP-1249
… (MCP-1249)
Hands-off half of Model B: a launchd timer runs gatekeeper-sweep.sh every 5m,
which invokes gatekeeper-approve.sh for each open PR. Codex ACCEPT -> App
approval -> GitHub auto-merge, no human, no admin.
- gatekeeper-approve.sh hardened to be safe under repeated/unattended runs:
- no-op if PR is closed/merged
- stale-verdict guard: only approve the exact SHA Codex reviewed (head moved
past it -> skip, re-review needed) [exit 6]
- idempotency: skip if the Gatekeeper already approved the current head
- resolver now also extracts the reviewer-pinned SHA
- gatekeeper-sweep.sh: bash-3.2 safe (macOS /bin/bash, no mapfile); skips
quietly when unconfigured or Paperclip unreachable; timestamped logging.
- app.mcpproxy.gatekeeper.sweep.plist: launchd template (StartInterval 300,
RunAtLoad, background/low-IO) + install/enable/disable instructions.
Validated: dry sweep over 14 open PRs no-ops correctly; idempotent no-op on the
already-merged #622; timer loaded and first run logged.
Related MCP-1249
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
📦 Build ArtifactsWorkflow Run: View Run Available Artifacts
How to DownloadOption 1: GitHub Web UI (easiest)
Option 2: GitHub CLI gh run download 27561387247 --repo smart-mcp-proxy/mcpproxy-go
|
|
Claude review (codex out) → REQUEST_CHANGES — one real security bug + notes. This auto-approves PRs as the Gatekeeper App on a Codex ACCEPT (it does NOT merge — GitHub native auto-merge still enforces CI/qa-gate, so branch protection isn't weakened). But: [BLOCKER] Stale-SHA guard is skippable → can approve unreviewed code. Secondary (non-blocking, worth a guard): Fix the fail-closed SHA guard and this is acceptable as a local operator tool. |
…tching reviewed SHA (MCP-1249) Codex REQUEST_CHANGES (PR #687): the stale-SHA guard in gatekeeper-approve.sh ran only `if [[ -n "$REVIEWED_SHA" && ... ]]`, so a verdict that pinned NO SHA (REVIEWED_SHA empty) — or the manual --verdict override path, which always yielded an empty SHA — bypassed the check and auto-approved the PR's CURRENT head. An old ACCEPT could thus approve unreviewed code after a post-review force-push. Fix (fail-closed): - Make the SHA checks UNCONDITIONAL. No reviewed SHA resolvable -> REFUSE (exit 7, explicit message); reviewed SHA != head -> REFUSE (exit 6, stale); only reviewed SHA == head approves. - Add --reviewed-sha to pair with --verdict so the manual override is held to the same fail-closed requirement (no blind manual approvals either). - Document the invariant + new exit code 7 in the header. Adds scripts/gatekeeper-approve.test.sh: hermetic (stubs gh, --dry-run, no network/GitHub) regression covering all four Codex acceptance cases. Red on the old script (case 1 approved blind), green on the fix. Co-Authored-By: Paperclip <noreply@paperclip.ing>
Deploying mcpproxy-docs with
|
| Latest commit: |
b369186
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://d997a5bc.mcpproxy-docs.pages.dev |
| Branch Preview URL: | https://mcp-1249-gatekeeper.mcpproxy-docs.pages.dev |
Fixed — fail-closed SHA guard (commit
|
There was a problem hiding this comment.
Claude re-review ACCEPT (codex out). Round-2 fix confirmed fail-closed: empty/unresolved REVIEWED_SHA now hits exit 7 unconditionally (3 sequential if/exit guards, no &&-compound bypass); stale SHA -> exit 6; --verdict accept override requires --reviewed-sha; transient gh failure = safe no-op (never approves). gatekeeper-approve.test.sh 3/3. Adoption approved by maintainer.
Gatekeeper App auto-approver bridge + auto-sweep (MCP-1249)
Lands the durable, version-controlled "Gatekeeper" GitHub App approver bridge — the missing agent-side piece of MCP-1249 (Option A, decided by Algis). The branded App was created by the owner (
~/.mcpproxy-gatekeeper/) and is already in active local use; this PR moves the proven mechanism out of/tmpinto the repo so it is reviewable and durable.What this adds (all under
scripts/, additive only)scripts/gatekeeper-approve.sh— turns a Paperclip CodexACCEPTverdict into a real GitHub approving review posted by the branded App identity, satisfying the "1 approving review, author ≠ approver" branch-protection rule without--admin. Idempotent; no-ops on closed/merged PRs, non-ACCEPT verdicts, already-approved heads, or stale reviewed-SHA (exit 6).--dry-runsupported. Pairs withscripts/arm-auto-merge.sh.scripts/gatekeeper-sweep.sh— periodic sweep that finds eligible PRs and runs the approver.scripts/app.mcpproxy.gatekeeper.sweep.plist— launchd timer for the sweep (operator-local).Safety / scope
GATEKEEPER_APP_ID,GATEKEEPER_INSTALLATION_ID, private key) are sourced at runtime from the gitignored~/.mcpproxy-gatekeeper/env. Confirmed clean (no inline keys/tokens).qa-gate+ the human Gate-3 button. Agents arm auto-merge; nothing here bypasses a gate or uses--admin.scripts/-only, no changes to existing files — no edition/runtime/release-pipeline impact.Decisions for reviewer / owner
arm-auto-merge.ymltherefore remains dormant (GitHub Actions cannot approve PRs anyway, org setting). Confirm this local-only posture is the intended end state, or whether a CI-secret variant is wanted as a follow-up.I will not merge my own PR (FR-005) — opening for review.
Co-Authored-By: Paperclip noreply@paperclip.ing