Filed by the os-dev seat working #13744, as an out-of-scope finding. That card's dispatch scoped the fix to packages/objectql/src/engine.ts and asked explicitly that a third file carrying the same false sentence be filed as its own finding rather than folded into that PR. This is that third file.
Measured, at origin/main (merge base eb649cb8bc)
packages/objectql/src/search-companion.ts:6 — the module docblock opens:
* `$search` (ADR-0061 Tier 1) is a `$contains` over source columns, so typing
* the full pinyin (`zhangwei`) or initials (`zw`) of a CJK name ("张伟") can
* never hit — the stored value is the CJK original.
The source-column clauses of the ADR-0061 expansion compile to $icontains, not $contains. The implementation is packages/objectql/src/search-filter.ts:109 / :111 (fieldClausesForTerm returns { [field]: { $icontains: term } }), and the adjudication is recorded in that file's own header at search-filter.ts:23:
* [#7641] The case-insensitive operator is `$icontains`, NOT `$contains`.
Two tests pin the live behaviour, both green on main this hour:
Severity: low, and the argument the sentence carries still holds
Comment-only, zero behaviour — same class and same severity as #13744. Note the reasoning in that sentence survives the correction: typing zhangwei cannot hit a stored 张伟 under either operator, because case folding does not transliterate. So this is a false spelling inside an argument that remains correct, which is precisely why it reads as fine and has survived.
Worth a card for the reason #13744 gives: it is one hop from the file an agent doing query-engine work reads first, and an agent trusting it re-introduces the spelling #7641 paid to retire.
Do NOT batch-replace this file — two $contains in it are CORRECT
The same file carries two further $contains mentions, both describing the hidden __search companion clause, where $contains is the right spelling and is deliberate:
search-companion.ts:237 — "ORed { __search: { $contains: term } } into every $search against it"search-companion.ts:286 — "which emits { __search: { $contains: term } }"
search-filter.ts:137-143 states why, and says so in the imperative: the companion column is a normalized blob already lowercase on both sides, so a case-SENSITIVE operator over two folded values is exact — "Do not 'align' the two." A naive whole-file find-and-replace here would turn two correct sentences false. Only :6 is wrong.
Adjacent, in the same docblock family (same file, separate from the above)
search-companion.ts:286 names the reader as buildSearchFilter; the exported function in search-filter.ts is expandSearchToFilter. buildSearchFilter is not an export of that module. Stale identifier, comment-only, no behaviour — folding it into the same fix would be natural, but it is a distinct claim and is recorded here rather than assumed.
Gate exposure
scripts/adr-anchors/packages__objectql__src__search-companion.ts.json anchors this file to ADR-0015 / ADR-0045 / ADR-0061 and check:adr-anchors requires those ids stay referenced in it. A spelling correction does not touch an ADR id, so the anchor is unaffected — but the anchor is worth knowing about before editing this file.
Observation class: finding label, no assignee, no lane label — routing belongs to central triage.
Refs: #13744 (the engine.ts card this was found from) - the $icontains adjudication trail cited in search-filter.ts (#7641 / #6520 / #6682).
Generated by Claude Code
Generated by Claude Code
Filed by the
os-devseat working #13744, as an out-of-scope finding. That card's dispatch scoped the fix topackages/objectql/src/engine.tsand asked explicitly that a third file carrying the same false sentence be filed as its own finding rather than folded into that PR. This is that third file.Measured, at
origin/main(merge baseeb649cb8bc)packages/objectql/src/search-companion.ts:6— the module docblock opens:The source-column clauses of the ADR-0061 expansion compile to
$icontains, not$contains. The implementation ispackages/objectql/src/search-filter.ts:109/:111(fieldClausesForTermreturns{ [field]: { $icontains: term } }), and the adjudication is recorded in that file's own header atsearch-filter.ts:23:Two tests pin the live behaviour, both green on
mainthis hour:search-filter.test.ts— "[$searchis case-sensitive on textual fields, contrary to three declarations that say case-insensitive #7641] textual fields compile to the case-folding operator > emits $icontains — never the case-SENSITIVE $contains — for text fields"global-search-palette-recall.test.ts— "[$searchis case-sensitive on textual fields, contrary to three declarations that say case-insensitive #7641] source columns still compile to $icontains, never the case-SENSITIVE $contains"Severity: low, and the argument the sentence carries still holds
Comment-only, zero behaviour — same class and same severity as #13744. Note the reasoning in that sentence survives the correction: typing
zhangweicannot hit a stored张伟under either operator, because case folding does not transliterate. So this is a false spelling inside an argument that remains correct, which is precisely why it reads as fine and has survived.Worth a card for the reason #13744 gives: it is one hop from the file an agent doing query-engine work reads first, and an agent trusting it re-introduces the spelling #7641 paid to retire.
Do NOT batch-replace this file — two
$containsin it are CORRECTThe same file carries two further
$containsmentions, both describing the hidden__searchcompanion clause, where$containsis the right spelling and is deliberate:search-companion.ts:237— "ORed{ __search: { $contains: term } }into every$searchagainst it"search-companion.ts:286— "which emits{ __search: { $contains: term } }"search-filter.ts:137-143states why, and says so in the imperative: the companion column is a normalized blob already lowercase on both sides, so a case-SENSITIVE operator over two folded values is exact — "Do not 'align' the two." A naive whole-file find-and-replace here would turn two correct sentences false. Only:6is wrong.Adjacent, in the same docblock family (same file, separate from the above)
search-companion.ts:286names the reader asbuildSearchFilter; the exported function insearch-filter.tsisexpandSearchToFilter.buildSearchFilteris not an export of that module. Stale identifier, comment-only, no behaviour — folding it into the same fix would be natural, but it is a distinct claim and is recorded here rather than assumed.Gate exposure
scripts/adr-anchors/packages__objectql__src__search-companion.ts.jsonanchors this file to ADR-0015 / ADR-0045 / ADR-0061 andcheck:adr-anchorsrequires those ids stay referenced in it. A spelling correction does not touch an ADR id, so the anchor is unaffected — but the anchor is worth knowing about before editing this file.Observation class:
findinglabel, no assignee, no lane label — routing belongs to central triage.Refs: #13744 (the engine.ts card this was found from) - the
$icontainsadjudication trail cited insearch-filter.ts(#7641 / #6520 / #6682).Generated by Claude Code
Generated by Claude Code