Skip to content

docs(agents): record the search qualifier-token hazard beside the channel-control rule - #7452

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-7185-search-qualifier-clause
Sep 3, 2026
Merged

docs(agents): record the search qualifier-token hazard beside the channel-control rule#7452
os-zhuang merged 1 commit into
mainfrom
claude/issue-7185-search-qualifier-clause

Conversation

@os-sales

@os-sales os-sales commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Fixes #7185

Option B of that card diagnosed why MCP search_issues returns a silent total_count 0 for an issue issue_read returns. This lands the documentation half the seat decided on: one clause, beside the channel-control rule that PR #7317 put in section 9's instrument-discipline area. The two rules are the same subject one level apart, so they belong together.

The card's own standing instruction — do not close it on the mitigation alone without recording which cause the diagnosis found — is satisfied: the cause is recorded on the card, so the closing line above is the one the seat ruled for.

What changed

AGENTS.md only. Net +1 line (2 insertions, 1 deletion) — one now-stale bullet is replaced by two.

  • New clause, the diagnosed cause. search_issues pastes the caller's query text verbatim into GitHub search q=, so GitHub's qualifier parser is live inside what the seat believes is free text. A bare word-colon-word token in pasted issue text is parsed as a search qualifier, ANDed with the rest of the query, matches nothing, and returns a silent zero.
  • Replaced bullet. The old final bullet declared the cause undiagnosed and warned against treating it as an answered question. That is now false, and it sat two lines from its own answer — leaving it would have made the file assert both "the cause is unknown" and "the cause is this" in adjacent bullets. It is replaced by a line recording the two candidates that were measured and ruled out.

The evidence the clause carries

query total_count
resolve record:quick_actions does 0
the same words with the middle token backticked 17

Identical words, identical order. The only difference is a pair of backticks.

Qualifiers are genuinely applied, not merely mishandled: state:open action-id lookup returns 0 while state:closed action-id lookup returns 2, and both target issues are closed — so that zero is a correct filter, which is what proves the parse is real.

Why this repository is unusually exposed: its component keys are word-colon-word, and 33 of 345 sampled titles (9.6%) carry one. So roughly one in ten near-verbatim title dedupe queries here is silently zeroed — a standing failure rate on the dedupe step every seat runs before filing.

The clause also records the two boundaries that keep it from over-reading: deliberate qualifiers (in:title, state:closed) are honoured and remain useful, so the hazard is only the accidental ones; and this does not retire the control requirement — an empty result still always needs a known-must-hit control.

The replaced bullet's ruled-out line keeps one correction worth not re-deriving: the unauthenticated REST search 403 seen in these containers is not from GitHub. It is the container's own egress proxy enforcing a repository-scoped path allowlist, and it says nothing about GitHub's search scope. It was briefly cited as scope evidence precisely because a status code was read without its body.

Scope

  • No tooling. Option C — a helper that backticks or strips colon tokens before a query is sent — was explicitly not taken. The clause is the load-bearing half and is correct without it; tooling should be pulled by evidence that the clause alone is not landing.
  • Nothing outside AGENTS.md. No .claude/, no skills/, no docs/adr/, no CLAUDE.md, no scripts, and nothing under content/docs/releases/.
  • The diagnosis itself is not re-litigated here; it is done and accepted, and this only writes it where agents read it.

⛔ Governed surface

AGENTS.md is a governed surface. This PR is a DRAFT and stays draft — it has not been flipped ready, not enqueued, and auto-merge has not been armed. A human merge is the review record.

node scripts/check-governed-queue-guard.mjs --test AGENTS.md exits 3, which is the correct verdict for a governed-path PR, not a failure to fix. It names the authorized approvers itself, and both are requested on this PR.

Gates

All run on the final commit 920c9ba87, working tree clean, every exit code captured by redirect before any pipe.

gate exit note
pnpm docs:check-links 0 reads AGENTS.md from disk
pnpm check:control-bytes 0 6135 tracked text files scanned
pnpm check:shell-escape-residue 0 resolved AGENTS.md: 1 file, 15 fences
pnpm check:governed-queue-guard (self-test) 0
check-governed-queue-guard.mjs --test AGENTS.md 3 expected governed verdict
check-changeset-presence.mjs 0 no changeset owed — answered at the gate
vitest, 4 suites reading AGENTS.md from disk 0 4 files, 159 tests passed

The gate set was re-derived on current main rather than taken from the dispatch list: every script under scripts/ where AGENTS.md appears as a data path rather than an error string, plus the suites that resolve the repo-root file.

🤖 Generated with Claude Code

https://claude.ai/code/session_019aCUUSwWefnbCJ4Xk1vqQW


Generated by Claude Code

…nnel-control rule

MCP `search_issues` pastes query text verbatim into GitHub search `q=`, so a
bare word-colon-word token in pasted issue text is parsed as a qualifier,
ANDed with the rest, and returns a silent zero. This repo's component keys
have that shape, so ~10% of its titles carry one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019aCUUSwWefnbCJ4Xk1vqQW
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

2 participants