fix: close ungated CLI merge bypasses in review_pr.py and merge_pr.py (#16)

Reviewer found the MCP merge surface is gated but two local CLI scripts remain
ungated merge paths that LLM automations in this project have been using.
Close them (Option B — minimal safe fix; full gated CLI merge left to a
follow-up):

- review_pr.py: `--merge` now fails closed BEFORE any API call with a clear
  message directing callers to the gated `gitea_merge_pr` MCP workflow. The
  review-only path is unchanged. The merge execution block was removed.
- merge_pr.py: main() is now a fail-closed no-op — reads no credentials and
  makes no merge API call; prints that merge is only available via the gated
  workflow.
- README: the `review_pr.py` row and Quick Examples no longer advertise a CLI
  `--merge` path; added an audit-logging clarification that #16 returns
  structured gate/merge results but does not add durable audit logging, which
  is tracked by #18.

Tests updated/added:
- test_review_pr.py: `--merge` fails closed with no API call; message points to
  the gated workflow.
- test_merge_pr.py: merge fails closed with no API call, even with
  --force/--do/--title/--message; message points to the gated workflow.
- test_mcp_server.py: README no longer advertises the ungated CLI merge example.

The gated MCP `gitea_merge_pr` is unchanged and still gated; `gitea_review_pr`
still fails closed on merge=True; `gitea_submit_pr_review` still cannot merge.
No secrets, auth headers, raw env, or credential paths are exposed. No
Jenkins/Ops/GlitchTip/Release/deploy/CI behavior added. #17/#18 not started.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-01 15:40:34 -04:00
parent f04cf44975
commit 4dee03b2aa
6 changed files with 105 additions and 88 deletions
+7 -3
View File
@@ -180,6 +180,9 @@ Notes:
can inspect which runtime it is talking to before deciding to act.
- See [`docs/gitea-execution-profiles.md`](docs/gitea-execution-profiles.md) for
the full profile model.
- **Audit logging:** #16 returns structured gate/merge results but does not add
durable audit logging. Durable audit logging for Gitea MCP mutating actions is
tracked by #18.
</details>
<details>
@@ -204,7 +207,7 @@ The MCP tools can also be used as standalone CLI scripts:
| `create_issue.py` | Create an issue (`--remote`, `--title`, `--body`, `--body-file`) |
| `create_pr.py` | Open a Pull Request (`--remote`, `--title`, `--head`, `--base`) |
| `edit_pr.py` | Edit a Pull Request (`--title`, `--body`, `--body-file`, etc.) |
| `review_pr.py` | Review and sign-off on a pull request (with optional merge) |
| `review_pr.py` | Review/sign-off on a pull request (`--merge` is disabled — fails closed; merge only via gated `gitea_merge_pr`) |
| `close_issue.py` | Close a specific issue |
| `mark_issue.py` | Claim/release an issue via `status:in-progress` label |
| `manage_labels.py` | Create label set and apply label mappings (`--dry` to preview) |
@@ -225,8 +228,9 @@ The MCP tools can also be used as standalone CLI scripts:
# Edit a PR's description or title
./edit_pr.py 155 --body "Updated description wording"
# Review and approve a PR, then automatically merge it
./review_pr.py --pr-number 12 --event APPROVE --body "Approved" --merge
# Review and approve a PR (review only — CLI merge is disabled; use the
# gated gitea_merge_pr MCP workflow to merge)
./review_pr.py --pr-number 12 --event APPROVE --body "Approved"
# Close issue #5
./close_issue.py 5