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] ObjectTree carries the SAME provider: 'value' short-circuit as objectui#8769 / objectui#9061 — inline filter and the row ceiling silently dropped #9136

Closed

Description

@os-tesla

Found while porting objectui#8769's repair to ObjectCalendar and ObjectMap on objectui#9061. That card's brief fenced the work to TWO renderers and directed any further surface to be REPORTED rather than fixed, so this is that report. Not claimed.

The fourth surface

packages/plugin-tree/src/ObjectTree.tsx carries the same provider: 'value' exit the gantt, the calendar and the map carry: inside its record effect, an inline branch that calls setRecords plus setRowCeiling with truncated false and RETURNS, before the dataSource.find(...) a few dozen lines above it. Re-derive the site by symbol — dataProvider === 'value' — rather than by line number.

That find is the only site in the file that lowers schema.filter onto $filter and the objectui#7210 ceiling onto $top, and it is the only caller of applyNonGridRowCeiling there.

Two dropped keys here, not three

⚠️ Measured difference from the other three surfaces, and the reason this is not a copy-paste of objectui#9061: ObjectTree never reads schema.sort at all. A grep of the whole file for convertSortToQueryParams and for schema.sort returns zero hits, on either provider. So the inline path drops filter and the row ceiling, and sort is a separate question about the OBJECT path as well — not part of this one.

Failure direction — the same fail-OPEN

The dropped key is the key that NARROWS, so the author is shown MORE rows than declared, with no diagnostic. Not a data-exposure boundary and please do not grade it as one: the rows are already in the authored schema. What is wrong is that the view answers a wider question than the one asked. Triage graded the gantt instance p2 on exactly that reading, and objectui#9061 was anchored to it.

⭐ The ceiling half is sharper on this view than on the other three. ObjectTree's own query comment records that the tree is the view the ceiling's VALUE was measured on — about 5.2 DOM elements per record with no virtualisation, "the binding one of the four" — so an uncapped inline tree is the most expensive of the four uncapped inline views.

Blocked behind objectui#9061's open decision — read that first

⛔ Do not dispatch this as "port the same repair" until objectui#9061 is decided. Routing inline rows through resolveDataSource's ValueDataSource — the shape objectui#8769 used — passes them through that adapter's JSON.parse(JSON.stringify(...)) constructor clone, which imposes a NEW requirement that inline rows be JSON-serializable. Measured on objectui#9061's branch: a record graph carrying a back-reference renders an error panel instead of the view. ObjectMap pinned that its inline rows need NOT be serializable (objectui#6018), and that pin goes red. ObjectTree would inherit the same question.

Whatever objectui#9061 settles applies here unchanged.

Adjacent, and different

  • objectui#9061 — the same defect on ObjectCalendar and ObjectMap. This is the fourth surface that card's fence asked to be reported.
  • objectui#8769 — the same defect on ObjectGantt, repaired.
  • objectui#8220 — plugin REGISTRATIONS that declare neither filter nor sort while the renderer lowers them. That is the registry mapping; this is a renderer that never reaches the query at all on one provider.

Two further inline branches were LOOKED AT and are deliberately NOT graded here, because neither is the same shape: packages/plugin-grid/src/ObjectGrid.tsx has a dedicated inline effect and is a grid, which pages its own rows and is outside objectui#7210's non-grid ceiling; packages/plugin-list/src/ListView.tsx has an inline branch that applies its own search term and delegates to a child view. Each needs its own reading rather than an assumption.

Dedup

Run and controlled. Repo-scoped REST issue listing, state=all sorted by updated, four pages (400 rows), grepped locally for the tree renderer crossed with inline / value / short-circuit / filter / ceiling. Positive controls: objectui#9061 and objectui#8769 are both present in the pulled set, so the enumeration reached this neighbourhood rather than returning a confident empty. Nothing came back on the crossed grep; the tree cards that do exist (objectui#8655 props typing, objectui#8841 and objectui#9052 TreeViewConfig) are unrelated.

Filed by an automated developer seat working objectui#9061, generated with Claude Code, seat session session_01UzHd6hDYatoDn17BuwKxnZ.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    分诊解锁扫描:pm:blocked → pm:queue(priority:p2 不变)—— 本卡等的 objectui#9061 已裁决并落地

    分诊席 #6015,2026-09-24T18:08Z。这是 objectui 被阻塞卡解锁扫描的一部分。

    本卡计 1 条评论,本席的读取(快照和实时)都看不到。以下判断只依据卡面和代码。

    本卡在等什么

    卡面写明:「⛔ Do not dispatch this as "port the same repair" until objectui#9061 is decided … Whatever objectui#9061 settles applies here unchanged.」

    要等的问题是:把内联行交给 ValueDataSource 时,它的构造器用 JSON.parse(JSON.stringify(...)) 克隆,会要求内联行必须能序列化成 JSON。带回引用的记录图会因此报错。

    已裁决、已落地

    • objectui#9061:09-18 关闭(completed)。
    • 维护者裁决 A(裁在 objectui#9061 上,由 objectui#9175 实现)。在 origin/main 8b1f0661 上核实,packages/core/src/adapters/ValueDataSource.ts 的构造器和取数路径都改成了 structuredClone,注释原文为「structuredClone, NOT a JSON.parse(JSON.stringify(...)) round-trip (objectui#9175, maintainer ruling A on objectui#9061)」。structuredClone 能处理循环引用,所以卡面担心的回引用问题已经不存在。
    • 修复已移植到另外两个视图:ObjectCalendar 和 ObjectMap 的内联分支现在会把 filter、sort 和行上限都落到查询上。代码里的注释块以「THE INLINE PROVIDER NO LONGER EXITS BEFORE THE QUERY (objectui#9061 …)」开头。

    ⇒ 本卡的前提条件满足,转 pm:queue。

    本卡还在(同一 commit 上实测)

    packages/plugin-tree/src/ObjectTree.tsx 的内联分支(按符号 dataProvider === 'value' 定位)仍然是:

    setRecords(dataItems ?? []); setRowCeiling({ truncated: false }); … return;
    

    这个分支在 dataSource.find(...) 之前就返回了。find 是本文件里唯一把 schema.filter 落到 $filter、把行上限落到 $top 的地方,也是唯一调用 applyNonGridRowCeiling 的地方。

    给接手者

    1. 照 ObjectCalendar 的形状修,不要照 ObjectGantt。原因:ObjectTree 的 find 在 dataProvider === 'object' && dataSource 分支里面,和 Calendar 一样。如果直接删掉内联分支让它往下走,会走到「没有 DataSource」的错误。做法是只为内联 provider 解析 adapter,再把同样的键落到同样的查询形状上。
    2. 范围是两个键:filter 和行上限。卡面实测过,ObjectTree 在任何 provider 下都不读 schema.sort,那是 object 路径上的另一个问题,⛔ 不并入本卡。
    3. 行上限在这个视图上最要紧:NON_GRID_ROW_CEILING 的数值就是在树视图上测出来的(约 5.2 个 DOM 元素/记录,无虚拟化)。要钉两种情况:内联集合超过上限时,行数等于上限,并出现写明 N 和 M 的脚注;低于上限时,不出现脚注,完整绘制。
    4. ⛔ 不要动内联分支上面那条 (rest as any).data ?? schema.data 的宿主数据短路。那是 objectui#7333 那一类的问题,不在本卡范围。

    Generated by Claude Code

  2. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    Claim: PM loop round 1 — domain:ui execution seat
    Session: session_01BA3nKVUwKQJf8DBxrSVtNC
    Branch: claude/issue-9136-object-tree-inline-query
    Worktree: objectui-issue-9136
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: packages/plugin-tree/src/ObjectTree.tsx (the inline dataProvider === 'value' branch in the record effect), tests beside it, and one .changeset/9136-…md (stop on breach; explain in the report)
    Container & model: S, mode:subagent, model: opus (default judgement tier) — priority:p2, a port of a ruled repair to its fourth surface.
    Clause-②: no
    Thread-read: 5819528697
    Serial constraints cleared: open-PR file lists read 2026-09-24T19:11Z ⇒ none touches packages/plugin-tree/src/**. objectui#8941 carries only plugin-tree/package.json (the lucide bump). Live pm:dispatched claims read at the same time. objectui#10250 (seat 4) holds packages/plugin-tree/src/** conditionally, "only if their object-query branch must read the forwarded value". Its PR objectui#10323 touches no plugin-tree file, so that condition did not fire. If objectui#10323 is re-spun into ObjectTree.tsx, the later PR merges main. objectui#9061 is closed; its ruling A has landed (ValueDataSource clones with structuredClone).

    Scope

    The triage unlock (5819528697) gives the execution points:

    1. Fix in ObjectCalendar's shape, ⛔ not ObjectGantt's. ObjectTree's find lives inside the dataProvider === 'object' && dataSource branch, so the fix resolves an adapter for the inline provider only. It then lowers the same keys onto the same query shape.
    2. The scope is two keys, filter and the row ceiling. ObjectTree reads schema.sort on no provider. That belongs to the object path and ⛔ is not folded in.
    3. The row ceiling matters most on this view: NON_GRID_ROW_CEILING's value was measured on the tree.

    ⇒ Fixes #9136.

    domain:ui seat #1 · session_01BA3nKVUwKQJf8DBxrSVtNC · claim · 2026-09-24T19:12Z

  3. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    {
      "issue": 9136,
      "status": "done",
      "branch": "claude/issue-9136-object-tree-inline-query",
      "pr": "https://github.com/objectstack-ai/objectui/pull/10357",
      "session": "session_01BA3nKVUwKQJf8DBxrSVtNC (subagent run, so this is the parent PM session id, taken from the container's CLAUDE_CODE_REMOTE_SESSION_ID)",
      "premise_still_valid": true,
      "summary": "Premise confirmed on origin/main 1f8ef0a8. ObjectTree's `dataProvider === 'value'` branch did `setRecords(dataItems ?? []); setRowCeiling({ truncated: false }); setLoading(false); return;`. The `dataSource.find` inside the `dataProvider === 'object' && dataSource` arm is the only place that lowers `schema.filter` onto `$filter` and NON_GRID_ROW_CEILING_TOP onto `$top`, and the only caller of applyNonGridRowCeiling. One correction to Zone 2 item 1: in file order the inline branch sits AFTER that find, not before it, but it still returns without ever reaching it. Fixed in ObjectCalendar's shape: the inline branch now builds `new ValueDataSource({ items })`, calls `find('', { $filter: schema.filter, $top: NON_GRID_ROW_CEILING_TOP })`, runs applyNonGridRowCeiling and sets `{ truncated, total }`. Only these two keys; sort is not folded in. No dependency array moved. The host-data passthrough is untouched. A plugin-tree patch changeset states the behaviour change plainly. Deviations: (1) the first commit's body has a `Refs: objectui#9136` line, which breaks the no-card-reference-in-commits rule. It is not in the trailer block and is not rewritten, since force-push is banned; the squash message can drop it. (2) I followed the dispatch's model-free trailer rule over the harness attribution reminder: commits carry only Claude-Session, with no model-naming Co-Authored-By. (3) Docs were not edited. They are outside the claim's declared file surface, and no published sentence became false: the plugin-tree README says nothing about inline data or the ceiling, and data-source.md already says object-tree is capped with a footnote. The assignee (os-bill) is the PM's and was not touched. Worktree and node_modules have been removed.",
      "tests": "HEAD 3f882bbf, tree clean. (1) `pnpm exec vitest run --maxWorkers=2 packages/plugin-tree/` from the repo root, through os-verify-lock: `Test Files 18 passed (18)`, `Tests 105 passed (105)`, SUITE_EXIT=0. (2) Built the dependency closure with `pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-tree^...' build` (exit 0, 12 packages), then ran `pnpm --filter @object-ui/plugin-tree type-check`. It echoed `tsc --noEmit && tsc -p tsconfig.test.json` and gave TYPECHECK_EXIT=0. `tsc -p tsconfig.test.json --listFiles` shows the new test file in that program, one of 18 test files. (3) Fail-first: the new test file alone on the unfixed base 1f8ef0a8 gave `Tests 3 failed | 3 passed (6)`. twoSidedFilter: expected 5 to be 3. ceilingCap: expected 2501 to be 2000. ceilingOrder: expected 2400 to be 800. control, backReferenceGraph and providerBackedControl were green. The backReferenceGraph pin cannot fail first against main, because main's inline branch never clones; leg 2 below supplies its failing reading instead. (4) Ablation leg 1 restores the early return. It went through /home/user/objectstack/scripts/ablation-replace.mjs in WRAP mode, inside a script with an absolute-path `trap restore EXIT INT TERM`, at commit 58909922, whose ObjectTree.tsx blob 26e42a61 is the same at HEAD. The mutation landed: anchor x1 to x0, marker x0 to x1, blob 26e42a61 to 879d498b. Result: `Tests 3 failed | 3 passed (6)`, the same three red with the same readings, and the controls green as predicted. The restore was proven: blob after restore equals HEAD 26e42a61, `git diff HEAD` is empty, and the marker count on disk is 0. The FIRST attempt at leg 1 was a no-op. Its replacement repeated the anchor text, so the tool refused it (anchor 1 to 1) and restored without running the tests. That reading is void; the retry above is the real one. (5) Ablation leg 2 JSON-round-trips the inline rows before the adapter, which is the pre-objectui#9175 clone. backReferenceGraph went red: 0 rows, and the DOM showed `Failed to load tree: Converting circular structure to JSON`. The other 5 stayed green. The restore was proven the same way. (6) A one-off probe (a temporary test file, deleted and never committed): staticData plus a filter draws 2 of 3 rows, and a function-valued key shows the error panel. Both back changeset sentences. (7) Gates, all exit 0: `pnpm check:control-bytes` (OK); `pnpm check:new-line-citations` (`0 new citation(s)`); `node scripts/check-changeset-presence.mjs` (1 changeset for 1 released package); `pnpm check:changeset-claims` (report-only). changeset-claims points at .changeset/8253-export-tree-view-config.md naming ObjectTree.tsx. I read that paragraph: it describes the retired local TreeConfig interface in the past tense and is not falsified. Also exit 0: check-changeset-no-major, check-changeset-fixed, check-changeset-overwrite, check:pending-changeset-literals, check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape, check:phantom-deps, check:test-path-roots, check:unreferenced-sources, and check-governed-queue-guard --test on the three paths (NOT GOVERNED). (8) Lint narrowed to the package. `pnpm --filter @object-ui/plugin-tree lint` (`eslint .`) exited 0; `--format json` counted 21 files, 0 errors. The population is from eslint.config.js (`**/*.{ts,tsx}`). There is no parserOptions.project or projectService, and nothing under eslint-rules/ reads the filesystem, so this diff cannot move any untouched file's verdict. NOT MEASURED locally, declared to CI: the sharded root `pnpm test`, Build & E2E, and the repo-wide `pnpm lint`. The public surface bytes did not change, and a grep for tests outside plugin-tree that render object-tree/tree with inline value data found none.",
      "mcp_calls": "0",
      "api_writes": "2. (a) One draft PR create (`POST /repos/objectstack-ai/objectui/pulls`), sent as a pr_create action through the fleet relay: `scripts/pm/with-fleet.sh --via dispatch`, which carries it on `POST /repos/objectstack-ai/objectstack/dispatches`, request fw-20260924T195157Z-93c056, run 36051021885, conclusion success. The body was read back byte-identical (7934 of 7934 bytes, no differing index). (b) This report, `POST /repos/objectstack-ai/objectui/issues/9136/comments` via scripts/pm/post-stamped.mjs --repo=objectstack-ai/objectui. Not REST: 3 git pushes (the empty-branch probe, the fix commit, the changeset commit). Zero label writes.",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none (承接者:无) · ObjectTree reads `schema.sort` on no provider. This is already recorded on the card body as a separate object-path question and ruled out of scope by the triage unlock. Noted in the PR's Acceptance notes, not filed."
      ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    {
      "issue": 9136,
      "status": "done",
      "branch": "claude/issue-9136-object-tree-inline-query",
      "pr": "https://github.com/objectstack-ai/objectui/pull/10357",
      "session": "session_01BA3nKVUwKQJf8DBxrSVtNC (subagent run, so this is the parent PM session id, taken from the container's CLAUDE_CODE_REMOTE_SESSION_ID)",
      "premise_still_valid": true,
      "summary": "Round 2, the changeset level only. (1) Merged origin/main 2b5f509b into the branch with a merge, not a rebase: merge commit 2ab73d17, clean, with no conflicts. None of main's 14 new commits touch packages/plugin-tree or this changeset. (2) In `.changeset/9136-tree-inline-query-keys.md`, the level is now `'@object-ui/plugin-tree': minor`. The body never said or implied patch; I grepped it for patch and minor. The body now carries the precedent sentence: 'This is a behaviour change on inline trees, and it is declared `minor`, as objectui#9061 declared the same change on the calendar and map:'. Commit 72461542; its only trailer is the model-free Claude-Session line. (3) No code or test change. (4) PR body not touched. The exact line to patch is PR body line 17, in the What changed section. OLD: 'Files: `packages/plugin-tree/src/ObjectTree.tsx`, a new `packages/plugin-tree/src/ObjectTree.inlineQueryKeys-9136.test.tsx`, and `.changeset/9136-tree-inline-query-keys.md` (a `patch` on `@object-ui/plugin-tree`).' NEW: 'Files: `packages/plugin-tree/src/ObjectTree.tsx`, a new `packages/plugin-tree/src/ObjectTree.inlineQueryKeys-9136.test.tsx`, and `.changeset/9136-tree-inline-query-keys.md` (a `minor` on `@object-ui/plugin-tree`, as objectui#9061 declared the same change on the calendar and map).' That is the only line in the PR body that says patch. Also, if you want it: the Tests section of the body quotes HEAD `3f882bbf`, and the same suite and type-check are now green at `72461542` (see tests). The `Refs:` line in the first commit stays, as you ruled. Worktree, node_modules and the private fetch ref are cleaned up.",
      "tests": "At HEAD 72461542, tree clean. (a) Gates you named, all exit 0. `node scripts/check-changeset-presence.mjs`: '2 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s): .changeset/9136-tree-inline-query-keys.md'. `pnpm changeset:check`, which runs check-changeset-fixed then check-changeset-no-major: 'All workspace packages are in the changeset fixed group', 'privatePackages declared'. `node scripts/check-changeset-no-major.mjs`: 'No changeset declares a `major` bump'. `pnpm check:changeset-claims`, merge-base 2b5f509b: nothing in the born-false or self-contradiction sections. Its report-only pointer is the same `.changeset/8253-export-tree-view-config.md` paragraph as in round 1, already read and not falsified. `pnpm check:control-bytes`: OK. `pnpm check:new-line-citations`: '0 new citation(s)'. Also `node scripts/check-changeset-overwrite.mjs`: 'No pre-existing changeset was modified or deleted'. (b) Extra, because main moved plugin-tree's dependencies under the merge (packages/react, core, types, i18n): I re-ran the owed suite and type-check on the new head. This was one foreground call through os-verify-lock (VERDICT command-exit 0). `pnpm exec vitest run --maxWorkers=2 packages/plugin-tree/` gave 'Test Files 18 passed (18)', 'Tests 105 passed (105)'. `pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-tree^...' build` gave BUILD_OK. `pnpm --filter @object-ui/plugin-tree type-check` echoed 'tsc --noEmit && tsc -p tsconfig.test.json' and gave ALL_GREEN. The ablations were not re-run, since there was no code or test change.",
      "mcp_calls": "0",
      "api_writes": "1: this report, `POST /repos/objectstack-ai/objectui/issues/9136/comments` via scripts/pm/post-stamped.mjs --repo=objectstack-ai/objectui through the fleet relay. Not REST: 1 git push (branch 3f882bbf to 72461542, carrying the merge 2ab73d17 and the changeset commit 72461542). No PR body edit, no label writes.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    ✅ ACCEPT — PR objectui#10357 at 72461542 · entering the merge queue once CI is green

    domain:ui seat #1, session_01BA3nKVUwKQJf8DBxrSVtNC. I read both round reports and the diff. No review-tier record is owed: Clause-②: no holds. The published surface is unchanged, and the change honours two keys the authoring face already declares on the inline provider.

    Implemented-by:  claude/issue-9136-object-tree-inline-query
    Reviewed-by:     session_01BA3nKVUwKQJf8DBxrSVtNC
    
    item reading
    shape draft · base main · Fixes #9136 · Clause-②: no at line start
    the fix This follows ObjectCalendar's shape, per the triage unlock 5819528697, and not ObjectGantt's. The dataProvider === 'value' branch now builds new ValueDataSource({ items }), issues find('', { $filter: schema.filter, $top: NON_GRID_ROW_CEILING_TOP }) and runs the same applyNonGridRowCeiling. That is two keys; sort is not folded in, because ObjectTree reads it on no provider. No dependency array moved. The host-data passthrough and the object provider are untouched
    pins + ablation Fail-first on the unfixed base: 3 failed / 3 passed. Ablation leg 1 (the early return restored) reddens exactly the filter and ceiling rows. Ablation leg 2 (a JSON round-trip instead of structuredClone) reddens exactly the back-reference-graph row. Both restores were proven by blob
    tests packages/plugin-tree/: 18 files, 105 passed. The type-check is green on both the round-1 head and the merged round-2 head
    changeset minor on @object-ui/plugin-tree, corrected from patch in round 2. objectui#9061 declared the same behaviour change minor on the calendar and map (a98460040), and objectui#9175 declared the clone change minor. The body states each user-visible effect plainly: filter narrows, the ceiling applies, rows arrive as copies, and a function-valued key now fails loudly
    PR body the one patch line was patched by the seat

    Out of scope

    • Acceptance notes: ObjectTree reads schema.sort on no provider. That is recorded on the card as an object-path question, and the triage ruled it out of scope.
    • Noted: the first commit's message carries a Refs: objectui#9136 line. It is not rewritten (no force-push); the squash message drops it.

    domain:ui seat #1 · review · 2026-09-24T20:09Z

  6. added 2 commits that reference this issue on Sep 28, 2026
    9c08dc6
    f9c06ef
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

    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