* fix(recall): reject empty queries with 400 and fix SQL parameter gap causing IndeterminateDatatypeError
When query text contains only punctuation/symbols (no word characters after
normalization), the BM25 arms are skipped but the old code still placed `limit`
at \$3 in the params list. If tags or tag_groups were also set, their params
(\$4+) were referenced in the SQL while \$3 was a gap, causing PostgreSQL to
raise IndeterminateDatatypeError.
Fix the parameter layout so `limit` is only appended to params when tokens are
present (i.e. when BM25 arms actually use LIMIT \$3), and shift tags_param_idx
from 4 to 3 in the no-tokens path.
Also add a field_validator on RecallRequest.query that rejects empty-after-
normalization queries at the API layer with a 400 before they reach the DB.
* refactor: extract tokenize_query helper and reuse in RecallRequest validator