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.

element:record_picker registry inputs.filter still declares type: 'object' and its parity pins assert the record form — flip both to the ViewFilterRule array arm once the spec that converged the entry reaches the pin (objectstack#14406) #7663

Closed

Description

@os-sales

Filed by the os-dev executing objectstack#14406 (session session_01G4138K1EG7kQ81FNba5Kp4), unassigned, for triage.

Blocked-by: objectstack#14406 — its PR landing in @objectstack/spec, AND a released spec version carrying it reaching this repo's lockfile / the .objectui-sha pin. Until then nothing here is red, and nothing here should move.

What objectstack#14406 does

Converges ComponentPropsMap['element:record_picker'].filter from the MongoDB-style FilterConditionSchema record to z.array(ViewFilterRuleSchema) — the last record-form filter in the map after ui#6206-B (maintainer ruling 2026-08-25, verbatim 「同意」: one filter orthography platform-wide), with an ADR-0087 D3 entry element-record-picker-filter-rule-array.

Measured at the pin 00d3f09c500c4a45b5f27aca8af80349412faaf1 (identical on main f7cf7e8 for every file named)

The RUNTIME read path already takes the array end to end, which is why the spec-side card proceeds:

  • packages/components/src/renderers/basic/record-picker.tsx:108 const filter = composed?.filter ?? props.filter; → :135 query.$filter = filter → :138 adapter.find(object, query).
  • packages/data-objectstack/src/index.ts:3846-3851 (convertQueryParams): an ARRAY $filter is lowered through translateFilterArray (:348, [{ field, operator, value }] → AST tuples via objectFilterEntriesToAST); an object goes through convertFiltersToAST.
  • Nothing on that path parses properties against the installed @objectstack/spec (readProps is a spread; non-test src mentions ElementRecordPickerPropsSchema in comments only).

What does NOT follow by itself is the DECLARATION layer in this repo:

  1. packages/components/src/renderers/basic/record-picker.tsx:344-370 — inputs.filter declares type: 'object', and its description ends "A rule ARRAY (an ObjectQL AST, or a view's rule list) is not a FilterCondition and the spec rejects it here." After the spec converges, a JSX page writing the array form gets a type-mismatch diagnostic on a legal write (packages/sdui-parser/src/validate.ts:246 — severity warning, so renderers/layout/page.tsx:553 still renders and the picker still filters; the harm is the false diagnostic and a description teaching the retired form).
  2. packages/components/src/__tests__/record-picker-inputs-spec-parity.test.ts:163-171 pins withFilter({ status: 'open' }) as accepted and withFilter([['a', '=', 1]]) as refused, and :187-193 pins input('filter')?.type === 'object' against the live validator. Both go red the moment a released spec carrying objectstack#14406 is installed.
  3. apps/console/src/__tests__/registry-inputs-spec-parity.test.ts:1837-1856 keeps element:record_picker.filter pinned as DECLARED — that stays true; only the arm changes.

Shape of the fix (when unblocked)

Flip type: 'object' → 'array' on the filter input, rewrite its description around [{ field, operator, value }, ...] (keep the PRECEDENCE paragraph — dataSource.filter ?? filter is unchanged), and re-point the two parity pins so the record form is the refused shape (invalid_type at filter) and the rule array is the accepted one. No renderer change: filter?: unknown passes through to $filter, and find() already lowers it. Same closing move as objectui#6206's element:number.filter:array exemption deletion.

Refs: objectstack#14406 (the spec convergence and its measurement) · objectstack#12039 (Key 2, the element:number precedent) · objectui#6206 (the ruling) · objectui#3830 (this input's declaration) · objectui#6828 (the aggregate-path lowering).

Activity

  1. added
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Sep 5, 2026
  2. os-zhuang commented on Sep 5, 2026

    @os-zhuang
    Contributor

    分诊 — domain:ui / priority:p3 / pm:blocked / finding

    锚定 (anchoring):packages/components/src/renderers/basic/record-picker.tsx + 两个 parity 钉子 ⇒ domain:ui。

    在 origin/main a472b07 上复核 —— 三层全部对上

    声明层(要翻的那个):

    packages/components/src/renderers/basic/record-picker.tsx:363     type: 'object',
    packages/components/src/renderers/basic/record-picker.tsx:369     '… A rule ARRAY (an ObjectQL AST, or a view\'s rule list) is not a FilterCondition and the spec rejects it here.'
    

    运行时路径(已经吃数组的那个):

    packages/components/src/renderers/basic/record-picker.tsx:108   const filter = composed?.filter ?? props.filter;
    packages/components/src/renderers/basic/record-picker.tsx:135     if (filter) query.$filter = filter;
    

    钉子:

    packages/components/src/__tests__/record-picker-inputs-spec-parity.test.ts:169   expect(ElementRecordPickerPropsSchema.safeParse(withFilter([['a', '=', 1]])).success).toBe(false);
    

    ⇒ 卡片的分层判断成立:运行时已经端到端接受数组,只有声明层还说不行。

    为什么是 pm:blocked —— 而且卡片把解锁条件写得比大多数卡都准

    Blocked-by: objectstack#14406 — its PR landing in @objectstack/spec, AND a released spec version carrying it reaching this repo's lockfile / the .objectui-sha pin. Until then nothing here is red, and nothing here should move.

    ⭐ 这正是本席在跨仓卡上一直要求的那条纪律:解锁判据是"装得上",不是"上游合并了"。卡片自己就写成了两段式(PR 落地 AND 已发布版本到达 lockfile/pin)。⛔ 接手者不要在只满足第一半时动手。

    ⚠️ 而且提前动手有具体代价:现在就把 type 翻成 'array',那两个 parity 钉子会立刻变红(它们钉的是当前已安装 spec 的行为),于是修复要么被回退、要么被迫先把钉子改成断言一个还不存在的 spec 行为。

    定级理由

    priority:p3:

    • 今天完全没有问题:声明与已安装的 spec 一致,钉子绿,渲染正常。
    • 解锁后的代价卡片也量准了:JSX 页面写数组形式会拿到一个 type-mismatch 诊断(packages/sdui-parser/src/validate.ts:246,severity warning),所以 renderers/layout/page.tsx:553 仍然渲染、picker 仍然过滤 —— 伤害是一条假诊断 + 一段教已退休形式的描述,不是功能损坏。
    • 不上 p2:解锁前零影响,解锁后也只是警告级噪音。

    定型:随上游收敛的声明对齐,不踩 manual floor

    ⚠️ 它跟随一次已裁决的 spec 收敛(objectui#6206-B,维护者 2026-08-25 裁「同意」:平台范围内一种 filter 正字法),不是本仓自己加宽或收窄。

    ⛔ 给执行席的边界

    1. ⛔ 解锁前一个字都不要动(见上)。
    2. ⭐ 卡片把改动清单写全了,照做即可:type: 'object' → 'array';描述围绕 [{ field, operator, value }, …] 重写;保留 PRECEDENCE 那一段(dataSource.filter ?? filter 的优先级没变);两个 parity 钉子调转(记录形式变成被拒的那个 invalid_type,规则数组变成被接受的)。⛔ 渲染器不需要改 —— filter?: unknown 直通 $filter,find() 已经会 lower 它。
    3. ⚠️ apps/console/src/__tests__/registry-inputs-spec-parity.test.ts:1837-1856 保持 DECLARED 不变,卡片说了:只有 arm 变,"已声明"这件事本身没变。⛔ 不要顺手动它。
    4. ⭐ 收尾动作与 objectui#6206 的 element:number.filter:array 豁免删除是同一招 —— 有现成样板,⛔ 别重新设计。

    ⛔ 分诊席不认领、不派单、不写码。


    Generated by Claude Code

  3. claude commented on Sep 5, 2026

    @claude
    Contributor

    PM 席:半状态普查 H19 在本卡上报「block 已过期」—— ⛔ 本席不放行,理由如下

    check-half-states 本轮(2026-09-05T22:5xZ,objectui 全板 146 个半状态)在本卡上报了 H19:

    pm:blocked while 1 of 1 Blocked-by: target(s) is CLOSED — the block has outlived its blocker.

    按「放行双查」第 ① 条 —— 只按最近一次转换评论里的条件放行,绝不按线程上更早的那个 blocker —— 本卡不满足放行条件。H19 读的是 body 里那个 Blocked-by: 目标;本卡真正的解锁条件写在最近一次转换评论里,是另一件事。

    本卡最近一次转换评论(os-zhuang,2026-09-05T02:48:41Z)背书了卡片自己写的两段式判据:

    Blocked-by: objectstack#14406 — its PR landing in @objectstack/spec, AND a released spec version carrying it reaching this repo's lockfile / the .objectui-sha pin. Until then nothing here is red, and nothing here should move.

    ⇒ H19 只看到第一段(objectstack#14406 已关)。第二段今天为假。

    今天的 pin 读数(本席实测,不是采信)

    pnpm-lock.yaml:4273    '@objectstack/spec@17.2.0':
    pnpm-lock.yaml:12756   '@objectstack/spec@17.2.0(ai@7.0.65(zod@4.4.3))':
    

    ⇒ objectui 的 lockfile 今天把 @objectstack/spec 解析在 17.2.0。package.json 里写的是 ^17.0.0 / ^17.2.0(caret),但决定装什么的是 lockfile,不是范围。

    ⇒ 上游即使已发 17.3.0,本仓的已安装面还没动。

    真正的解锁在 PR #7685

    chore(deps): resolve @objectstack/spec at 17.3.0 in the lockfile —— open · draft · mergeable_state: blocked · 带 needs:contract-review · 44 files +1207/−375。它的正文自陈 ⛔ "Not a merge candidate",仍有 6 条红(Bundle Analysis 超预算 275.0 KB、1 条 Type Check、8 条断言 / 6 个文件)。

    ⇒ 本卡(以及同一道闸后面的 #7551 / #7599 / #7663 / #7707 / #7635 / #7122 / #7267 / #7714 / #7716)的解锁是 #7685 落地,不是任何一个上游单子关闭。⛔ 在此之前不要因为看到上游合并/关单就翻牌。

    ⚠️ #7685 带 needs:contract-review,而本 lane 现在没有契约复审能力(按用户指令,契约复审一律等总监席)。⇒ 本席对它只做记录,不推进。

    ⚠️ 提前动手有具体代价,评论已经量过:现在把 type 翻成 'array',两个 parity 钉子会立刻变红(它们钉的是当前已安装 spec 的行为)。⇒ 放行 = 制造一次红。


    Generated by Claude Code

  4. self-assigned this
    on Sep 9, 2026
  5. os-bill commented on Sep 9, 2026

    @os-bill
    Collaborator

    Claim: PM loop — FOLDED into the #8772 family dispatch
    Session: session_019wtfW1ZxGnP1XKGc9uZVms
    Branch: claude/issue-8772-objectstack-17-4-0-line (shared, named for the chain head #8772)
    Worktree: objectui-issue-8772
    Domain: domain:ui
    File surface: packages/components/__tests__/record-picker-inputs-spec-parity.test.ts, apps/console registry-inputs-spec-parity.test.ts (the element:record_picker arm) — stop on breach
    Container & model: M, mode:subagent, model: opus
    Clause-②: no — the spec narrowed the entry (objectstack#14406 converged filter onto the ViewFilterRule array); following it back is pulling this repo onto a declared contract, not widening one.
    Thread-read: none new since the card's last comment
    Serial constraints cleared: full check on the chain-head claim (#8772). ⚠️ Shares apps/console/…/registry-inputs-spec-parity.test.ts with #8172 — same-file HARD SERIAL, and the reason both are in one dispatch instead of two.

    Trigger CONFIRMED by the card's own words. It states its condition as "both go red the moment a released spec carrying objectstack#14406 is installed". PR #8783 installed it; both went red, exactly as written. ⭐ This is one of the four cards in this repo that predicted its own flip precisely enough to be actioned without re-derivation.

    ⭐ Why folded: repairing this alone still leaves #8783 red on the other thirteen, so it could not merge as its own PR. The bump and its by-design flips are one queue position.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpm:dispatchedpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions