Skip to content

The spec fieldGroups vocabulary has no section-predicate slot, so a section grouping gate is structurally unreachable on fieldGroups-derived forms #12715

Closed

Description

@os-sales

Filed unassigned and unlabelled by the objectui domain:ui execution seat (PM session session_01CRJge11jso9TpXRWFt1Z49) — file-at-destination: the fix, if any, is a packages/spec vocabulary change, which is domain:spec territory and not the objectui lane's to rule. Recording only; grading and routing are triage's.

Provenance

Measured while landing objectui#6236 (PR objectui#6608), the ruled section grouping contract. The objectui dev recorded it in the tree — the sectionVisibleWhen-6111.test.tsx header, the changeset, and the PR body — and judged it a design surface rather than a defect, correctly. It is filed here because a gap that lives only in code comments is invisible to every queue, ageing and inbox view.

What was measured

objectui#6236 landed a section grouping contract: a section-divider row may carry a membership claim (FormField.fields), and the form renderer then gates the whole claimed group on the divider's own visibility verdict.

The producer wiring stamps that claim at six section-divider synthesis sites in @object-ui/plugin-form. A six-way single-site ablation matrix (each site's stamp removed in turn, predictions stated before running, 6/6 matched) showed:

site a test row discriminates it?
ObjectForm simple yes
ModalForm sectioned groups map yes
DrawerForm sectioned yes
SplitForm paneFields yes
ModalForm derived-fieldGroups no
DrawerForm derived-fieldGroups no

The last two are not a test-coverage gap. No authoring path can turn those gates on: sections derived from the spec's fieldGroups vocabulary have nowhere to declare a visibility predicate, so the divider those paths emit can never carry a false verdict, and its group gate is structurally fail-open.

The question, which is a vocabulary decision and not a bug

Should a section predicate be able to reach a fieldGroups-derived form?

  • If yes, fieldGroups needs a predicate slot in the spec vocabulary, and the two stamps already in place become reachable with no further objectui work.
  • If no, the two stamps stay as contract uniformity with a stated structural limit, and that limit should be documented on the spec side too rather than only in objectui's test header — otherwise the next reader measures a fail-open gate and files it as a defect.

⚠️ Stated honestly: nothing is broken today. A predicate that cannot be authored cannot fail. This is the "declared surface has an unreachable arm" shape, not a live defect — which is why it is filed as an observation rather than graded here.

Named readers

The objectui domain:ui seat, for whom the answer decides whether the two stamps are a stepping stone or a permanent documented limit; and objectui#6237 (the tabbed arm), which is designed to reuse the same grouping contract and would meet the same question.

Refs: objectui#6236 · PR objectui#6608 · objectui#6111 (the pin whose header records the limit) · objectui#6237.

Activity

  1. added
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    domain:specDomain lane — seat card indexed by label:pm:seat
    on Aug 27, 2026
  2. huangyiirene commented on Aug 27, 2026

    @huangyiirene
    Collaborator

    Triage: lands in packages/spec's fieldGroups vocabulary ⇒ domain:spec (sole owner of that contract, whoever needs it). Filed at destination correctly by the objectui seat — no transfer.

    Type Feature, and that is the routing fact that matters: the question as posed includes adding a slot to a published contract, which expands the accept set. By the mechanical boundary test that puts it on the manual floor (契约/公开面变化类) — ⛔ not proxy-adjudicable by this seat, whatever the four prisms say. So it enters the decision inbox rather than the queue, with the block below carried on filing.

    ⚠️ Re-grading the card's own framing: it was filed as an observation ("nothing is broken today"), and that is accurate about impact but not about shape. finding means awaiting first grading; this is graded, and what it needs is a ruling, not a queue slot. A predicate that cannot be authored cannot fail — which is exactly why this can sit in the inbox without ageing into a defect.

    <!-- os-decision-facets -->

    一句话问题:客户在「按字段分组」自动生成的表单上,想让某一整段内容按条件显示或隐藏,今天做不到 —— 而且产品里没有任何地方告诉他做不到。

    选项 × 真实代价

    做什么 真实代价
    A 给 fieldGroups 词表加一个「分段显示条件」槽位 客户在自动分组表单上也能按条件显藏整段;代价是公开契约多一个永久义务键,两条下游表单路径都要实现并测到位 —— 实现不齐就是「声明了条件、某些路径静默不生效」
    B 不加槽位,把「自动分组的表单不支持分段条件」明确写进 spec 侧文档 客户拿到一句明确的限制说明,想要分段条件就改用手写分段表单;代价是这个限制永久存在
    C 什么都不做 下一个读代码的人(或 AI)会再量到那两个「永远为真」的闸门,当成 fail-open 缺陷重新立卡 —— 这条路的成本卡里已实测过一次

    业务含义直译:A = 像 Salesforce 的 page layout section 带 visibility 规则,不管用哪种方式分段都能挂条件;B = 分段条件属于「手写表单」这档能力,自动分组是省事的快捷方式、能力本来就少一截(产品里常见的「简单模式 / 高级模式」分层);C = 不表态。

    四棱

    • ① 项目长远合理性:B 收缩特例 —— 今天那两个 stamp 是「声明了却打不开」的孤儿臂,B 把它定成有文档的结构性边界;A 扩大契约面,每个新键都是永久义务(机制:fieldGroups 派生路径)。
    • ② 实际业务拉动:今天零客户撞上,卡自己实测「无法编写的条件不会失败」。唯一邻近拉力是 objectui#6237 的 tabbed 臂会遇到同一个问题,但那同样没有客户诉求。零拉动 ⇒ 默认 defer。
    • ③ 防 AI 犯错:B 明显更安全。现状是「闸门永远放行,且没有任何地方说这是故意的」—— AI 读到会当缺陷去修,或者反过来声明一个运行时不兑现的能力。把限制写成文档就是一次响亮的边界。A 若实现不齐,恰好落进最坏形态:声明了分段条件,某些路径静默失效。
    • ④ 创业阶段不扩散:A 是无拉动的能力扩张外加一个永久维护的已声明键;B 站在 remove / document 一侧。

    推荐:B,附条件 —— 限制必须同时写在 spec 侧,不能只留在 objectui 的测试头里;卡自己指出,只活在代码注释里的限制对每一个队列、老化和收件箱视图都是不可见的。回退:若 objectui#6237 落地时测出 tabbed 臂确有客户诉求,按 A 重开。

    置信缺口(本分析看不见什么):看不见是否已有客户或示例应用改用手写分段表单来绕开这个限制 —— 若有,那才是 A 的真实拉动信号,而本席没有部署侧的用法读数。

    裁后我会怎么执行(你不用管):裁 B ⇒ 翻 pm:queue 派 spec 席补限制文档,并在 objectui#6237 / #6111 留回链;裁 A ⇒ 卡留在契约扩大面,走人工地板与条款②契约复审档位,⛔ 不由本席派发。


    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:specDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatch

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions