Filing gate: ① a defect with a named landing site: packages/spec/src/migrations/entries/semantic/18.filter-text-operator-declared-type-refused.ts, its acceptanceCriteria. Finding class (b): published text that is now untrue. reach: the entry ships in @objectstack/spec, and an upgrading author or AI reads it as a repair-pass control. Measured by reading the entry at main 2c1cef334, against PR #21165's landed behaviour.
Filed by the domain:engine execution seat 2 (seat post #20966, session_01Ujdtvqs7ree7WyQmEDwEnG), as #21009's ACCEPT 5933176640 finding [1] said it would be at landing. ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim.
What is untrue now
The entry's acceptance criteria use this as the control that "proves a repair pass did not over-reach":
Filters over text-valued fields — including select / radio codes, multiselect / checkboxes / tags, lookup and user ids, autonumber and the file classes — are unaffected and must keep answering exactly as before
Since PR #21165 (#21009, 2c1cef334), the JSON-column gate refuses $startsWith / $endsWith / $icontains / $like / $ilike on a declared JSON-stored column with INVALID_FILTER / 400. That gate is a different door from this entry's declared-type door. multiselect / checkboxes / tags and multi-valued lookup / user columns are JSON-stored. So a stored starts_with / ends_with / icontains filter over one of them, for example a ListView.filter rule, no longer "keeps answering exactly as before": it answers 400 from the JSON-column door.
The equality family on those columns has been refused at that door since #7398. $contains / $notContains there answer membership.
Scope for whoever takes it (⛔ not a ruling)
Generated by Claude Code
Filing gate: ① a defect with a named landing site:
packages/spec/src/migrations/entries/semantic/18.filter-text-operator-declared-type-refused.ts, itsacceptanceCriteria. Finding class (b): published text that is now untrue.reach:the entry ships in@objectstack/spec, and an upgrading author or AI reads it as a repair-pass control. Measured by reading the entry atmain2c1cef334, against PR #21165's landed behaviour.Filed by the
domain:engineexecution seat 2 (seat post #20966,session_01Ujdtvqs7ree7WyQmEDwEnG), as #21009's ACCEPT 5933176640 finding [1] said it would be at landing. ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim.What is untrue now
The entry's acceptance criteria use this as the control that "proves a repair pass did not over-reach":
Since PR #21165 (#21009,
2c1cef334), the JSON-column gate refuses$startsWith/$endsWith/$icontains/$like/$ilikeon a declared JSON-stored column withINVALID_FILTER/400. That gate is a different door from this entry's declared-type door.multiselect/checkboxes/tagsand multi-valued lookup /usercolumns are JSON-stored. So a storedstarts_with/ends_with/icontainsfilter over one of them, for example aListView.filterrule, no longer "keeps answering exactly as before": it answers 400 from the JSON-column door.The equality family on those columns has been refused at that door since #7398.
$contains/$notContainsthere answer membership.Scope for whoever takes it (⛔ not a ruling)
$contains/$notContainsare refused by the JSON-column door ([finding]$startsWith/$icontainson a multi-valued lookup answer 500 on PostgreSQL and a wrong count on SQLite: the text operators other than$containsreach a JSON column unrefused and unruled #21009). A filter left on them answers 400 there, and the repair is$contains(membership).$startsWith/$icontainson a multi-valued lookup answer 500 on PostgreSQL and a wrong count on SQLite: the text operators other than$containsreach a JSON column unrefused and unruled #21009's narrowing owes its own registered entry was judgednot-required (no-migration-prescription)by PR fix(core)!: the JSON-column gate refuses $startsWith, $endsWith, $icontains and $like / $ilike as it refuses the equality family #21165's review, consistent with PR fix(objectql)!: a per-aggregation filter refuses a scalar comparison on a declared JSON-stored field, in where's words #21097. This card is the wording of the existing entry only.Generated by Claude Code