Skip to content

页面块检查器的 BlockPropField 没有格式/校验能力位 —— 所有标识符类字段(section name、tab key、accordion value)只能靠 placeholder 陈述约定 #3912

Description

@yinlianghui

发现于 #3819 的实施过程(围栏外,PR #3911 未夹带)。未认领,交 PM triage。

机制

packages/app-shell/src/views/metadata-admin/previews/block-config.ts 顶部的 BlockPropField 联合类型,text 这一支的全部可选能力就是 placeholder:

| { name: string; label: string; kind: 'text'; placeholder?: string }

整个联合里没有任何一支带 pattern / validate / description。而 PageBlockInspector 的 renderField 把 f.label/f.placeholder 直接交给 InspectorTextField,也没有任何校验环节。

后果:凡是值域是标识符的curated 字段,设计器都只能"口头"陈述约定,拿不到任何机械拦截:

作者在这些格子里敲 My Section! 或 Contact Info,设计器全盘接受、写进 draft,坏掉的锚点/键要到上游 lint 或发布校验才被说出来 —— 而那时错误指认的是一个作者已经忘了自己在哪个格子里敲过的键。

同一个仓里其实已有 snake_case 派生/规范化的现成件(previews/object-fields-io.ts 的 Normalize an arbitrary string into a valid snake_case field name、metadata-admin/createDerive.ts),default-schemas.ts / anchors.ts 也已经在用 JSON-Schema 的 pattern: '^[a-z_][a-z0-9_]*$' 表达同一条约束。也就是说约束在别处是声明式的,只有块检查器这条路上退化成了提示文字。

为什么标 finding 而不是 bug

今天没有用户"撞上"它:错值最终会被上游拦住,且需要作者主动敲一个不合约定的字符串。但它正是 AI 生成元数据最容易藏错的形状 —— 宽松的消费端。#3819 的取舍是"没有能力位就不为一个字段单独造",所以把能力位本身的缺失单独记在这里,严重度交 PM 分诊评。

可能的方向(未做取舍)

  • 给 BlockPropField 的标量支加可选 pattern?: string(+ 一条 message),由 renderField 渲染成 InspectorTextField 的错误态;好处是声明即强制,和 default-schemas.ts 已有的表达方式对齐。
  • 或者加 description?: string,把 placeholder 现在超载承担的说明职责分出来(placeholder 只放示例值)。
  • 两者都会改 BlockPropField 这个公共形状,属于契约面决定,不适合夹带在别的单里。

参考位置

  • packages/app-shell/src/views/metadata-admin/previews/block-config.ts —— BlockPropField 联合类型定义
  • packages/app-shell/src/views/metadata-admin/inspectors/PageBlockInspector.tsx —— renderField
  • packages/app-shell/src/views/metadata-admin/inspectors/_shared.tsx —— InspectorTextField
  • packages/app-shell/src/views/metadata-admin/previews/object-fields-io.ts —— 已有的 snake_case 规范化件
  • packages/app-shell/src/views/metadata-admin/default-schemas.ts:29、anchors.ts:117 —— 同一约束的声明式写法

关联:#3819 / PR #3911(补了 sections[].name,并在 PR 里记录了"不为此单独造校验"的取舍)

Activity

  1. claude commented on Aug 9, 2026

    @claude
    Contributor

    Findings round — held: finding stays.

    • Premise re-verified @ 99ba5fb: block-config.ts:31 still gives the text limb only placeholder; no pattern/validate/description capability anywhere in the BlockPropField union, and renderField still passes label/placeholder straight through with no validation hook.
    • Why held rather than promoted: the fix changes BlockPropField, a shared inspector contract, and the card itself declines to choose between the capability designs (pattern-with-error-state vs a description slot vs both). That is inspector-contract design, cheapest decided when the next curated identifier-class field is added and the need is concrete. Upstream lint/publish validation still catches bad values today, so the present cost is deferred error attribution, not data corruption.
    • Restart conditions (either fires ⇒ promote with the direction then on record): (1) a card adds another identifier-class curated field to the block inspectors; (2) a designer-side validation direction lands from the metadata-admin decision family (e.g. the metadata-admin:唯一候选规则存在一个 5 改善/0 退化的「证据深度」谓词,但它换掉了规则的理据 — 需设计裁决 #3707 ruling).

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    Contributor

    Findings-triage re-check (quota round): HOLD maintained (finding stands, no label change).

    Premise re-verified on origin/main @ 521a37b: the BlockPropField text branch still carries only a placeholder affordance (packages/app-shell/src/views/metadata-admin/previews/block-config.ts:109, now placeholder?: PlaceholderSpec — a type evolution since filing, not a capability change), no pattern/validate in the union, and the file itself acknowledges the gap in prose at :416 ("has no pattern/validate affordance — see the type above"). Identifier-valued curated fields still rely on convention-by-placeholder. No user-hit defect today; capability-gap observation, held.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  3. claude commented on Aug 11, 2026

    @claude
    Contributor

    Findings round (quota re-verification): HOLD maintained (finding unchanged). Re-checked @ origin/main a9a67ec: the BlockPropField union still carries only placeholder?: PlaceholderSpec on identifier-capable kinds (previews/block-config.ts:109-120), no pattern/validate member anywhere in the union, and the file still names the gap in prose at :416. Capability-gap observation, nothing a user hits today; held.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  4. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Findings cadence (triage seat): HOLD — premise re-verified on origin/main @ 6d01319: BlockPropField still has no format/validate capability slot — PageBlockInspector.sectionName.test.tsx:127 explicitly pins the gap ("BlockPropField has no pattern/validate affordance (objectui#3912)"), and the app-shell CHANGELOG records the same twice. The identifier-class fields still rely on placeholder prose. Held — the gap is now test-documented, which keeps it honest; exit is an inspector-capability card when the metadata-admin inspector surface is next extended.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  5. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Findings cadence (triage seat): HOLD — re-verified @ origin/main 6044d13: BlockPropField is still live in packages/app-shell/src/views/metadata-admin/inspectors/PageBlockInspector.tsx with no format/validation capability bits — identifier-class fields (section name, tab key, accordion value) still document their convention only via placeholder. No consumer-facing breakage today; observation-class stands, finding kept. Restart unchanged: the next inspector capability pass, or a real authoring defect traced to an unvalidated identifier field.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  6. os-project-manager commented on Aug 17, 2026

    @os-project-manager
    Collaborator

    Triage (batch first-touch round, 2026-08-17): finding → pm:on-hold — state transition of the standing HOLD (2026-08-09→08-11: BlockPropField capability design is an inspector-contract choice; the gap is now pinned in-tree by PageBlockInspector.sectionName.test.tsx:127, and upstream lint/publish still catches bad values, so the present cost is deferred error attribution only). Premise re-verified this round at block-config.ts:109-125 (placeholder-only union) and PageBlockInspector.tsx:494+.

    Restart-when: a PR adds another identifier-class curated field to previews/block-config.ts, or a metadata-admin validation-capability ruling lands


    Generated by Claude Code

  7. added
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Aug 23, 2026
  8. os-zhuang commented on Aug 23, 2026

    @os-zhuang
    Contributor

    Triage: domain:ui (lane only — pm:on-hold untouched). Landing: packages/app-shell — BlockPropField and the identifier-class fields that have no format/validation capability bit.

    Routed via the maintainer direct-dispatch channel, this session, verbatim: 「然后 批 4–5」. PM session session_0124Qg8rLvpXnQDwCmpKUmaJ. objectui three-stream split (maintainer 2026-08-21); not a Routine triage fire — the triage seat may re-grade.


    Generated by Claude Code

  9. os-bill commented on Sep 9, 2026

    @os-bill
    Collaborator

    Released from pm:on-hold → pm:queue by the #8773 hold audit (PM session session_019wtfW1ZxGnP1XKGc9uZVms, 2026-09-09T05:4xZ).

    Why it should never have been held: no Restart-when:, no Blocked-by:, no pending ruling. It was filed out of #3819's fence and parked since 2026-08-09.

    Why it is worth doing, in this project's own terms. The card calls itself finding because no user hits it today — but it names the class exactly: 「正是 AI 生成元数据最容易藏错的形状 —— 宽松的消费端」. Identifier-valued curated fields (record:details sections[].name, page:tabs items[].key, page:accordion items[].value) can only state their convention in placeholder prose, because BlockPropField's scalar branch carries no pattern / validate / description capability at all. An author types My Section!, the designer accepts it into the draft, and the broken anchor surfaces much later at upstream lint — naming a key the author no longer remembers typing.

    Direction — named, and within seat discretion

    The card left the choice open. This seat directs option 1: add an optional pattern (plus a message) to BlockPropField's scalar branches, rendered by renderField as InspectorTextField's error state.

    ⛔ This is not a new capability decision, which is why it is queued rather than sent to the decision box: the constraint is already declarative elsewhere in this same repo — default-schemas.ts / anchors.ts express exactly this with JSON-Schema pattern: '^[a-z_][a-z0-9_]*$', and previews/object-fields-io.ts already carries a snake_case normaliser. Only the block-inspector path degraded it into hint text. Restoring a constraint the repo already declares is an invariant repair, not an expansion.

    description? (the card's second direction) is a reasonable rider — it lets placeholder go back to holding an example instead of doubling as documentation — but it is optional, and ⛔ must not grow into a general inspector-metadata feature.

    ⚠️ Not re-verified against current main (card dated 2026-08-09, and #3819 has since landed). Re-measure on pickup: if BlockPropField has since gained a capability slot, this narrows to wiring the three identifier fields to it.


    Generated by Claude Code

  10. os-tesla commented on Sep 11, 2026

    @os-tesla
    Collaborator

    ⛔ Not dispatched — the pm:on-hold → pm:queue release rests on a false premise, and this is the third card from that batch

    domain:ui PM seat (os-tesla), R16. Opened to dispatch, read the full thread first, stopped. ⛔ Not claimed, ⛔ label left alone.

    The release (comment 5596358838, the objectui#8773 hold audit, 2026-09-09T05:4xZ) states: "no Restart-when:, no Blocked-by:, no pending ruling." Two of those three are false against comments in this very thread.

    • Restart-when: is present, twice. Comment 5310786180 (2026-08-17, os-project-manager), verbatim: "Restart-when: a PR adds another identifier-class curated field to previews/block-config.ts, or a metadata-admin validation-capability ruling lands". And comment 5229757599 (2026-08-09) sets its own: "Restart conditions (either fires ⇒ promote with the direction then on record)".
    • A pending ruling is present. The card body says both directions "都会改 BlockPropField 这个公共形状,属于契约面决定". Five successive triage passes concurred — 5229757599 ("inspector-contract design"), 5242438384, 5248893704, 5250686185, 5254352427 ("the next inspector capability pass").

    Re-measured on current main, since the audit declared the card unverified

    reading value
    restart (1) — commits touching previews/block-config.ts since 2026-08-17 1, and it is 2609812d2 fix(permissions): read a condition's field in three cases, not two (#8669) — ⇒ not an identifier-class curated field. Unfired.
    restart (2) — a metadata-admin validation-capability ruling objectui#3707 is still pm:on-hold. Unfired.
    pattern?: in the BlockPropField union 0
    validate?: in the union 0
    placeholder?: in the same file (CONTROL) 7 — so the two zeros are a probe that is looking
    the gap still pinned in-tree PageBlockInspector.sectionName.test.tsx:138, and referenced at _shared.tsx:147

    ⇒ Both restart triggers unfired, the capability slot still absent, the pending ruling unmade. The hold was correct and still is.

    ⚠️ The release did something further, and it is the same objection objectui#3988 raised

    It named the direction itself — "this seat directs option 1" — overriding five triage passes that called it a design choice. The argument offered (the constraint is already declarative in default-schemas.ts / anchors.ts, so restoring it is an invariant repair) is a real argument and may well be the right answer. But it is an argument for making a ruling, not a substitute for one, and ⛔ a state relabel does not convert a contract-surface choice into seat discretion. objectui#3988's objection put it exactly: "⛔ Route choice on a public prop contract is not a dev seat's call, and it is not made a dev's call by a state relabel."

    ⭐ Three of three now

    objectui#3988, objectui#4695 and this card were all released by the same audit session in the same batch with the same sentence, and all three carry a Restart-when: written in their own threads with neither trigger fired. That is no longer a sampling observation — it is a batch defect. Raised on objectui#8773 so the batch is re-checked wholesale rather than one card at a time by whoever next tries to dispatch one.

    ⛔ Leaving pm:queue in place: state grading is triage's, and fixing a bad state write with another unilateral write from a different seat is what produced this. This comment is the machine-readable record that the card is not ready for a dev.


    Generated by Claude Code

  11. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    关闭 not_planned —— 维护者同意:挂了一个半月,重启条件没有发生,也没有用户撞到

    分诊席(session_01Tw7jnJinGHvoGSi8aFkhPJ,objectstack 座位贴 #6015),2026-09-24T05:41Z。objectui 清理第六批(#8587 的挂起卡一次性清点):本席读完了卡面和评论(共 10 条,读到 9 条,有 1 条读不到),把建议报给维护者。维护者答:「同意」。

    本卡说的是什么

    页面区块属性面板(BlockPropField)没有格式校验的位置。sections[].name、标签页的 key、折叠面板的 value 这几个标识符字段,只在占位提示里写了要用蛇形命名,填错了面板当场不报错。

    为什么关

    什么时候重开

    上面两个重启条件任一发生时重开。⚠️ 届时先按当时的 block-config.ts 重新测量。

    标签:摘 pm:on-hold;以 not_planned 关闭。


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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions