Skip to content

finding(core): the BINDING's own limit — the other operand of config.limit ?? savedViewLimit(view) — is still admitted unchecked, and the precedence question is live #10016

Description

@os-tesla

维护者速读

事情:一个节点的行数上限由 config.limit ?? savedViewLimit(view) 决定。PR #10014右边那个操作数(视图那一半)加了正数检查,左边那个 —— 绑定自己的 limit —— 仍然不检查。⇒ 作者写 dataSource: { object, limit: 0 },那个 0 会原样到达 DataFetcher.fetchRecords

为什么是你拍板、而不是席位直接补一个检查:补检查容易,难的是补完之后取什么值。三条路各自都说得通,而且它们对作者的含义完全不同:

  • A(荐) —— 把被拒的绑定上限当作没写过,落到视图的那一半。⭐ 这不是新发明:fix(react): a row cap the contract refuses is not "authored" in the shared gate (objectui#9899) #10009 已经裁过同形的一次 —— 一个被契约拒绝的值被判为「not authored」,于是另一个来源胜出。选 A 等于让一条规则覆盖两对操作数,⛔ 而不是为每一对各留一条。
  • B —— 丢掉它,直接落到站点默认值,忽略视图。作者写了个坏值,结果连他视图里那个好值也不算数 —— 最难解释的一种。
  • C —— 响亮拒绝,什么都不渲染。契约上最干净,但代价是一个作者的手误让整块区域空白。

席位意见:荐 A⚠️ 但把话说全:章程的防错轴确实偏向「响亮拒绝优于消费端宽容」,也就是偏向 C —— 本席认为那条偏好指的是发布/授权时响亮拒绝,⛔ 不是渲染时白屏。⇒ 真正的终态更像「A + 在写入面把 limit: 0 拒掉」,而那第二半是另一张卡的事。

⚠️ 一个没测的:本席没有量到任何一个真实作者写过 limit: 0。这条轴今天投不了票。

你要做的:回一个字母 —— A / B / C

os-decision-facets

  • ① 项目长远合理性 — 同一个问题(「一个被拒的行数上限该让位给谁」)已经在 fix(react): a row cap the contract refuses is not "authored" in the shared gate (objectui#9899) #10009 上被裁过一次。A 把那次裁决推广成规则;B/C 让这个仓拥有两条关于同一件事的优先级规则。两年后的终态:一条写下来的优先级链,⛔ 不是每对操作数一次裁决。
  • ② 实际业务拉动 — ⛔ NOT MEASURED:没有量到任何真实作者写 limit: 0。⇒ 这条轴不投票,并且它说明这件事不急 —— 它是在一次相邻修复的交还里被发现的,不是被用户撞出来的。
  • ③ 防 AI 写代码/写元数据犯错 — 最有张力的一条。章程逐字:「契约收紧(严格 schema、publish 时响亮拒绝)优于消费端宽容(?? 回退、静默容错)」。字面读偏向 C⚠️ 但本席认为那句话的重心在 publish 时:渲染时白屏并不让 AI 更难写错,只是让错误更贵。⇒ A + 写入面拒绝才是这条轴真正要的形状,而 A 单独并不违背它。
  • ④ 创业阶段不扩散 — A 复用既有裁决,零新概念;C 新增一种「拒绝即空渲染」的运行时行为,是新面。⇒ 指向 A。

Governing text: objectui#10009 的裁决(被契约拒绝的值判为 not authored,另一来源胜出)· 〈升级与决策〉四轴防错条 · composeElementDataSourceconfig.limit ?? savedViewLimit(view)

⚠️ 立卡席刻意没有就地修,这一点是对的:bounded-fix 豁免的第二条不成立 —— 优先级的答案是一个活的设计问题,⛔ 不是执行细节。本卡记录的正是那个判断。


composeElementDataSource resolves a node's row cap as
config.limit ?? savedViewLimit(view). PR objectui#10014 (card objectui#9928) puts a positivity
check on the right-hand operand — the saved view's half. The left-hand one, the binding's own
limit, is still admitted unchecked, so an authored dataSource: { object, limit: 0 } reaches
DataFetcher.fetchRecords as 0 on the same unguarded ViewDataProvider path that card repaired
for the view's half.

Filed by the domain:ui#2 execution seat (session_018HrVaotisyhgmot9o2MLRq) at 2026-09-19T11:27Z, from objectui#9928's hand-back, where the dev
found it and ⛔ deliberately did not fix it in place. This card records why that was right.

Why it was left out of objectui#10014 rather than folded in

The bounded-fix exemption fails its second condition: the precedence answer is a live design
question
, not an execution detail.

Does a refused binding cap suppress the view's legitimate one?

⇒ that is the same question objectui#10009 settled for the component/view pair one layer up, where
it took a measurement and an argument to settle — and it was settled for a relay, ⛔ not for this
layer. Folding it into objectui#10014 would have meant answering it silently inside a PR whose stated
scope was the view's operand.

⭐ And the dev did the one thing that keeps this card cheap: nothing in objectui#10014's new pin
asserts the current answer.
So whoever settles the precedence question will not have to edit a pin
that endorsed one. That is deliberate and it is worth preserving.

What a taker must settle first

  1. Which answer. Drop the refused binding cap and fall through to the view's? Drop it and fall to
    the site's default, ignoring the view? Refuse loudly and render nothing? ⭐ objectui#10009's
    precedent is the nearest evidence — there, a value the contract refuses was ruled not authored,
    so the other source won. ⚠️ But that was a relay deciding between a component and a view; here it
    is the same key's two operands inside one pure resolver.
  2. Whether it owes a diagnostic, and on which channel. objectui#10014 added a pure builder
    (elementDataSourceRefusedLimitMessage) reported by each caller, because
    composeElementDataSource is pure and the render path calls it from a useMemo. Any answer here
    should use that channel rather than minting a third.
  3. ⚠️ The population, with a lit control. objectui#9928's headline instrument was DARK — the tree
    holds two authored saved views and neither carries a cap in any spelling. Expect the same for
    authored bindings, and say so if the control is dark rather than reporting the zero as green.

Related

objectui#9928 → PR objectui#10014 (the view's operand, landing) · objectui#10015 (the renderer path
has no reporter after that PR, and the family's second consumer) · objectui#9899 → PR objectui#10009
(the precedence precedent, one layer up) · objectui#9853 / objectui#9897 / objectui#9925 (the read
points, all landed).

⚠️ ⭐ Say which consumer any future card in this family means: on the renderer path a refused cap
is dropped and the read goes WIDER; on the ViewDataProvider path it reached the fetcher verbatim
and the read was STARVED. Both are measured, on different paths.

Dedupe words: element data source binding limit non-positive · config.limit zero lowered ·
dataSource limit positivity · composeElementDataSource left operand ·
binding cap suppresses view cap precedence

⛔ Attribution corrected 2026-09-19T12:08Z: this card was filed without a session id, which the half-state patrol's H64 row named — a seat artefact whose author GitHub records only as a token (os-tesla), and the token records the token, ⛔ not the seat. The writing session is session_018HrVaotisyhgmot9o2MLRq, seat domain:ui#2 at objectstack-ai/objectui. ⛔ Nothing else in this card changed.


Generated by Claude Code

Activity

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:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:queuepriority:p3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions