feat: add read-only gitea_check_pr_eligibility (#14) #24
Reference in New Issue
Block a user
Delete Branch "feature/14-gitea-pr-eligibility-checks"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #14
Roadmap parent: #10
Summary
Adds a read-only MCP tool
gitea_check_pr_eligibility(pr_number, action, remote, …)that decides whether the current authenticated identity + active runtime profile is eligible to perform an action on a specific PR. Evaluation only — it never reviews, approves, requests changes, merges, or mutates anything.Inspects:
GET /api/v1/user)get_profile: allowed/forbidden operations)GET /pulls/{n}: author, state, head SHA, mergeability)Returns:
Fail-closed rules
allowed_operations, or listed inforbidden_operations→ not eligible.approveormerge(the PR #8 dogfooding blocker, now machine-checkable).mergerequires a positive mergeable signal (mergeable is FalseorNone→ not eligible).eligibleis true only when there are zero blocking reasons.Files changed (3, +246)
mcp_server.pygitea_check_pr_eligibilitytool +_ELIGIBILITY_ACTIONS(+143)tests/test_mcp_server.pyTestPrEligibility(8 tests) (+102)README.mdValidation
git diff --check→ clean.python3 -m py_compile mcp_server.py tests/test_mcp_server.py gitea_auth.py→ OK.pytest tests/test_mcp_server.py→ 49 passed (was 41; +8 new).super-secret-tokenasserted absent from output).Explicit statements
Scoped to #14 only. Does not touch #15–#18. Do not merge — awaiting independent review.
Add a read-only MCP tool that decides whether the current authenticated identity + active runtime profile is eligible to review, approve, request_changes, or merge a specific PR. Evaluation only — it never reviews, approves, requests changes, merges, or mutates anything. Inspects: authenticated username (/user), active profile metadata (allowed/forbidden operations), and PR facts (author, state, head SHA, mergeability). Returns {eligible, requested_action, authenticated_user, profile_name, pr_author, pr_state, head_sha, mergeable, reasons}. Fail-closed rules: - unknown action / unknown remote -> not eligible - action not in allowed ops, or in forbidden ops -> not eligible - identity undetermined -> not eligible - authenticated user == PR author -> cannot approve/merge - PR not open -> not eligible - merge requires a positive mergeable signal No token/auth-header exposure. No review/approve/request-changes mutation. No merge mutation. No multi-token switching. No Jenkins/Ops/GlitchTip/Release/deploy behavior. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Independent review for issue #14 is held.
Validation performed:
master.jcwalker3, which matches the PR author, so I cannot approve this PR from this account.fbbbd53.README.md,mcp_server.py,tests/test_mcp_server.py.git fetch --all --prunecompleted.git diff --check prgs/master...fbbbd53passed.git diff --name-only prgs/master...fbbbd53returned only the expected files.python3 -m py_compile mcp_server.py tests/test_mcp_server.py gitea_auth.pypassed.pytest tests/test_mcp_server.pypassed: 49 passed.Manual review notes:
gitea_check_pr_eligibilityis read-only: it uses GETs for authenticated user and PR details and does not submit reviews, approvals, request-changes, merges, comments, labels, branch writes, deploys, rollbacks, restarts, or migrations.Blockers:
jcwalker3, same as PR author, so approval requires a different reviewer account.mergeable is Noneformerge).merge, but not explicitly forapprove.Review blockers addressed — commit
baf4eaeBoth requested test-coverage blockers are now covered. Tests only — no implementation change (behavior was already enforced by
gitea_check_pr_eligibility).approve—test_self_author_cannot_approve: authenticated user == PR author, actionapprove→eligible == false, reason"authenticated user is PR author".test_merge_fails_closed_when_mergeability_unknown: actionmerge, Gitea returnsmergeable = None→eligible == false,mergeablenull, reason"PR mergeability unknown".Validation performed
git diff --check→ cleanpython3 -m py_compile mcp_server.py tests/test_mcp_server.py gitea_auth.py→ OKpytest tests/test_mcp_server.py→ 51 passed (was 49; +2 new)tests/test_mcp_server.pychanged this round.Confirmations
/user,/pulls/{n}).super-secret-tokenasserted absent from output).Scoped to #14 only. Did not start #15–#18. Not merging — awaiting reviewer.
Issue #14 test-coverage blockers fixed on
feature/14-gitea-pr-eligibility-checks.approvetest: authenticated user matching PR author is ineligible and reportsauthenticated user is PR author.mergeable: Noneformergereturnseligible: falsewithPR mergeability unknown.git diff --check,python3 -m py_compile mcp_server.py tests/test_mcp_server.py gitea_auth.py, andpytest tests/test_mcp_server.py(51 passed).tests/test_mcp_server.py.Content, scope, and validation passed. Confirmed explicit tests for self-author approval block and unknown-mergeability fail-closed are present. 51 tests passed. All checks pass.
Re-review for issue #14 after test-coverage fix is held only due reviewer eligibility.
Validation performed:
master.jcwalker3, which matches the PR author, so I cannot approve this PR from this account.baf4eae.README.md,mcp_server.py,tests/test_mcp_server.py.git fetch --all --prunecompleted.git diff --check prgs/master...baf4eaepassed.git diff --name-only prgs/master...baf4eaereturned only the expected files.python3 -m py_compile mcp_server.py tests/test_mcp_server.py gitea_auth.pypassed.pytest tests/test_mcp_server.pypassed: 51 passed.Previous blockers verified fixed:
approvetest is present:test_self_author_cannot_approve.test_merge_fails_closed_when_mergeability_unknown.Manual review notes:
gitea_check_pr_eligibilityremains read-only and uses GETs for authenticated user and PR details.No remaining content blockers found. A different reviewer account is required to approve.
Final review — content PASSES, merge HELD on identity
Read-only verification at head
baf4eae:baf4eae30ba6c0092867f6dd546874e2423f03ef— unchanged since review ✓mergeable: true✓README.md,mcp_server.py,tests/test_mcp_server.py✓git diff --check(master...head) → clean ✓test_self_author_cannot_approveandtest_merge_fails_closed_when_mergeability_unknownpresent ✓Blocker (unchanged): reviewer identity == author. The gitea-tools MCP is authenticated as
jcwalker3, which is the PR author. Per policy (and the very self-approval/self-merge rule this PR implements), the author must not approve or merge their own PR. No non-author Gitea identity is configured for this runtime, so I cannot perform an eligible merge.Action required: a genuinely separate Gitea account must approve + merge PR #24. Content and scope have no blockers. Issue #14 stays open until an eligible account merges.
Final review complete, merging PR #24.