Skip to content

feat: route non-member PR reviews through warpdotdev/warp-ownership#459

Draft
vkodithala wants to merge 3 commits into
mainfrom
varoon/integrate-ownership-areas
Draft

feat: route non-member PR reviews through warpdotdev/warp-ownership#459
vkodithala wants to merge 3 commits into
mainfrom
varoon/integrate-ownership-areas

Conversation

@vkodithala
Copy link
Copy Markdown
Contributor

Why

Non-member PR reviews currently guess a reviewer login out of .github/STAKEHOLDERS from agent free-form output. This PR moves the source of truth to warpdotdev/warp-ownership/ownership-areas/*.md so reviewer selection is bounded by a Warp-curated allowlist, distributed evenly across owners of the matched area, and auditable as PR → area → owner.

Flow

  • Dispatch (Vercel): gather_review_context reads ownership-areas/*.md via the payload installation token (org-wide install on warpdotdev already covers warp-ownership; outside orgs fail open). It inlines the prose block and a JSON list of canonical area names into the cloud prompt and serializes the parsed list onto RunState.payload_subset.
  • Agent (cloud): returns recommended_area — exactly one area name copied verbatim, or "" to defer — alongside verdict/body/comments. The bundled validate_review_json.py reads ownership_areas.json (also inlined for the agent to write) via --ownership-areas; it rejects unknown names on APPROVE and any non-empty recommended_area on REJECT.
  • Apply (Vercel cron): the new resolver maps recommended_area → eligible owners, excludes the PR author, and uses random.SystemRandom.choice for uniform load-balancing across area owners. STAKEHOLDERS is loaded lazily as the deterministic last-resort fallback when the agent can't commit or ownership-areas resolution yields nothing.

Reason

  • Eliminates hallucinated reviewer logins by structurally bounding the agent's choice to known areas.
  • Gives true uniform distribution of reviewers within an area via SystemRandom.choice instead of always pinging the first listed owner.
  • Adds an agent-side validator gate (--ownership-areas) so invalid recommended_area values are caught before review.json is uploaded, not silently dropped at apply time.
  • Keeps STAKEHOLDERS in place for the long tail (org-wide install doesn't cover ownership repo, ambiguous PRs, agent gives up), so consumers outside warpdotdev keep the existing behavior automatically.

Validation

  • python3 -m unittest tests.test_ownership tests.test_review_pr_reviewer_sampling tests.test_prompts tests.test_webhook_dispatch tests.test_builders → 103 tests pass.
  • validate_review_json.py exercised manually across 6 cases (valid area / unknown area / REJECT-with-area / empty fallback / missing ownership file / REJECT-empty); each produced the expected pass/fail outcome.

Artifacts

Co-Authored-By: Oz oz-agent@warp.dev

vkodithala and others added 2 commits May 15, 2026 09:55
For non-member PRs the review workflow now picks the human reviewer
from the canonical ownership-areas list in warpdotdev/warp-ownership
instead of guessing logins out of .github/STAKEHOLDERS. The cloud
review agent picks a single area name, the validator enforces it
against the parsed list, and the apply step maps area -> eligible
owner with a uniform random pick. STAKEHOLDERS remains the
deterministic last-resort fallback when the agent can't commit to one
area or the org-wide GitHub App install doesn't cover the ownership
repo.

Flow:
- Dispatch: gather_review_context reads ownership-areas/*.md via the
  payload installation token, inlines the prose block plus a JSON
  list of canonical names in the cloud prompt, and serializes the
  list into RunState.payload_subset.
- Agent: returns 'recommended_area' (or '') alongside verdict/body/
  comments. validate_review_json.py rejects unknown areas on APPROVE
  and any non-empty area on REJECT, gated by --ownership-areas
  ownership_areas.json (missing file = no ownership areas in scope).
- Apply: _resolve_recommended_reviewers picks one eligible owner via
  random.SystemRandom.choice for the chosen area, excluding the PR
  author. Falls back lazily to STAKEHOLDERS only when ownership-areas
  resolution yields nothing.

The webhook reuses the payload-keyed GitHub client for ownership-repo
access; failures fail open so consumers outside the warpdotdev org
keep the legacy STAKEHOLDERS behavior automatically.

Co-Authored-By: Oz <oz-agent@warp.dev>
@vkodithala vkodithala requested a review from captainsafia May 15, 2026 20:46
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 15, 2026

@vkodithala

I'm starting a first review of this pull request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@vkodithala vkodithala requested a review from acarl005 May 15, 2026 20:46
Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This PR moves non-member reviewer selection from agent-supplied reviewer handles to ownership-area selection, adds ownership-area parsing, threads the dispatch/apply context, and extends validation to check recommended_area.

Concerns

  • The new ownership-area validator option is always populated with a default file path, so omitted and explicit --ownership-areas usage cannot be distinguished. That can make local/non-ownership validations depend on a stale ambient file and can also let ownership-scoped dispatches silently skip the required gate when the file was not written.

Verdict

Found: 0 critical, 1 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

)
parser.add_argument(
"--ownership-areas",
default="ownership_areas.json",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] This default makes omitted and explicit --ownership-areas calls indistinguishable: local runs that intentionally omit the flag can be affected by a stale ownership_areas.json, while ownership-scoped dispatches that pass the flag still silently disable the gate if the file was not written. Default this to None and only tolerate a missing file when the flag was omitted.

For non-member PRs reviewed via the review-pull-request workflow, the
control plane now enumerates other PRs that reference the same issue
(closing keyword, manual link, or plain #N mention) and prefers reusing
a same-issue reviewer before falling back to the existing ownership-area
or STAKEHOLDERS resolution.

- Add 'Issue.timelineItems(CROSS_REFERENCED_EVENT)' GraphQL discovery
  in 'oz/helpers.py' plus a paginated 'find_related_prs_for_issue'
  helper that enriches each sibling PR with reviewer signals via
  PullRequest.get_review_requests and PullRequest.get_reviews. Bots,
  the current PR's author, and cross-repo sources are filtered out.
- Add 'build_related_pr_reviewer_candidates' which produces an
  ordered, deterministic candidate list with two tiers:
  - 'requested-open': human reviewers currently requested on an open
    sibling PR (strongest signal).
  - 'prior-review': humans who already submitted a non-PENDING review
    on a sibling PR (weaker fallback signal).
- Extend ReviewContext with 'linked_issue_number', 'related_prs', and
  'related_pr_reviewer_candidates'. These are populated only for
  non-member, non-spec PRs that resolve to a single linked issue.
- Render a 'Related same-issue PRs' block in the dispatched review
  prompt so the agent sees the same context the control plane uses.
  No review.json schema change.
- Insert a same-issue reviewer-reuse step ahead of the existing
  ownership-area / STAKEHOLDERS resolution. Eligibility is filtered
  through the union of ownership-area owners when ownership areas are
  loaded; otherwise the STAKEHOLDERS owner set is used. Ambiguous
  tiers log and fall through rather than picking randomly.

Refs #456.

Co-Authored-By: Oz <oz-agent@warp.dev>
@vkodithala vkodithala force-pushed the varoon/integrate-ownership-areas branch from b52a22f to 3aacab2 Compare May 18, 2026 12:43
@vkodithala vkodithala marked this pull request as draft May 18, 2026 12:44
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.

1 participant