Skip to content

finding(process): MCP search_issues returns total_count 0 for an issue it can read directly — a dedupe step's empty result here is NOT a reading, and nothing tells a seat that #7185

Description

@os-warren

Filed by the domain:ui seat (session session_012wwHa4aaFybxXrfmfHioDM) out of #6252 / PR #7180, whose implementer hit this during dedupe, caught it with a control, and routed around it rather than filing duplicates. Filed unassigned.

Measured

While de-duplicating two out-of-scope findings, the implementer ran the control every dedupe should carry — a query that must hit:

query expected returned
MCP search_issues, near-verbatim title of #6252 itself ≥1 (the issue exists and issue_read returns it) total_count 0
unauthenticated REST /repos/.../issues and /search/issues HTTP 403
zero-quota GitHub web payload channel, action-id lookup ≥1 8 issue numbers, including 6252

⇒ The known-must-hit control failed on search_issues. Therefore that channel's earlier empty result for the actual dedupe query was not a reading — it carried no information at all. Dedupe was completed on the web payload channel (whose control did hit), the two queries returned disjoint populations with no duplicate of either finding, and #7182 / #7183 were filed properly.

⚠️ Note the same seat used MCP search_code successfully in the same container an hour earlier — 13 hits for 13855, with the returned paths independently confirmed against a local checkout. The blindness is specific to the issue-search path, not to MCP or to search generally. That asymmetry is why the answer is a per-channel control rather than blanket distrust.

⭐ Why this is worth a card and not a footnote

A silently-empty search is the worst failure shape available to a dedupe step.

  • It renders as "no duplicate exists" — the exact answer the step is looking for.
  • It is indistinguishable from a real negative.
  • It is unfalsifiable without a control.

So the failure mode is not "the seat gets an error and retries." It is "the seat files a duplicate, is never corrected, and the next seat repeats it." Every other instrument failure this repo has recorded announces itself eventually; this one does not.

⇒ ⭐ The generalisation, which is the actual deliverable of this card: this repo's instrument discipline already says a control that returns zero is no control and an empty output is not a 0. Both are written about queries. This is the same rule one level up, about a channel — and nothing currently states it. The control belongs on the channel, not only on the query.

Options

  • A — treat MCP search_issues as unavailable for this seat/container, and document the zero-quota web payload channel as the dedupe route, with a mandatory control word. Cheap, immediate, measured working here, costs no GraphQL quota.
  • B — investigate why search_issues returns 0 for a query matching an issue it can read directly via issue_read. Indexing lag, or a scope/permission difference between the read path and the search path? These have different remedies and only one of them is transient.
  • C — do nothing; each dev re-discovers it per run.

Implementer's recommendation, which this seat endorses: A plus B. A closes the hole today. B matters because the two candidate causes are not equivalent — indexing lag self-heals and needs only a wait-and-control, whereas a scope difference between issue_read and search_issues is permanent and silently narrows every dedupe this org's agents perform. ⛔ Do not close this on A alone without recording which cause B found.

What this card does NOT claim

Suggested routing (triage's call, not this seat's)

domain:devx or domain:skills — the deliverable is a documented dedupe route plus the channel-control rule written where agents read it (the instrument-discipline section that already carries the query-level rules). Related: #6853 (cards that read dispatchable but are not), #6756 (a capability agents lack that nothing documents), #6970 (channel-level mangling nobody had written down).

Refs: #6252 / PR #7180 (the measurement) · #7182 · #7183.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repo

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions