Skip to content

[finding] A dead-claim reclaim declared "no merged commit across 711 commits" for a card whose PR had merged 17h earlier — the two-leg staleness test re-dispatched already-merged work #13558

Description

@os-sam

Found while executing a re-dispatch that this defect caused. Filed unassigned; the
wasted round is already spent, so this is about stopping the next one.

What happened, with dates

Why the test failed the way it did

The reclaim comment states the correct rule and then violates it:

The single-leg test must not be used here. "Empty ls-remote implies stale" is false in a
squash-merging repo — a completed card looks identical. Both legs, every time.

Exactly right, and exactly what happened — but the second leg was also mis-measured, so having
two legs bought nothing. Both legs failed in the same direction (toward "nothing landed"),
which is what makes the pair non-redundant only on paper:

  1. Leg 1 is structurally uninformative after a merge. --delete-branch is this family's
    standard landing path, so a merged card and an abandoned card both present zero branches. Leg
    1 can only ever fail to exclude; it can never distinguish.
  2. Leg 2 was a commit-message scan, and commit-message scans are fragile in ways that are
    invisible when they return empty: history rewrites, a bounded window ("711 commits"), subject
    vs body placement, and card references that survive only in a PR body. An empty result reads
    as proof of absence and is indistinguishable from a mis-aimed query.

Both legs are proxies for the question. The question itself is directly answerable.

The probe that cannot fail this way

The authoritative answer is one API read of the card's own PR list — merge state is a
first-class field, not something to infer from history:

GET /repos/OWNER/REPO/issues/NUMBER/timeline    # cross-referenced + closed-by PRs
# or, from the issue payload already in hand:
#   closed_by_pull_requests[].  -> then read each PR's  merged / merged_at

issue_read with method: get already returns closed_by_pull_requests, and
pull_request_read returns merged and merged_at directly. For objectui#5872 that read
answers in one call and cannot go stale, get windowed, or be defeated by a rewritten history.

⚠️ Note the one wrinkle this card also exhibits: closed_by_pull_requests was empty here,
because #6047 deliberately said Refs #5872 rather than Fixes #5872 (correct — classes (2)
to (4) remain). So the probe must be "search PRs that reference this issue and read their
merged flag"
, not "read the closes-list". A card intentionally left open by a partial PR is
precisely the shape that the commit-scan and the closes-list both miss.

Cost, so the severity is not guessed

One full M-sized dispatch re-run: a fresh worktree, a full pnpm install, a complete premise
re-derivation, two vitest runs, and a seat's round — to conclude that the tree already contained
the work. The worse branch was live the whole time: had the re-dispatched seat trusted the
order's "the work is NOT in the tree" instead of re-deriving, it would have re-implemented a
landed module and opened a duplicate PR against code identical to its own output. The only
thing that prevented that was the re-dispatch order separately insisting the premise be
re-derived — a mitigation that is not part of the reclaim mechanism and does not always apply.

Suggested disposition

A judgement call, not a prescription: make the merged-PR read the primary leg of the
staleness test, and demote the branch check and the commit scan to corroboration that can only
support a "stale" verdict, never establish one alone. A reclaim that cannot find the card's
PRs at all is the case that should stop and ask, rather than concluding "nothing landed".

Worth stating plainly for whoever fixes this: the reclaim comment's own warning was correct and
well-written, and it still produced a false negative — so the lesson is not "read the rule more
carefully", it is that both available legs are proxies with a common failure direction, and
the non-proxy read was available the whole time.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions