fix(lint): walk page filterBy and lookup-field lookupFilters as authored filters - #19818
Conversation
…red filters FILTER_KEYS gains the two consumed rule-array carriers the walk never entered, so filter-preset-comparand (and filter-token-unknown) judge them. The preset rule binds filterBy through interfaceConfig.source and lookupFilters through the field's reference, never the owning object. Claude-Session: https://claude.ai/code/session_01UDXER3sdqfeVYpEWZs5mZx Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UDXER3sdqfeVYpEWZs5mZx Co-authored-by: Claude <noreply@anthropic.com>
…ters Claude-Session: https://claude.ai/code/session_01UDXER3sdqfeVYpEWZs5mZx Co-authored-by: Claude <noreply@anthropic.com>
…nt-filter-walk-carriers
📓 Docs Drift CheckThis PR changes 2 package(s): 11 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 6 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 136 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 7e3437801980c821e5f7aaef01f8b2cdf03e61fc && git checkout 7e3437801980c821e5f7aaef01f8b2cdf03e61fc
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 1f89ba0d704a797225ab8cf306e4cdec89edae8e 4dda1fd0fd8bda0888711cabaa737711350cce08 && git checkout -B drift-repro 1f89ba0d704a797225ab8cf306e4cdec89edae8e && git merge --no-ff 4dda1fd0fd8bda0888711cabaa737711350cce08
node scripts/docs-audit/affected-docs.mjs --json 1f89ba0d704a797225ab8cf306e4cdec89edae8e
|
…nt-filter-walk-carriers
… clause The lint's filter walk now descends a page's interfaceConfig.filterBy and a lookup field's lookupFilters, so the entry's surface group that put both keys beyond every publish door, and the by-hand search its acceptanceCriteria prescribed for them, no longer describe the platform. Both are deleted; the surface's group count goes with them. registry.ts is regenerated with gen:migration-registry. Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1 Co-authored-by: Claude <noreply@anthropic.com>
The lint now walks a page's interfaceConfig.filterBy and a lookup field's lookupFilters, so the reason clause saying both are reached by neither door is false. The clause is deleted; the sentence ends on the surface's groups. registry.ts is regenerated with gen:migration-registry. Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1 Co-authored-by: Claude <noreply@anthropic.com>
The pending preset-entry changeset's third group said filterBy and lookupFilters lint green and are swept by hand; this branch makes both false, so the item and the group count go. The spec patch changeset now names reason beside surface. Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1 Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: Reviewed and posted 2026-09-23T13:21Z by the at-tier review subagent the ① Derived judgments
② Semver level
③ Boundary flags
Blocking: F1 — three one-phrase edits ("two of the consumed rule-array carriers …; object-grid Implemented-by: VERDICT: FAIL |
…ule-array carriers
filterBy and lookupFilters are not the only consumed rule-array carriers
outside the walk (object-grid defaultFilters is another), so the article
that said so goes from the lint changeset, the FILTER_KEYS docblock and the
test header; relatedListFilter is no longer the one member off the filter
spelling either. The empty-combinator and flow-token rules did change for
values the lint receives (filterBy: {} and a flow node config.lookupFilters),
so the clauses and the changeset bullet calling them unchanged are cut.
Comments and changeset prose only; no code moves.
Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1
Co-authored-by: Claude <noreply@anthropic.com>
… preset note This branch deletes sentences that count was taken over, so the count no longer holds for the release that ships the note. Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1 Co-authored-by: Claude <noreply@anthropic.com>
With the two unchanged clauses gone, the sentence framed as what the entry changes per walking rule named two of the four rules and implied the rest held still, which the empty-node and flow-token measurements refute. Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1 Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: Reviewed and posted 2026-09-23T14:26Z by the at-tier review subagent the ① Derived judgments
② Semver level
③ Boundary flags
Blocking: F1 and F2 — two one-phrase cuts in test comments, no code moves: drop "— the lit control every block below keeps" (or scope it to block 1), and replace "the same silent literal it is in" with wording that does not assert a silent runtime (the engine refuses it). Implemented-by: VERDICT: FAIL |
|
…comments The preset test header claimed its dataSource.filter lit control in every block below; only the first block carries one. The token test comment called an unknown token a silent literal; the engine's token resolver throws FILTER_TOKEN_UNKNOWN on it. The FILTER_KEYS docblock said an ordering preset in either carrier was refused at query time; the engine's temporal door refuses only on a date, datetime or time field. Each clause is cut; comments only, no code moves. Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1 Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: Reviewed and posted 2026-09-23T15:27Z by the at-tier review subagent the ① Derived judgments
② Semver level
③ Boundary flags
Blocking: none. Implemented-by: VERDICT: PASS |
Maintainer confirmation — the DELIBERATE CORRECTION of
|
Fixes #19791
Clause-②: no
Rewritten short by the
domain:spec#5seat (2026-09-23T15:28Z), which took this PR over from seat 2. The earlier body is in the edit history; the dev reports are on #19791.A page's
interfaceConfig.filterByand a lookup field'slookupFiltershold filter rules that reach the engine'swhere, but the lint's shared filter walk did not enter them. A date-range preset in either, such as{ field: 'close_date', operator: 'gt', value: 'last_30_days' }, parsed, linted and published green.What changed
@objectstack/lintpatch):FILTER_KEYSinpackages/lint/src/filter-walk.tsaddsfilterByandlookupFilters.filter-preset-comparandbinds afilterByrule tointerfaceConfig.source(else the page'sobject), and alookupFiltersrule to the field'sreference. ArelatedListFilteron the same field still binds to the owning object.filter-token-unknownreaches both keys through the same walk.18.filter-preset-ordering-comparand-refused(@objectstack/specpatch; rulings5793402649and5794625162on [finding] the lint's filter walk (FILTER_KEYS = filter · filters · runtimeFilter · relatedListFilter) never reaches a page's interfaceConfig.filterBy — a bare date-range preset in that rule array parses green AND lints green, so nothing refuses it at publish #19791): the fix makes parts of it false, and they are deleted with no replacement:surfacegroup (3) and the word "three" before it, the by-hand clause inacceptanceCriteria, and the "reached by neither" clause inreason.registry.tsis regenerated..changeset/19778-preset-entry-carriers.md(from fix(spec): the preset-comparand entry puts each carrier under the door that refuses it #19801, not yet released): its item 3 said both keys lint green and must be swept by hand. That is false after this PR, so item 3 is deleted, "The three groups" becomes "The groups", and the Reach sub-bullet counting "nine sentences" is deleted too.Check Changesetis red on purposeThis PR edits a pending changeset it did not add (the #19778 note above).
check-empty-changeset.mjscalls this a DELIBERATE CORRECTION: the check stays red. The correction is recorded on this PR (5796661306) and awaits the maintainer's written confirmation.Check Changesetis not a required context.Measured (dev reports on #19791)
os lint,os validateand the runtime publish gate refuse it at this head; none of them refuses it atafc3b64928. Lit control (a componentdataSource.filter): refused on both trees. Dark control (an ISO date): green on both trees.validate-preset-comparands.test.tsand 1 invalidate-filter-tokens.test.ts. Restoring the base source turns 5 red. Three ablations each turn their pin red: dropping the two keys, dropping thelookupFiltersbinding, and dropping theinterfaceConfigreader.5795612549,5796648031) failed sentences, not code. Rounds 4 and 5 cut them: three "the two carriers" exclusives (object-griddefaultFiltersis also outside the walk), a lit-control claim, an unknown token called "silent" (the engine throwsFILTER_TOKEN_UNKNOWN), and "refused only at query time".4dda1fd0fd: all seven required contexts pass.Check Changesetis red as described above; the gate comment is5796661306.🤖 Generated with Claude Code
https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1