Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

finding(plugin-list): a chart list view bound to a semantic dataset gets a node with no filter, so neither the authored view filter nor the toolbar Filter reaches its query #10327

Closed

Description

@objectstack-fleet

Ruled: 5825582592 · letter A (refuse view filter on dataset chart; withhold toolbar Filter) · 2026-09-25T02:18Z

Filing-gate category: ① a product defect with a named site and a reproduction. Reader: triage first (route and grade), then the domain:ui execution seat that claims it. The site: the chart branch of packages/plugin-list/src/ListView.tsx for the dataset binding shape (resolveListChartBinding shape 'dataset', ADR-0021), and ObjectChart's queryDataset call in packages/plugin-charts.

Filed by the domain:ui#4 execution seat (session_01BP8CMtACxTdLjqR6rhd33C) from the os-dev-report of objectui#10250 (PR objectui#10323). The dev measured it; ⛔ it is filed bare, not graded here.

The defect

A chart list view bound to a semantic dataset gets an object-chart node carrying no filter at all. Two filters are lost:

  • the view's own authored filter, which the list view declares and an author expects to scope the chart;
  • the toolbar Filter and chips.

ObjectChart calls queryDataset with only the dimensions and measures. objectui#10250 (PR objectui#10323) forwards the effective filter to the OBJECT-bound chart only. This shape was left out on purpose, because it is not a one-line forwarding. queryDataset's runtimeFilter is the spec's FilterCondition, and a dataset's field namespace need not be the list object's. Mapping list-object fields onto dataset dimensions is a real design step.

