feat: diagnose reviewer lease handoff next actions (#599)
Add read-only diagnose_reviewer_pr_lease_handoff and MCP tool gitea_diagnose_reviewer_pr_lease_handoff so open-PR foreign leases, instructed-lease replacement, reclaimable release, and worktree binding mismatch return a canonical next_action without steal paths. Closes #599
This commit is contained in:
@@ -7154,6 +7154,62 @@ def gitea_assess_reviewer_pr_lease(
|
||||
}
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def gitea_diagnose_reviewer_pr_lease_handoff(
|
||||
pr_number: int,
|
||||
proposed_worktree: str | None = None,
|
||||
instructed_session_id: str | None = None,
|
||||
instructed_comment_id: int | None = None,
|
||||
remote: str = "dadeschools",
|
||||
host: str | None = None,
|
||||
org: str | None = None,
|
||||
repo: str | None = None,
|
||||
) -> dict:
|
||||
"""Read-only: diagnose open-PR reviewer lease handoff and emit next action (#599).
|
||||
|
||||
Classifies no-lease / own / foreign / instructed-lease-missing-with-replacement
|
||||
and worktree binding mismatch. Returns a canonical ``next_action`` without
|
||||
mutating Gitea state. Never steals foreign leases.
|
||||
"""
|
||||
read_block = _profile_operation_gate("gitea.read")
|
||||
if read_block:
|
||||
return {
|
||||
"success": False,
|
||||
"reasons": read_block,
|
||||
"permission_report": _permission_block_report("gitea.read"),
|
||||
}
|
||||
comments = _fetch_pr_comments(
|
||||
pr_number, remote=remote, host=host, org=org, repo=repo)
|
||||
h, _o, _r = _resolve(remote, host, org, repo)
|
||||
try:
|
||||
username = _authenticated_username(h)
|
||||
except Exception:
|
||||
username = None
|
||||
session_lease = reviewer_pr_lease.get_session_lease() or {}
|
||||
env_wt = (
|
||||
(os.environ.get("GITEA_REVIEWER_WORKTREE") or "").strip()
|
||||
or (os.environ.get("GITEA_ACTIVE_WORKTREE") or "").strip()
|
||||
or None
|
||||
)
|
||||
# Prefer in-session lease id when present; otherwise diagnose as a fresh
|
||||
# caller without inventing ownership of an on-thread lease.
|
||||
session_id = (session_lease.get("session_id") or "").strip() or None
|
||||
diagnosis = reviewer_pr_lease.diagnose_reviewer_pr_lease_handoff(
|
||||
comments,
|
||||
pr_number=pr_number,
|
||||
current_session_id=session_id,
|
||||
current_reviewer_identity=username,
|
||||
proposed_worktree=proposed_worktree,
|
||||
env_bound_worktree=env_wt,
|
||||
instructed_session_id=instructed_session_id,
|
||||
instructed_comment_id=instructed_comment_id,
|
||||
)
|
||||
diagnosis["success"] = True
|
||||
diagnosis["remote"] = remote
|
||||
diagnosis["authenticated_user"] = username
|
||||
return diagnosis
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def gitea_cleanup_post_merge_moot_lease(
|
||||
pr_number: int,
|
||||
|
||||
Reference in New Issue
Block a user