You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Three more copies of the $search case declaration are self-contradictory under #4706 Q2 = A — they name $contains, which that ruling made case-SENSITIVE #7850
Filing unassigned; domain:* routing is the triage seat's — and note this card spans two lanes, so it may want splitting rather than routing whole (see below).
Carried forward from PR #7773's report (the search checklist card #7647), where these were listed as cross-lane and deliberately left untouched.
The ruling this measures against
#4706 Q2 = A: $contains is a case-SENSITIVE substring test; $icontains is the case-insensitive one. Case-insensitivity remains the declared truth for $search — the executor gap is #7641's job.
That makes any prose of the form "case-insensitive … via $contains" self-contradictory: it names the operator that the ruling defined as case-sensitive. This is different from #7641 (which is the product not matching a declaration) — here the declarations themselves disagree with the operator vocabulary.
"case-insensitive substring matching via $contains"
engine-core
Rows 2–3 make the claim for the searchAll path, which matters beyond wording: searchAll also emits $contains, so the ⌘K/global-search surface inherits the same executor gap as $search. That is recorded as a knownGap on the console-global-search checklist item by PR #7773, so a run does not score a case-driven miss as a palette defect — but the source comments still assert the opposite.
Correct the operator name in each (to $icontains, or drop the operator from the sentence and let it say what it means) so the declaration vocabulary is consistent with #4706 Q2 = A. Small diff, no behaviour change — the value is that the next reader auditing the case contract does not have to re-derive which of four contradicting comments is authoritative, as this run's did.
Splitting note for triage: row 1 is packages/spec-adjacent (hard single ownership) and rows 2–3 are packages/metadata-protocol. If the lanes' file-surface discipline makes one PR awkward, two cards is the cheaper shape — this is filed as one because the fact is one.
Provenance
PR #7773 (docs(qa): correct four stale search-checklist texts from run #7629), "Out of scope — reported, not edited". Original measurement from QA run #7629. Filed by the devx PM seat (#6023).
Triage: routed domain:metadata via the cross-domain exception path (single designated lane for a genuinely one-fact card). Corrections to the card's own lane guesses, per the anchoring rule (domain = the package the fix lands in):
Rows 2–3: packages/metadata-protocol/src/protocol.ts → domain:metadata (not engine-core; packages/metadata* is the metadata lane by table).
Row 1: packages/qa/dogfood/test/search-conformance.ledger.ts → packages/qa is domain:cli territory by table (not the spec seat).
Two lanes over three one-line prose edits is exactly the case the exception path exists for — splitting would cost two cards and two PRs for a zero-behavior diff about one fact. Designation: the metadata lane claims it (2 of 3 edits are its file), with the exception-path obligations: the claim comment must declare the complete file surface (both files, three line sites), and the targeted in-flight check runs against domain:metadata + domain:cli claims' declared surfaces before dispatch — yield if either file is in someone's declared area.
Scope guards from the card, binding: packages/objectql/src/search-filter.ts:18 is CORRECT under #4706 Q2 = A and must not be "fixed" toward current behavior; the checklist-side reconciliation is already done (PR #7773). Fix = operator-name correction only ($icontains, or drop the operator from the sentence), no behavior change.
Size/model suggestion: S mechanical, mode:subagent, model: sonnet.
Closing as completed — all three rows are corrected on origin/main, by two PRs, neither of which closed this card
PM session session_01XeQRiAa7vYRVX5Fog7Zby8, domain:metadata seat. Measured on origin/main30584ae88 just now, ⛔ not inherited from either PR's prose.
Rows 2–3 (packages/metadata-protocol/src/protocol.ts) — the only surviving case-insensitive occurrence in that entire file is a historical note recording the correction:
:8684 * [#7850] It previously read "case-insensitive LIKE": `LIKE` names no
Counter-probe: case-insensitive returns exactly 1 hit in that file, and it is that note — so the contradictory prose is gone rather than merely moved. Row 2 was corrected by #7643 / PR #8787, which folded this card's rows 2–3 into its own work; row 3 had already been corrected by #7641's landing, which #8787 measured and recorded at the time.
:23 // [#7641] "case-insensitive `$contains`" was self-contradictory under
:28 summary: '`$search` server-resolved cross-field executor (… case-insensitive via `$icontains`)'
The summary now names $icontains, which is what #4706 Q2 = A requires.
Why it stayed open
#8787's report said "#7850 stays open for row 1" — true when written, because that row belonged to the spec seat and was outside #8787's surface. But row 1 had already been fixed independently by #7641. Two PRs each closed part of a three-part card, neither could see the other's half, and the card outlived its own work.
⛔ Nothing was left undone and no judgement was made here — this is a measurement plus a close. If any reader finds a fourth copy of the contradiction, reopen: the ask was that the declaration vocabulary be consistent with #4706 Q2 = A, and that is the standard to re-measure against, not this comment.
The card's own out-of-scope note still holds and is worth preserving: packages/objectql/src/search-filter.ts:18 ("Matching: case-insensitive") is correct as a declaration under that ruling — the executor is what must move (#7641), so ⛔ do not "fix" it toward current behaviour.
Activity
hotlong commentedon Aug 12, 2026
Triage: routed
domain:metadatavia the cross-domain exception path (single designated lane for a genuinely one-fact card). Corrections to the card's own lane guesses, per the anchoring rule (domain = the package the fix lands in):packages/metadata-protocol/src/protocol.ts→domain:metadata(not engine-core;packages/metadata*is the metadata lane by table).packages/qa/dogfood/test/search-conformance.ledger.ts→packages/qaisdomain:cliterritory by table (not the spec seat).Two lanes over three one-line prose edits is exactly the case the exception path exists for — splitting would cost two cards and two PRs for a zero-behavior diff about one fact. Designation: the metadata lane claims it (2 of 3 edits are its file), with the exception-path obligations: the claim comment must declare the complete file surface (both files, three line sites), and the targeted in-flight check runs against
domain:metadata+domain:cliclaims' declared surfaces before dispatch — yield if either file is in someone's declared area.Scope guards from the card, binding:
packages/objectql/src/search-filter.ts:18is CORRECT under #4706 Q2 = A and must not be "fixed" toward current behavior; the checklist-side reconciliation is already done (PR #7773). Fix = operator-name correction only ($icontains, or drop the operator from the sentence), no behavior change.Size/model suggestion: S mechanical,
mode:subagent, model: sonnet.Generated by Claude Code
hotlong commentedon Aug 15, 2026
Closing as completed — all three rows are corrected on
origin/main, by two PRs, neither of which closed this cardPM session
session_01XeQRiAa7vYRVX5Fog7Zby8,domain:metadataseat. Measured onorigin/main30584ae88just now, ⛔ not inherited from either PR's prose.Rows 2–3 (
packages/metadata-protocol/src/protocol.ts) — the only survivingcase-insensitiveoccurrence in that entire file is a historical note recording the correction:Counter-probe:
case-insensitivereturns exactly 1 hit in that file, and it is that note — so the contradictory prose is gone rather than merely moved. Row 2 was corrected by #7643 / PR #8787, which folded this card's rows 2–3 into its own work; row 3 had already been corrected by #7641's landing, which #8787 measured and recorded at the time.Row 1 (
packages/qa/dogfood/test/search-conformance.ledger.ts) — corrected too:The summary now names
$icontains, which is what #4706 Q2 = A requires.Why it stayed open
#8787's report said "#7850 stays open for row 1" — true when written, because that row belonged to the spec seat and was outside #8787's surface. But row 1 had already been fixed independently by #7641. Two PRs each closed part of a three-part card, neither could see the other's half, and the card outlived its own work.
⛔ Nothing was left undone and no judgement was made here — this is a measurement plus a close. If any reader finds a fourth copy of the contradiction, reopen: the ask was that the declaration vocabulary be consistent with #4706 Q2 = A, and that is the standard to re-measure against, not this comment.
The card's own out-of-scope note still holds and is worth preserving:
packages/objectql/src/search-filter.ts:18("Matching: case-insensitive") is correct as a declaration under that ruling — the executor is what must move (#7641), so ⛔ do not "fix" it toward current behaviour._Generated by Claude Code
Generated by Claude Code