Skip to content

[finding] mcp__github__list_issues treats labels as OR, not AND — any seat computing "pm:queue ∩ domain:X" from one query gets an inflated count that looks plausible #11559

Description

@os-warren

Filed unassigned by the domain:devx @ objectui seat (objectui#5748), round R3, PM session session_01PQ3NihCHE9LUtHoGxo6A9f. A platform reading, so it belongs in the pm-dispatch fact table (references/platform-readings.md) rather than in a lane queue — one line, and it changes a number every seat reports.

Measured, both directions, 2026-08-24 against objectstack-ai/objectui

querytotalCount
list_issues labels=["domain:devx"] state=OPEN61
list_issues labels=["domain:devx","pm:queue"] state=OPEN135

A subset cannot exceed its superset. If labels were AND, the second result would be ≤ 61. It is more than double, so the filter is a union.

Confirmed by inspecting the members rather than resting on the arithmetic — the 135-set contains both error directions:

  • Cards in the lane that are not pm:queue: #5194 and #4986 (pm:on-hold + domain:devx), #5440 (pm:blocked + domain:devx). They qualify on the domain:devx term alone.
  • Cards that are pm:queue but not in the lane: #5936, #5935, #5926, #5923, #5916, #5909, #5903 and others, none of which appear in the 61-card domain:devx read. They qualify on the pm:queue term alone.

Why it is worth a line in the fact table

The wrong number is plausible and directionally comforting, which is the dangerous kind. A seat reporting "dispatchable inventory" from a two-label query reports a figure roughly 2–3× the truth, and nothing about the result looks malformed — it is a well-formed list of real cards. Here the true reading is 49pm:queue unassigned in the lane (47 once the two cards held behind objectui#5442 are excluded); the two-label query said 135. That number feeds the round report's health indicators and the maintainer's read on whether a lane is draining.

It also silently breaks the pm:queue without domain:* sweep shape the triage seat runs: a card matching either term comes back, so a "half-labelled cards" query built this way returns mostly fully-labelled ones.

The rule that already defends against it, and why it should say so explicitly

The skill already prescribes the right shape — 「整车道一次读全,本地求交」 (read the whole lane in one query, intersect locally), on the stated grounds that per-state slices are a structural blind spot. This finding gives that rule a second, sharper reason: it is not only that a narrow query hides cards, it is that a multi-label query invents them. Suggested one-liner for the fact table:

list_issueslabels is a union, ⛔ not an intersection — measured objectui 2026-08-24: ["domain:devx"] → 61, ["domain:devx","pm:queue"] → 135. Never compute a lane ∩ state count from one query; read the lane on its single domain:* label and intersect locally.

⚠️ Not verified here and worth one cheap check by whoever picks this up: whether search_issues with label:a label:b in the query string is AND (GitHub's own search syntax says it should be). If it is, that is the tool to reach for when a genuine intersection is wanted — but ⛔ do not assume it; the whole point of this card is that the plausible assumption was wrong.

Evidence: objectui#5748 (seat post, R3 closing brief), objectui#5458 / #5367 / #3840 (the round in which it surfaced).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions