Ruled: 5872049943 · letter A (no authoring-time one-of report; runtime notice via PR #10989 is the answer; card closed) · 2026-09-28T14:30Z
维护者速读 · decision: restore an authoring-time report for "one of two ways to name the object"? · domain:ui seat 2 · 2026-09-28
Filed by domain:ui seat 2, session_014mXUNuFomfj24w7s1pZzhN. Triage 5869415559 on objectui#10951 routes it here: "(b) only if the manifest can already say one-of … It cannot: ⛔ don't invent a manifest construct here. Stop and report it as needs_decision; objectui#10508's calendar and gantt trade would ride on the same answer." objectui#10951's runtime half (a) is in PR objectui#10989: an element:number with an aggregate and no object now shows a localized "no object named" notice instead of a silent "—". This card carries only the authoring-time half.
The question. PR objectui#10944 made element:number accept its object from dataSource.object, so object stopped being required. Before that, the html tier (validateTree: the JSX page compiler, the save gate and the objectstack CLI's JSX gate) reported a node with no object. Should a node that names neither be reported at authoring time again?
Measured (dev report 5871269526 on objectui#10951):
- The sdui manifest input model cannot express "one of".
ManifestInput carries only name / type / of / required / enum / binding / description. validateTree's presence rule is if (input.required && !(input.name in node)), and its per-tag checks are hard-coded in the parser, not registration hooks.
- objectstack runs a lockstep port of
packages/sdui-parser/src, so any parser or manifest change lands in both repos.
- Reach: 0 non-test
element:number authoring sites in objectui examples and apps, and 0 in objectstack examples (git grep on origin/main, with element:text as the lit control). The producer at risk is AI page authoring, which is not measured.
- The same answer decides
element:record_picker (object or binding) and the calendar and gantt record source of objectui#10508 (one of data / staticData / objectName).
Options, on the four axes:
- A (recommended). Keep the runtime notice (PR objectui#10989), and add no authoring-time check.
- Business need: 0 measured authoring sites.
- Long-term: no new contract. The author sees the notice when the page renders, not at save, which is later than before PR objectui#10944.
- AI-error: the mistake is visible, not silent, but nothing refuses it at publish.
- Startup focus: no new surface and no new gate.
- B. A parser-local per-tag rule in
validateTree, like checkKanbanQuickAdd and checkDashboardWidgetOptions.
- Business need: the same as A.
- Long-term: one hard-coded arm per one-of family (
element:number, record_picker, calendar, gantt), each a two-repo lockstep change. This is the workaround shape.
- AI-error: a loud refusal on both JSX doors once ported.
- Startup focus: a new gate no maintainer has named, so the default is no.
- C. One new manifest input-model construct: a component-level required-one-of list that can name a nested path such as
dataSource.object. It is serialized into sdui.manifest.json, read by validateTree in both repos, and declared by the four families.
- Business need: the same as A.
- Long-term: the contract-first shape. One declaration replaces N parser arms and restores the report objectui#10944 lost.
- AI-error: the strongest, since what is declared is enforced at publish.
- Startup focus: it widens a published contract (
Clause-②: yes, the lockstep port, codegen and type readers) and adds a gate the maintainer has not named.
The seat recommends A. Nothing measured pulls for an authoring-time refusal, and a new gate or contract surface defaults to no until the maintainer names one. If the maintainer does want the refusal back, choose C over B: one contract-first construct covers all four families, where B repeats a parser arm per family in both repos.
After the decision: A closes this card with no code change. B or C each become a dispatchable card, and C also needs the objectstack lockstep port.
domain:ui seat 2 · decision card · 2026-09-28
Ruled: 5872049943 · letter A (no authoring-time one-of report; runtime notice via PR #10989 is the answer; card closed) · 2026-09-28T14:30Z
维护者速读 · decision: restore an authoring-time report for "one of two ways to name the object"? ·
domain:uiseat 2 · 2026-09-28Filed by
domain:uiseat 2,session_014mXUNuFomfj24w7s1pZzhN. Triage5869415559on objectui#10951 routes it here: "(b) only if the manifest can already say one-of … It cannot: ⛔ don't invent a manifest construct here. Stop and report it asneeds_decision; objectui#10508's calendar and gantt trade would ride on the same answer." objectui#10951's runtime half (a) is in PR objectui#10989: anelement:numberwith anaggregateand no object now shows a localized "no object named" notice instead of a silent "—". This card carries only the authoring-time half.The question. PR objectui#10944 made
element:numberaccept its object fromdataSource.object, soobjectstopped beingrequired. Before that, the html tier (validateTree: the JSX page compiler, the save gate and the objectstack CLI's JSX gate) reported a node with no object. Should a node that names neither be reported at authoring time again?Measured (dev report
5871269526on objectui#10951):ManifestInputcarries onlyname/type/of/required/enum/binding/description.validateTree's presence rule isif (input.required && !(input.name in node)), and its per-tag checks are hard-coded in the parser, not registration hooks.packages/sdui-parser/src, so any parser or manifest change lands in both repos.element:numberauthoring sites in objectui examples and apps, and 0 in objectstack examples (git greponorigin/main, withelement:textas the lit control). The producer at risk is AI page authoring, which is not measured.element:record_picker(object or binding) and the calendar and gantt record source of objectui#10508 (one ofdata/staticData/objectName).Options, on the four axes:
validateTree, likecheckKanbanQuickAddandcheckDashboardWidgetOptions.element:number,record_picker, calendar, gantt), each a two-repo lockstep change. This is the workaround shape.dataSource.object. It is serialized intosdui.manifest.json, read byvalidateTreein both repos, and declared by the four families.Clause-②: yes, the lockstep port, codegen and type readers) and adds a gate the maintainer has not named.The seat recommends A. Nothing measured pulls for an authoring-time refusal, and a new gate or contract surface defaults to no until the maintainer names one. If the maintainer does want the refusal back, choose C over B: one contract-first construct covers all four families, where B repeats a parser arm per family in both repos.
After the decision: A closes this card with no code change. B or C each become a dispatchable card, and C also needs the objectstack lockstep port.
domain:uiseat 2 · decision card · 2026-09-28