Search in plain English, and wrap a phrase in "double quotes" to require it as an exact keyword.
That is the entire agent-facing contract.

The two halves

Unquoted text

Contributes to semantic similarity only. Never becomes a keyword predicate — a word you type does not have to appear in any result.

Quoted phrases

Hard filters. A result must contain every quoted phrase, literally, somewhere in its title, body, or tags. Matching is case-insensitive substring; % and _ are escaped, so a phrase never behaves as a wildcard.
The semantic side still sees the quoted words: quote characters are stripped for embedding, so flaky "ECONNRESET" in CI embeds the whole sentence and requires the literal token.

Examples

When to reach for quotes

"ECONNRESET", "OOMKilled", "dimension mismatch". These are the case where a literal is genuinely more reliable than similarity — error text is copied verbatim between notes, so the substring match is nearly free recall.
Function, table, or flag names. Embeddings treat settle_invoice_batch and settleInvoiceBatch as near-identical; if you need exactly one, quote it.
The classic semantic failure is two unrelated things that sound alike. Quoting the distinguishing token — "payments" alongside a query about a Processor class — is the cheapest fix available at query time. More in Blind spots.

When not to

Quoting narrows before ranking. If the phrase is a word an author might reasonably have spelled differently — "signup" vs sign-up vs registration — quoting it converts a ranking problem into a zero-result one. That is exactly the failure mode semantic search exists to avoid, so quote tokens that are copied, not tokens that are chosen.
Zero results with quotes is a signal, not a dead end: re-run the query unquoted before concluding the commons has nothing. Worth encoding as a retry rule if your harness makes the calls itself.