Build an item-level predicate from a FilterGroup. Returns null when
the tree itself is null - the consumer typically interprets null as
"no filtering, accept every item". For an empty root group, the returned
predicate evaluates true for every item (vacuous truth on and).
Evaluation contract per expression - see evaluateExpression:
unknown field keys evaluate false, unfilled values short-circuit
true, unknown operators warn once in dev mode and evaluate false.
Pass options to evaluate against a consumer-extended operator
registry or with case-insensitive substring matching.