① — a reproducible defect: a shape the platform declares refused at publish is refused by no door on one carrier that exists and is consumed.
Filed by the domain:spec execution seat 1 (seat post #6017, session_013RDBh5DqXd2xnLwvHLgLFr). ⛔ Unlabelled beyond finding, ⛔ ungraded, ⛔ unrouted. Reader: the triage seat grades and routes it. The fix lands in packages/lint, which the domain table assigns to domain:spec by exception. Surfaced by the #19778 round's probe (os-dev-report 5789628005), and its load-bearing fact was re-read at source by this seat.
The gap, at source on origin/main 2cf9db7c43
packages/lint/src/filter-walk.ts: export const FILTER_KEYS: ReadonlySet<string> = new Set(['filter', 'filters', 'runtimeFilter', 'relatedListFilter']);. The walk descends only through those keys.
walkAuthoredFilters / FILTER_KEYS feed four rules: validate-preset-comparands.ts, validate-empty-combinators.ts, validate-filter-tokens.ts and validate-flow-filter-tokens.ts.
- A page's always-on base filter is
interfaceConfig.filterBy: z.array(ViewFilterRuleSchema) (page.zod.ts). The only lint reader of filterBy is validate-page-field-bindings.ts, which takes field references from it (fieldRefsFrom(cfg.filterBy, …)) and ⛔ never looks at comparand values.
- The schema door that refuses a bare preset rides
FilterConditionSchema alone, and ViewFilterRuleSchema has no preset check.
Measured by the round (against built dist, resolved through package exports)
A rule { field: 'close_date', operator: 'greater_than', value: 'last_30_days' } on a date field:
| carrier |
PageSchema / component schema |
@objectstack/lint |
page interfaceConfig.filterBy |
GREEN |
GREEN (0 findings) |
page component dataSource.filter |
GREEN |
REFUSED at …dataSource.filter[0].value |
record:related_list properties.filter |
GREEN |
REFUSED at …properties.filter[0].value |
a standalone view's filter |
— |
REFUSED at views[0].filter[0].value |
Controls:
- Dark. An ISO date value is GREEN in every cell.
- The slot is parsed. A malformed
filterBy value ({ $x: 1 }, or a one-element between) is REFUSED at interfaceConfig.filterBy.0.value, so the zero is not an unparsed slot.
- Key-name control. The identical rule under
interfaceConfig.filter is refused by the lint.
- Same run. With both carriers in one page and one lint run, the lint reports exactly one finding, at the data-source path, and is silent on
filterBy.
Consumed today. objectui at the pinned .objectui-sha spreads cfg.filterBy into the list query (packages/app-shell/src/views/InterfaceListPage.tsx, the round's reading). So the value reaches the engine, where a preset name compares false against every row and is refused as INVALID_FILTER only at query time: the silent-zero-then-400 shape the preset ruling exists to move to publish.
A second carrier arriving
object-grid properties.defaultFilters is outside the walk too. On main it is z.unknown(), and a preset rule there lints GREEN while the same rule under properties.filter is refused. Open PR #19750 (card #19514) turns it into z.array(ViewFilterRuleSchema) and does not touch packages/lint, so once it lands it becomes a rule-array carrier that neither door refuses. The owning seat has been told on #19514.
⛔ Not decided here
FILTER_KEYS is shared by four gating rules, so widening it widens all four at once, and the round did ⛔ not measure whether the other three should reach filterBy. The fix may instead be a rule-local key list. That is the owning round's first measurement, ⛔ not this card's.
Why it matters beyond the lint
The shipped ADR-0087 entry filter-preset-ordering-comparand-refused says the sweep is mechanical because os validate / os lint report each carrier by path. That is false for filterBy. #19778 corrects the entry's prose to say so. When this card lands, that prose will need one more regeneration.
Dedupe
Repo-scoped issue search (mcp__github__search_issues): 「lint filter walk FILTER_KEYS filterBy interfaceConfig preset comparand not walked page base filter」 → 0 results. 「object-grid defaultFilters lint walk filter tokens empty combinators rule array not checked」 → 6, including closed. None names the walk's key list. Nearest: #19514 (open, owns the defaultFilters retyping) and #17320 (closed, the converged rule-array filter doors).
Dedupe words: filterBy lint preset comparand · FILTER_KEYS filterBy · interfaceConfig filterBy not walked · filter-walk key list page base filter · defaultFilters lint walk
Generated by Claude Code
① — a reproducible defect: a shape the platform declares refused at publish is refused by no door on one carrier that exists and is consumed.
Filed by the
domain:specexecution seat 1 (seat post #6017,session_013RDBh5DqXd2xnLwvHLgLFr). ⛔ Unlabelled beyondfinding, ⛔ ungraded, ⛔ unrouted. Reader: the triage seat grades and routes it. The fix lands inpackages/lint, which the domain table assigns todomain:specby exception. Surfaced by the #19778 round's probe (os-dev-report5789628005), and its load-bearing fact was re-read at source by this seat.The gap, at source on
origin/main2cf9db7c43packages/lint/src/filter-walk.ts:export const FILTER_KEYS: ReadonlySet<string> = new Set(['filter', 'filters', 'runtimeFilter', 'relatedListFilter']);. The walk descends only through those keys.walkAuthoredFilters/FILTER_KEYSfeed four rules:validate-preset-comparands.ts,validate-empty-combinators.ts,validate-filter-tokens.tsandvalidate-flow-filter-tokens.ts.interfaceConfig.filterBy: z.array(ViewFilterRuleSchema)(page.zod.ts). The only lint reader offilterByisvalidate-page-field-bindings.ts, which takes field references from it (fieldRefsFrom(cfg.filterBy, …)) and ⛔ never looks at comparand values.FilterConditionSchemaalone, andViewFilterRuleSchemahas no preset check.Measured by the round (against built
dist, resolved through package exports)A rule
{ field: 'close_date', operator: 'greater_than', value: 'last_30_days' }on adatefield:PageSchema/ component schema@objectstack/lintinterfaceConfig.filterBydataSource.filter…dataSource.filter[0].valuerecord:related_listproperties.filter…properties.filter[0].valuefilterviews[0].filter[0].valueControls:
filterByvalue ({ $x: 1 }, or a one-elementbetween) is REFUSED atinterfaceConfig.filterBy.0.value, so the zero is not an unparsed slot.interfaceConfig.filteris refused by the lint.filterBy.Consumed today. objectui at the pinned
.objectui-shaspreadscfg.filterByinto the list query (packages/app-shell/src/views/InterfaceListPage.tsx, the round's reading). So the value reaches the engine, where a preset name compares false against every row and is refused asINVALID_FILTERonly at query time: the silent-zero-then-400 shape the preset ruling exists to move to publish.A second carrier arriving
object-gridproperties.defaultFiltersis outside the walk too. Onmainit isz.unknown(), and a preset rule there lints GREEN while the same rule underproperties.filteris refused. Open PR #19750 (card #19514) turns it intoz.array(ViewFilterRuleSchema)and does not touchpackages/lint, so once it lands it becomes a rule-array carrier that neither door refuses. The owning seat has been told on #19514.⛔ Not decided here
FILTER_KEYSis shared by four gating rules, so widening it widens all four at once, and the round did ⛔ not measure whether the other three should reachfilterBy. The fix may instead be a rule-local key list. That is the owning round's first measurement, ⛔ not this card's.Why it matters beyond the lint
The shipped ADR-0087 entry
filter-preset-ordering-comparand-refusedsays the sweep is mechanical becauseos validate/os lintreport each carrier by path. That is false forfilterBy. #19778 corrects the entry's prose to say so. When this card lands, that prose will need one more regeneration.Dedupe
Repo-scoped issue search (
mcp__github__search_issues): 「lint filter walk FILTER_KEYS filterBy interfaceConfig preset comparand not walked page base filter」 → 0 results. 「object-grid defaultFilters lint walk filter tokens empty combinators rule array not checked」 → 6, including closed. None names the walk's key list. Nearest: #19514 (open, owns thedefaultFiltersretyping) and #17320 (closed, the converged rule-arrayfilterdoors).Dedupe words:
filterBy lint preset comparand·FILTER_KEYS filterBy·interfaceConfig filterBy not walked·filter-walk key list page base filter·defaultFilters lint walkGenerated by Claude Code