You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 3ac9125
Browse filesBrowse the repository at this point in the historyBrowse files
fix(spec): re-measure the six #20371 rows at objectui dd3f7e1be and declare objectName
The objectui pin moved from f8a9d0fb0596 to dd3f7e1be356. Every read
point the action:* and element:* rows cite was re-derived at the new
pin and re-anchored; the asserting citations now name dd3f7e1be.
The new pin forwards `objectName` to the action runner from
action:button and action:icon, so both rows declare it (the ActionDef
string scalar, per the #7751 value posture). action:group and
action:menu forward it per member, so the container rows gain no key.
`params` keeps its meaning on the page path (array = input list,
object = static values via properties.params).
The dogfood expression-conformance rows for these keys are re-anchored
at the same pin; their fault policies are unchanged across the hop.
Claude-Session: https://claude.ai/code/session_01B3TqpoQbTAfG7G74GMDWNW
Co-authored-by: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: .changeset/20371-component-props-action-element-rows.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,7 +15,7 @@ What changes at the authoring doors (`os validate` / `os build` / `os lint`):
15
15
16
16
Measured decisions worth knowing when you author these blocks:
17
17
18
-
-**`action:button` / `action:icon`** — `name` is optional (the renderer reads `name ?? label`). The executor is `actionType`; `type` inside `properties` is refused with a rename to `actionType` (on a page component `type` is the component itself). `visible` / `disabled` take a boolean, a CEL string or a `{ dialect, source }` envelope. The legacy `enabled` fallback and the host-only `autoTrigger` flag are refused with a prescription. `action:icon` reads no `size`.
19
-
-**`action:group` / `action:menu`** — `actions` is a LIST of action objects (a member's executor is its own `type`); a bare list of action names is refused. `action:group` reads no group-level `name`, so it is refused with a prescription. `variant` / `size` take the Button primitive's vocabulary; `primary` and `md` are accepted only on `action:button` (and `primary` on `action:icon`), where the renderer maps them.
18
+
-**`action:button` / `action:icon`** — `name` is optional (the renderer reads `name ?? label`). The executor is `actionType`; `type` inside `properties` is refused with a rename to `actionType` (on a page component `type` is the component itself). `visible` / `disabled` take a boolean, a CEL string or a `{ dialect, source }` envelope. The legacy `enabled` fallback and the host-only `autoTrigger` flag are refused with a prescription. `action:icon` reads no `size`.`objectName` names the object the action acts on (forwarded to the runner; omitted, the action acts on the page's object).
19
+
-**`action:group` / `action:menu`** — `actions` is a LIST of action objects (a member's executor is its own `type`); a bare list of action names is refused. A member's `objectName` rides the member object; the containers themselves read no `objectName`. `action:group` reads no group-level `name`, so it is refused with a prescription. `variant` / `size` take the Button primitive's vocabulary; `primary` and `md` are accepted only on `action:button` (and `primary` on `action:icon`), where the renderer maps them.
20
20
-**`element:definition-list`** — `items` of strict `{ term, description? }`; `columns` is the NUMBER `1` or `2` (the string `'2'` renders one column and is refused).
21
21
-**`element:repeater`** — `object` is required; `filter` / `sort` take the family's one orthography (`ViewFilterRule[]`, `SortItem[]`); `fields` takes a field name or `{ field }` (an unrendered `label` is refused).
'BUILD-TIME GATE, measured here: lint/page-envelope-audit.ts door 3 parses `ComponentPropsMap["action:button" | "action:menu"]`, the one door that reaches `properties.visible`. EVALUATOR, two legs: (1) SchemaRenderer node gate `evaluateVisibilityPredicate` on the hoisted value, page scope — a fault there answers `evaluateCondition`\'s fail-soft `true` (shown) and is REPORTED in every build; (2) the renderer\'s own `useCondition(toPredicateInput(schema.visible), recordData, { throwOnError: true })` (action-button.tsx:116-119, action-menu.tsx:219-222) against the host-bound row — a fault returns `false` and warns once per predicate (useExpression.ts:215-238), and the block returns null (action-button.tsx:298, action-menu.tsx:293). The legs AND, so a faulting predicate HIDES the block: fail-CLOSED, the face `cel-action-visible` records for a registered action',
416
+
'BUILD-TIME GATE, measured here: lint/page-envelope-audit.ts door 3 parses `ComponentPropsMap["action:button" | "action:menu"]`, the one door that reaches `properties.visible`. EVALUATOR, two legs: (1) SchemaRenderer node gate `evaluateVisibilityPredicate` on the hoisted value, page scope — a fault there answers `evaluateCondition`\'s fail-soft `true` (shown) and is REPORTED in every build; (2) the renderer\'s own `useCondition(toPredicateInput(schema.visible), recordData, { throwOnError: true })` (action-button.tsx:117-120, action-menu.tsx:224-227) against the host-bound row — a fault returns `false` and warns once per predicate (useExpression.ts:215-238), and the block returns null (action-button.tsx:335, action-menu.tsx:322). The legs AND, so a faulting predicate HIDES the block: fail-CLOSED, the face `cel-action-visible` records for a registered action',
'BUILD-TIME GATE, measured here: lint/page-envelope-audit.ts door 3 parses `ComponentPropsMap["action:icon" | "action:group"]`. EVALUATOR, two legs: (1) SchemaRenderer node gate `evaluateVisibilityPredicate` on the hoisted value — a fault answers the fail-soft `true` (shown) and is REPORTED in every build; (2) the renderer\'s own `useCondition(toPredicateInput(schema.visible), recordData)` WITHOUT `throwOnError` (action-icon.tsx:96, action-group.tsx:233) — a fault answers `evaluateCondition`\'s fail-soft `true` as well (ExpressionEvaluator.ts:387-408), and action-icon.tsx:197-199 names that policy "fail-soft, unlike `action:button`\'s fail-closed one". Both legs show, so a faulting predicate leaves the block RENDERED, and the node gate is the leg that logs it: fail-SOFT-LOG',
428
+
'BUILD-TIME GATE, measured here: lint/page-envelope-audit.ts door 3 parses `ComponentPropsMap["action:icon" | "action:group"]`. EVALUATOR, two legs: (1) SchemaRenderer node gate `evaluateVisibilityPredicate` on the hoisted value — a fault answers the fail-soft `true` (shown) and is REPORTED in every build; (2) the renderer\'s own `useCondition(toPredicateInput(schema.visible), recordData)` WITHOUT `throwOnError` (action-icon.tsx:97, action-group.tsx:238) — a fault answers `evaluateCondition`\'s fail-soft `true` as well (ExpressionEvaluator.ts:387-408), and action-icon.tsx:219-221 names that policy "fail-soft, unlike `action:button`\'s fail-closed one". Both legs show, so a faulting predicate leaves the block RENDERED, and the node gate is the leg that logs it: fail-SOFT-LOG',
note: 'The opposite fault face to `cel-action-block-visible-closed` on the same key, which is why the two do not share a row. The `-log` half rests on the node gate\'s report; the renderer leg itself is silent for a bare string and warns only on the `{dialect:"cel"}` route. A literal `false` on `action:group` is honoured by the node gate, not by the renderer, whose `:306` check is a truthiness test. Same bare-string limit as `cel-action-block-visible-closed`. ⛔ NOT MEASURED HERE: the renderers were read at the pin, not run.',
433
+
note: 'The opposite fault face to `cel-action-block-visible-closed` on the same key, which is why the two do not share a row. The `-log` half rests on the node gate\'s report; the renderer leg itself is silent for a bare string and warns only on the `{dialect:"cel"}` route. A literal `false` on `action:group` is honoured by the node gate, not by the renderer, whose `:343` check is a truthiness test. Same bare-string limit as `cel-action-block-visible-closed`. ⛔ NOT MEASURED HERE: the renderers were read at the pin, not run.',
432
434
},
433
435
{
434
436
id: 'cel-action-block-disabled',
435
437
summary: '`action:button` / `action:icon` page-block disabling (props `disabled`) — the button stays on screen and cannot be pressed while the predicate is TRUE',
'BUILD-TIME GATE, measured here: lint/page-envelope-audit.ts door 3 parses `ComponentPropsMap["action:button" | "action:icon"]`. EVALUATOR, two legs, both un-negated: (1) SchemaRenderer node gate `evaluateEnablementPredicate` on the hoisted `disabled` (SchemaRenderer.tsx:1772-1784), forwarded as the `disabled` prop — a fault answers `evaluateCondition`\'s fail-soft `true`, which on this leg means GREYED OUT, and is REPORTED in every build (SchemaRenderer.tsx:1138-1165); (2) the renderer\'s own `useCondition(toPredicateInput(schema.disabled), recordData)` (action-button.tsx:129 + :333-339, action-icon.tsx:101 + :235-241), the same `true` on a fault. The legs OR, so a faulting predicate leaves the button DISABLED: the action is refused, fail-CLOSED',
440
+
'BUILD-TIME GATE, measured here: lint/page-envelope-audit.ts door 3 parses `ComponentPropsMap["action:button" | "action:icon"]`. EVALUATOR, two legs, both un-negated: (1) SchemaRenderer node gate `evaluateEnablementPredicate` on the hoisted `disabled` (SchemaRenderer.tsx:1879-1891), forwarded as the `disabled` prop — a fault answers `evaluateCondition`\'s fail-soft `true`, which on this leg means GREYED OUT, and is REPORTED in every build (SchemaRenderer.tsx:1247-1274); (2) the renderer\'s own `useCondition(toPredicateInput(schema.disabled), recordData)` (action-button.tsx:130 + :370-376, action-icon.tsx:102 + :257-263), the same `true` on a fault. The legs OR, so a faulting predicate leaves the button DISABLED: the action is refused, fail-CLOSED',
note: 'Deliberately NOT `fail-soft-log` like `cel-action-disabled`: the renderers measured here answer a faulting `disabled` with `true`, and on an un-negated enablement leg that `true` greys the control out — SchemaRenderer.tsx:1149-1156 states exactly that asymmetry ("on the negated visibility legs that means SHOWN, here it means GREYED OUT"). The objectui fix `cel-action-disabled` cites is about an EMPTY `disabled: \'\'`, which `hasDeclaredVisibilityGate` / `hasDeclaredPredicate` now treat as no gate, not about a faulting one. ⚠️ Scope consequence worth knowing: the node-gate leg evaluates at PAGE scope, so a row-scoped `record.*` predicate that does not resolve there faults and greys the button out whatever the row says. Same bare-string limit as `cel-action-block-visible-closed`. ⛔ NOT MEASURED HERE: the renderers were read at the pin, not run.',
445
+
note: 'Deliberately NOT `fail-soft-log` like `cel-action-disabled`: the renderers measured here answer a faulting `disabled` with `true`, and on an un-negated enablement leg that `true` greys the control out — SchemaRenderer.tsx:1258-1265 states exactly that asymmetry ("on the negated visibility legs that means SHOWN, here it means GREYED OUT"). The objectui fix `cel-action-disabled` cites is about an EMPTY `disabled: \'\'`, which `hasDeclaredVisibilityGate` / `hasDeclaredPredicate` now treat as no gate, not about a faulting one. ⚠️ Scope consequence worth knowing: the node-gate leg evaluates at PAGE scope, so a row-scoped `record.*` predicate that does not resolve there faults and greys the button out whatever the row says. Same bare-string limit as `cel-action-block-visible-closed`. ⛔ NOT MEASURED HERE: the renderers were read at the pin, not run.',
0 commit comments