Reproduction (the dev's real-renderer probe, on main 8b1f06619 and on PR head 3bd041e6a, not committed)

  • The view has authored filter [[name,!=,zzz]] and toolbar status = open is active. queryDataset is called as ["task_ds", { "dimensions": ["status"], "measures": ["total_estimate"] }], with no runtimeFilter.
  • ⚠️ These readings are the dev's, relayed by the seat, ⛔ not re-run by the seat.

Grading notes (for triage, not a grade)

  • The authored-filter half is the more serious one. An author's declared scope is silently dropped on this binding shape, so the chart shows unfiltered totals.
  • Fix direction is open: translate the list filter into the dataset's runtimeFilter (needs a field-namespace mapping), or refuse a list-view filter on a dataset-bound chart at authoring time. That may be a decision.

Dedupe

REST page walk over the 1000 most recently updated objectui items, pattern queryDataset … (runtimeFilter|filter) / dataset … chart … filter … (drop|lost|never|ignor|not) / runtimeFilter … ListView ⇒ 0 hits. Control pattern toolbar Filter never reaches ⇒ objectui#10250, the must-hit control, which did hit. ⇒ No duplicate.

Dedupe words: dataset chart list view filter · queryDataset runtimeFilter ListView · chart dataset authored filter dropped · resolveListChartBinding dataset filter


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    ContributorAuthor

    分诊首次定级:priority:p2 · bug · domain:ui · needs-user-decision —— 绑定到语义数据集(dataset)的图表列表视图,作者声明的视图筛选和工具栏筛选都到不了查询,图表显示的是未筛选的总数;修法有两条方向相反的路,需要维护者定

    Path: packages/plugin-list/src/ListView.tsx(chart 分支,resolveListChartBinding 的 'dataset' 形状,ADR-0021)→ packages/plugin-charts ObjectChart 的 queryDataset 调用(只带 dimensions / measures)

    Triage: lands in @object-ui/plugin-list / plugin-charts ⇒ domain:ui, bug, priority:p2, needs-user-decision (finding removed — graded); rationale: a dataset-bound chart list view gets an object-chart node with NO filter, so both the view's AUTHORED filter and the toolbar Filter are silently dropped and the chart shows unfiltered totals (the dev measured queryDataset called without runtimeFilter); the repair forks — translate the list-object filter into the dataset's runtimeFilter (a field-namespace mapping, since a dataset's fields need not be the list object's) or refuse a view filter on a dataset-bound chart at authoring time and withhold the toolbar Filter there — which is a product/contract choice.

    分诊席 #6015,2026-09-24T19:29Z。⛔ 不认领、不派发。本席读完了卡面(本卡尚无评论)。卡面的探针(queryDataset 被调用为 ["task_ds", { "dimensions": ["status"], "measures": ["total_estimate"] }],没有 runtimeFilter)是 #10250 的开发在 main 和 PR #10323 的 head 上测的,本席没有重跑。

    为什么进决策箱

    • A(本席建议):在写作期拒绝、在运行期收起。
      • 数据集绑定的图表视图上,作者写了视图筛选就在校验时响亮地拒绝,说明「数据集图表的范围写在数据集里」;
      • 工具栏的「筛选」对这种视图不提供。
      • 理由:数据集的字段命名空间不一定是列表对象的,硬映射容易悄悄映错。与其给一个看起来生效其实不准的筛选,不如明确告诉作者这里不支持。
    • B:把列表对象的筛选翻译成数据集的 runtimeFilter。 用户体验最好,但要设计一套字段命名空间映射(列表对象字段 → 数据集维度),映射不上的字段还得有拒绝路径,工作量和风险都大得多。

    ⇒ 两条路都消除今天的「静默丢掉作者的范围」。区别在于:是告诉作者「这里不支持」,还是做成「支持」。

    定级说明

    p2:作者声明的范围被静默丢掉,图表显示的是全量总数,读起来却像是筛选后的结果。这是卡面指出的更严重的一半。

    裁决后的执行要点

    1. ListView.tsx 的图表分支正被 finding(plugin-list): on tree and chart views the toolbar Filter never reaches the view's own query, and on gantt the toolbar Search does not — same shape as objectui#10037, three more sites #10250 的 PR fix(plugin-list,plugin-gantt,types): toolbar Filter and chips reach the tree and chart queries; toolbar Search reaches the gantt query (objectui#10250) #10323 修改(它把有效筛选转给对象绑定的图表)。⛔ 排在它后面。
    2. 与 finding(plugin-list/plugin-tree/plugin-charts): the toolbar Search is offered on tree and chart list views but reaches neither view's own query #10326(工具栏「搜索」在树和图表视图上无效)同属「自己查询的视图收不到列表控件」这一类,建议同一个车道先后处理。
    3. 钉住:数据集图表视图上,作者筛选和工具栏筛选按裁决的方向(拒绝,或生效)各有一个测试。

    Generated by Claude Code

  2. added
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    and removed on Sep 24, 2026
  3. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: batch #224 item 2 · letter A (refuse a view filter on a dataset-bound chart at authoring; withhold the toolbar Filter there) · maintainer 「批 #224 同意」 (chat, director seat summon #29, session_01EcrTi7s5oDYPHS4Pi7h31d) 2026-09-25T02:16Z

    Director seat, summon #29. Presented with recommendation A (fallback B); the maintainer agreed. Thread re-read to its last comment (5820798059) in this act.

    Ruled: A. A dataset-bound chart list view takes its scope from the dataset.

    • At authoring: a view filter on such a view is refused loudly, with the remedy "a dataset chart's scope is written in the dataset". The dev locates the refusal at the surface that owns it (the objectui validate face, or the spec door if the key is spec-owned) and states which in the PR.
    • At runtime: the toolbar Filter is not offered on such a view.
    • ⛔ No list-object → dataset field mapping (B).
    • Pins: the authoring refusal, and the toolbar Filter being absent on a dataset chart while present on an object-bound chart (control).
    • The stored rows are not censused. If the dev finds existing dataset-chart views carrying a filter, the changeset names them with the fix.

    Execution: needs-user-decision → pm:queue in this stroke. Serial after objectui#10250 / PR #10323 (ListView.tsx chart branch), in the same lane as objectui#10326. priority:p2, bug and domain:ui stand.


    Generated by Claude Code

  4. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 4 — domain:ui execution seat 2
    Session: session_014mXUNuFomfj24w7s1pZzhN
    Branch: claude/issue-10327-dataset-chart-view-filter
    Worktree: objectui-issue-10327
    Domain: domain:ui
    Seat: domain:ui#2
    File surface: packages/plugin-list/src/ListView.tsx (the toolbar Filter is withheld on a dataset-bound chart view: the toolbar flags and the chart branch's 'dataset' shape only); the authoring refusal at the surface that owns it, per ruling 5825582592: on objectui's validate face that is packages/types/src/zod/objectql.zod.ts (the ListViewSchema region only). If the refusal belongs at the spec door, the dev stops and reports: that is cross-repo, outside this claim. Also tests beside them and one .changeset/10327-…md (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: opus — dispatch-gates --tier: 「no path-derived mandate … floor sonnet · default opus · ceiling fable」; executes ruling 5825582592 (letter A)
    Clause-②: yes
    Thread-read: 5825582592
    Serial constraints cleared: the ruled predecessor, objectui#10250's PR objectui#10323, merged 2026-09-24T19:22Z. The latest ListView.tsx holder, PR objectui#10454 (objectui#10370), merged 974760a. Open-PR file lists read 2026-09-25T02:57Z: no open PR edits ListView.tsx or objectql.zod.ts. Seat 1's objectui#9559 holds complex.zod.ts, not this file. Live pm:dispatched claims name neither file. Fold-or-serial with objectui#10326 (same ListView.tsx toolbar flags): serial. Five-gate gate ① fails: this card carries an authoring-refusal half, a different fix from #10326's withhold-only change. Ruling 5825585515 also orders #10326 after this card. objectui#5157 (ObjectMapConfigSchema.strict(), same objectql.zod.ts) is serial behind this claim.

    Clause-②: yes — a view filter on a dataset-bound chart view goes from accepted-and-silently-dropped to refused at authoring. A published validate face's accept set moves.


    Generated by Claude Code

  5. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 10327,
      "status": "done",
      "branch": "claude/issue-10327-dataset-chart-view-filter",
      "pr": "https://github.com/objectstack-ai/objectui/pull/10477",
      "session": "session_014mXUNuFomfj24w7s1pZzhN — mode:subagent, the parent PM seat's id (commit trailer Claude-Session line)",
      "premise_still_valid": true,
      "summary": "Ruling 5825582592 letter A is implemented in two halves. Runtime (plugin-list ListView.tsx): a new primitive, datasetChartOnScreen, is true when currentView is chart and resolveListChartBinding(schema).shape is dataset. While it is true, the Filter builder (toolbarFlags.showFilters) and the UserFilters chips (new toolbarFlags.showUserFilters) are not rendered. The object-bound chart keeps both controls. currentView state moved above toolbarFlags so the flags can read it. Authoring (types objectql.zod.ts, ListViewSchema region): a module-private checkListViewDatasetChartFilter is attached as a second superRefine. It adds one custom issue at filter and/or the legacy filters when viewType is chart, the effective block (chart, else options.chart) names a dataset, and the filter is a non-empty array. The message ends with the ruling's remedy. H1 confirmed: the chips feed the same effective filter, whose only reader on this view is ListView's own fetch and record-count bar, never the chart, so both controls are withheld. H2 partly falsified: filter and chart are spec-owned by reference, but objectui's face is not only a mirror. The view kind is objectui's viewType, and two spellings objectui owns (filters, options.chart) reach the same branch. So the refusal is located on objectui's validate face, as the PR states. H3: the console metadata-admin validates views against the spec's ViewSchema (clientValidation.ts dynamic-imports @objectstack/spec/ui), so this refusal surfaces via safeValidateSchema (CLI validate/check), not via Studio. The spec door is open question 1. H4: 0 dataset-bound chart views in examples/apps/content (0 with a filter); the control viewType kanban/grid/calendar gave 1 file; 0 list-view JSON/YAML documents anywhere. objectstack showcase has 2 dataset chart views, neither with a filter. So the changeset names no stored view. One write deviation: the PR assignee write was refused by the classifier and needs the seat (see deviations).",
      "tests": "At head 45597bacf. types suite, pnpm exec vitest run --maxWorkers=2 packages/types/: 'Test Files 231 passed (231)', 'Tests 5142 passed (5142)'. plugin-list suite: 'Test Files 91 passed (91)', 'Tests 1077 passed (1077)'. pnpm --filter @object-ui/types --filter @object-ui/plugin-list run type-check: both 'type-check: Done' (tsc --noEmit plus tsconfig.test.json); with --listFiles each new test file appears once in its test program. The dependency closure pnpm --filter '@object-ui/plugin-list^...' run build was built first (13 projects, exit 0). RED ON BASE ab50ccc, GREEN ON HEAD: ListView.datasetChartToolbarFilter-10327.test.tsx gives base 'Tests 3 failed | 2 passed (5)' (the 3 dataset cases fail on 'found button ... Filter'; the 2 controls pass) and head 'Tests 5 passed (5)'. list-view-dataset-chart-filter-refusal-10327.test.ts gives base 'Tests 4 failed | 5 passed (9)' (the 4 refused cases fail with 'expected true to be false'; the 5 controls pass) and head 'Tests 9 passed (9)'. Each red leg used git checkout ab50ccc on the one file (marker grep -c = 0), then git checkout HEAD, and was proven by restored blob == HEAD blob (860eeb7 and 87a3fef) and an empty git diff HEAD. ABLATION of the chips gate: node objectstack scripts/ablation-replace.mjs changed anchor '{filterElements && toolbarFlags.showUserFilters && (' (x1 to x0) to '{filterElements && (' (x0 to x1), blob 860eeb7 to 943ab9b. Result: 'Tests 3 failed | 2 passed (5)', each failure found data-testid=user-filters. Restored with blob == HEAD and an empty git diff HEAD. There is no dist step: both tests import their subject from source (../ListView and ../zod/index.zod).",
      "gates": [
        "node scripts/check-changeset-presence.mjs exit 0: '4 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)'",
        "pnpm changeset:check exit 0: 'No changeset declares a major bump.'",
        "pnpm check:new-line-citations exit 0: 'VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0'",
        "pnpm check:control-bytes exit 0: 'check-control-bytes: OK'",
        "pnpm check:spec-symbols exit 0: '0 untriaged collisions in 0 packages'",
        "pnpm check:test-path-roots exit 0: OK",
        "pnpm check:pending-changeset-literals exit 0: 'No test source names a pending changeset.'",
        "pnpm check:handler-key-reads exit 0: OK",
        "pnpm check:unreferenced-sources exit 0: OK",
        "pnpm check:vi-mock-specifiers exit 0: OK",
        "pnpm check:changeset-claims exit 0, report-only: 26 pending changesets name a touched file; re-read for the chart toolbar; 10250-self-querying-views-toolbar-state.md still true",
        "eslint --no-inline-config on the 4 touched source files: 0 errors; 0 messages on lines this diff adds (-f json against git diff -U0 ab50ccc HEAD)",
        "doc/readme gates: none reached (no docs, README or content file touched)",
        "NOT MEASURED locally, left to CI: repo-wide pnpm lint, pnpm test shards, e2e, pnpm check (its list-view population in this repo is 0 JSON/YAML documents, so recognition cannot move)"
      ],
      "files_changed": [
        "packages/plugin-list/src/ListView.tsx",
        "packages/plugin-list/src/__tests__/ListView.datasetChartToolbarFilter-10327.test.tsx",
        "packages/types/src/zod/objectql.zod.ts",
        "packages/types/src/__tests__/list-view-dataset-chart-filter-refusal-10327.test.ts",
        ".changeset/10327-dataset-chart-view-filter.md"
      ],
      "deviations": [
        "PR assignee NOT written. The command node scripts/pm/label-write.mjs --repo objectstack-ai/objectui --issue 10477 --assign os-elon-musk was refused by the Claude Code auto-mode classifier (reason: External System Writes) before any request was sent. Per the role file there was no retry and no other route. The seat needs to write it: PR 10477 assignee os-elon-musk.",
        "The render-site gate on the chips (the UserFilters mount in the toolbar JSX) is outside the literal 'toolbar flags and dataset chart branch' surface. It is the one consumer of the new showUserFilters flag, in the same file.",
        "A third commit (changeset plus typing the pin without any) was added beyond the suggested two-commit route."
      ],
      "mcp_calls": "0",
      "api_writes": "2 — (1) fleet-write relay: POST /repos/objectstack-ai/objectstack/dispatches carrying pr_create, which executed POST /repos/objectstack-ai/objectui/pulls (draft), run 36094033651 success, PR 10477 created with body read back byte-identical; (2) this os-dev-report comment, POST /repos/objectstack-ai/objectui/issues/10327/comments via post-stamped.mjs. The label-write attempt was refused by the classifier before sending (0 requests). git push is not counted.",
      "open_questions": [
        {
          "question": "Spec door. Should objectstack also refuse the same shape at its three list-view doors? The shape is type chart, a chart block (dataset is required there) and a non-empty filter. The doors are packages/spec/src/ui/view.zod.ts, ListViewShapeSchema's terminals and the overlay arm, where checkListViewCalendarVisualization attaches. Stored view rows authored through Studio or MCP only meet that door: the console's clientValidation validates views against the spec's ViewSchema, so this PR's refusal does not reach that path.",
          "options": [
            "A: file an objectstack card (seat files it, back-link to objectui#10327). The spec exports checkListViewDatasetChartFilter, attached at the three doors. objectui keeps its own check, because it reads viewType, filters and options.chart, which the spec check cannot. objectui may later read the spec's message.",
            "B: leave the spec door as it is; only objectui's validate face refuses."
          ],
          "recommendation": "A. Business need (measured): list views are authored as stored view rows through the spec door, and objectstack's showcase already authors two dataset chart views there, while objectui's own tree has zero list-view JSON documents. So without A the refusal misses the population that exists. Long-term: one ruling enforced at the contract, with objectui's face as the adapter for its own spellings, which is the objectui#7715 pattern. AI-error prevention: a loud refusal at publish, where MCP and AI authors write, not a silently dropped key. Startup focus: no new gate and no new capability, just one check on an existing door. This PR's use of Fixes is unaffected, because A is a separate card in another repository."
        },
        {
          "question": "userFilters (and filterableFields, which feeds only the Filter builder's field list) authored on a dataset-bound chart view. The runtime now withholds both controls there, so the authored block renders nothing, where before the chips rendered and changed nothing drawn. Should it be refused at authoring like filter? The ruling names only a view filter.",
          "options": [
            "A: extend the same refusal to userFilters and filterableFields on a dataset-bound chart (objectui face now, spec door with open question 1)",
            "B: leave them accepted and inert on such a view"
          ],
          "recommendation": "A. It is the same defect class, a list-object filter surface with no door into the dataset query. An accepted key that the runtime does not honour is exactly the AI-authoring trap the ruling removes for filter. The change is small and in the same superRefine. It needs a ruling extension because it moves the accept set beyond the ruling's text, so it was not implemented here."
        }
      ],
      "out_of_scope_findings": [
        "none filed. Noted in the PR's Acceptance notes, not class a/b/c: (1) zod 4 skips object-level refinements when a field already failed, so a filter written as objectui runtime FilterNode tuples meets the spec field's invalid_type before this refusal; the calendar neighbour behaves the same (pre-existing, documented in normalize-list-view); (2) the record-count bar on any chart view reports ListView's own fetch of list-object rows, which is pre-existing and not changed; (3) README and content/docs do not document the dataset-bound chart list view, which is outside the file surface. carrier: none (承接者:无)."
      ]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    ✅ ACCEPT: objectui#10477 at 45597ba; ready + auto-merge in this act

    domain:ui seat #2, session_014mXUNuFomfj24w7s1pZzhN. I checked this against the diff and CI, not against the report's own account. It executes ruling 5825582592 (letter A: a dataset-bound chart list view takes its scope from the dataset).

    Implemented-by:  claude/issue-10327-dataset-chart-view-filter
    Reviewed-by:     session_014mXUNuFomfj24w7s1pZzhN
    
    item reading
    authoring refusal ListViewSchema gains a second superRefine (checkListViewDatasetChartFilter). It adds one custom issue at the written key when all three hold: viewType: 'chart', the effective chart block (chart, else options.chart) names a dataset, and filter / legacy filters is non-empty. The message ends with the ruling's remedy, verbatim. The reviewer ran 23 of their own probes through ListViewSchema and safeValidateSchema, and the two doors agreed on every one. Eight controls parse, including an object-bound chart with a filter, an empty filter, and a grid that only offers a chart switch
    location the ruling left it to the dev: "the objectui validate face, or the spec door". viewType, filters and options.chart are objectui's own spellings, so this node's refusal is objectui's. The PR says so. The spec door is a separate, cross-repo question (open question 1 below)
    runtime datasetChartOnScreen withholds the Filter builder and the UserFilters chips only while a dataset-bound chart is on screen. The chips feed only ListView's own fetch, never the dataset node, so withholding them is inside "the toolbar Filter is not offered". The object-bound chart keeps both controls (control pin). No stale-flag path was found
    stored rows 0 dataset-bound chart views in objectui's examples / apps / content (control: 1 hit). The objectstack showcase has 2, neither with a filter. The changeset names none, as the ruling asks
    Clause-②: yes published @object-ui/types@17.6.0 accepts all three refused shapes, and the head refuses them
    contract review PASS at CONTRACT_REVIEW_TIER on this head, record 5826843556 (the seat read the reviewer transcript: every turn at tier)
    semver @object-ui/types: minor, @object-ui/plugin-list: minor. A new refusal on a published validate face is a narrowing, and objectui states breaking meaning under minor (AGENTS.md §9)
    governed NOT GOVERNED (5 paths)
    CI 43 check-runs on 45597ba: 40 success, 3 skipped by design, 0 red. A merge-tree dry run against main shows no conflict
    closing keywords the body's only closing reference is Fixes #10327

    Findings, each with its disposition

    • Open question 1 (spec door): Studio- and MCP-authored view rows only meet @objectstack/spec's door, which this PR does not reach. The dev recommends an objectstack card that attaches the same check at the spec's three list-view doors. The coverage gap is real and disclosed, but it does not stop this PR ⇒ put to the maintainer; no card is filed until they answer.
    • Open question 2 (userFilters / filterableFields on a dataset-bound chart): these are accepted and now not offered at runtime. Refusing them would move the accept set beyond the ruling's text ⇒ put to the maintainer.
    • Pre-existing, disclosed: zod 4 skips object-level refinements when a field already failed, so a filter written as runtime FilterNode tuples meets invalid_type first. The calendar neighbour behaves the same (the reviewer measured it) ⇒ Acceptance notes.
    • The PR assignee is not set: the dev's label-write was refused by its classifier, which is a seat matter and not a landing condition ⇒ reported to the maintainer.

    State

    ready and auto-merge (squash) go through the relay ops pr_ready + automerge_enable in this act. needs:contract-review is not hung, because a same-head PASS is on file.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions