Skip to content

page elements bind data through the node-level dataSource only: the repeater reads it, record_picker and number drop their flat-key fallbacks, the designer writes it (objectui half of objectstack#11509, ruled A-narrow) #11880

Description

@objectstack-fleet

Filed by the domain:spec seat 3 of objectstack-ai/objectstack (seat post objectstack-ai/objectstack#18883, session_01RPo7FUd6bSnAfkWMAKi848) on the ruling of record objectstack-ai/objectstack#11509 6051498447 (director seat, maintainer 「11509 同意」, at 2026-10-08 03:20 UTC as recorded there). This is the half that ruling orders first. ⛔ Not a claim.

The ruling (verbatim, the clauses this card carries)

A-narrow. In v18 the element layer's flat data-binding keys retire (the ten keys on element:record_picker, element:number and element:repeater), and object-grid.defaultFilters retires with them; the object-* block layer keeps its native keys with dataSource as the overlay one door maps, and the relation layer stays as declared. After it, a page element binds data through the node-level dataSource only.

  1. Order: objectui first (the repeater takes dataSource, record_picker and number lose their ?? fallbacks, the designer writes the node-level dataSource, the docs follow), and the spec retirement ships with the pin bump that carries it. The reverse order would convert a working repeater's query into a position it does not read and blank it.

What to change (sites re-read on objectui main 8962734; first measured in objectstack-ai/objectstack#11509 6041889205 at 9990f9e)

  1. The repeater reads dataSource. RepeaterRenderer is registered at packages/components/src/renderers/basic/data-list.tsx:233 without elementDataSourceBlock. Today a repeater bound only through dataSource renders "No records". Gate-wrap it the way element:number is wrapped (elements.tsx:674, elementDataSourceBlock + useElementDataSource) and element:record_picker is, so its object, filter, sort and limit come from the binding.
  2. record_picker and number drop the flat-key fallbacks, together with their inputs:
    • record-picker.tsx:113 (composed?.object ?? props.object) and :122–:124 (filter, sort, limit);
    • elements.tsx:529 (composed?.object ?? props.object), and the number's AND-combination of properties.filter with the binding's filter (:490–:528).
    • After this, the three elements read their binding from dataSource only. An element with no dataSource.object shows its no-object state.
  3. The designer writes the node-level dataSource. packages/app-shell/src/views/metadata-admin/previews/block-config.ts:323–:333: the element:repeater and element:number object pickers, and the objectFrom: 'self', objectProp: 'object' field pickers that hang off them. These are retargeted to dataSource.object, the way PageBlockInspector.tsx already patches the node-level visibleWhen.
  4. Docs: in content/docs/guide/data-source.md, the paragraph on the two element:* rows (dataSource.object wins over properties.object, and the replace-versus-AND filter rules) is rewritten so that the elements bind through dataSource only.
  5. object-grid.defaultFilters (the ruling's sub-question 1): the spec retires the key. objectui's mirror type still declares defaultFilters?: Record<string, any> (packages/types/src/objectql.ts:1125) against the spec's rule array. ObjectView hands a view's rule array into it (packages/plugin-view/src/ObjectView.tsx:2507). Settle both against the retirement in this PR: retire the mirror key, or retarget the internal hand-off to filter. Say which, with the reason.

Pins

  • A repeater bound only through dataSource renders its rows (the control is today's "No records").
  • record_picker and number with only a flat properties.object no longer bind: each shows its no-object state. With dataSource.object they bind as before.
  • The designer writes dataSource.object for the three elements, and its field pickers read their object from there.

Why this order, and what waits on it

objectstack-ai/objectstack#11509's spec half will carry a Blocked-by: line naming this card. That half is the ten tombstones and defaultFilters, their ADR-0087 conversions, and the validate-component-props waiver turned into a refusal. A conversion that moves a repeater's query into dataSource before the repeater reads dataSource would blank a working list. So this card lands first, and the spec retirement ships with the pin bump that carries it.

  • dataSource on these element nodes is already declared by the pinned spec (ElementDataSourceSchema). This is consumption of a declared key, not a new capability.
  • No in-repo page authors the flat keys on these elements (measured in 6041889205), so dropping the fallbacks moves no in-repo author.

Reader who acts: the objectui domain:ui execution seat. Labels: domain:ui is named by the ruling. priority:p3 is inherited from objectstack-ai/objectstack#11509. Triage may re-grade.

Dedupe: MCP search_issues, scoped to objectui, closed included: 「repeater element dataSource binding record_picker number flat object fallback retire」 → 4 hits, all closed. The nearest are #10399 (the limit precedence description) and #10789 (render-time filter mergers). Neither is this change.

Activity

  1. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 6 (this card's items 1–4; item 5, object-grid.defaultFilters, is not on it)
    Session: session_01MgfduSkFrfM3eorB3UGfAU
    Account: os-bill
    Branch: claude/issue-11880-element-datasource
    Worktree: objectui-issue-11880
    Domain: domain:ui
    Seat: domain:ui#2
    File surface (on 402adc8aa):

    • packages/components/src/renderers/basic/data-list.tsx: the repeater registration (about :233) gate-wrapped with elementDataSourceBlock + useElementDataSource, as element:number is (item 1).
    • packages/components/src/renderers/basic/record-picker.tsx (about :113–:124) and packages/components/src/renderers/basic/elements.tsx (about :490–:529): the flat-key fallbacks and the number's AND-combination with properties.filter are dropped (item 2).
    • packages/app-shell/src/views/metadata-admin/previews/block-config.ts (about :323–:333), plus PageBlockInspector.tsx only if the retarget needs its node-level patch path: the designer writes dataSource.object (item 3). The existing label keys are reused.
    • content/docs/guide/data-source.md: the element:* paragraph (item 4).
    • The tests beside these, and .changeset/11880-*.md.

    ⛔ Not on it:

    • item 5, object-grid.defaultFilters: packages/types/src/objectql.ts is held by objectui#6152 round 9 (claim 6061068534), which names defaultFilters as its round 10 on the same files;
    • packages/types/** and packages/plugin-view/src/ObjectView.tsx: the element types keep their flat keys until the spec retirement's pin bump;
    • packages/components/src/ui/** and packages/i18n/**;
    • any new export, prop or language-pack key.

    Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report).
    Container & model: S, mode:subagent, model: opus (dispatch-gates --tier --repo objectstack-ai/objectui over these paths: no path-derived mandate; default tier)
    Clause-②: no
    Responsibility: objectui page elements: a repeater bound only through the node-level dataSource renders "No records", while record_picker and number still read flat keys the ruling retires | ruling objectstack-ai/objectstack#11509 6051498447 (A-narrow, objectui first) | every page author binding a repeater, record picker or number element, and the spec half that waits on this card
    Thread-read: none
    Serial constraints cleared: none blocking.

    • In-flight claims read 2026-10-08T14:35Z: objectui#6152 round 9 holds objectql.ts / objectql.zod.ts, which this claim leaves out. No claim names the other files.
    • Open objectui PRs, read 2026-10-08T14:35Z: none touches any file on this surface.
    • First-load bytes: the eager-closure headroom is about 1 KB. The budget bot's reading must stay at or under 3312.0 KB, and the dev stops if it reads over.

    Why Clause-②: no: it consumes dataSource, which the pinned spec already declares (ElementDataSourceSchema), and drops reads the ruling of record retires. No export, prop, spec key or packages/i18n key changes, and the element types are untouched.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 11880,
    "status": "blocked",
    "branch": "claude/issue-11880-element-datasource",
    "pr": null,
    "session": "session_01MgfduSkFrfM3eorB3UGfAU (the claim's session; mode:subagent, the executor's identity is the branch)",
    "premise_still_valid": true,
    "summary": "Items 1-4 are implemented and pushed at 3dc0d8b (three commits on base 989b190). The draft PR is NOT opened: the change needs files outside the claim's surface (claim 6062231663), two of them in its explicit Not-on-it list (packages/types/, packages/i18n/). The dispatch says to stop and report before opening the PR. WHAT LANDED ON THE BRANCH: (1) element:repeater is registered through elementDataSourceBlock and reads object / filter / sort / limit from useElementDataSource only. A resolving view draws the loading panel; an unresolvable one draws the configuration-error panel and lists nothing. The registry inputs object (it was required), filter, sort and limit are dropped, and the injected dataSource input replaces them. (2) element:record_picker and element:number no longer read composed?.x ?? props.x. The number's AND with properties.filter is gone; its filter is the binding's, lowered by toFilterNodeSafely. Their flat query inputs are dropped (record_picker: object, filter, sort, limit; number: object, filter), following the card's 'together with their inputs'. (3) Designer: BlockPropField gains at: 'dataSource' and ObjectSource gains objectFrom: 'dataSource'. block-config homes element:repeater object + limit and element:number object in the binding, and their field pickers read dataSource.object. PageBlockInspector patches dataSource at node level, as it patches visibleWhen. A stored flat properties.object stays visible under Advanced. Existing label keys are reused; there is no new export, prop or language-pack key. (4) data-source.md: the element rows paragraph now states the dataSource-only rule, with a repeater row in the table and a repeater example. Changeset: .changeset/11880-element-datasource-only.md (components + app-shell patch). PREMISES: H1 confirmed by ablation E (with the binding read removed, the dataSource-only repeater renders No records). H2 and H3 are confirmed by the pins and ablations below. H3: of the ten retired keys, the designer wrote element:repeater object and limit and element:number object. element:record_picker has no designer panel (palette exclusion). Every retired key has an ElementDataSourceSchema member (object, view, filter, sort, limit), so no stop condition fired. H5: examples/** authors none of the three elements, and content/** only in data-source.md, now rewritten. Test fixtures that authored the flat keys are updated, as H5 instructs. apps/console/src/dev/DevLists.tsx (a dev-harness route) authors flat object + limit on element:repeater and is reported, not converted (off-surface). H6 NOT MEASURED: no PR, so no budget-bot reading.",
    "tests": "Final union at HEAD 3dc0d8b (the run printed HEAD=3dc0d8b1e), repo root, one locked run: pnpm exec vitest run --maxWorkers=2 over 105 files: every test naming record-picker / elements / data-list / repeater / block-config / PageBlockInspector, every test authoring element:repeater / element:number / element:record_picker, the two new pins, packages/core/src/utils/tests/column-identity.ratchet.test.ts and scripts/tests/one-authority-per-exported-name-6273.test.ts. VERDICT command-exit 1, 'Test Files 2 failed | 103 passed (105)', 'Tests 9 failed | 3323 passed (3332)'. The 2 red files are exactly the off-surface blockers B1 and B2 (see open_questions); column-identity.ratchet and one-authority-6273 are green. Type-check, after turbo built the app-shell closure (28/28 tasks, CLOSURE_BUILD_EXIT=0): pnpm --filter @object-ui/components type-check COMPONENTS_TC_EXIT=0; pnpm --filter @object-ui/app-shell type-check APPSHELL_TC_EXIT=0 (lock VERDICT command-exit 0, HEAD=3dc0d8b1e). Gate scripts at HEAD 3dc0d8b, all exit 0: check-changeset-presence ('25 source file(s) of 3 released package(s) changed ... declares 1 changeset'), check-changeset-no-major, check:new-line-citations ('0 new citation(s)'), check:control-bytes, check:i18n-keys, check:spec-symbols, check:element-data-source-declaration ('15 gate-consuming file(s) ... all reach the seam and take it from core'), check:changeset-claims, check:doc-types, check:doc-fences, check:doc-example-ids, check:doc-example-readers, docs:check-links. eslint on the 25 touched ts/tsx files: exit 0, '0 errors, 87 warnings' (pre-existing). NOT MEASURED: check:doc-snippets and check:doc-examples, exit 2 'THE GATE COULD NOT RUN' (their 34-package build closure is not built; the diff adds no ts/tsx fence and no @example). ABLATIONS, one locked run at 3d4811a (renderer and designer sources are identical at 3dc0d8b), each through objectstack scripts/ablation-replace.mjs: the anchor hit exactly once, the mutation landed by blob change, and each restore was proven by 'blob == HEAD and git diff HEAD is empty'. Final tree check: 0 diff lines, 0 status lines. A: picker ?? props.object put back: 1 red ('a flat properties.object alone binds nothing'), 6 green incl. 'beside a binding, the flat filter/sort/limit are not read'. B: number ?? props.object put back: 3 red ('flat properties form alone binds nothing', 'binding naming no object supplies nothing', 10951 'properties.object alone is authored absence'), 22 green. C: number AND with properties.filter put back: 2 red (both properties.filter rows), 16 green. D: repeater registered without elementDataSourceBlock (the old registration): 1 red ('publishes dataSource and none of the four flat query keys'), 6 green. E: repeater reads no binding: 4 red incl. H1's 'a repeater bound only through dataSource lists its rows', with both controls green (no dataSource.object issues no query; flat keys alone list nothing). F: designer repeater object without at: 'dataSource': 1 red (the repeater Object-picker row), 6 green incl. the element:number twin.",
    "files_changed": "Runtime: packages/components/src/renderers/basic/{data-list.tsx, record-picker.tsx, elements.tsx}; packages/app-shell/src/views/metadata-admin/previews/block-config.ts; packages/app-shell/src/views/metadata-admin/inspectors/PageBlockInspector.tsx. Docs: content/docs/guide/data-source.md. Changeset: .changeset/11880-element-datasource-only.md. New pins: packages/components/src/renderers/basic/tests/data-list.elementDataSource-11880.test.tsx; packages/app-shell/src/views/metadata-admin/inspectors/PageBlockInspector.elementDataSource-11880.test.tsx. Updated tests, packages/components: record-picker-element-data-source, record-picker-inputs-spec-parity, record-picker-sort-members, and under renderers/basic/tests: data-list.contractEnvelope-6726, data-list.sortKey-10664, element-list-inputs-11168, element-number.contractEnvelope-6726, elementNumber.dataSourceBinding-10909, elementNumber.noObjectState-10951, elementNumber.recordIdFilterToken-7297, elementNumberFilterMembers-8071, elementReaders.invalidationRefetch-10623, record-picker.busReread-10853, record-picker.contractEnvelope-6726, record-picker.sortKey-10664. Updated tests, app-shell: previews/tests/block-config-schema-parity-8216 (a binding-homed control is judged against ElementDataSourceSchema). H5 fixture updates outside the listed surface: apps/console/src/tests/filterContextTokensSweep-10666.test.tsx; packages/app-shell/src/tests/widget-dom-leak-sweep.test.tsx.",
    "deviations": "(1) PR not opened, so no pr_create and no label-write (the PR assignee): the stop rule fired. See open_questions. (2) Conflict, named rather than silently resolved: the card's item 2 says the fallbacks go 'together with their inputs', and the claim's Clause-2 rationale says 'No export, prop ... changes'. I followed the card and dropped the flat registry inputs. Publishing an input the renderer no longer reads is the declared-but-unhonoured shape the ruling cures, and for the repeater a required object input would make the html tier refuse a dataSource-only repeater. Commit 07ed35f carries the drop; it can be reverted on its own if the PM rules otherwise. (3) Two H5 test-fixture files sit outside the listed surface (apps/console filterContextTokensSweep-10666, app-shell widget-dom-leak-sweep). I updated them because H5 directs fixture updates. They are named here because they are off the listed surface. (4) check-changeset-presence counts 3 released packages (apps/console via that test file under src/), and the changeset lists 2. Add @object-ui/console: patch if the surface is widened to apps/console. (5) Ablations ran at 3d4811a; the last commit 3dc0d8b changes one assertion in the new inspector test only. (6) Docs checks doc-snippets and doc-examples NOT MEASURED (exit 2, unbuilt 34-package closure).",
    "mcp_calls": "0 - no MCP GitHub calls",
    "api_writes": "1 - POST /repos//issues/11880/comments (this os-dev-report, via scripts/pm/post-stamped.mjs through the fleet-write relay). Also git push of the branch (not a REST write). Reads: single-card REST GETs of objectui#11880 + its comments, and objectstack#11509 comments 6051498447 and 6041889205.",
    "open_questions": [
    {
    "question": "B1 - apps/console/src/tests/registry-inputs-spec-parity.test.ts: 8 red tests, test-only bookkeeping forced by items 1 and 2. Item 1 alone forces 'element:repeater pins the member shape of every array/object input' and the member-shape census (the injected element:repeater.dataSource has no MEMBER_PINS row). Dropping the inputs forces the rest: REVERSE 'publishes every top-level key' for element:number [object, filter], element:record_picker and element:repeater [object, filter, sort, limit]; 'every member pin names a key that is still array/object-armed' (stale rows element:repeater.filter/.sort, element:number.filter, element:record_picker.filter/.sort); and the two named pins 'the five A-class keys objectui#3808 / #3830' (record_picker.filter) and 'the three keys the rc.6 bump added' (record_picker sort, limit). Not barred, but off the claim's surface. Widen?",
    "options": [
    "A widen the surface to that one file: 10 UNPUBLISHED_EXEMPTIONS rows citing objectui#11880 / objectstack#11509 (they leave with the spec pin bump); delete the 5 stale MEMBER_PINS rows; add element:repeater.dataSource pointing at data-list.elementDataSource-11880.test.tsx; drop record_picker filter/sort/limit from the two named discoverability pins; re-word the element:number.dataSource and element:record_picker.dataSource pin prose, which still describes the flat precedence",
    "B keep the flat inputs published (revert that half of 07ed35f): B1 shrinks to the one forced element:repeater.dataSource row, but the manifest then advertises 10 keys the renderers drop"
    ],
    "recommendation": "A. It is mechanical, the exemptions resolve themselves at the pin bump, and B leaves the declared-but-unread surface that pushes an AI author back onto the flat keys."
    },
    {
    "question": "B2 - packages/types/src/zod/public-blocks.zod.ts (barred: packages/types/**). ElementRepeaterBlockSchema requires properties.object with no dataSource waiver, and its docblock says the renderer never reads dataSource. Measured: packages/types/src/tests/element-data-source-objectname-waiver-11117.test.ts 'content/docs/guide/data-source.md: each binding fence parses' is red on the ruling's own repeater example: element:repeater invalid_type at properties.object. So safeValidateSchema (which objectui validate runs) refuses the only binding the repeater now reads. Clear the bar for this one file?",
    "options": [
    "A widen to public-blocks.zod.ts only: mirror element:number's arm on element:repeater (bag .partial on object, the node refinement through dataSourceSuppliesObject, dataSource declared by reference to ElementDataSourceSchema) and fix the docblock. The flat keys stay declared until the pin bump, as the claim intends. The file is not objectql.ts / objectql.zod.ts, which objectui#6152 round 9 holds",
    "B drop the repeater JSON fence from data-source.md and leave the types face refusing the binding until the spec pin bump"
    ],
    "recommendation": "A. B hides the measurement, and objectui's own validator keeps refusing what the renderer and the ruling require."
    },
    {
    "question": "B3 - packages/i18n (barred). The element.number.noObject value in all ten locales reads 'No object named: set object or dataSource.object.'. After item 2, setting object binds nothing, so the notice now prescribes a dead key. check:i18n-keys holds the inline defaultValue in elements.tsx byte-identical to the en pack, so the renderer cannot correct it alone. Widen for a value-only change (no new key)?",
    "options": [
    "A widen to the ten locale files plus the defaultValue in elements.tsx: value change only, no new key",
    "B land without it and file a follow-up: the shipped notice misleads until that lands"
    ],
    "recommendation": "A, because the change makes the published text false, and a change that makes published text false owes the fix in the same landing."
    },
    {
    "question": "B4 - apps/console/src/dev/DevLists.tsx, the dev-harness route in App.tsx, authors flat object + limit on element:repeater, and after item 1 it renders its empty text. H5: report it, and convert it only if it is on the surface. Widen?",
    "options": [
    "A widen and move object/limit into dataSource (a 3-line change)",
    "B leave it: a dev harness, not product nav"
    ],
    "recommendation": "A, since it is the one in-repo author of the flat keys, and the measurement 6041889205 named it."
    }
    ],
    "out_of_scope_findings": [
    "carrier: the objectstack#11509 spec half (pin bump) · noted, not filed: the element:number arm in packages/types (ElementNumberPropsBag waiver) still accepts a bag carrying a flat properties.object and no binding. After item 2 that node passes safeValidateSchema and renders the no-object notice. This is the declared-but-unread window the ruling's order accepts; it closes when the spec tombstones the key and the mirror follows."
    ]
    }


    Generated by Claude Code

  3. added
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 8, 2026
  4. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Retriage asked: the repeater half of item 1–3 forks on the spec · domain:ui seat 2 · 2026-10-08T15:49Z

    From the seat holding claim 6062231663 (items 1–4; item 5 is left to objectui#6152 round 10). pm:retriage is added beside pm:dispatched; the claim stays. Asked of: triage, or the owner of ruling objectstack-ai/objectstack#11509 6051498447. Question: does element:repeater drop its flat query keys in the objectui-first step, or only gain dataSource?

    The fork, measured (dev report 6063588533):

    • The spec at the pin requires object on the repeater. objectstack packages/spec/src/ui/component.zod.ts, ElementRepeaterPropsSchema, declares object as required ("without it the list never queries"). Its docblock adds: "NOT read at the pin … the node-level dataSource binding". objectui's mirror, ElementRepeaterBlockSchema in packages/types/src/zod/public-blocks.zod.ts, also requires properties.object, with no dataSource waiver. element:number's arm does have one.
    • What the ruling says: "the repeater takes dataSource, record_picker and number lose their ?? fallbacks". It does not say the repeater loses its flat keys before v18. The card's item 2 says "the three elements read their binding from dataSource only".
    • What the dev built, with its consequence: the repeater reading dataSource only. objectui's own validator (safeValidateSchema) then refuses the ruling's own dataSource-only repeater, at properties.object. Meanwhile a spec-valid repeater, which must carry properties.object, would render nothing until the spec half's conversion moves the key.

    Options:

    • A: in this step the repeater reads dataSource with its flat keys as the fallback, as element:number did before this card. It loses them at the v18 pin bump, with the spec half. No contract change.
    • B: the repeater drops its flat keys now. The spec and objectui's mirror must first waive object when dataSource supplies it, as for element:number. That changes accept/reject behaviour, so it is spec-lane work and lands before objectui's repeater change.

    The seat's recommendation is A. It is what the ruling's text says, it changes no contract, and it cannot blank a conforming repeater. B moves work into the spec lane ahead of a step the ruling orders "objectui first".

    What lands meanwhile, under the same claim, as Part of #11880:

    • items 2–4 for element:record_picker and element:number (the fallbacks and the number's AND are dropped, the designer writes the number's dataSource.object, the docs rows for the two);
    • the element.number.noObject notice, corrected to name only dataSource.object, as a value-only change with no new key.

    The flat registry inputs stay published: their retirement, and the validate-component-props refusal, ship with the spec half's pin bump, as the ruling orders. The repeater half waits for this answer.

    Noted (carrier: the spec half's pin bump, not filed):

    • apps/console/src/dev/DevLists.tsx, a dev-harness route, authors flat object + limit on element:repeater. It is the one in-repo author of those keys, so 6041889205's "no in-repo author" holds only for product pages.

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Retriage answered: A. The governing text answers it, so this is not a decision. pm:retriage removed; the claim stands

    Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-08T15:53Z. ⛔ Not a claim, ⛔ not a dispatch.

    Thread-read: the seat's ask (pm:retriage, 6063588533's dev report).

    • Ruling 6051498447, sub-question 2, verbatim: "objectui first (the repeater takes dataSource, record_picker and number lose their ?? fallbacks …), and the spec retirement ships with the pin bump that carries it."
      • The ruling drops the fallbacks for the other two elements, not for the repeater.
      • For the repeater it says only "takes dataSource".
      • Its flat keys retire with the spec half, and sub-question 4's trap fix is the first landing PR's.
    • So A: in this step the repeater reads dataSource with its flat keys as the fallback, and loses them at the v18 pin bump with the spec half. No contract changes, and a conforming repeater cannot blank.
    • B is not taken: it would move spec-lane work ahead of a step the ruling orders "objectui first".
    • The dev-harness author (DevLists.tsx): as the seat noted, it is carried by the spec half's pin bump.
  6. removed
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 8, 2026
  7. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 11880,
    "status": "blocked",
    "branch": "claude/issue-11880-element-datasource",
    "pr": "#11989",
    "session": "session_01MgfduSkFrfM3eorB3UGfAU (the claim's session; mode:subagent, the executor's identity is the branch)",
    "premise_still_valid": true,
    "summary": "FOLLOW-UP to report 6063588533, after the seat's rulings. Draft PR objectui#11989 is open at head 400f1f3. Its first line is 'Part of #11880', and it carries items 2-4 for element:record_picker and element:number. Changes: the fallbacks are dropped; the number's AND with properties.filter is dropped; the designer writes the number's dataSource.object through PageBlockInspector's node-level patch; the docs rows for the two elements are rewritten; and B3 is applied (element.number.noObject names only dataSource.object, in the ten packs plus the inline defaultValue). Per B1 option B, the flat inputs stay published, and their descriptions now say NOT READ and name the binding member. B2 is not taken, and B4 is left to the spec half. The PR body names item 5 as left to objectui#6152 round 10. CI on 400f1f3: 43 check runs, 40 success, 3 skipped, 0 failed. The budget bot reads Eager closure 3311.2 KB against the 3312.0 KB ceiling, PASS; main's reading, on objectui#11980 (main's tip), is 3311.1 KB. STOPPED on the repeater's A form, by the seat's own stop condition. A throwaway probe (deleted, never committed) measured a designer-shaped repeater carrying BOTH properties.object and a node-level dataSource. objectui's tolerant face safeValidateSchema: ACCEPT. Spec PageComponentSchema: ACCEPT. Spec ComponentPropsMap element:repeater on its properties: ACCEPT. But the published strict face StrictAnyComponentSchema (packages/types strict-authoring-face) REFUSES it with unrecognized_keys [dataSource], because the repeater arm declares no dataSource. CONTROL: a flat-only repeater is ACCEPT on all four faces, and a bogus node key is refused by the strict face and the spec. Once the repeater reads dataSource, that refusal names a key the renderer honours, and clearing it needs packages/types, which is barred. Separately, a dataSource-ONLY repeater (the shape the designer would write if its rows moved) is REFUSED by the tolerant face (invalid_type properties.object), the strict face and the spec props row. So the repeater's designer rows stay on properties either way. No repeater code is on the branch. The PR is the narrowed shape and is coherent on its own.",
    "tests": "All at HEAD 400f1f3. Union (repo root, pnpm exec vitest run, one locked run): every test naming record-picker / elements / data-list / repeater / block-config / PageBlockInspector, every test authoring the three elements, packages/i18n/, column-identity.ratchet and one-authority-per-exported-name-6273. Result: lock VERDICT command-exit 0, 'Test Files 186 passed (186)', 'Tests 4642 passed | 13 skipped (4655)'. Type-check after a turbo build of the app-shell closure: CLOSURE_BUILD_EXIT=0, COMPONENTS_TC_EXIT=0, APPSHELL_TC_EXIT=0. Gate scripts, all exit 0: check-changeset-presence ('31 source file(s) of 4 released package(s) changed ... declares 1 changeset'), check-changeset-no-major, check:changeset-claims, check:new-line-citations (0 new), check:control-bytes, check:i18n-keys, check:i18n-drift ('Every changed en value was followed by all nine translation packs'), check:i18n-designer-parity, check:i18n-dead-keys, check:spec-symbols, check:element-data-source-declaration, check:doc-types, check:doc-fences, check:doc-example-ids, check:doc-example-readers, docs:check-links. eslint on the 31 touched ts/tsx files: 0 errors. NOT MEASURED: check:doc-snippets and check:doc-examples (exit 2, their closure is unbuilt; the diff adds no ts/tsx fence and no @example). Ablations through ablation-replace, each restore proven by blob == HEAD and an empty git diff HEAD; final tree 0 diff lines. A, picker ?? props.object put back: 1 red, 6 green. B, number ?? props.object put back: 3 red, 22 green. C, number AND with properties.filter put back: 2 red, 16 green. F, the number's Object picker without at: 'dataSource': 2 red, 3 green, the repeater control row among the greens.",
    "files_changed": "Net against main 1473757 (33 files): runtime packages/components/src/renderers/basic/{record-picker.tsx, elements.tsx}; packages/app-shell/src/views/metadata-admin/{previews/block-config.ts, inspectors/PageBlockInspector.tsx}; packages/i18n/src/locales/{ar,de,en,es,fr,ja,ko,pt,ru,zh}.ts (one value each, plus two en comments); content/docs/guide/data-source.md; .changeset/11880-element-datasource-only.md (components, app-shell, i18n: patch); new pin PageBlockInspector.elementDataSource-11880.test.tsx; updated beside-tests for the picker and the number, plus block-config-schema-parity-8216; apps/console/src/tests/filterContextTokensSweep-10666.test.tsx (forced fixture moves, number and picker rows only); apps/console/src/tests/registry-inputs-spec-parity.test.ts (MEMBER_PINS prose only, four rows; no row, exemption or count changes). data-list.tsx and every repeater fixture are byte-identical to base.",
    "deviations": "(1) Branch history: the repeater commits from the first round stay in history and are reverted by a new commit (no force-push, no rebase). main was merged in at 699f6e8. I amended the unpushed merge commit and the unpushed narrowing commit for their messages and trailer pair before the first push of each. (2) B1 option B: the published flat inputs keep their names and types, but their DESCRIPTIONS changed. The old text stated a precedence (binding wins, flat applies otherwise) that this change makes false, so each now says NOT READ and names the binding member. (3) Comment-only drift left off-surface: the ElementDataSourceNoObjectPanel docblock in packages/react says its wording is element:number's notice with the property as a hole, which is approximate after B3. The ElementRepeaterBlockSchema docblock in packages/types is unaffected, since no repeater change landed. (4) The worktree /home/user/objectui-issue-11880 is kept for the repeater follow-up; the tree is clean and the branch is pushed (remote == local == 400f1f3).",
    "mcp_calls": "0 - no MCP GitHub calls",
    "api_writes": "4 in total for this card, all via the fleet-write relay, each read back: POST issues/11880/comments (report 6063588533); pr_create objectui#11989 (draft, 5364 bytes sent = stored); label-write assign os-bill on objectui#11989 (read back MATCHES: assignee os-bill, labeler labels untouched); POST issues/11880/comments (this follow-up). Plus git push (not REST). Reads: card, PR, check-runs and bot comments via REST GET.",
    "open_questions": [
    {
    "question": "Repeater A form: the published strict face StrictAnyComponentSchema refuses unrecognized_keys [dataSource] on an element:repeater that carries properties.object plus a node-level dataSource, the node a repeater that reads dataSource first takes. The tolerant face and the spec accept it. Clearing the refusal needs packages/types/src/zod/public-blocks.zod.ts, which is barred. How should the repeater proceed?",
    "options": [
    "A clear public-blocks.zod.ts for ONE change: declare dataSource on ElementRepeaterBlockSchema by reference to ElementDataSourceSchema, as element:number's arm does, with no waiver (properties.object stays required) and the docblock corrected; then add the repeater A form (gate-wrap, binding first with flat fallback, the three pins, both ablations) to objectui#11989",
    "B add the repeater A form without a types change and record the strict-face refusal as a known gap until the spec half's pin bump",
    "C land objectui#11989 as it stands (record_picker + number, green), and do the repeater A form as a follow-up round on this claim once the types question is ruled"
    ],
    "recommendation": "A. A validator that refuses the one key the renderer reads is the objectui#6678 class, and it fills the exact gap AGENTS.md #0.1 says the strict face exists for. The change is a declaration by reference with no new accept rule for properties.object. If the types file cannot be cleared now, C keeps the green PR moving."
    }
    ],
    "out_of_scope_findings": [
    "carrier: the objectstack#11509 spec half (pin bump) · noted, not filed: element:number's arm in packages/types (ElementNumberPropsBag waiver) still accepts a bag carrying a flat properties.object and no binding, which now renders the no-object notice. This is the declared-but-unread window the ruling's order accepts until the spec tombstones the key."
    ]
    }


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: ACCEPT — PR objectui#11989 (items 2–4 for record_picker and number, Part of) · domain:ui seat 2 · 2026-10-08T16:31Z

    Implemented-by: os-dev subagent of session_01MgfduSkFrfM3eorB3UGfAU, branch claude/issue-11880-element-datasource, head 400f1f3. Reports 6063588533 (blocked, four surface questions) and 6064387711 (the PR).
    Reviewed-by: domain:ui seat 2 (session_01MgfduSkFrfM3eorB3UGfAU), against GitHub and the branch diff, not against the report's prose.

    Checklist:

    • PR shape: draft, first line Part of #11880, with no closing keyword. Clause-②: no is at the start of a line. The assignee is os-bill. The body names item 5 as left to objectui#6152 round 10, and the flat-key retirement as left to the spec half's pin bump.
    • The seat's rulings on the four questions, recorded as bounded in-place amendments:
      • B1, option B: the flat registry inputs stay published until the spec half's pin bump, which carries the validate-component-props refusal. Their descriptions now say "not read" and name the binding member, because the old text stated a precedence this change makes false. registry-inputs-spec-parity.test.ts changes in pin prose only, with no row, exemption or count change.
      • B2, not taken: no packages/types change.
      • B3, option A: element.number.noObject names only dataSource.object. It is a value-only change in the ten packs plus the inline defaultValue; no key is added, and check:i18n-drift passes with all nine translations following.
      • B4: left to the spec half.
      • Forced fixture moves: filterContextTokensSweep-10666 (apps/console), number and picker rows only.
    • Items 2–4 met (ruling 6051498447):
      • element:record_picker and element:number read their query from dataSource only.
      • The number's AND with properties.filter is gone; its filter is the binding's, lowered by toFilterNodeSafely.
      • The designer writes the number's dataSource.object through PageBlockInspector's node-level patch.
      • The data-source.md rows for the two elements are rewritten.
      • data-list.tsx and every repeater fixture are byte-identical to the base.
    • The repeater half is not in this PR. Triage answered A (6063784959). The dev then measured that A needs a packages/types change: the published strict face (StrictAnyComponentSchema) refuses unrecognized_keys [dataSource] on a repeater that carries properties.object plus a node-level dataSource, while the tolerant face and the spec accept it. That face refuses a key the renderer does not read on main, which is right today. So the face and the repeater's read must change together, in one landing that changes a published face's accept/reject. That is Clause-② work, and this seat releases it to triage when this PR lands.
    • Evidence:
      • 186 files and 4,642 tests pass: every test naming the three elements, block-config or PageBlockInspector, packages/i18n, column-identity.ratchet and one-authority-per-exported-name-6273.
      • Both type-checks pass, and so do the i18n, docs and changeset gates.
      • Ablations A, B, C and F each turned their pins red, and each restore was proven.
    • Changeset: @object-ui/components, @object-ui/app-shell and @object-ui/i18n, patch.
    • First-load bytes: the budget bot reads 3311.2 KB, against main's 3311.1 KB (objectui#11980), and the 3312.0 KB ceiling: a PASS.
    • CI: 400f1f3 is green, 40 of 43 with 3 skipped. The PR lands through the merge queue.

    Out-of-scope note (carrier: the objectstack-ai/objectstack#11509 spec half): element:number's arm in packages/types still accepts a flat properties.object with no binding, which now renders the no-object notice. That is the declared-but-unread window the ruling's order accepts until the pin bump.


    Generated by Claude Code

  9. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Partial landing: record_picker and number bind through dataSource only; the repeater half goes to triage as Clause-② · domain:ui seat 2 · 2026-10-08T16:50Z

    Release: session_01MgfduSkFrfM3eorB3UGfAU (domain:ui seat 2, account os-bill) closes claim 6062231663. That claim covered items 1–4; item 5 was never on it.

    Delivered. PR objectui#11989 (Part of #11880) merged as 74add0c, checked on origin/main by content:

    • element:record_picker and element:number read their query from dataSource only. No composed?.object ?? props.object is left, and the number's AND with properties.filter (mergeFilterNodes) is gone.
    • The designer writes the number's dataSource.object through PageBlockInspector's node-level patch.
    • element.number.noObject reads "No object named: set dataSource.object." in all ten packs.
    • The data-source.md rows for the two elements are rewritten.
    • The flat registry inputs stay published until the spec half's pin bump, with descriptions saying they are not read.
    • The seat's review is 6064461026.

    Remaining, routed (pm:retriage added):

    • The repeater half (items 1–3 for element:repeater, and its docs row). Triage answered A (6063784959): the repeater reads dataSource with its flat keys as the fallback until v18.
      • The dev's probe (6064387711) then measured a repeater carrying properties.object plus a node-level dataSource. The tolerant face (safeValidateSchema) and the spec accept it. objectui's published strict face (StrictAnyComponentSchema, packages/types) refuses it with unrecognized_keys [dataSource], because ElementRepeaterBlockSchema declares no dataSource.
      • That refusal is right on main, where the repeater does not read the key. So the strict face's change, declaring dataSource by reference to ElementDataSourceSchema with properties.object still required, must land together with the repeater's read.
      • That is a change to a published face's accept/reject, owed a contract-review-tier review. So this seat does not take it in place, and routes it to the lane that takes Clause-②: yes work.
    • Item 5 (object-grid.defaultFilters): left to objectui#6152 round 10, as the claim said.

    Labels: pm:dispatched → pm:queue and pm:retriage. The assignee is cleared.


    Generated by Claude Code

  10. 22 remaining items

  11. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 2 (this card's item 5 only, object-grid.defaultFilters and ObjectView's hand-off, per the ruling objectstack-ai/objectstack#11509 6051498447 (A-narrow, sub-question 1, and the order clause); the repeater half landed in PR objectui#12002)
    Session: session_01DBZ9bntPZ7VKyQNtJeNsgw
    Account: huangyiirene (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-11880-default-filters-handoff
    Worktree: objectui-issue-11880-item5
    Domain: domain:spec
    Seat: domain:spec#1
    File surface (on objectui main aa67386a):

    • packages/plugin-view/src/ObjectView.tsx: the grid branch's hand-off only, the defaultFilters / filter pair the node for its own ObjectGrid carries. ObjectView stops writing the spec-retiring defaultFilters and hands the same precedence (named view, then table.filter, then the authored table.defaultFilters) through filter.
    • The tests beside it: the plugin-view filter-precedence and table-slot relay pins.
    • One .changeset/11880-*.md: patch for @object-ui/plugin-view.
    • Wherever the plugin-view README or content/docs names the hand-off.

    ⛔ Not on it:

    • packages/types/src/objectql.ts / zod/objectql.zod.ts. The mirror key stays declared while the pinned spec declares it. Under the ruling's order, it retires with the pin bump that carries the spec half. objectui#6152 round 11 also holds that file.
    • ObjectGrid's read of defaultFilters (useResolvedGridFilters), and ObjectView's read of the authored table.defaultFilters. These are readers of a key the pinned spec still declares, and they retire with it.
    • ListView.tsx and every non-grid branch.

    Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report).
    Container & model: M, mode:subagent, model: default (dispatch-gates --tier: no path-derived mandate). No contract review is owed if the diff stays inside this surface: an internal hand-off moves no accept set and no public surface. If the dev finds the change reaches either, the seat re-grades it.
    Clause-②: no
    Ruling-ref: objectstack-ai/objectstack#11509 6051498447 (A-narrow; order: objectui first, then the spec retirement with its pin bump), triage 6063784959 and 6065828018
    Responsibility: n/a — not a defect card
    Thread-read: 6068642853
    Serial constraints cleared: read at 2026-10-08T20:43Z on objectui main aa67386a. No open PR touches packages/plugin-view/src/ObjectView.tsx. Open PR objectui#12003 (objectui#6152 round 11) holds objectql.ts, which is off this surface.

    Clause-② reads no because ObjectView changes which slot of its own grid node carries a filter, not what any published schema accepts.

  12. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 11880,
    "status": "needs_decision",
    "branch": "claude/issue-11880-default-filters-handoff",
    "pr": null,
    "session": "session_01DBZ9bntPZ7VKyQNtJeNsgw (the seat's; mode subagent; this run's identity is the branch named in claim 6068695486)",
    "premise_still_valid": true,
    "summary": "Stopped before building, on the order's own stop rule for H2 ('A different answer anywhere is a stop'): ObjectGrid does not treat its two filter slots alike, so moving ObjectView's grid hand-off onto filter alone changes two answers on route 2 (the registered object-view renderer, no renderListView). Measured through the real ObjectView, the real ObjectGrid and a ValueDataSource that applies $filter (instrument committed and pushed as 601aeaf, no PR): (1) the server-streamed export reads only the canonical slot, so today a named view's filter and the authored table.defaultFilters reach the rows but NOT the export, which is handed filter: undefined and downloads the whole object while the screen is filtered; after the retarget the export carries the filter. (2) The page-reset effect keys on the canonical slot only, so today an in-place change of a named-view filter or of table.defaultFilters keeps the old page index ($skip stays above 0) while table.filter returns to page 1; after the retarget both return to page 1. Every rung and pair H1 names, the empty named-view filter and the refused named-view filter give identical $filter, rows and refusal panel under a faithful retarget (13 of 13 readings unchanged). The card's premise holds (ObjectView is the one in-tree producer writing defaultFilters); what is falsified is PM assumption H2, so the seat must decide whether the retarget may ship with those two changes (they are corrections: route 1's ListView export already carries the view filter), see open_questions.",
    "tests": "All on branch HEAD 601aeaf (base aa67386), single file, under os-verify-lock slot issue-11880-i5. BEFORE: pnpm exec vitest run --maxWorkers=2 packages/plugin-view/src/__tests__/ObjectView.gridFilterHandoff-11880.test.tsx → 'Tests 17 passed (17)', 'VERDICT command-exit 0'. Readings (rows Acme/open, Beta/won, Cyan/lost, Dune/open; VIEW=open, TABLE=won, DEFAULTS=lost): none → no $filter, 4 rows; view → [['stage','equals','open']] Acme+Dune; table → won, Beta; defaults → lost, Cyan; view+table, view+defaults, view+table+defaults → open, Acme+Dune; table+defaults → won, Beta; view [] with table+defaults → no $filter, 4 rows; table [] with defaults → lost, Cyan (H1 refined: ObjectGrid falls to defaultFilters when filter LOWERS to nothing, not only when it is absent). Export: view → fetch carries open, exportDownload handed filter undefined; defaults alone → fetch carries lost, export undefined; lit control table → export carries won. Page reset (8 rows, pageSize 2, advance to last page, rerender with a changed filter in the same slot, same view id so no remount): view and defaults → last $skip above 0; lit control table.filter → 0. Refused named-view filter (equals with an array value) → malformed-filter panel naming 'equals', zero finds, no 'Error loading grid'. H2 CANDIDATE A (faithful: filter: viewFilter || (mergeFilterNodes(table) !== undefined ? table : tableDefaults), defaultFilters write dropped), applied by objectstack's scripts/ablation-replace.mjs in WRAP mode: 'anchor 1 → 0, blob dd6e482fb668 → d3c5f7425f88', run → 'Tests 4 failed | 13 passed (17)': export view 'expected [ [ stage, equals, open ] ] to be undefined', export defaults 'expected [ [ stage, equals, lost ] ] to be undefined', page reset view and defaults 'expected 0 to be greater than 0'; restore 'blob == HEAD (dd6e482fb668) and git diff HEAD is empty'. CANDIDATE B (naive filter: viewFilter || table || tableDefaults): 'anchor 1 → 0, blob dd6e482fb668 → a093785496bc', 'Tests 5 failed | 12 passed (17)': the same four plus the empty-canonical pair (table [] with defaults: no $filter and all four rows instead of lost/Cyan); restored blob == HEAD, git diff HEAD empty. NON-GRID control (scratch file, deleted after the run, not committed): calendar route with table.filter [] and table.defaultFilters [lost] queries with $filter undefined; control defaults alone queries the lowered rule; so the grid and non-grid routes already disagree on that pair. Gates on the pushed branch: pnpm check:control-bytes exit 0 ('OK (scanned 8110 tracked text file(s)'), pnpm check:new-line-citations exit 0 ('0 new citation(s)'). NOT MEASURED, reason no PR and no source change: type-check, check:doc-snippets / readme-exports / docs:check-links, changeset gates, the whole plugin-view / plugin-grid / scripts suites. NOT MEASURED: check:eager-closure, reason: the coordinator's delta rule gates opening the PR, and the H2 stop came first; the branch's only diff is a file under tests, outside the console build graph, so its delta is zero by construction; the candidate's delta is owed by the build run if the seat rules A.",
    "mcp_calls": "0",
    "api_writes": "1 — POST /repos//issues/11880/comments (this os-dev-report, via objectstack scripts/pm/post-stamped.mjs). No pr_create, no label-write (no PR). git push x2 (empty branch, then 601aeaf) is not REST.",
    "files_changed": [
    "packages/plugin-view/src/tests/ObjectView.gridFilterHandoff-11880.test.tsx (new, 295 lines; the H1/H2 instrument; pins TODAY's readings, including the export reading that option A corrects, so it is an instrument, not a pin to land as written)"
    ],
    "gates": {
    "check:control-bytes": "exit 0",
    "check:new-line-citations": "exit 0, 0 new",
    "vitest instrument": "17/17 on 601aeaf",
    "check:eager-closure": "NOT MEASURED (see tests)",
    "type-check": "NOT MEASURED (no source change)"
    },
    "deviations": [
    "Stopped at H2 per the order; no ObjectView change, no changeset, no doc edit, no PR. The pushed branch carries the measurement instrument only.",
    "Bundle: not measured; the coordinator's delta rule was read as the PR gate it states, which the stop pre-empted.",
    "Conflict named, not chosen silently: the order says a different answer is a stop; os-dev standard text says a published defect the change touches must be fixed. They agree on what A must contain (the export correction is inherent to the retarget, not optional), so the stop only defers the call to the seat."
    ],
    "open_questions": [
    {
    "question": "Retargeting ObjectView's grid hand-off onto filter alone changes two route-2 answers (the server export starts carrying a named view's filter or the authored table.defaultFilters, and an in-place change of either returns the grid to page 1). Retarget now with those two changes as declared corrections, or keep the two-slot hand-off until the v18 pin bump?",
    "options": [
    "A. Retarget now: filter = named view filter, else table.filter unless it lowers to nothing, else table.defaultFilters (the faithful chain; needs toFilterNodeSafely from @object-ui/core so a refused table.filter still shows its panel); drop the defaultFilters write. Business need, measured: on route 2 today the downloaded file holds every record while the screen shows the filtered view, and route 1 (host ListView) already exports the view; the page reset makes these two slots page like table.filter already does. Long-term: one slot inside objectui before the spec retires the key, so the v18 bump deletes readers only, as the ruling's order intends. Anti-AI-error: removes an internal two-slot contract under which one reader (export) silently honours only half the filter. Startup scope: no capability added, one write removed; the export and paging changes are corrections, stated in the changeset. Cost: a user-visible change on route-2 exports and paging; four existing plugin-view pins that assert grid.defaultFilters (canonicalTableKeys, namedViewContextTokens-10506, specShapedNamedView-8254, tableSlotRelay-10976) are respelled; the instrument's export and page-reset rows flip to the corrected answers; README and plugin-view.mdx sentences 'forwarding both slots rather than re-resolving the pair' are rewritten; bundle delta measured at build.",
    "B. Keep today's hand-off until the v18 pin bump (that bump's retirement of ObjectGridSchema.defaultFilters makes the write a type error and forces the retarget then). Business need: keeps a measured wrong export on route 2 until v18. Long-term: the pin-bump PR then carries a behaviour change and a contract retirement together, the larger blast the ruling's order avoids. Anti-AI-error: objectui keeps writing, in its own built node, the key the ruling retires. Startup scope: zero work now. Cost: item 5 stays open against the ruling's 'objectui first' order.",
    "C. Retarget but keep the export and paging answers identical. Not available inside the fence: it means editing ObjectGrid's export and page-reset readers (fenced as ObjectGrid's legacy read) to keep a wrong export on purpose. Listed only to close it."
    ],
    "recommendation": "A. On business need it corrects a measured wrong download on a reachable door (any object-view node with a filtered named view and exportOptions rendered by the registered renderer, including the Studio's stored-view preview) and aligns route 2 with route 1; on the long-term and anti-AI axes it leaves one filter slot inside objectui before the spec retires the other, which is the order the ruling chose; on the startup axis it adds nothing and removes a write. The two changed answers are the honest cost and belong in the changeset as corrections. The os-dev standard text points the same way: once the retarget touches the export, its fix is owed, not optional."
    },
    {
    "question": "If A: keep today's grid answer for table.filter: [] (or {}) beside a non-empty table.defaultFilters (the grid falls through to the legacy rung), or adopt the naive || chain the non-grid fetch and host delegation already use (an empty table.filter wins and nothing is filtered)?",
    "options": [
    "A1. Faithful: keep the grid's fall-through (the order asked to keep today's truthiness exactly; zero changed answers on the rung readings, 13 of 13).",
    "A2. Naive ||: one more changed grid answer (measured: Cyan only becomes all four rows), making the grid agree with the non-grid route; no authored node writes the pair (census 0)."
    ],
    "recommendation": "A1: it is the zero-change reading the order asked for, the pair has no author, and the disagreement disappears with the legacy read at the v18 bump, so aligning it now buys nothing."
    }
    ],
    "out_of_scope_findings": [
    "In scope of this card, not a separate filing: route 2's server export ignores whatever rides defaultFilters (a named view's filter, the authored table.defaultFilters). Reproduced by the instrument rows 'a named view filter: what the export is handed' and 'table.defaultFilters alone: what the export is handed' on 601aeaf. Option A corrects it; option B keeps it until v18.",
    "carrier: the v18 pin-bump PR that retires ObjectGrid's legacy read · noted, not filed: an authored object-grid node's own defaultFilters is skipped by ObjectGrid's export and page reset the same way (ObjectGrid reads only schemaFilter there). No reach: the authored corpus writes no defaultFilters (census below), and the read retires with the key.",
    "carrier: the v18 pin-bump PR · noted, not filed: grid vs non-grid disagree on table.filter: [] beside table.defaultFilters (grid draws the legacy rule, calendar route queries nothing). No producer (census 0).",
    "carrier: the build PR for item 5 if the seat rules A, else the v18 pin-bump PR · noted, not filed: round 10's acceptance note stands, the gridSchema memo comment in ObjectView.tsx still says ObjectGrid 'raw-assigns the legacy one', false since objectui#4082.",
    "H3 census, for the seat (populations enumerated with git ls-tree on HEAD: packages 6325, apps 349, examples 513, content 203, docs 25, skills 27 files): write-shaped defaultFilters keys (regex allows a quoted key) outside tests and CHANGELOGs: 7 hits, of which exactly one writes a node: ObjectView.tsx defaultFilters: viewFilter || authoredFilters.tableDefaults; the rest are ObjectGrid's resolver input object and interface member, an ObjectGrid comment, the zod declaration, and the two docs rows teaching it as legacy (plugin-view.mdx, plugin-view README). apps / examples / docs / skills: 0. Matcher control on examples: objectName keys 36 hits with the same regex shape. Test fixtures writing it: 10 files.",
    "H4, for the build run if A: the sentence 'ObjectView defers to it by forwarding both slots rather than re-resolving the pair itself' (plugin-view.mdx and packages/plugin-view/README.md, the canonical-wins paragraph) describes today's hand-off and becomes false under A; the three-tier precedence paragraph stays true."
    ]
    }


    Generated by Claude Code

  13. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Item 5: the seat answers report 6068935827. Q1 → A and Q2 → A1. The round continues on claim 6068695486. From the domain:spec @ objectui seat (objectui#10217), session session_01DBZ9bntPZ7VKyQNtJeNsgw, 2026-10-08T21:00Z.

    The correction, stated openly. The dispatch's H2 assumed that ObjectGrid treats its two filter slots alike. The dev measured that it does not. On route 2 (the registered object-view renderer):

    • the server export reads only filter;
    • the page-reset effect keys only on filter.

    So today a named view's filter, and an authored table.defaultFilters, narrow the rows on screen, but the downloaded file holds every record, and an in-place change of either keeps the old page. Stopping on the order's own rule was right.

    Q1 → A: retarget now, with the two changed answers declared as corrections. This is mechanism inside the ruling objectstack-ai/objectstack#11509 6051498447, "objectui first, and the spec retirement ships with the pin bump that carries it", and inside item 5's own "retarget the internal hand-off to filter". It is not a new ruling.

    • The two answers are defects, measured, on a reachable door. A download that ignores the filter the screen applies is wrong. Route 1, the host ListView, already exports the view's filter. Returning to page 1 when the filter changes is what table.filter already does on the same grid. Keeping either answer would mean preserving a wrong export on purpose: that is option C, which the report rightly closes.
    • The ruling's order. One slot inside objectui before the spec retires the other means the v18 pin bump deletes readers only. Option B would make that bump carry a behaviour change and a contract retirement together, the larger blast the order avoids.
    • No capability is added and one write is removed. The changeset states both corrections as user-visible: route-2 exports now carry the view's filter, and a filter change returns the grid to page 1.

    Q2 → A1: the faithful chain.

    • The named view's filter applies first. Otherwise table.filter applies, unless it lowers to nothing. Otherwise the authored table.defaultFilters applies.
    • A refused table.filter still draws its panel (toFilterNodeSafely), which keeps today's grid answer on all 13 rung readings.
    • The grid / non-grid disagreement on an empty table.filter beside table.defaultFilters has no author (census 0). It goes away with the legacy read at the v18 pin bump, so aligning it now buys nothing.

    Shape of the build, for the dev:

    • ObjectView's grid branch writes filter from that chain and no longer writes defaultFilters.
    • The instrument's export and page-reset rows flip to the corrected answers and become the pins, each lit by its own before-reading.
    • The four plugin-view pins that assert grid.defaultFilters are re-spelled, as are the README and plugin-view.mdx sentence about "forwarding both slots", and the stale gridSchema memo comment (round 10's acceptance note).
    • @object-ui/plugin-view: patch, with the corrections named.
    • Clause-②: no: no accept set and no public surface move. The PR first line is Fixes #11880.
    • Bundle: measure the delta against a green main (after objectui#12007's revert). A small positive delta is reported with both byte counts, not a stop, as long as the tree fits under the ceiling. ⛔ Never touch the constant. The seat queues byte-adding PRs one at a time.

    Generated by Claude Code

  14. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 11880,
    "status": "done",
    "branch": "claude/issue-11880-default-filters-handoff",
    "pr": "#12010",
    "session": "session_01DBZ9bntPZ7VKyQNtJeNsgw (the seat's; mode subagent; this run's identity is the branch named in claim 6068695486)",
    "premise_still_valid": true,
    "summary": "Item 5 built on the seat's answer 6068966481 (Q1 to A, Q2 to A1): draft PR objectui#12010 (first line 'Fixes #11880', 'Clause-②: no' with its reason at the start of a body line), head d9f895b on base aa67386. ObjectView's grid branch now hands its ObjectGrid the whole filter chain in filter alone (viewFilter || gridTableFilterRung(authoredFilters): the named view's filter with today's truthiness, else table.filter unless toFilterNodeSafely lowers it to nothing, else table.defaultFilters; a refused table.filter is kept so its panel still draws) and writes no defaultFilters; the mirror key and its two readers stay for the v18 pin bump, as the ruling orders. Two user-visible corrections on route 2, stated in the PR body and the @object-ui/plugin-view patch changeset: the server export now carries a named view's filter or table.defaultFilters, and an in-place change of either returns the grid to page 1. The instrument became the pin file (18 tests), four plugin-view pins were re-spelled, the README / plugin-view.mdx 'forwarding both slots' sentence and the stale gridSchema memo comment were rewritten.",
    "tests": "All on head d9f895b, vitest under os-verify-lock. (1) pnpm exec vitest run --maxWorkers=2 packages/plugin-view/ packages/plugin-grid/ apps/console/src/__tests__/registry-inputs-spec-parity.test.ts packages/core/src/utils/__tests__/filter-source-merge.test.ts packages/plugin-list/src/__tests__/ListView.exportMatchesView.test.tsx packages/types/src/__tests__/grid-default-filters-gantt-map-filter-round10-6152.test.ts → 'Test Files 269 passed (269)', 'Tests 2858 passed (2858)', 'VERDICT command-exit 0'. (2) pnpm exec vitest run --maxWorkers=2 scripts/__tests__/ → 'Test Files 179 passed | 2 skipped (181)', 'Tests 5452 passed | 2 skipped (5454)'. (3) pnpm --filter @object-ui/plugin-view type-check and pnpm --filter @object-ui/plugin-grid type-check, both script names echoed, VERDICT command-exit 0, after turbo run build --filter='@object-ui/console^...' --filter='@object-ui/example-schema-catalog^...' plus the doc-snippet build filter with cli and plugin-ai; tsconfig.test.json lists all 5 edited test files (--listFilesOnly, 5 of 5). (4) pnpm check:doc-snippets '784 of 784 block(s) judged, 0 failed'; pnpm check:readme-exports OK '579 of them self-imports judged (579 real'; pnpm docs:check-links 'Links are valid across 17 scan roots'. (5) node scripts/check-changeset-presence.mjs '6 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)'; check-changeset-no-major OK; check:changeset-claims OK; check:pending-changeset-literals OK; check:new-line-citations '0 new citation(s)'; check:control-bytes OK. (6) ESLint over the 6 changed TS files: 0 errors (138 pre-existing warnings, none in the new pin file or the edited ObjectView regions). (7) governed-queue-guard --test over 9 paths: NOT GOVERNED. ABLATIONS (objectstack scripts/ablation-replace.mjs, wrap mode, each 'ok mutation landed: anchor 1 → 0' and 'ok restored: blob == HEAD (80b144c54a0e) and git diff HEAD is empty'; run = the pin file plus the four re-spelled pins, 80 tests): two-slot hand-off restored → 'Tests 12 failed | 68 passed (80)': in the pin file exactly the 4 corrected rows red with their before-readings ('expected undefined to deeply equal [ [ stage, equals, open ] ]' / '… lost ]', and 'expected 2 to be +0' for both page resets) while the 10 rung rows, 2 controls and 2 refusal rows stay green; the other 8 are the re-spelled grid.filter / grid.defaultFilters assertions. Refused table.filter skipped → 1 failed ('a refused table.filter is kept'). Naive || chain → 1 failed ('an EMPTY table.filter lowers to nothing'). BUNDLE: check:eager-closure under the lock; base = this tree with only ObjectView.tsx put back to aa67386 (blob dd6e482f verified on disk, marker 0/1, trap-restored to HEAD blob 80b144c5 with git diff HEAD empty; the console build aliases plugin-view to src and the branch's other files are tests, docs and a changeset): eagerGzipBytes 3,391,602; this tree 3,391,635 (identical on a second build); delta +33 B. main is red before this change (base 118 B over 3,391,484); objectui#12007 is still an open issue, the revert had not landed, origin/main had moved to fb361ef and was not merged, so whether the tree fits on a green main is NOT MEASURED. Ceiling constant untouched. CI on the PR: in_progress, not awaited.",
    "mcp_calls": "0",
    "api_writes": "4 across both rounds of this run — POST /repos//issues/11880/comments (the needs_decision os-dev-report, 6068935827); POST /repos/objectstack-ai/objectui/pulls (pr_create, draft #12010, via fleet-write; read back 11385 bytes sent = stored, draft true, base main); POST /repos//issues/12010/assignees (label-write.mjs --assign huangyiirene; read back assignee huangyiirene, labels documentation/plugin/tests are labeler.yml's); POST /repos//issues/11880/comments (this final os-dev-report). git push x3 (empty branch, 601aeaf, d9f895b) are not REST.",
    "files_changed": [
    "packages/plugin-view/src/ObjectView.tsx",
    "packages/plugin-view/src/tests/ObjectView.gridFilterHandoff-11880.test.tsx (new)",
    "packages/plugin-view/src/tests/ObjectView.canonicalTableKeys.test.tsx",
    "packages/plugin-view/src/tests/ObjectView.namedViewContextTokens-10506.test.tsx",
    "packages/plugin-view/src/tests/ObjectView.specShapedNamedView-8254.test.tsx",
    "packages/plugin-view/src/tests/ObjectView.tableSlotRelay-10976.test.tsx",
    "packages/plugin-view/README.md",
    "content/docs/plugins/plugin-view.mdx",
    ".changeset/11880-grid-filter-handoff.md (new; @object-ui/plugin-view patch)"
    ],
    "gates": {
    "vitest plugin-view + plugin-grid + named-key tests": "269 files / 2858 tests passed on d9f895b",
    "vitest scripts/tests": "179 passed, 2 skipped files; 5452 passed, 2 skipped tests",
    "type-check plugin-view, plugin-grid": "exit 0, names echoed",
    "check:doc-snippets": "exit 0, 784/784",
    "check:readme-exports": "exit 0",
    "docs:check-links": "exit 0",
    "check-changeset-presence": "exit 0",
    "check-changeset-no-major": "exit 0",
    "check:changeset-claims": "exit 0",
    "check:pending-changeset-literals": "exit 0",
    "check:new-line-citations": "exit 0, 0 new",
    "check:control-bytes": "exit 0",
    "check:eager-closure": "tree 3,391,635 B vs base 3,391,602 B, delta +33 B; red on both (main red before the change); green-main fit NOT MEASURED",
    "CI": "in_progress"
    },
    "deviations": [
    "The base bundle reading is this tree with ObjectView.tsx put back to aa67386, not a separate main checkout: the console build aliases @object-ui/plugin-view to src and every other changed file is outside the console build, so it reads the base's bundle without a second full install and build.",
    "origin/main moved to fb361ef after the branch was cut; not merged, because the coordinator's merge condition (objectui#12007's revert landed) did not hold.",
    "Two sentences this change makes false sit in fenced files and were not edited (stop-on-breach): listed under out_of_scope_findings and in the PR's Acceptance notes.",
    "A second os-dev-report comment was posted for this build round (the first carried the needs_decision report), counted in api_writes."
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: the v18 pin-bump PR that retires ObjectGrid's legacy read · noted, not filed: ObjectGrid.tsx's legacy-read comment ('plugin-view also forwards an active named view's ViewFilterRule[] into this slot (ObjectView.tsx, the gridSchema memo)') is false after this PR; the file is fenced for this claim, and the comment goes with the legacy read.",
    "carrier: objectui#6152 round 11 (PR #12003, which holds packages/types/src/objectql.ts), else the v18 pin-bump PR · noted, not filed: the ObjectGridSchema.defaultFilters docblock says 'ObjectView hands it an active named view's filter', false after this PR.",
    "carrier: the v18 pin-bump PR · noted, not filed: an authored object-grid node's own defaultFilters is still skipped by ObjectGrid's export and page reset (both read filter only). No reach: census 0 authored defaultFilters, and the read retires with the key.",
    "carrier: the v18 pin-bump PR · noted, not filed: grid and non-grid routes still disagree on an empty table.filter beside table.defaultFilters (kept by Q2 to A1; census 0)."
    ]
    }


    Generated by Claude Code

  15. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim 6068695486, amended by the seat: two now-false sentences join the file surface, comment and TSDoc only. From the domain:spec @ objectui seat (objectui#10217), session session_01DBZ9bntPZ7VKyQNtJeNsgw, 2026-10-08T21:40Z. Report 6069543066 names both.

    PR #12010 makes two sentences false, and each sits in a file the claim fenced:

    • packages/types/src/objectql.ts: the ObjectGridSchema.defaultFilters docblock sentence "ObjectView hands it an active named view's filter". This TSDoc ships in @object-ui/types' published .d.ts. A published sentence the round makes false is fixed in the same round. objectui#6152 round 11 held the file, and it landed as cf62edf6, so the file is free.
    • packages/plugin-grid/src/ObjectGrid.tsx: the legacy-read comment saying plugin-view forwards an active named view's rule array into defaultFilters.

    Both become the reading the PR makes true. ⛔ No code changes in either file: the mirror key, ObjectGrid's legacy read and its export / page-reset readers stay, as the ruling's order requires. The patch round also merges main (902fbe19, green after objectui#12009's revert) for a bundle reading on a green base. @object-ui/types takes a patch entry for the docblock if the presence gate asks for one.


    Generated by Claude Code

  16. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 11880,
    "status": "done",
    "branch": "claude/issue-11880-default-filters-handoff",
    "pr": "#12010",
    "session": "session_01DBZ9bntPZ7VKyQNtJeNsgw (the seat's; mode subagent; this run's identity is the branch named in claim 6068695486, amended in 6069594612)",
    "premise_still_valid": true,
    "summary": "Patch round on PR objectui#12010, new head c8cf036 (pushed fast-forward from d9f895b; no rebase, no force). (1) git merge --no-edit origin/main at 902fbe1 merged with no conflict (merge commit d0df62e, trailer pair added before the push). (2) The two sentences the amendment 6069594612 added to the surface were rewritten, comment and TSDoc only (0 non-comment lines in that commit's diff): the ObjectGridSchema.defaultFilters TSDoc in packages/types/src/objectql.ts now says that since objectui#11880 item 5 ObjectView no longer writes this slot on the grid it draws, and that a named view's filter and an authored table.defaultFilters reach that grid in filter, so its export and page reset follow them; ObjectGrid.tsx's legacy-read comment now says plugin-view forwarded a named view's rule array here until objectui#11880 item 5 and hands its whole chain to filter since. The changeset presence gate did not ask for a @object-ui/types or plugin-grid entry ('8 source file(s) of 3 released package(s) changed, and this change declares 1 changeset(s)'), so the changeset is unchanged. (3) Bundle on a green base: this tree 3,391,347 B, origin/main 3,391,326 B, delta +21 B, headroom 137 B under 3,391,484 B (main's own headroom 158 B).",
    "tests": "All on head c8cf036; vitest, builds and type-checks under os-verify-lock. (1) pnpm exec vitest run --maxWorkers=2 packages/plugin-view/ packages/plugin-grid/ packages/types/ plus the 14 test files outside those dirs that name objectql.ts or ObjectGrid.tsx, filter-source-merge and ListView.exportMatchesView → 'Test Files 647 passed (647)', 'Tests 13494 passed (13494)', 'VERDICT command-exit 0'. The types suite covers grid-default-filters-gantt-map-filter-round10-6152, the one types test naming defaultFilters. (2) pnpm exec vitest run --maxWorkers=2 scripts/__tests__/ → 'Test Files 179 passed | 2 skipped (181)', 'Tests 5452 passed | 2 skipped (5454)'; several of these read objectql.ts from disk. (3) pnpm --filter @object-ui/types type-check, @object-ui/plugin-grid type-check, @object-ui/plugin-view type-check: all three script names echoed, VERDICT command-exit 0. (4) pnpm check:readme-exports OK ('579 of them self-imports judged (579 real'); pnpm check:doc-snippets '784 of 784 block(s) judged, 0 failed'. Both ran after turbo run build --filter='@object-ui/console^...' --filter='@object-ui/example-schema-catalog^...' --filter=@object-ui/cli --filter=@object-ui/plugin-ai on c8cf036 (36/36 tasks). (5) node scripts/check-changeset-presence.mjs exit 0; check-changeset-no-major exit 0; pnpm check:changeset-claims exit 0; pnpm check:pending-changeset-literals exit 0; pnpm check:new-line-citations 'VERDICT new-cross-file-line-citations: 0 new citation(s)'; pnpm check:control-bytes 'OK (scanned 8114 tracked text file(s)'. BUNDLE, check:eager-closure under the lock. Tree c8cf036: '✅ Console eager closure is 3311.9 KB gzipped across 336 of 2458 chunks (budget: 3312.0 KB, headroom: 0.1 KB)', eagerGzipBytes 3,391,347, identical on a second console build. origin/main 902fbe1: this tree with the three published src files the branch changes put back to 902fbe1 (ObjectView.tsx, ObjectGrid.tsx, objectql.ts). Each blob was verified on disk and trap-restored to its HEAD blob, git diff HEAD empty. The console build aliases these packages to src, and the branch's other files are tests, docs and a changeset. Reading: eagerGzipBytes 3,391,326. Delta +21 B; tree headroom 3,391,484 - 3,391,347 = 137 B. Ceiling constant untouched. CI on c8cf036: in_progress, not awaited.",
    "mcp_calls": "0",
    "api_writes": "1 this round — POST /repos//issues/11880/comments (this os-dev-report, via post-stamped.mjs). git push of c8cf036 is not REST. No PR body edit: the dev writes the body once, so the needed change is named under deviations for the seat to write.",
    "files_changed": [
    "packages/types/src/objectql.ts (TSDoc only)",
    "packages/plugin-grid/src/ObjectGrid.tsx (comment only)",
    "merge of origin/main 902fbe1 (no conflict)"
    ],
    "gates": {
    "vitest plugin-view + plugin-grid + types + source readers": "647 files / 13494 tests passed on c8cf036",
    "vitest scripts/tests": "179 passed, 2 skipped files; 5452 passed, 2 skipped tests",
    "type-check types, plugin-grid, plugin-view": "exit 0, names echoed",
    "check:readme-exports": "exit 0",
    "check:doc-snippets": "exit 0, 784/784",
    "check-changeset-presence": "exit 0",
    "check-changeset-no-major": "exit 0",
    "check:changeset-claims": "exit 0",
    "check:pending-changeset-literals": "exit 0",
    "check:new-line-citations": "exit 0, 0 new",
    "check:control-bytes": "exit 0",
    "check:eager-closure": "tree 3,391,347 B (green, headroom 137 B); main 3,391,326 B; delta +21 B",
    "CI": "in_progress"
    },
    "deviations": [
    "The PR body (written once, not patched) is now stale in three places, for the seat to rewrite. (a) Its Bundle section should read: 'tree c8cf036 3,391,347 B; origin/main 902fbe1 3,391,326 B; delta +21 B; headroom 137 B under 3,391,484 B'. (b) Its first Acceptance note should say that both fenced sentences were fixed in c8cf036 under the amendment 6069594612. (c) Its Tests section's head and counts are superseded by this report's.",
    "The merge commit's default message gained the model-free trailer pair before the push (git commit --amend on the unpushed merge commit; parents unchanged: d9f895b and 902fbe1).",
    "The base bundle reading puts the branch's three published src files back to 902fbe1 in this tree, rather than measuring in a separate main checkout; both readings come from the same toolchain on the same box.",
    "Beyond the order's gate list, the tests outside the named suites that name objectql.ts or ObjectGrid.tsx, and scripts/tests, were also run, because those tests read the edited files from disk."
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: the v18 pin-bump PR · noted, not filed: ObjectGrid's export and page reset still skip an authored object-grid node's own defaultFilters, because both read filter only. No reach: the census found 0 authored defaultFilters, and the read retires with the key.",
    "carrier: the v18 pin-bump PR · noted, not filed: the grid and non-grid routes still disagree on an empty table.filter beside table.defaultFilters. Q2 to A1 keeps this; census 0."
    ]
    }


    Generated by Claude Code

  17. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 11880,
    "status": "done",
    "branch": "claude/issue-11880-default-filters-handoff",
    "pr": "#12010",
    "session": "session_01DBZ9bntPZ7VKyQNtJeNsgw (the seat's; mode subagent; this run's identity is the branch named in claim 6068695486, amended in 6069594612)",
    "premise_still_valid": true,
    "summary": "Base-merge round on PR objectui#12010. The new head is 1f29d78, a fast-forward from c8cf036 with no rebase and no force. git merge --no-edit origin/main at 7ebff39 merged with no conflict; its parents are c8cf036 and 7ebff39, and the trailer pair was added before the push. None of the 22 files main changed since 902fbe1 is a file this branch changes. The net diff is unchanged: git patch-id --stable gives 39130482e46a863d5cceeac9dacfc302cea3e87c against the old merge base 902fbe1 and the same id against the new one, 7ebff39. Bundle on the new main: this tree 3,391,439 B, origin/main 3,391,414 B, delta +25 B. That leaves 45 B of headroom under 3,391,484 B, so the tree fits; main's own headroom is 70 B.",
    "tests": "BUNDLE, check:eager-closure under os-verify-lock. Tree 1f29d78, read after turbo run build --filter='@object-ui/console^...' (34/34 tasks) and the console build: '✅ Console eager closure is 3312.0 KB gzipped across 336 of 2458 chunks (budget: 3312.0 KB, headroom: 0.0 KB)', eagerGzipBytes 3,391,439, identical on a second console build. origin/main 7ebff39 was measured on this tree with the three published src files the branch changes put back to 7ebff39 (ObjectView.tsx dd6e482f, ObjectGrid.tsx 444faefb, objectql.ts 653667e0). Each blob was verified on disk and trap-restored to its HEAD blob, with git diff HEAD empty afterwards. Reading: eagerGzipBytes 3,391,414. Delta +25 B; tree headroom 3,391,484 - 3,391,439 = 45 B. Ceiling constant untouched. Because the merge touched no file this branch changes and the patch-id is identical, the plugin-view / plugin-grid suites and the type-checks were not re-run, per the order. Their last readings are on c8cf036: 647 files / 13494 tests passed, and type-check of types, plugin-grid and plugin-view exit 0. node scripts/check-changeset-presence.mjs on 1f29d78: exit 0. CI on 1f29d78: in_progress, not awaited.",
    "mcp_calls": "0",
    "api_writes": "1 this round: POST /repos//issues/11880/comments (this os-dev-report, via post-stamped.mjs). The git push of 1f29d78 is not REST. PR body not edited, per the order.",
    "files_changed": [
    "merge of origin/main 7ebff39 (no conflict; no file of this branch's diff touched)"
    ],
    "gates": {
    "patch-id (net diff vs merge base)": "old 39130482e46a (vs 902fbe1) = new 39130482e46a (vs 7ebff39)",
    "check:eager-closure": "tree 3,391,439 B (green, headroom 45 B); main 3,391,414 B; delta +25 B",
    "check-changeset-presence": "exit 0",
    "suites and type-checks": "not re-run (merge touched no branch file); last green on c8cf036",
    "CI": "in_progress"
    },
    "deviations": [
    "The merge commit's default message gained the model-free trailer pair before the push (git commit --amend on the unpushed merge commit; parents unchanged).",
    "The delta moved from +21 B on 902fbe1 to +25 B on 7ebff39 while the patch-id stayed the same. Gzip size depends on neighbouring bytes in the shared chunks, so the same diff can cost a few bytes more or less on a different base."
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: the v18 pin-bump PR · noted, not filed: ObjectGrid's export and page reset still skip an authored object-grid node's own defaultFilters. No reach: census 0.",
    "carrier: the v18 pin-bump PR · noted, not filed: the grid and non-grid routes still disagree when an empty table.filter sits beside table.defaultFilters. Q2 to A1 keeps that behaviour; census 0."
    ]
    }


    Generated by Claude Code

  18. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT, item 5: PR #12010 at 1f29d78c. Reports 6068935827 (the measurement, answered 6068966481), 6069543066 (the build), 6070098582 (the patch round) and 6070640858 (the base merge). From the domain:spec @ objectui seat (objectui#10217), session session_01DBZ9bntPZ7VKyQNtJeNsgw, 2026-10-08T23:10Z. Ready and auto-merge follow in this act. This is the card's last item, and the PR's first line is Fixes #11880.

    Review face. Clause-②: no agrees across the claim, its amendment 6069594612, the PR body and the changeset:

    • ObjectView changes which slot of its own grid node carries a filter;
    • the two other files change only a TSDoc sentence and a comment;
    • no accept set and no published type, schema or export moves.

    So no at-tier contract review is owed. This is the seat's review against GitHub and the diff.

    Checked against the PR, not the reports:

    • Draft, base main, first line Fixes #11880, with no other closing keyword. Not governed: 0 of 11 paths (check-governed-merges). No content/docs/releases/ path.
    • On 1f29d78c: 43 checks, 40 success and 3 skipped by design, Lint and Type Check among the successes; Bundle Analysis reads 3312.0 KB, PASS. Mergeable, clean.
    • The code (ObjectView.tsx): the grid branch writes filter: viewFilter || gridTableFilterRung(authoredFilters) and no defaultFilters.
      • gridTableFilterRung returns table.filter unless toFilterNodeSafely lowers it to nothing, else table.defaultFilters.
      • A refused table.filter is kept, so the grid still draws its panel.
      • This is the seat's answer A1, the grid's own choice made one step earlier.
    • Pins: the 18-test pin file runs through the real ObjectView, the real ObjectGrid and a ValueDataSource that applies $filter. Its 10 rung rows, 2 controls and 2 refusal rows stay green under the base's two-slot hand-off. Exactly its 4 corrected rows go red with their before-readings: the export of a named-view filter and of table.defaultFilters, and the page reset after either changes. The naive chain and a skipped refusal each turn one named row red.
    • Two now-false sentences fixed in this PR, under the amendment, as comment / TSDoc only: the published ObjectGridSchema.defaultFilters TSDoc in objectql.ts, and ObjectGrid.tsx's legacy-read comment. The mirror key, ObjectGrid's legacy read and its export / page-reset readers are untouched, per the ruling's order.
    • Bundle: on main 7ebff399 (green), the tree reads 3,391,439 B against main's 3,391,414 B: +25 B, which leaves 45 B under the 3,391,484 B ceiling. Byte-adding PRs queue one at a time in this lane, and nothing else from it is queued.
    • Prose face, read sentence by sentence against the diff:
      • the changeset: both corrections, the routes they apply to, and "what did not change";
      • the plugin-view README and plugin-view.mdx paragraph: the paging pairs are forwarded, while the filter pair is resolved and handed over in filter, with its two effects;
      • the TSDoc and the comment named above.
        Each holds at this head.
    • PR body corrected in this act: the body becomes the squash commit's message. Its Bundle section, its Tests head and its first acceptance note described an earlier head and a red main. The seat rewrote those three parts from the dev's reports, and the read-back is identical.

    Out of scope, one line each (both carried to the v18 pin-bump PR that retires the key):

    • ObjectGrid's export and page reset still skip an authored object-grid node's own defaultFilters. Census 0.
    • The grid and non-grid routes still disagree on an empty table.filter beside table.defaultFilters. Kept by A1; census 0.

    After this lands: Fixes #11880 closes the card. The seat posts the landing check and removes pm:dispatched. objectstack-ai/objectstack#11509's spec half, which waits on this card, can then proceed.


    Generated by Claude Code

  19. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed, item 5: PR #12010 merged through the merge queue as 5bc55c0c. This card is closed completed by its Fixes #11880. pm:dispatched removed and unassigned in this act. From the domain:spec @ objectui seat (objectui#10217), session session_01DBZ9bntPZ7VKyQNtJeNsgw, 2026-10-08T23:58Z.

    Verification

    • Merge content matches the PR: the landed commit's git patch-id --stable equals the PR's net diff against its merge base 7ebff399 (39130482e46a on both sides).
    • On main, by content: packages/plugin-view/src/ObjectView.tsx's grid branch writes filter: viewFilter || gridTableFilterRung(authoredFilters), and no defaultFilters. main's push Bundle Analysis is green.
    • Reviewed head is the landed head: the seat's ACCEPT 6070864975 reviewed 1f29d78c (Clause-②: no, no contract review owed), and nothing was pushed after it.

    Delivered, the whole card:

    • Items 1–3 for element:repeater: PR objectui#12002, aaba8655.
    • Items 2–4 for record_picker and number: PR objectui#11989, 74add0c.
    • Item 5: ObjectView no longer writes the spec-retiring object-grid.defaultFilters. Its grid takes the whole filter chain in filter. Route-2 exports now carry the view's filter, and a filter change returns the grid to page 1.

    For objectstack-ai/objectstack#11509's spec half: objectui now reads the node-level dataSource on all three elements, and writes no defaultFilters, so the spec retirement can ship with the pin bump that carries it, as the ruling orders. The objectui-side readers that remain retire with that bump: the repeater's flat-key fallback, ObjectGrid's legacy defaultFilters read, and the mirror key.


    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

No one assigned

    Labels

    domain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lanepriority:p3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions