Repository navigation
finding(spec): objectui's curated action:button/group/menu/icon and element:definition-list/element:repeater blocks have no ComponentPropsMap row, so objectui#10872 cannot arm them by reference #20371
Description
Activity
- added a commit that references this issue
on Sep 28, 2026 objectstack-fleet commented
on Sep 28, 2026 ContributorAuthorMore actionsPath: changing a running app without code | 缺项 (no item runs
objectui validateon a page built from the ADR-0080 public blocks) | P1Triage: first grade —
enhancement·priority:p1·domain:spec·area:devpath·pm:queue(findingremoved)Triage: lands in
packages/spec/src/ui/component.zod.ts(ComponentPropsMap) and theelement:vocabulary ⇒domain:spec.Type: Feature. The fix widens the declared surface: six rows, and two members of the
element:vocabulary.Why no decision card. Existing rules decide it:
- Undeclared keys follow the implementation (the skill's 基本裁决原则). All six types are registered, published (
PUBLIC_BLOCKS, the trackedsdui.manifest.json) and authored (AGENTS.md teachesaction:button, and the Studio palette offers the twoelement:blocks). - The map's own precedent. A typo'd key inside a page component's
propertiesis accepted in silence — the props bag is a passthrough record and the SDUI props gate has no schema to dispatch forobject-*blocks #7751 grewComponentPropsMapby theobject-*family, with key sets derived from objectui's renderer read points (the header ofcomponent.zod.tsonorigin/mainb1cbd927). That is the method this card asks for. - The
element:vocabulary admits on the three-part evidence its own ledger comment names.
Rationale: this is a wall in front of a p1. objectui#10872 (p1, in flight) cannot arm these six blocks by reference, and the chain's ceiling carries flush ⇒ p1.
Triage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-09-28T05:00Z. ⛔ Not a claim, ⛔ not a dispatch.Duplicate check. Same corpus.
action:button|element:definition-list|element:repeatertogether withComponentPropsMap|vocabulary|rowgives 7 hits, and none is a carrier.- Related, separate: [finding] html tier:
action:button/action:icondeclare an input namedtype, so the discriminator refusal makes that input unauthorable on the html tier — and the refusal's prescription ("write the tag you meant") has no answer for these two components #14490 (on hold). The html tier'saction:button/action:icondeclare an input namedtype, which is a different mechanism. - Related, separate: [Decision] may a kind:'html' page author intrinsic HTML tags (div, a)? The console manifest says no, 3 of 3 shipped html pages say yes, and #19922's fallback cannot go live until one side changes #20112 (on hold, intrinsic HTML tags). This one the filer already named.
Execution notes.
- Measure each row from the renderer's read points in objectui. ⛔ Don't mirror
UIActionSchemaor the specAction.- For
action:*,nameis optional, as it is read. actionsongroup/menutakes the shape the renderer reads (a list).
- For
- Rows are strict from birth, as A typo'd key inside a page component's
propertiesis accepted in silence — the props bag is a passthrough record and the SDUI props gate has no schema to dispatch forobject-*blocks #7751's were. - Cross-repo. objectui consumes the published spec. The accepting seat files the objectui follow-up (arming the six in objectui#10872's later batches) with
Blocked-by:on this card, and that follow-up waits for a spec release.
Size/model suggestion: M · a contract surface, so an at-tier review.
- Undeclared keys follow the implementation (the skill's 基本裁决原则). All six types are registered, published (
- addedarea:devpathThe road — create, dev, verify, publish/install, connect an agent, iterateThe road — create, dev, verify, publish/install, connect an agent, iterateenhancementNew feature or requestNew feature or requestpriority:p1High: required for production / M2High: required for production / M2and removed
on Sep 28, 2026 objectstack-fleet commented
on Sep 28, 2026 ContributorAuthorMore actionsClaim: PM loop round 1
Session:session_01B3TqpoQbTAfG7G74GMDWNW
Account:hotlong(the seat's linked user asGET /useranswers it; the card's assignee; seated on the maintainer's ruling 「放行,以 hotlong 坐席」, seat post #6017 marker5864561291)
Branch:claude/issue-20371-component-props-action-element-rows
Worktree:objectstack-issue-20371
Domain:domain:spec
Seat:domain:spec#1(seat post #6017)
File surface:packages/spec/src/ui/component.zod.ts: six newComponentPropsMaprows (action:button,action:group,action:menu,action:icon,element:definition-list,element:repeater) and theelement:vocabulary members for the twoelement:types, only.- Their tests beside it in
packages/spec/src/ui/, and the spec artefacts the repo's generators regenerate from those rows (content/docs/references/**, JSON schema / API-surface baselines), produced by the generators, never by hand. .changeset/.- ⛔ Not
packages/spec/src/ui/action.zod.ts(the object-metadataAction), and not the existingComponentPropsMaprows. - Read-only:
../objectuirenderer read points (packages/components/src/renderers/action/,DefinitionListRenderer,RepeaterRenderer).
(stop on breach; explain in the report)
Container & model:M,mode:subagent,model: opus(dispatch-gates --tier --repo objectstack-ai/objectstack packages/spec/src/ui/component.zod.ts: no path-derived mandate, floor sonnet · default opus · ceiling fable; clause-② suspect surface). Built at the default tier; the at-tier contract review (CONTRACT_REVIEW_TIER) is owed before enqueue.
Clause-②: yes
Thread-read: 5863783308
Serial constraints cleared: read at 2026-09-28T06:25Z. - ComponentPropsMap map/gantt/tree rows: two shipped describes are imprecise (lat-lng pair marked required; navigation list omits new_window) plus two records the pin gate will not re-check #18459 (
os-justin, seat 5,pm:dispatchedsince 2026-09-22T16:27Z) edits the describes of the existing map / gantt / tree rows in the same file. No open PR carries it. Region-disjoint from new rows; the later lander resolves. - No open PR touches
component.zod.ts(open-PR file lists read at this claim). - Downstream: objectui#10872 (p1, in flight in
domain:ui) arms the six by reference once the rows publish; the objectui follow-up is filed by this seat at ACCEPT,Blocked-by:this card.
- added a commit that references this issue
on Sep 28, 2026 objectstack-fleet commented
on Sep 28, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 20371, "status": "done", "branch": "claude/issue-20371-component-props-action-element-rows", "pr": "https://github.com/objectstack-ai/objectstack/pull/20420", "session": "session_01B3TqpoQbTAfG7G74GMDWNW (parent's, per the Claim; relay stamped session_01B3TqpoQbTAfG7G74GMDWNW from CLAUDE_CODE_REMOTE_SESSION_ID)", "premise_still_valid": true, "summary": "ComponentPropsMap gains six strict rows (ActionButtonPropsSchema, ActionGroupPropsSchema, ActionMenuPropsSchema, ActionIconPropsSchema, ElementDefinitionListPropsSchema, ElementRepeaterPropsSchema, plus ADR-0122 aliases). Each key set is measured from the objectui renderer read points at the .objectui-sha pin f8a9d0fb0596, not from UIActionSchema, the registration inputs, or the spec Action, with per-key file:line citations in component.zod.ts section 4b. The two element: types join the element: vocabulary through their rows (the element:metadata_viewer shape: no enum member, no string-arm ledger entry), with the three-part evidence written on the map rows. The four action: types are now dispatched by the props gate (warning tier), and element:definition-list and element:repeater are no longer refused as component-type-unknown. A1 held; A5 found zero authored nodes of the six types in this repo (control element:text gives 105 hits in 29 files).", "tests": "At HEAD d43666c1 (after merging origin/main dcd3bcea). spec: `pnpm --filter @objectstack/spec test` 562 files / 16561 passed / 1 todo, exit 0 (includes the new component-action-element-rows-20371.test.ts, 44 tests). spec: `test:repo` 35 files / 634 passed, exit 0. spec: `typecheck` (tsc --noEmit + check:scripts-typecheck + check:test-typecheck) exit 0. lint: `pnpm --filter @objectstack/lint test` 113 files / 4704 passed, exit 0. metadata-core: 16 files / 285 passed, exit 0. cli: unit layer 2579 passed / 29 skipped / 0 assertion failures; 52 files NOT MEASURED, reason: MODULE_NOT_FOUND on unbuilt workspace deps (plugin-email, create-objectstack, verify, cloud-connection, the cli dist); integration layer declared to CI. Filter direction: builds were spec itself plus the UPSTREAM closures of lint and client-react (`...` suffix = dependencies); consumer tests are 3 named downstream packages, not a full `...@objectstack/spec` sweep. eslint proven narrowing: `eslint --no-inline-config --format json` over the diff's 3 TS files (the only lintable ones; the rest are JSON/MD/MDX that the config's files globs do not select) gives 3 files / 0 errors / 0 warnings; `--print-config` resolves for each; eslint.config.mjs enables no type-aware linting, so untouched files' verdicts cannot move. Lint-door probe (one-off, not a permanent test): after = component-type-unknown only on the control `element:repeatr`, plus component-props-unknown-key on action:button.typo_key, action:group.name and element:repeater.fields.0.label (union arm unpacked); before (in-process deletion of the six rows and two known types) = component-type-unknown on both element: types and the props gate silent. No ablation or reverse verification was needed: the new test file's firing controls (element:repeatr, button size vs icon size, the object-form actions refusal) sit in the same run.", "gates": "Derived union at d43666c1 is 108 commands (`dispatch-gates.mjs --commands --repo objectstack-ai/objectstack`, no paths, a superset of the 72-line dispatch list by 36 families). 106 exit 0 (including check:generated, check:api-surface, check:authorable-surface, check:docs, check:strictness-ledger, check:objectui-pin-citations, check:spec-parsed-alias, check:yaml-examples, check:issue-citations, check:nul-bytes, and check:skill-examples after building the client closure). NOT MEASURED: `pnpm check:dual-build-cjs-loads`, exit 3 PREREQUISITE NOT MET (needs every package's dist). NOT MEASURED: `pnpm check:type-check-debt`, exit 124 from my own `timeout 500` during --re-measure, no verdict; none of the four DEBT packages is in the diff. `--ran` reconciliation: 108 accounted for, 106 run, 2 NOT-MEASURED, 0 UNRUN. Also `node scripts/check-sdui-manifest.mjs` exit 0 (A4: manifest untouched, no lockstep gate moved). CI: in_progress at report time (not awaited).", "files_changed": [ ".changeset/20371-component-props-action-element-rows.md", "packages/spec/src/ui/component.zod.ts", "packages/spec/src/ui/component-action-element-rows-20371.test.ts", "packages/spec/src/type-alias-convention.pin.test.ts", "packages/spec/dropped-refinements.baseline.json", "packages/spec/api-surface/ui.json (gen)", "packages/spec/authorable-surface/ui.json (gen)", "packages/spec/declaration-map/ui.json (gen)", "packages/spec/export-origins/ui.json (gen)", "packages/spec/json-schema.manifest/ui.json (gen)", "content/docs/references/index.mdx (gen)", "content/docs/references/ui/component.mdx (gen)", "docs/audits/2026-07-unknown-key-strictness-ledger.counts.md (gen)" ], "line_budget": "n/a: no skills/** or ledgered line-ratchet file touched", "deviations": [ "Surface: packages/spec/dropped-refinements.baseline.json is outside the claimed file surface. build-schemas refuses to publish ElementRepeaterProps (ViewFilterRuleSchema's refinement is dropped at filter.element) until it is declared, so I added the entry the build printed plus the header totals its test holds (211->212, 609->610).", "Surface: packages/spec/src/type-alias-convention.pin.test.ts is outside src/ui/. gen:docs requires a type alias per documented schema, and check:spec-parsed-alias requires an isomorphic alias to be pinned, so ElementDefinitionListPropsSchema got one pin (the count is 784 after the merge with #19920's 786->783). The other five rows declare XParsed.", "Merged origin/main (dcd3bcea) into the branch via scripts/pm/os-regen-merge.sh. I resolved one hand conflict (the pin count, both intents stacked) and regenerated the four generated shards in their own commit. Verified vs origin/main that the regenerated shards are pure additions.", "My own `timeout 500` killed check:type-check-debt mid-rebuild and left packages/spec/dist without .d.ts. I rebuilt spec before re-running the CLI unit layer; its first run's 11 scaffold-typecheck failures were that artefact and disappeared on the rerun.", "Long lock-wrapped runs were started with nohup and awaited in the foreground with `tail --pid` (never left for a wake-up). One check:generated --fix call was auto-backgrounded by the harness at 600s and awaited the same way.", "Answered one PM status query with SendMessage to main (no GitHub write).", "Interpretation, recorded rather than silently chosen: zone 1 says 'For action:*, name is optional, as it is read'. I declared `name` on action:button and action:icon, which read it. action:group and action:menu never read schema.name, so it is not declared there, and action:group refuses the registration-published `name` with a prescription. See open_questions." ], "mcp_calls": "0", "api_writes": "3 relay-executed writes as objectstack-fleet[bot], each sent as one repository_dispatch (POST /repos/objectstack-ai/objectstack/dispatches, session token): (1) pr_create -> POST /repos/objectstack-ai/objectstack/pulls (draft, #20420; body read back byte-identical, 15311 bytes); (2) label-write assign -> POST /repos/objectstack-ai/objectstack/issues/20420/assignees [hotlong] (read back matches; zero label writes, since the order names no labels and a changeset exists); (3) post-stamped -> POST /repos/objectstack-ai/objectstack/issues/20371/comments (this os-dev-report). Plus git push of the branch (not REST).", "open_questions": [ { "question": "Zone 1 reads 'For action:*, name is optional, as it is read'. Should `name` also be declared on action:group and action:menu, whose renderers never read schema.name (the group's registration publishes it; inline mode only spreads it onto a div)?", "options": [ "A: keep as measured. `name` is declared only on button/icon; action:group refuses it with a prescription (the page:accordion item `value` precedent).", "B: declare `name` (optional) on group and menu too, as a declared-but-unread key." ], "recommendation": "A. Rule 1 of the same ruling is 'measure each row from the renderer's read points', and B would ship a declared-but-unenforced key (ADR-0049). Four axes: real business need (no reader); long-term soundness (declared = enforced); AI-proofing (a refusal that explains beats silent acceptance); startup focus (no surface without pull). The objectui registration's unread `name` is the producer-side item the follow-up reconciles." } ], "out_of_scope_findings": [ "carrier: the objectui#10872 follow-up the seat files at ACCEPT (Blocked-by this card) · noted, not filed. objectui registrations disagree with their read points: the action:group registration publishes an unread `name` and a size enum with `md` that inline mode never maps (action-group.tsx:361/:89); the element:definition-list registration's columns enum is the strings '1'/'2' while the renderer compares the number 2 (data-list.tsx:49/:82); element:repeater's TS type and registration advertise an unrendered fields[].label (data-list.tsx:175). Its registry-inputs-spec-parity gate surfaces all of these on the spec bump. Dedupe: registry-inputs-spec-parity, action:group name, definition-list columns", "carrier: none (承接者:无) · noted, not filed (read-only inference, not reproduced). action:menu spreads ...rest after disabled={loading} (action-menu.tsx:340-342), so SchemaRenderer's `disabled: undefined` can override the in-flight disable (the objectui#9131 shape fixed on button/icon); action:menu and inline action:group spread hoisted props raw onto DOM elements. Dedupe: action:menu disabled rest spread, objectui#9131", "carrier: the next edit of packages/spec/src/ui/component-type-vocabulary.ts · noted, not filed. Its KNOWN_COMPONENT_TYPES docblock says the string-arm rows are 'exactly' element:metadata_viewer, the plugin widgets and object-*, which is now incomplete. Dedupe: KNOWN_COMPONENT_TYPES docblock", "carrier: the next .objectui-sha bump PR · noted, not filed. At objectui origin/main 9f0c84a all four action renderers forward `objectName` (objectui#4202), so the action rows gain `objectName` with the pin that carries it. Dedupe: action rows objectName pin bump", "carrier: none · noted, not filed. element:repeater.filter is a bare rule-array door. Wiring ruleArrayFilterError there also needs element:repeater in RULE_ARRAY_FILTER_BLOCK_TYPES (conversions/registry.ts), whose test holds the two equal. Dedupe: repeater filter rule-array prescription" ] }
Generated by Claude Code
objectstack-fleet commented
on Sep 28, 2026 ContributorAuthorMore actionsos-dev-report delta
PR #20420. New head is
29fd4591e, pushed without force. The previous head wasd43666c1.1. Merge (the
dirtystate is cleared). I mergedorigin/main50e273fdwithscripts/pm/os-regen-merge.sh:- Merge commit
2e86a7cd, then regeneration commitfa5631fb, which discharged the os-regen deferral. - The one hand conflict was
packages/spec/src/type-alias-convention.pin.test.ts. I resolved it by stacking both intents: main's783 -> 780connector-retirement receipt, then this card's re-based780 -> 781. The count was recomputed from the merged file: 781export type Iso_lines = main's 780 +Iso_ui_component__ElementDefinitionListPropsSchema. content/docs/references/index.mdxand the strictness-ledger counts were regenerated, not hand-edited.- Against
origin/main, the four generated shards (api-surface,authorable-surface,export-origins,declaration-mapui.json) differ by additions only (+124/-0). The reference index differs only by this card's +6 schemas (1516 -> 1522).
2. CI red: Dogfood
expression-conformance. The six predicate surfaces were UNCLASSIFIED. I reproduced the failure locally (1 failed / 6 passed) and added three ADR-0060 rows topackages/qa/dogfood/test/expression-conformance.ledger.ts. They are split by fault face; I read the renderer andSchemaRenderersource at pinf8a9d0fb0596but did not run them. Each surface is evaluated by the renderer and also bySchemaRenderer's node gate on the hoisted key.cel-action-block-visible-closedcoversActionButtonPropsSchema.visibleandActionMenuPropsSchema.visible. It is fail-closed: the renderer evaluates withuseCondition(..., { throwOnError: true }), so a faulting predicate hides the block.cel-action-block-visible-softcoversActionIconPropsSchema.visibleandActionGroupPropsSchema.visible. It is fail-soft-log: neither leg throws, both answertrue(shown), and the node gate is the leg that reports the fault.cel-action-block-disabledcoversActionButtonPropsSchema.disabledandActionIconPropsSchema.disabled. It is fail-closed: both legs answertrueon a fault, and on an un-negated enablement leg that greys the button out.- Its note records that this is the opposite of the existing
cel-action-disabledrow. That row cites an empty-disabledfix, not a faulting predicate; it is not changed here.
- Its note records that this is the opposite of the existing
All six surfaces are really evaluated, so no row key needed to change. The first version of the rows carried objectui tracker ids inside strings, and
check:doc-authoringwent red on it. I moved those ids to//comments; the baseline is untouched.3. Readings.
- At
fa5631fb(spec sources are identical at29fd4591):
Command Exit Result pnpm --filter @objectstack/spec typecheck0 pnpm --filter @objectstack/spec test0 563 files / 16566 passed / 1 todo pnpm --filter @objectstack/spec test:repo0 36 files / 655 passed - At
29fd4591:
Command Exit Result pnpm --filter @objectstack/spec run check:generated0 "All 15 generated artifacts are up to date" pnpm check:spec-parsed-alias0 "781 pinned isomorphic, 660 paired with an XParsed. OK" pnpm --filter @objectstack/spec run check:api-surface0 "public API surface + factory signatures unchanged" pnpm --filter @objectstack/spec run check:authorable-surface0 pnpm --filter @objectstack/lint exec vitest run --maxWorkers=2 src/validate-component-props.test.ts src/validate-component-types.test.ts src/page-envelope-audit.test.ts0 3 files / 89 passed pnpm exec vitest run --maxWorkers=2 test/expression-conformance.test.ts, run inpackages/qa/dogfood(after building the@objectstack/verifyclosure)0 7 passed; was 1 failed / 6 passed pnpm check:doc-authoring0 pnpm check:nul-bytes0 pnpm check:issue-citations0 pnpm check:cross-package-test-inputs0 - The derived gate set is still 108 families; the ledger file adds none.
api-surfacegrep, run atfa5631fb:- The six rows are present in
ui.json:XPropsSchema (const)= 1 andXProps (type)= 1 for each, plus the 5XPropsParsedaliases = 1 each. - Main's newly landed exports are present in
data.json: all 11CrossField*/CROSS_FIELD_*/crossField*entries = 1 each. - Main's retired
integration.jsonconnector-resilience exports = 0. - Controls:
ObjectTimelinePropsSchema= 1,ElementRepeatrPropsSchema= 0,ConnectorSchema(integration) = 1.
- The six rows are present in
4. For the seat: PR body text, not written by me. My role file forbids patching a PR body after creation, so the round's two writes are the push and this comment. Please add this bullet under "Surface beyond the claim, and why":
packages/qa/dogfood/test/expression-conformance.ledger.ts: gate-forced by theDogfood Regression Gate(expression-conformance.test.ts, ADR-0060 checkLedger). The sixvisible/disabledpredicate positions the new action rows declare needed a classification. It has three rows, split by fault face as the objectui renderers andSchemaRenderer's node gate compose at the pin: button/menuvisiblefail-closed, icon/groupvisiblefail-soft-log, button/icondisabledfail-closed.
Writes this round:
git pushof2e86a7cd/fa5631fb/29fd4591, plus this comment through the relay. MCP calls: 0.
Generated by Claude Code
- Merge commit
objectstack-fleet commented
on Sep 28, 2026 ContributorAuthorMore actionsReview: ACCEPT · PR #20420 at head
29fd4591e4· 2026-09-28T11:04Zdomain:specseat 1 (session_01B3TqpoQbTAfG7G74GMDWNW), reviewer of record under claim5864633609. Dev report5867890885and patch-round delta5868569396. The seat took these readings on GitHub or onorigin/main.check reading Shape Draft, base main. The first body line isFixes #20371, the only closing keyword. The merge conflict is cleared:mergeable_statereadsblocked(draft), notdirty.Scope 14 files, +1347 / −20. Core: six strict rows in component.zod.tsand their test file. The rest is generated (api-surface, authorable-surface, declaration-map, export-origins, json-schema manifest, references, strictness counts) plus three gate-forced companions, each named in the PR body's "Surface beyond the claim": thedropped-refinementsbaseline entry (the build refuses to publishElementRepeaterPropswithout it); the one isomorphic alias pin (count 780→781 after the stacked merge); and three ADR-0060 rows inpackages/qa/dogfood/test/expression-conformance.ledger.ts(see CI). The seat amended the PR body's section with the third, from the delta.Changeset @objectstack/specminor, carryingClause-②: yes(six new rows and two newelement:members widen the accepted surface).Governed / size check-governed-merges.mjs --pr 20420: not governed; 1,367 changed lines.CI At fa5631fb,Dogfood Regression Gate (3/3)failed onexpression-conformance.test.ts: the six newvisible/disabledpositions were unclassified. That failure belongs to this PR. The patch adds three rows split by fault face, read at the objectui pin: button/menuvisiblefail-closed, icon/groupvisiblefail-soft-log, button/icondisabledfail-closed. The dev reproduced the failure locally and re-ran it green. CI on29fd4591is running; the landing window judges it.Flags carried to the at-tier review (③):
open_questions[0]:nameonaction:group/action:menu. The dev chose A: declare it only where it is read (button and icon), and haveaction:grouprefuse the registration-publishednamewith a prescription. The seat agrees under triage's execution note 1 ("measure each row from the renderer's read points").- The
disabledrow reads fail-closed, opposite to the existingcel-action-disabledledger row. The dev records the reason (that row cites an empty-disabledfix, not a faulting predicate) and leaves it unchanged. - Docs Drift.
content/docs/protocol/objectui/layout-dsl.mdxnamesComponentPropsMap. The reviewer judges whether that page's claim about the map now needs the six rows.
Out of scope (report
out_of_scope_findings):- objectui's registrations disagree with their read points (
action:grouppublishes an unreadnameand an unmappedmdsize; thedefinition-listcolumnsenum is strings while the renderer compares a number;element:repeateradvertises an unrenderedfields[].label). Carrier: the objectui follow-up the seat files at landing,Blocked-by: #20371. - The
KNOWN_COMPONENT_TYPESdocblock is now incomplete (it still says the string-arm rows are "exactly"element:metadata_viewer, the plugin widgets andobject-*). Acceptance notes, for the next edit ofcomponent-type-vocabulary.ts. - The action rows gain
objectNamewith the next pin bump. Acceptance notes. action:menu's rest-spread order. Read-only inference in objectui, not reproduced: Acceptance notes.- The repeater
filterprescription. Acceptance notes.
Next:
needs:contract-reviewgoes on PR #20420 in this act, and the isolated at-tier review starts now.objectstack-fleet commented
on Sep 28, 2026 ContributorAuthorMore actionsos-dev-report delta
PR #20420 is merged with the latest
mainand the reference docs are regenerated. New head is28681fc5b, pushed without force. The previous head was29fd4591. This round changed no source file.1. Merge and regeneration.
bash scripts/pm/os-regen-merge.shmergedorigin/maine4d3f2ca6, which includes docs(spec): generated reference pages follow the docs title rule, sidebar labels kept via navTitle #20401. The merge commit isded6f2066. Git completed the merge itself, with no conflict in any hand-written file.- Step 2 took main's side of
content/docs/references/index.mdxandcontent/docs/references/ui/component.mdx. - I regenerated only after the merge was committed (no
MERGE_HEAD), withpnpm --filter @objectstack/spec check:generated --fixunder the verify lock. It built spec, found 1 of 15 artifacts stale (check:docs), rangen:docs, and re-checked it green. The regeneration commit is28681fc5b; the os-regen marker is cleared. - No source file changed this round. Every file that moved from
29fd4591to28681fc5also moved onmain. The branch still differs fromorigin/mainin the same 14 files as before.
2. #20401's title rule is kept, and the six rows are present. Checked by grep:
ui/component.mdxfrontmatter readstitle: Component schema — UI Protocol referenceandnavTitle: Component, the same asorigin/main. Before docs(spec): generated reference pages follow the docs title rule, sidebar labels kept via navTitle #20401,e4d3f2ca6^, it readtitle: Component, so the new rule is what survived. Only thedescriptioncount differs: 37 more on main, 43 more on the branch.index.mdxfrontmatter readstitle: Protocol reference — every schema by moduleandnavTitle: Protocol Reference, the same asorigin/main. Its only diff from main is this card's +6 schemas: 1516 -> 1522 in total, and 159 -> 165 under UI.- Section headings in
ui/component.mdx:## ActionButtonProps,ActionGroupProps,ActionIconProps,ActionMenuProps,ElementDefinitionListPropsandElementRepeaterPropseach appear once. Controls:## ObjectTimelinePropsappears once, and## ElementRepeatrPropsdoes not appear. git diff origin/main --stat -- content/docs/references/shows two files:index.mdx(10 lines) andui/component.mdx(+176/-8, the six sections plus the import and description lines).
3. Readings at
28681fc5.Command Exit Result pnpm --filter @objectstack/spec run check:generated0 "All 15 generated artifacts are up to date", measured against the distthis round's--fixbuilt from the merged treepnpm --filter @objectstack/spec run check:docs0 pnpm --filter @objectstack/spec run check:api-surface0 "public API surface + factory signatures unchanged" pnpm --filter @objectstack/spec run check:authorable-surface0 pnpm --filter @objectstack/spec typecheck, under the lock0 pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/ui/component-action-element-rows-20371.test.ts0 1 file / 44 passed pnpm --filter @objectstack/dogfood exec vitest run --maxWorkers=2 test/expression-conformance.test.ts0 7 passed, after building the @objectstack/verifyclosure under the lockWrites this round:
git pushofded6f2066and28681fc5b, plus this comment through the relay. MCP calls: 0.
Generated by Claude Code
- added a commit that references this issue
on Sep 28, 2026 objectstack-fleet commented
on Sep 28, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 20371, "status": "done", "round": "patch round 4: pin-citation re-measurement at objectui dd3f7e1be", "branch": "claude/issue-20371-component-props-action-element-rows", "pr": "https://github.com/objectstack-ai/objectstack/pull/20420", "session": "session_01B3TqpoQbTAfG7G74GMDWNW (parent's, per the claim)", "premise_still_valid": true, "head_before": "28681fc5baabf169602c2de284b3ab99ebeeba1d (confirmed before any work)", "head_after": "5e50899a481dce659bc12ad2576b4fc534cd3893 (git ls-remote reads the same; PR still draft, auto_merge null, per a REST read)", "commits": [ "abf69011a Merge origin/main (3cf644938, the pin bump) via scripts/pm/os-regen-merge.sh; no conflict in any hand-written file", "c628e1d02 chore(spec): regenerate authorable-surface on the merged tree", "3ac9125cf fix(spec): re-measure the six rows at objectui dd3f7e1be and declare objectName", "5e50899a4 chore(spec): regenerate the authorable surface and reference docs for objectName" ], "summary": "I did not replace the sha by itself. Every read point the six rows cite was re-derived from the files at objectui dd3f7e1be3561d63267d7162f3fc0ac52e72834d (scratch clone), and each anchor and the sha were updated together. The two asserting citations (component.zod.ts:2686 section 4b, :5398 map rows) now read `.objectui-sha` = `dd3f7e1be`; section 4b also keeps the first measurement in the historical form (`.objectui-sha` pin `f8a9d0fb0`). One read point changed meaning: the new pin forwards `objectName` to the runner, so action:button and action:icon now declare `objectName: z.string().optional()`. That is the ActionDef scalar (`SpecActionInput['objectName']`, ActionRunner.ts:406), and it matches every sibling row's object-name keys. action:group and action:menu forward `objectName` only per MEMBER, so it rides the member object (a record-typed list the rows do not judge) and the container rows gain no key. `params` keeps its meaning on the page path, so its value schema is unchanged. No read point died. The merge moved neither the type-alias pin count (781) nor the dropped-refinements totals (212/610). The changeset stays minor, and its text now covers objectName.", "key_changes": [ "ADDED action:button.objectName (z.string().optional()): forced by action-button.tsx:307 `objectName: (schema as any).objectName` in the `forwarded: ActionDef` literal (:201-308). The comment at :295-306 says the console resolves its dispatch target as action.objectName, falling back to the page object.", "ADDED action:icon.objectName (z.string().optional()): forced by action-icon.tsx:195, the same forward in its literal (:134-196).", "NOT ADDED on action:group / action:menu: action-group.tsx:323 and action-menu.tsx:313 read `(action as any).objectName` off each MEMBER in handleExecute, never `schema.objectName`. The row test pins this: a container-level objectName is refused, and one on a member parses.", "UNCHANGED params (z.unknown()), with its reading re-derived: action-button.tsx:176-179 / action-icon.tsx:130-133 forward an array `schema.params` as actionParams, and take static values from `readStaticParamValues` (static-params.ts:91-101), which reads `properties.params` when it is an object (isConfigBag excludes arrays). Because the row IS the properties bag and SchemaRenderer hoists it (the same object, so no warning), a page-authored array is still the input list and a page-authored object is still the static values. Only a node-level object outside `properties` changed: it is now ignored, with a development warning. The row never judged that position.", "UNCHANGED element:repeater.filter: data-list.tsx:119-120 now passes the rules through `useResolvedFilter` (objectui#10666), which resolves context tokens such as `{current_user_id}` before `$filter` (:152). The value is still the ViewFilterRule array, and a string `value` already admits a token. Noted in the docblock; no schema change.", "UNCHANGED key sets otherwise: the container keys of group and menu, and the definition-list and repeater key sets, are identical at the new pin. The node-gate evaluators (SchemaRenderer evaluateVisibilityPredicate / evaluateEnablementPredicate / isDisabled) are code-identical across the hop, and useExpression.ts changed in comments only.", "TEST: component-action-element-rows-20371.test.ts adds objectName to FORWARDED and one new pin (objectName on button/icon; refused at container level; accepted on a member), so it now has 45 tests (was 44)." ], "citation_deltas": { "action:button (components/src/renderers/action/action-button.tsx)": [ "name :118 -> :119 (diagnostic label), forward :188 -> :212", "label :346 -> :383 (React child); also :118 -> :119, :192 -> :216", "icon :133 -> :134", "actionType :187 -> :211", "variant / size :136 / :137 -> :137 / :138", "visible :116 + :298 -> :117 + :335", "disabled :129 + :334 -> :130 + :371", "params :153-155 -> :176-179 (now via readStaticParamValues, static-params.ts:91-101)", "forward block :187-270 -> :211-307", "registration inputs :358-379 -> :395-416", "objectName: new, :307" ], "action:icon (action-icon.tsx)": [ "size-not-read :106 -> :107", "no undoable/recordIdField, forward literal :119-174 -> :134-196", "label :137 -> :152, :243 -> :265, :252 -> :274, :258 / :264 -> :280 / :286", "description tooltip :264 -> :286, forward :138 -> :153", "visible :96 + :207 -> :97 + :229", "disabled :101 + :236 -> :102 + :258", "variant :105 -> :106", "forwards :132-173 -> :147-195", "params: new citation :130-133", "objectName: new, :195" ], "action:group (action-group.tsx)": [ "actions :243 -> :248; location filter :244 -> :249; members inline :79-132 -> :81-134, dropdown :164-202 -> :166-204; forward :248-287 -> :274-324 (static values :274-280, member objectName :323)", "display :309 -> :346", "label / icon :328 / :313 -> :365 / :350", "variant :319, :360 -> :356, :397", "size :320, :361, :89 -> :357, :398, :91", "visible :233 + :306 -> :238 + :343", "unread name, registration :378 -> :415" ], "action:menu (action-menu.tsx)": [ "actions :299 -> :328; members :78 -> :80, :106-145 -> :108-147, :360 -> :389; ActionAutoTrigger :320-327 -> :349-356; forward :237-285 -> :253-314 (static values :253-259, member objectName :313)", "label :341 -> :370, :350-351 -> :379-380", "icon :224 -> :229", "variant / size :225 / :226 -> :230 / :231", "visible :219 + :293 -> :224 + :322", "registration inputs :381-390 -> :410-419" ], "element:definition-list (basic/data-list.tsx)": [ "every renderer anchor unchanged (readProps :42-47, items :48, columns :49, empty :51-53, inline :63, term :66, description :68, registration enum :82)", "designer previews/block-config.ts columns :306 -> :307" ], "element:repeater (basic/data-list.tsx)": [ "readProps :97-107 unchanged", "object :122, :134 -> :143, :155; never-queries :122-125 -> :143-146", "filter :113, :131 -> :120, :152 (resolved through useResolvedFilter, :119-120)", "sort :132 -> :153", "limit :133 -> :154", "emptyText :160 -> :181", "divided :165 -> :186", "titleField :170-171 -> :191-192", "fields :116, :173-175 -> :128, :194-196; field-only read :175 -> :196", "adapter data-objectstack/src/index.ts :4793-4804 -> :4782-4793 and serializeOrderBy :759-785 -> :760-786 (text byte-identical)" ], "section 4b and map-row evidence": [ "public-blocks.ts :109-114 -> :117-122; element pair :109-110 -> :117-118; action quartet :111-114 -> :119-122", "registration data-list.tsx :75 unchanged, :184 -> :205", "palette block-types.ts :129-130 -> :136-137", "inspector block-config.ts :282-316 -> :283-317", "ui/button.tsx :19-35 and auto-trigger.ts :18-19 unchanged", "the section 4b bullet 'objectName: not read at the pin' is replaced by a paragraph that declares it with the four anchors above", "actionMemberList docblock: members now also carry objectName and properties.params static values (readMemberStaticParamValues, static-params.ts:142-148)" ], "dogfood ledger (packages/qa/dogfood/test/expression-conformance.ledger.ts, 3 rows; historical form now `.objectui-sha` pin `dd3f7e1be356`, first read at f8a9d0fb0596)": [ "action-button.tsx:116-119 -> :117-120, :298 -> :335, :129 + :333-339 -> :130 + :370-376", "action-menu.tsx:219-222 -> :224-227, :293 -> :322", "action-icon.tsx:96 -> :97, :197-199 -> :219-221, :101 + :235-241 -> :102 + :257-263", "action-group.tsx:233 -> :238, truthiness :306 -> :343", "SchemaRenderer.tsx evaluateVisibilityPredicate :1048 -> :1157, evaluateEnablementPredicate :1138 -> :1247, :1138-1165 -> :1247-1274, :1149-1156 -> :1258-1265, isDisabled :1772-1784 -> :1879-1891 (ranges diffed identical); :469 unchanged", "useExpression.ts:200-244 / :215-238 and ExpressionEvaluator.ts:387-408 unchanged", "failPolicy of all three rows unchanged: the evaluators are code-identical across the hop" ] }, "tests": "All exit codes were written to disk before any output was read, at HEAD 5e50899a4 (source identical to 3ac9125cf). Under scripts/pm/os-verify-lock.sh: (1) build of the @objectstack/verify closure minus spec, exit 0; (2) `pnpm --filter @objectstack/spec test` (local): 565 files, 16684 passed, 1 todo, exit 0; (3) spec `test:repo`: 37 files, 684 passed, exit 0; (4) spec `typecheck`: exit 0 (tsc, scripts-typecheck, test-typecheck: 251 errors / 138 pinned signatures held); (5) lint suite (`exec vitest run --maxWorkers=2`): 115 files, 5331 passed, exit 0; (6) metadata-core suite: 16 files, 289 passed, exit 0; (7) dogfood `test/expression-conformance.test.ts`: 7 passed, exit 0; (8) the row test alone: 45 passed, exit 0. Pin gate: `check:objectui-pin-citations` exit 0 ('49 asserting objectui pin citation(s) match .objectui-sha (dd3f7e1be), 61 historical'); `--verify-anchors` with OBJECTUI_ROOT at the dd3f7e1be scratch clone exit 0 ('7 anchor content assertion(s) verified against objectui at dd3f7e1be'). My anchors carry no quoted first line, so that mode checks their sha label, not their content; the content was re-read by hand, file by file. `check:generated --fix` (built spec in 276s) rewrote exactly two artifacts: authorable-surface/ui.json (+2 lines, ActionButtonProps:objectName and ActionIconProps:objectName) and content/docs/references/ui/component.mdx (+2). The re-check then read 'All 15 generated artifacts are up to date'. `node scripts/check-sdui-manifest.mjs` exit 0 ('recorded at the live objectui pin dd3f7e1be356'). Type-alias pin count 781 and dropped-refinements 212/610 are unchanged, and spec test holds both. No eslint run this round: component.zod.ts / the row test / the ledger are CI's `pnpm lint` population, and the round-1 narrowing proof still applies (no type-aware linting).", "gates": "dispatch-gates at 5e50899a4 (no paths, merge base 3cf644938): 108 derived commands. I ran 104 unlocked and 4 locked, with a runner that records each exit code before its output is read. Result: 107 exit 0, including check:generated, check:api-surface, check:authorable-surface, check:docs, check:objectui-pin-citations, check:spec-parsed-alias, check:doc-authoring, check:issue-citations, check:nul-bytes, check:strictness-ledger, check:liveness, check:dts-closure and check:type-check-debt (this time to a verdict: '4 ledger entr(ies) re-measured in 590.5s … none above its recorded number'). check:skill-examples first exited 3 (PREREQUISITE NOT MET: no client-react .d.ts). After building the client-react closure minus spec, it exited 0. NOT MEASURED: `pnpm check:dual-build-cjs-loads`, exit 3 PREREQUISITE NOT MET (it reads every workspace package's dist/, a whole-repo build; this diff changes only @objectstack/spec's output). `--ran` verdict: '108 derived famil(ies) accounted for — 107 run, 1 NOT-MEASURED'. CI convergence is the seat's to read. origin/main has since moved 10 commits past the merge base; none of them touches any file in this diff.", "pr_body_delta": [ "Heading 'Read points: measured at the pin (`.objectui-sha` `f8a9d0fb0596`)' becomes 'Read points: measured at the pin (`.objectui-sha` `dd3f7e1be356`)'. Add one sentence under it: 'First measured at `f8a9d0fb0596`; after #20436 moved the pin, every read point was re-derived at `dd3f7e1be356` (2026-09-28) and re-anchored with the sha.'", "Read-points table, action:button row: in 'Declared keys', '+ 20 keys forwarded' becomes '+ 21 keys forwarded' and gains `objectName`. Anchors: `action-button.tsx:118` -> `:119`, `(:136-137)` -> `(:137-138)`.", "Read-points table, action:icon row: `:106` -> `:107`, `(:119-174)` -> `(:134-196)`. Declared keys still 'same as the button, minus size, undoable, recordIdField', so it now includes objectName.", "Read-points table, action:group row: `(:243)` -> `(:248)`, `(:378)` -> `(:415)`, `(:320)` -> `(:357)`, `(:361, :89)` -> `(:398, :91)`.", "Read-points table, action:menu row: `(:225-226)` -> `(:230-231)`. Definition-list `data-list.tsx:49` is unchanged.", "Replace the paragraph 'Pin vs objectui origin/main (9f0c84a)' with: '**objectName, carried by the new pin.** At `dd3f7e1be356`, action:button and action:icon forward `objectName` to the runner (`action-button.tsx:307`, `action-icon.tsx:195`), and the console dispatches to that object instead of the page object. Both rows declare `objectName` as the ActionDef string scalar. action:group and action:menu forward it per member (`action-group.tsx:323`, `action-menu.tsx:313`), so it rides each member object and the container rows gain no key. The same pin reads static values from `properties.params` (objectui#10289, `static-params.ts:91-101`). On a page node that is the row itself, so `params` keeps its meaning: an array is the input list and an object is the static values. Its value schema is unchanged.'", "Acceptance notes: delete the bullet '`objectName` on the four action rows is to be added with the next `.objectui-sha` bump…', which this round discharged. The other bullets stand.", "Tests: replace the lead line with 'The readings below are at HEAD `5e50899a4` (after merging `origin/main` at `3cf644938`, the pin bump)'. Update the readings: spec test **565 files, 16684 passed**, 1 todo; the row test **45 tests** (was 44); test:repo **37 files, 684 passed**; typecheck exit 0; lint **115 files, 5331 passed**; metadata-core **16 files, 289 passed**; dogfood expression-conformance **7 passed**. Mark the cli unit-layer bullet 'not re-run this round (round-1 reading)'. The eslint bullet stands (round-1 narrowing, no type-aware linting).", "Gates: 'The derived union at `5e50899a4` is 108 commands.' '**107 exit 0**', adding check:dts-closure and check:type-check-debt (this time to a verdict: 4 ledger entries re-measured, none above its number). check:dual-build-cjs-loads stays NOT MEASURED (exit 3), and the check:type-check-debt NOT MEASURED bullet is deleted. `--ran`: '108 derived famil(ies) accounted for — 107 run, 1 NOT-MEASURED'. The sdui-manifest line reads 'recorded at pin `dd3f7e1be356`'. Add: '`check:objectui-pin-citations` exit 0 (49 asserting citations match `dd3f7e1be`); `--verify-anchors` against a `dd3f7e1be` clone exit 0.'", "Surface beyond the claim, dogfood bullet: append 'Re-anchored at `dd3f7e1be356` in round 4; the fault faces are unchanged because the evaluators are code-identical across the hop.'", "Downstream: the read-but-unpublished counts become 22 on action:button (was 21) and 20 on action:icon (was 19), both because of objectName.", "Changeset section: unchanged ('minor'). The changeset file itself now names objectName on the button and icon and states that group and menu carry it per member." ], "mcp_calls": "0", "api_writes": "1 relay write: post-stamped -> POST /repos/objectstack-ai/objectstack/issues/20371/comments (this report), through the fleet-write relay. Plus git push (not REST): two pushes, c628e1d02 and then 5e50899a4, neither forced. Reads only otherwise: one unauthenticated GET /repos/objectstack-ai/objectstack/pulls/20420 for the live body and head. PR body, labels, draft state and auto-merge were not touched.", "deviations": [ "The order says 'declare objectName on the four action rows'. The renderer read declares it on two: group and menu forward `objectName` only per member (anchors above), so a container-level key would be read by nothing. The row test pins the refusal.", "No quoted first lines were added to my anchors, and ASSERTED_ANCHOR_FLOOR is unchanged. Raising coverage would mean editing the gate script and running its own suite, which is outside this round. This remains an option for the seat." ], "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted, not filed. Read-only inference from the renderer, not reproduced: action:group/action:menu call readActionEntryParamValues for a member whose params is an object. For type 'api' that still returns the object as the request payload until 18 (static-params.ts:162-182). No change is needed to this row, because members are not judged here." ], "cleanup": "Done: rm -rf the worktree's node_modules, then `git worktree remove /home/user/objectstack-issue-20371` (not forced), exit 0, after git status read clean and the remote head read 5e50899a4. The scratch objectui clones (f8a9d0f, dd3f7e1) were deleted too. No background process of mine is left running; every locked run had its VERDICT read." }
Generated by Claude Code
objectstack-fleet commented
on Sep 28, 2026 ContributorAuthorMore actionsClose-out by the
domain:specseat 1 (session_01B3TqpoQbTAfG7G74GMDWNW) at 2026-09-28T16:25Z.Delivered. PR #20420 merged as
75b216924through the merge queue. This card closedcompletedon the PR'sFixesline.pm:dispatchedis removed.ComponentPropsMapgains strict rows foraction:button,action:group,action:menu,action:icon,element:definition-listandelement:repeater. The twoelement:types are admitted to the vocabulary through their rows.- Every key set was measured from the renderer's read points. The rows were re-measured at
.objectui-shadd3f7e1be356after PR chore(objectui): bump the console pin to dd3f7e1be356 (carries the injected-client boot fix) with the showcase div→box and trash-icon follow-through #20436 moved the pin mid-queue (round 4; audit comment5871523278). objectNameis declared onaction:buttonandaction:icon.- At-tier record
5873778605PASS at5e50899a.
What remains, and who carries it.
- Arming the six in objectui: objectui#10872 (
domain:ui). It waits for an installable@objectstack/specrelease carrying these rows. The landing note, with the producer-side findings re-read at the new pin, is posted there. - The dogfood ledger row
cel-action-disabledmay be mis-measured: [finding] the dogfood ledger rowcel-action-disabledmay be mis-measured:action:group/action:menumembers evaluate a registered action'sdisabledwithoutthrowOnErrorand grey out on a fault #20470, filed from the at-tier records. - The six rows' objectui anchors carry no quoted first line, so
--verify-anchorschecks none of their content: [finding] the sixComponentPropsMaprows #20371 added cite about a hundred objectui anchors by line number alone: no quoted first line, so--verify-anchorschecks none of their content #20471. component-type-vocabulary.ts'sKNOWN_COMPONENT_TYPESdocblock still says "exactly" the string-arm rows. This is prose drift, and its carrier is the next edit of that file. Noted here, not filed.
Generated by Claude Code
- added a commit that references this issue
on Sep 29, 2026 - added a commit that references this issue
on Oct 7, 2026
Filing-gate category: ① a type a registered, published and authored surface writes, with no spec declaration. Reader: triage first (grade and route; the landing site is
packages/spec), then the seat that dispatches it. Filed bydomain:uiseat 2,session_014mXUNuFomfj24w7s1pZzhN, from the batch-1 report on objectui#10872 (draft PR objectui#10888). ⛔ Not graded here.Why this blocks objectui
objectui#10872 arms
objectui validatefor its ADR-0080 public blocks. Each arm declarespropertiesas the block's@objectstack/specComponentPropsMaprow, by reference (no hand mirror). Batch 1 arms 20 of 28 blocks. Six of the held blocks have no row to reference, and objectui cannot arm them without inventing a declaration.Measured
action:button,action:group,action:menu,action:icon@object-ui/components(renderers/action/).PUBLIC_BLOCKS.{ "type": "action:button", "label": "Open details", "actionType": "url", "target": "/users/ada" }, and the validator's own handler-key remedy text teaches it.action:is not a reserved namespace.action-button.tsxreadsschema.name ?? schema.label, sonameis optional where it is read.UIActionSchemadeclaresnameandlabelrequired.inputsdeclare 5 to 8 optional members;action:group/action:menudeclareactionsas an object, while the renderers read a list.Action(object-metadata actions, keyed byname) is a different declaration. objectui'sui-action.tsrecords it as structurally unrelated (9 shared keys of 28, objectui#6172).element:definition-list,element:repeater@object-ui/components(DefinitionListRenderer,RepeaterRenderer).PUBLIC_BLOCKS→getPublicConfigs→ objectstack's trackedsdui.manifest.jsoncarries both.isKnownComponentTypeis false andhasReservedComponentNamespaceis true.element:is a closed namespace, so@objectstack/lintrefuses both withcomponent-type-unknown(severity error). This is read from the spec source; noos validaterun measured it.Direction (for triage to grade)
ComponentPropsMaprows for the six types. Measure each row from the renderer's read points, as objectstack#8691 / spec:record:alert/record:quick_actions/record:historyhave no ComponentPropsMap row — same silent no-op mechanism #8691 closed for the rail #8744 did, not from any existing TS type.action:*, the row statesnameoptional, as it is read.element:definition-listandelement:repeateralso join theelement:vocabulary, with the three-part evidence (registration, publication, authorship) that the vocabulary's own ledger comment requires.UIActionSchemaor the specActioninto the rows; the read points decide.action:*andelement:*batches. Itsaction:buttonpage pin waits on that.Dedupe
Scanned the open issues on both boards (5 pages each) for
action:button,element:definition-list,element:repeatertogether withComponentPropsMapor vocabulary. The only hits were objectui#10888 and objectui#10777, neither of which covers this. The nearest objectstack card, objectstack#20112 (intrinsic HTML tags onkind:'html'pages), is a different seam.domain:uiseat 2 · finding · 2026-09-28