Skip to content

Commit 23443ce

Browse files
committed
docs(lint,spec): describe the field-typed arm at the registration and in the shared message's TSDoc
The rule's registration comment said it needs no resolution context; arm 2 reads the stack's objects and datasets when present. The shared refusal wording's TSDoc said "ordering comparand"; it is now also the wording for the field-typed equality/membership positions. The TSDoc publishes in dist/*.d.ts (measured), so the spec change carries a patch changeset. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno
1 parent 96ff8f5 commit 23443ce

3 files changed

Lines changed: 24 additions & 11 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
`bareDateRangePresetComparandMessage`'s TSDoc — published in `dist/*.d.ts` — now states both moments the wording is reported at: the field-agnostic schema door in `data/filter.zod.ts` (ordering positions only: without a field type, equality on a select column is legitimate) and `@objectstack/lint`'s `filter-preset-comparand` rule, which with the field type in hand refuses every comparand position on a declared `date` / `datetime` field (#16106). The message text itself is unchanged.

packages/lint/src/authoring-rules.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -607,13 +607,17 @@ export const AUTHORING_RULES: readonly AuthoringRule[] = [
607607
// no layer: the engine refuses it on a declared temporal field at query time
608608
// (INVALID_FILTER / 400, PR #8808), and anywhere else it compares as a
609609
// literal string. This is the authoring-time refusal the ruling shipped
610-
// alongside the engine door, judging the filter literal in isolation —
611-
// ordering positions only, all three authored filter shapes. Like
612-
// `validateEmptyCombinators` it needs NO resolution context, so
613-
// RUNTIME_NEEDS_FULL_SNAPSHOT does not apply and the runtime gate runs it
614-
// for every filter-carrying type the gate already maps: the write path is
615-
// the one door an AI author uses, and dashboards/views are where the preset
616-
// vocabulary is near enough to reach for.
610+
// alongside the engine door. Two arms (the rule's header is the authority):
611+
// arm 1 judges the filter literal in isolation — ordering positions only,
612+
// all three authored filter shapes, no resolution context; arm 2 (#16106,
613+
// maintainer-ruled 1′) judges equality / membership positions WITH the field
614+
// type in hand, read from the stack's own `objects` (and `datasets`, to bind
615+
// a widget or report) — both collections the per-write snapshot carries —
616+
// and stays silent wherever they are absent. So RUNTIME_NEEDS_FULL_SNAPSHOT
617+
// still does not apply and the runtime gate runs it for every
618+
// filter-carrying type the gate already maps: the write path is the one door
619+
// an AI author uses, and dashboards/views are where the preset vocabulary is
620+
// near enough to reach for.
617621
{
618622
name: 'validatePresetComparands',
619623
tier: 'gating',

packages/spec/src/data/date-range-presets.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,14 @@ export const DATE_RANGE_PRESET_MACRO_WINDOWS: Readonly<
9999

100100
/**
101101
* The one refusal wording for "a declared preset name authored as a bare
102-
* ordering comparand", shared by the two moments it can be reported — the
103-
* schema door in `data/filter.zod.ts` and `@objectstack/lint`'s
104-
* `filter-preset-comparand` rule — so one condition keeps one wording
105-
* (the #5240 convention).
102+
* filter comparand", shared by the moments it can be reported — the
103+
* field-agnostic schema door in `data/filter.zod.ts` (ordering positions
104+
* only: without a field type, equality on a select column is legitimate) and
105+
* `@objectstack/lint`'s `filter-preset-comparand` rule (the same ordering
106+
* positions, plus — with the field type in hand — EVERY comparand position on
107+
* a declared `date` / `datetime` field: bare, `$eq` / `$ne`, `$in` / `$nin`
108+
* and their view-rule and triple spellings; #16106, maintainer-ruled 1′) — so
109+
* one condition keeps one wording (the #5240 convention).
106110
*
107111
* Why this is refused at all (#8690, C half, maintainer-ruled 2026-08-15):
108112
* `last_30_days` and its siblings are REAL declared names — but only for the

0 commit comments

Comments
 (0)