Repository navigation
decision: on an app page, how does record:related_list find its parent record, given that its dataSource already binds its child rows? (the related-list half of objectui#12294) #12296
Description
Ruled: 6137226306 · letter B · 2026-10-13T03:02Z · execution card objectstack-ai/objectstack#23134 (domain:spec, pm:queue); the objectui leg lands on #12294 once the spec release is installable
This card carries the record:related_list half of objectui#12294's item 3. The parent keeps the other three record blocks (record:details, record:highlights, record:quick_actions), dispatched now under claim 6137033601. Once this card is ruled, the parent's related-list half executes.
Filing gate ② a decision only the maintainer can make. Filed by objectui domain:ui seat 1 (seat post objectui#5560) · session_01CsyMRsFJBKNEMa4oPY1b5z, while claiming objectui#12294 on the maintainer's instruction 「12294 插队」. ⛔ Not a claim. The ruling is recorded on this card and on the parent, then this card closes.
- Who acts after the ruling:
- A or B: the objectstack
domain:specseat first, for the spec addition; then objectuidomain:uion objectui#12294. - C or D: objectui
domain:uialone.
- A or B: the objectstack
- Dedupe: MCP
search_issues, closed included.- objectui, query
record related list dataSource parent record app page binding: 15 hits. None asks this. The nearest are record blocks honour the per-element dataSource the spec already declares — record:details / record:highlights / record:quick_actions / record:related_list on an app page bind their record from the component's dataSource, so a product page composes without the record shell (maintainer ruling cloud#2839 Q1 D, 2026-10-13) #12294 (the parent), 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 (node-leveldataSourceonly) and No record-context binding for filter values —element:numberand everydataSourcefilter on a record page can only be scoped to the VIEWER, never to the record #7297 ({record_id}in a filter, record in scope only). - objectstack, query
record scope one record binding page region record context related list parent: 4 hits. The prior ruling chore(config): retire the dead tailwind.config.js eslint ignore; reword the postcss blind-spot docblock (#4350) #4444 and its cause fix(fields): currency formatting follows each currency's ISO 4217 minor-unit width #4413 bear on this question and are quoted below.
- objectui, query
维护者速读
objectui#12294 让记录类块在普通应用页上用自己的 dataSource 绑定一条记录,这样产品页不用再套记录页外壳(你在 objectstack-ai/cloud#2839 Q1 选的 D)。详情、要点、快捷操作三个块已经派发。
第四个「相关列表」不一样:它的 dataSource 早就有含义,绑定的是它要列出的子记录(objectstack#6953 已发布)。父记录则来自记录页上下文,应用页上没有这个上下文。卡上要求它「按绑定行的 id 查子记录」,等于让同一个键同时指父记录和子记录。
八月的 objectstack#4444 已经决定不做会自己取数的「记录范围」组件(not_planned,那次针对 react 页),列了翻转条件和最低门槛。所以选项是:
- A:加一个「记录范围」,绑一次记录,里面的块都读它。这等于翻转 chore(config): retire the dead tailwind.config.js eslint ignore; reword the postcss blind-spot docblock (#4350) #4444,要满足它列的最低门槛。
- B:给相关列表加一个指向父记录的绑定,和前三个块「各自绑定」的做法一致。
- C:设置了关系字段时,把相关列表的
dataSource改读成父记录。这会推翻已发布的含义。 - D:不做。需要相关列表的页面继续用记录页。
推荐 B。回一个字母:A / B / C / D。
四棱(os-decision-facets)
- ① 项目长远合理性:B 沿用你在 cloud#2839 选的「每个块自带绑定」这一种机制,相关列表多一个父绑定,不引入第二种绑定方式。A 在每块绑定之外再加一个范围组件,两种机制并存。C 让一个键在一个块上有两种含义。D 不增长契约,但和 cloud#2839「产品页不套外壳」的方向相反。
- ② 实际业务拉动:objectstack-ai/cloud#2774(环境与成员页)和 feat(studio): surface the enable.searchable toggle in ObjectSettingsPanel #2801(首页 v2)在等相关行能放上应用页,这是 objectui#12294 卡上点名的消费方。它们具体要几个相关列表没测。
- ③ 防 AI 犯错:B 下每个相关列表各写一份父绑定,可能和同页详情块的绑定写得不一致,需要
validate提醒。A 的错误面 chore(config): retire the dead tailwind.config.js eslint ignore; reword the postcss blind-spot docblock (#4350) #4444 已经写过:范围内的块不得再带自己的绑定,而 AI 的习惯是「块自带绑定」,静默忽略就会出错。C 下按已发布含义写的子绑定被当成父记录读,静默出错。D 写不出来,但会响亮地缺失。 - ④ 创业阶段不扩散:D 不新增。B 新增一个键。A 新增一个组件,加上 chore(config): retire the dead tailwind.config.js eslint ignore; reword the postcss blind-spot docblock (#4350) #4444 列的整套门槛(失效总线、属性形状 lint)。C 不新增键,但改了已发布键的含义。
Prior rulings read: RecordScope, record context, related_list parent, record_id filter → objectstack#4444 (<RecordScope> 不做, not_planned, react pages; flip conditions and minimum bar), objectstack#4413 / PR #4450 (record blocks withdrawn from the react tier because renderers did not read their bindings), objectstack#6953 (the related list's child binding), objectui#7297 (a {record_id} filter token resolves only with a record in scope), objectstack-ai/cloud#2839 Q1 D (per-block bindings, as objectui#12294 quotes it; not reachable from this session); ADR none found; thread: objectui#12294.
一句话问题
在一个不是记录页的普通应用页上,「相关列表」不知道该列谁的子记录。它自己的数据绑定已经用来指定子记录,没有地方说明父记录是哪一条。
Governing text
- objectstack#4444(决策记录,
not_planned):「kind:'react'页面上的record:*家族维持 fix(fields): currency formatting follows each currency's ISO 4217 minor-unit width #4413 的撤回状态……不引入<RecordScope>(会取数的记录作用域组件),直到下述翻转条件成立。」- 翻转条件 1 是:「用户反馈中出现指名
record:details的真实需求」。 - 最低门槛第 1 条是失效总线集成:「"陈旧但看起来正确"比 fix(fields): currency formatting follows each currency's ISO 4217 minor-unit width #4413 修掉的"渲染成空"更难发现」。第 2 条是:「scope 内的 record 块不得携带
objectName/recordId(RecordRelatedList子对象objectName除外)」。 - 它还写明:「
record:related_list≤<ListView filters>」,这一点在 react 页成立,因为父记录是普通 React state。
- 翻转条件 1 是:「用户反馈中出现指名
- objectui
@object-ui/coreELEMENT_DATA_SOURCE_INPUT:「Per-element data binding: { object, view, filter, sort, limit }. Overrides the page-level object context for this block」。对列表类块来说,绑定指的就是这个块自己的数据。 - 协议声明: A 和 B 都要在 spec 里加东西(A 加组件或模式,B 加一个键),属于契约修改,要做契约复核;A 同时翻转 chore(config): retire the dead tailwind.config.js eslint ignore; reword the postcss blind-spot docblock (#4350) #4444。C 改变已发布键的含义。D 不改协议。
前提(每条带 re-check 命令,在 objectui 仓里跑)
- 相关列表的
dataSource已经是子记录绑定。 objectuimain45ae6b8:record-related-list.tsx的导出被elementDataSourceBlock包裹,绑定映射到objectName。
Re-check:grep -n "elementDataSourceBlock(\|dataSource?: ElementDataSourceConfig" packages/plugin-detail/src/renderers/record-related-list.tsx。 - 相关列表的父记录来自记录页上下文。 块体读的是
useRecordContext(),应用页上没有这个上下文,所以 objectui#12294 卡上实测它什么都不渲染。
Re-check:grep -n "useRecordContext" packages/plugin-detail/src/renderers/record-related-list.tsx。 - 筛选条件在应用页上够不到父记录。
{record_id}只在有记录上下文时才能解析(objectui#7297 的落地说明:useFilterScope()只读useRecordContext()?.recordId)。- objectstack spec
packages/spec/src/data/filter.zod.ts的注释写明,query.joins已移除(Synthesizedasideregion carriesclassName, whichPageRegionSchemarejects — a Reference Rail page has no persistable spelling #4286),按关系路径的点号引用会被 SQL 下推以INVALID_FILTER拒绝。这条读的是$field引用的注释,筛选键本身带点号的情况没有实测。
Re-check:grep -n "useRecordContext" packages/react/src/hooks/useFilterScope.ts;在 objectstack 仓里跑grep -n "joins\|INVALID_FILTER" packages/spec/src/data/filter.zod.ts。
选项 × 真实代价 × 工作量
| 选项 | 做什么 | 客户感受到的后果 | 工作量 |
|---|---|---|---|
| A | spec 加一个记录范围,绑一条记录并为里面的块提供记录上下文;翻转 #4444,按它的最低门槛接失效总线、加属性形状 lint | 一个区域只绑一次记录,里面的详情、要点、操作和相关列表都读它 | objectstack domain:spec 1 个 PR(加契约复核和 lint)+ objectui domain:ui 1 个 PR;没有先例 |
| B | spec 给 record:related_list 加一个父记录绑定键(形状和 dataSource 一样,按单记录规则取第一行);validate 提醒同页详情块和相关列表的父绑定不一致 |
产品页上的相关列表能列出那条记录的子记录 | objectstack spec 1 个键 + objectui 1 个 PR;无先例(objectui#12294 前半张卡在飞,落地后可复用它的单记录读取) |
| C | 设置了 relationshipField 时,dataSource 改读为父记录 |
已按 objectstack#6953 写的子绑定被当成父记录,现有页面出错 | 只改 objectui,但是破坏性变更 |
| D | 不做 | cloud 的成员页这类需要相关行的页面继续用记录页外壳 | 无 |
业务含义
- A:像一个文件夹,先说「这一格讲的是哪位客户」,格子里的卡片都看这位客户。
- B:「往来记录」卡片自己注明「客户是谁」,和旁边几张卡的做法一样。
- C:把印好的「子项」标签改成「父项」,旧表格全看错。
- D:这类卡片只能放在客户档案页里。
推荐 + 回退 + 置信缺口
- 推荐 B。 两年后,每个记录类块都自己声明绑定哪条记录,平台只有一种绑定机制,相关列表是唯一需要两个绑定(父记录和子记录)的块。这和 Salesforce LWC 的建模一致:
lightning-record-form、lightning-record-view-form等组件各自带record-id/object-api-name,不依赖外层范围。它也和你在 objectstack-ai/cloud#2839 选的「每块绑定」、以及 chore(config): retire the dead tailwind.config.js eslint ignore; reword the postcss blind-spot docblock (#4350) #4444「不做记录范围」两条已有裁决同向。 - 回退 D:等 chore(config): retire the dead tailwind.config.js eslint ignore; reword the postcss blind-spot docblock (#4350) #4444 的翻转条件被你明确宣布成立,再按 A 重新设计。
- 置信缺口:
- cloud 的页面具体要几个相关列表、它们和详情块是否总是绑同一条记录,没有测。如果总是同一条,A 的「只绑一次」优势会变大。
- chore(config): retire the dead tailwind.config.js eslint ignore; reword the postcss blind-spot docblock (#4350) #4444 的翻转条件 1 是否已经由 cloud 的需求满足,需要你判断。本卡不替你宣布翻转。
- objectstack-ai/cloud#2839 的原始讨论本会话读不到。
- 只看①选 B;②③④ 是否翻转:否。
裁后执行
- A: 在 chore(config): retire the dead tailwind.config.js eslint ignore; reword the postcss blind-spot docblock (#4350) #4444 上记录翻转。objectstack spec 车道开执行卡,定义记录范围并按 chore(config): retire the dead tailwind.config.js eslint ignore; reword the postcss blind-spot docblock (#4350) #4444 的门槛接失效总线、加 lint,契约复核把关;发版后 objectui 在 objectui#12294 上执行相关列表这一半。
- B: objectstack spec 车道开执行卡,给
record:related_list加父绑定键(名字和形状由 spec 席实测后提,契约复核把关);发版后 objectui 在 objectui#12294 上执行,复用前半张卡的单记录读取和失效总线接入。 - C: objectui#12294 直接执行,带一份破坏性变更说明,objectstack#6953 的写法要迁移。
- D: objectui#12294 的相关列表这一半记为
not_planned,引用裁决;前三个块落地时 objectui#12294 关闭。
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 13, 2026
Ruling: batch #335 item 1 · letter B · maintainer 「同意」 2026-10-13T02:59Z
Director seat, summon #40,
session_01TJKP6W6UDYEBHtccVdpVoz(GitHubos-steve; seat post objectstack-ai/objectstack#12708; written asobjectstack-fleet[bot]through the relay, read back). Presented in this seat's chat as batch #335, the one card, with recommendation B (the filing seat recommended B; this seat reached the same letter on the long-term axis); the maintainer's word was 「同意」. The three premises were re-read by this seat on objectui and objectstackorigin/mainbefore the batch and hold (RecordRelatedListRendereris wrapped byelementDataSourceBlockand itsdataSourcebinds the child rows; the block readsuseRecordContext();useFilterScoperesolves{record_id}from the record context only, andquery.joinsis gone per #4286). Thread-read: none (no comment on the card at this write).B —
record:related_listgains a parent-record binding key of its own.@objectstack/specadds one key on therecord:related_listcomponent (name and shape proposed by the spec seat after measurement; the shape isdataSource's, read by the single-record rule: the first row, and a loud absence when no row answers, the same rule the other three record blocks take under objectui#12294).dataSourcekeeps its published meaning, the child rows (objectstack#6953). Every record block therefore declares its own binding and the platform has one binding mechanism; the related list is the one block with two bindings. Governing text: objectstack-ai/cloud#2839 Q1 D (per-block bindings, as objectui#12294 quotes it); objectstack#4444 (no self-fetching record scope on react pages; its flip conditions are not declared met by this ruling); theELEMENT_DATA_SOURCE_INPUTcontract ("per-element data binding"). A (a record scope) is not taken: it overturns a recorded ruling and puts two binding mechanisms side by side. C is not taken: a published key would change meaning. D is not taken: it runs against cloud#2839's direction. ⛔ No newvalidatefinding for a parent binding that differs from a sibling details block: a new gate defaults to no, and none was named.domain:spec· 1 key, 1 PR (the key, its description, the component-props door, a contract review) · objectuidomain:ui· the related-list half of objectui#12294 once the spec release is installable (reuse the first half's single-record read and invalidation wiring) · no precedent.domain:spec·pm:queue, with the ruling quoted; this card records the ruling, carries a pointer to that card, and closescompletedas its own text prescribes. The parent objectui#12294 carries the same ruling in a comment: its related-list half waits on the spec release (the cross-repo unlock rule: installable, not merged) and lands on the parent, not on a new card.dataSourceonrecord:related_listis read by objectui as the child binding and by no reader as the parent. If the spec seat finds a reader that already treats it as the parent, or a shape the single-record rule cannot carry, it reports the fork and stops; ⛔ no silent C.objectstack-fleet commentedon Oct 13, 2026
Closed
completedat 2026-10-13T03:03Z by the director seat (summon #40,session_01TJKP6W6UDYEBHtccVdpVoz, written asobjectstack-fleet[bot]through the relay), as this card's own text prescribes once the ruling is recorded: letter B (ruling 6137226306, the maintainer's 「同意」), recorded here, on the parent #12294 (6137246293), and carried by the execution card objectstack-ai/objectstack#23134 (domain:spec,pm:queue). The objectui leg lands on the parent once the spec release carrying the key is installable.needs-user-decisionleaves with the close;domain:ui,priority:p1andenhancementstay as attribution.