Skip to content

work-items open-linked-PR filter: closedByPullRequestsReferences(first:20) can miss an OPEN closing PR past page 1 → double-dispatch #677

Description

@kyle-sexton

Context

Deferred from the review thread on #668 (the fix for #654). The bot raised a P2 (paginate close-linkage before deciding no PR is open); triaged as a file-an-issue disposition rather than a fix-in-diff, because the failure is a reversible edge (see "Why not fixed in #668" below).

The filter

plugins/work-items/tools/work-item-tracker/adapters/github/README.mdOpen linked PRs) documents the open-linked-PR signal that drops an in-flight candidate from the /work-items:work pickable frontier. It queries GitHub's computed close-linkage:

closedByPullRequestsReferences(first:20, includeClosedPrs:false) { nodes { number state } }

then reports true iff any node has state == OPEN.

The bug

first:20 bounds the connection to the first page. includeClosedPrs:false suppresses only CLOSED (unmerged) PRs, so MERGED nodes are retained (correctly, per the filter's own rationale). An issue with more than 20 linked closing PRs whose single OPEN closing PR sorts after the first page therefore returns a page of all-MERGED nodes, the filter sees no OPEN, and reports false = pickable.

Consequence — false-keep → double-dispatch: an issue whose work is already in flight is re-picked from the frontier, so two runs can be dispatched against the same item (duplicate PRs).

Remedy

Root-cause fix is cursor pagination — walk pages (pageInfo { hasNextPage endCursor }) until an OPEN node is found or the connection is exhausted. A first:100 bump is not a fix (it only moves the boundary). Note the connection exposes no server-side OPEN-state filter — its args are after/before/first/last/includeClosedPrs/orderBy/userLinkedOnly, and orderBy (CREATED_AT/UPDATED_AT) cannot guarantee OPEN-first ordering — so pagination is the only correct route. This is a documentation-driven adapter, so the fix is to the documented query snippet (and any executing wrapper), not compiled code.

Why not fixed in #668

The trigger (>20 linked closing PRs on one issue, with the OPEN one paginated past page 1) is implausible in practice, and the failure mode — double-dispatch producing a duplicate PR — is detectable and reversible (close the dup). That places it outside the fix-in-diff carve-out (data-loss / fail-open-gate / security / silent-wrong-feeding-irreversible), so it is captured here for prioritization rather than blocking #668. The #668 README already documents the first:20 bound and flags pagination as the remedy; this issue tracks doing it.

Refs #668, #654

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: mediumReal value, no hard deadline; normal backlog flow.status: readyTriaged, unblocked, and fully specified; eligible to pick up.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions