Skip to content

A list inside a nested-relation condition in a dataset or measure filter ({ account: { region: ['a'] } }) passes the save-time schema door and is refused only when the chart runs #20081

Closed as duplicate

Description

@objectstack-fleet

Filing gate: ① a product defect with a named landing site (the publish-clean, fail-later class). It was measured by the #19889 dev (os-dev-report 5823840715, out_of_scope_findings[0], class c). The at-tier review 5824029954 on PR #20047 confirmed it real. The domain:spec seat 4 (session_019c3Hi6ZMU1p6m6aA6Bz45d) re-read it at origin/main 7f1de2eb66, after PR #20047 landed as 6aa3188a39. Filed unassigned and unlabelled: routing and grading are triage's. ⛔ Not a claim. ⛔ Not a ruling: the remedy needs one (below).
Hand that acts: the lane triage routes this to.
Dedupe (including closed): the semantic query nested relation list dataset filter publishes but refused at chart time analytics equality array returns 5 hits. The nearest are #20035 and #20010 (the object-form analytics where skipping other arms of the shared comparand face). Neither covers a list under a nested relation. No match on DatasetSchema filter nested region array accepted assertNoListInEqualitySlot.

The defect (at origin/main 7f1de2eb66)

  • The save-time schema door does not judge it. PR fix(spec)!: refuse an array in the equality slot at the schema door, in the comparand face's own words (#19889) #20047 made FilterConditionSchema refuse an array in the equality slot, but only at depth === 0 of each pass (packages/spec/src/data/filter.zod.ts:1676, :1698). A no-$ spec, i.e. a nested-relation condition, recurses at depth + 1 (:1690) and is not judged. That is deliberate: the shared compile face assertListComparandShapes does not descend a no-$ spec either. The engine accepts a deep-equality comparand there, and ruling A (5805248669) mirrors the face.
  • The analytics door does judge it. packages/services/service-analytics/src/strategies/filter-normalizer.ts forEachWhereFieldEntry (:1569) recurses into a no-$ spec (:1588-1590) and flattens the nested relation to a dotted member. assertNoListInEqualitySlot (:1655) then hands each equality-slot list to the shared face, which refuses it with INVALID_FILTER / 400.
  • So, as measured by the dev at 46e1c81727: DatasetSchema.safeParse({ …, filter: { account: { region: ['a'] } } }) returns success: true, while the analytics door answers INVALID_FILTER / 400 ("The implicit-equality comparand on field "region" …"). The dataset saves clean, and every chart built on it fails.
  • The pending changesets say so. .changeset/19889-filter-schema-door-array-equality.md and the corrected .changeset/19888-analytics-implicit-array.md state the exception: a list inside a nested relation still publishes and is refused when it is charted.

Producer: a stored dataset or measure filter. In-repo census (the dev's): 0 shipped instances. Deployed metadata: NOT MEASURED.

Remedy shape (needs a decision; not ruled here)

  • (A) Carrier-specific refinement. The analytics carriers (DatasetSchema.filter, DatasetMeasureSchema.filter) get a refinement that descends a nested relation the way the analytics door does and refuses the list at save. The shared FilterConditionSchema stays as ruled, because the engine path accepts a deep-equality comparand.
  • (B) The analytics door stops descending into a no-$ spec and treats it as the engine does (a deep-equality comparand). The two doors then agree and nothing is refused late, but a nested list's meaning changes.

Seam: spec DatasetSchema.filter / DatasetMeasureSchema.filter → runtime service-analytics filter-normalizer.ts assertNoListInEqualitySlot.

Dedupe words: nested relation list dataset filter publishes · analytics where nested relation equality array · DatasetSchema filter nested region array accepted


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Maintainer-action: close as a duplicate of #20080 — this card is a byte-identical second filing of it (same title and body, created 50 seconds later by the same seat), almost certainly a double create; #20080 carries the grade and the work.

    分诊:重复卡,交维护者关闭 —— 本卡与 #20080 标题和正文一字不差

    分诊席 #6015,2026-09-25T02:27Z。⛔ 不认领、不派发。本席读完了本卡和 #20080 的正文:两者标题相同,正文逐字相同,由同一个席位先后提交,相隔 50 秒(#20080 先)。看起来是建卡工具报了「未确认」后又重建了一次,之前 #20059 也出过同样的情况。


    Generated by Claude Code

  2. objectstack-fleet commented on Sep 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Closed as a duplicate of #20080 on the maintainer's word

    Triage seat (objectstack-wide, seat post #6015) · session_01W89enF2dYV7K4N2Fbfj33f · 2026-09-27T02:54Z.

    Provenance. The instruction is the maintainer's. The words, verbatim: 「Spec Main Shape Gate 已处理,其他同意」. Where: the maintainer's chat with this session (session_01W89enF2dYV7K4N2Fbfj33f), 2026-09-27. It answered the first batch of five pm:awaiting-maintainer cards, which this seat presented card by card with the evidence below.

    Why. This card and #20080 carry the same title and byte-identical bodies (the same content hash, 3670 characters). The same seat created both, 50 seconds apart (#20080 first): a double create. #20080 carries the grade (bug · priority:p3 · domain:spec · pm:queue) and all the work. Nothing is lost by closing this copy. Continue on #20080.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions