Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .changeset/filter-builder-like-ilike-ruling-harvest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
---

Test-comment only: harvests the maintainer ruling on objectui#4911 into the
`KNOWN_UNREACHABLE` entry for `$like` / `$ilike` in
`FilterConditionField.operators.test.ts`. The entry's justification was landed as a CITED
OPEN QUESTION ("undecided — see #4911") to unblock the queue while the authoring-surface
call was pending; it is now rewritten as the decision it became — ruled B on 2026-08-17,
the visual FilterBuilder deliberately does not offer raw pattern-matching authoring, the
constrained intents (`contains` / `containsCaseInsensitive` / `startsWith` / `endsWith`)
are the authorable surface, and the API surface is unaffected since spec goes on accepting
both operators for hand-written ObjectQL and direct JSON authors. The ruling's named
reopen condition (a real user or deployment asks to author wildcard patterns in the UI) is
recorded on the entry, because the exclusion ratchet can only check that a member is still
a spec operator, never that its reason is still the true one.

The two `KNOWN_UNREACHABLE` members, the reachability sweep and the exclusion ratchet are
unchanged; no operator was added or removed. Declared as releasing nothing.
Original file line number Diff line number Diff line change
Expand Up @@ -60,29 +60,33 @@ const noTypes = () => undefined;
* the parity assertion below is what holds that honest.
*
* `$like` and `$ilike` arrived with the `@objectstack/spec` 17.0.0 GA pin
* (objectui#4636). Their entry here is **undecided — see #4911**, and it claims
* nothing else: whether this builder should offer raw pattern matching at all is
* an authoring-surface question that has NOT been ruled on, so this is a CITED
* OPEN QUESTION, not a finding that the tokens should stay unauthorable. It was
* taken because the sweep below is red on `main` itself under the GA pin, which
* every open PR inherits (objectui#4977); the question keeps waiting on the
* maintainer either way.
* (objectui#4636), and their entry here is a DECISION, not an open question:
* objectui#4911, maintainer-ruled B on 2026-08-17 — this visual builder
* deliberately does not offer raw pattern-matching authoring. The constrained
* intents are the authorable surface and already reach the dropdown (`contains`
* / `containsCaseInsensitive` / `startsWith` / `endsWith`), so what a `$like`
* row would add on top of them is exactly the raw `%`/`_` wildcard form — the
* one operator where a mis-authored value silently returns the wrong rows
* instead of erroring, which is an error bed in an end-user filter UI, and for
* zero measured author pull.
*
* Harvest condition — a ruling on #4911 must change these two members or this
* paragraph. Neither survives the ruling untouched:
* This is a BUILDER-surface refusal, not a capability removal: the API surface
* is unaffected and `FieldOperatorsSchema` goes on accepting both operators for
* hand-written ObjectQL, direct JSON authors and integrations. That is what
* makes the exclusion honest rather than a gap papered over — the tokens stay
* reachable, just not from this dropdown.
*
* - ruled A (build the operators): delete both members and add the builder
* operators that author them; the parity assertion below then holds that
* honest, exactly as it did when objectui#4023 retired `$icontains`.
* - ruled B (the builder will not offer raw pattern matching): rewrite this
* paragraph as the refusal the ruling makes it — stated as a decision, with
* the ruling's own reopen condition on the entry — and reopen #4911 if that
* condition is ever met.
* Reopen condition, named by the ruling: a real user or deployment asks to
* author wildcard patterns in the UI. If that happens, reopen objectui#4911,
* delete these two members and add the builder operators that author them; the
* parity assertion below then holds that honest, exactly as it did when
* objectui#4023 retired `$icontains`.
*
* Leaving it reading "undecided" after a ruling lands is the stale-exclusion rot
* this comment block already warns about, one level up: the ratchet below can
* only check that a member is still a spec operator, never that its reason is
* still the true one.
* Nothing mechanical can hold that condition for you — the ratchet below checks
* only that a member is still a spec operator, never that its reason is still
* the true one. A refusal that outlives its rationale is the stale-exclusion rot
* this comment block warns about one level up, and a reader is what catches it,
* not a run.
*/
const KNOWN_UNREACHABLE = new Set(['$eq', '$between', '$like', '$ilike']);

Expand Down
Loading