Skip to content

feat(contract:change-proposal): backend-neutral change-proposal contract for non-GitHub PR/patch review #669

Description

@potiuk

Problem

The pr-management-* skills (triage, code-review, quick-merge, stats) are hardwired to GitHub: gh pr …, owner/name repo form, GraphQL has_next_page pagination, a GitHub-login "viewer". There is no abstract "pull request" binding the way tools/github/source-control.md abstracts VCS operations.

Consequences:

The ASF-world equivalents of a PR — a patch attached to a JIRA/Bugzilla issue, or a [PATCH] thread on dev@ — have no first-class model in the framework.

Proposal: a new peer contract contract:change-proposal

Model the unit that is forge-shaped today (a PR) as a backend-neutral change proposal: a diff + metadata + a review/discussion thread + a lifecycle, decoupled from where it lives. This is a peer of contract:tracker and contract:source-control, not an extension of either. tools/asf-svn needs no change — it already exposes the land primitive (svn patch + confirmed svn commit).

Minimal operation set

Abstract op GitHub PR GitLab MR JIRA + SVN (patch-on-issue) dev@ [PATCH] thread
list_open gh pr list MR list JQL attachment + "patch available" PonyMail thread search
get(id) → diff + meta gh pr diff/view MR diff download .patch attachment extract patch from mbox
get_discussion PR comments/reviews MR notes JIRA comments thread replies (ponymail)
post_review gh pr review MR note JIRA comment mail-draft reply
land merge PR merge MR asf-svn: svn patch + confirmed commit same → asf-svn
reject/close close PR close MR JIRA transition + comment reply, no commit
status (CI / mergeable) checks API pipelines — / Jenkins link

The two right-hand columns are the SVN-first ASF paths; both delegate land to asf-svn's source-control binding, gated by asf-svn/authorization.md (committer check). Clean seam: the change-proposal adapter owns review/triage; asf-svn owns apply/commit.

Tool + config layout

tools/change-proposal/     # contract:change-proposal — pure interface spec (like tools/cve-tool/)
tools/github/              # ALSO implements contract:change-proposal (PR backend)
tools/jira-patch/          # JIRA patch-on-issue adapter  → lands via asf-svn
tools/mail-patch/          # dev@ [PATCH] thread adapter   → reuses ponymail + mail-draft, lands via asf-svn
# SVN-first ASF project manifest
tools_enabled:
  source_control:       asf-svn
  release_distribution: asf-svn
  tracker:              jira
  change_proposal:      jira-patch     # or: mail-patch

Phasing

  • Phase 1 — define contract:change-proposal; make tools/github implement it; refactor only pr-management-triage to the binding (proves the abstraction, zero behavior change on GitHub).
  • Phase 2tools/jira-patch adapter + landasf-svn wiring; validate end-to-end on a real JIRA+SVN project.
  • Phase 3tools/mail-patch (dev@ threads) reusing ponymail / mail-draft. Hardest, because there is no proposal object — identity is synthesized from thread-id + message-id.

Open questions

  • Diff identity across backends — GitHub PR = branch; JIRA patch = file; mail patch = git format-patch / raw svn diff. Needs a normalized diff representation and a stable proposal-id scheme (esp. mail, where one proposal = a thread carrying patch v1/v2/v3).
  • No "mergeable"/CI equivalent off GitHub — triage classification that leans on check-status must degrade gracefully.
  • Apply idempotency & conflictssvn patch partial-apply/reject is messier than a server-side merge; land needs a defined failure contract.
  • Authorization & attribution — mail/JIRA contributors aren't committers; land must resolve the acting committer via asf-svn/authorization.md, and patch-author ≠ committer attribution must survive into the commit message.

Relationships

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions