Repository navigation
fix(components): element:definition-list, element:repeater and action:button publish their spec-declared inputs; types retires ActionGroup (objectui#11168 slice 2) - #11313
Conversation
… what their renderer reads (objectui#11168 slice 2) Each key decided by its own measurement through the real SchemaRenderer, per objectui#11111 decision 3 = B: - element:definition-list.columns: the enum members are the NUMBERS 1 and 2. The renderer compares `props.columns === 2`, so the published strings '1' / '2' drew one column, the spec row refuses them, and the page validator refused the number the designer writes. - element:definition-list.items: no longer required. Absent renders the "No details" state and the spec row does not require it; the validator raised missing-required-prop on a list both accept. Declared `of: object`. - element:repeater.fields: the description stops advertising a `label` member, which is never printed and which the spec refuses. - element:repeater.filter / sort: declared `of: object`, the only member kind the spec rows accept. Member pins for items, fields, filter and sort, plus the columns and items rows, live in element-list-inputs-11168.test.tsx. The guard strikes the refused arm and the four member-pin bookings: refusedArms 2 -> 1, memberPins 4 -> 0, MEMBER_PIN_EXEMPTION_CEILING 4 -> 0, owner count objectui#11168 13 -> 8, and element:repeater.fields joins MULTI_KIND_MEMBER_CONTRACTS. Claude-Session: https://claude.ai/code/session_01VhxTqosz7wn54ahqyxgERT Co-authored-by: Claude <noreply@anthropic.com>
…declares (objectui#11168 slice 2) The registration published `sm` / `md` / `lg`; the 17.5.0 row declares `default`, `sm`, `lg`, `icon` and `md`. Measured through the real SchemaRenderer: `default`, `sm`, `lg` and `icon` reach the Button primitive as-is, and `md` renders as `default` (the renderer's mapping). So the page validator refused two sizes the renderer honours. The input now publishes all five, with a description that says `md` renders as `default`. Pinned in action-button-icon-inputs-11168.test.tsx: the published set equals the spec's accepted set, each size draws the primitive's classes for that size (md draws default's), and the validator accepts each and reports one outside the set. Claude-Session: https://claude.ai/code/session_01VhxTqosz7wn54ahqyxgERT Co-authored-by: Claude <noreply@anthropic.com>
…1168 slice 2) `ActionGroup` was re-exported from the @object-ui/types entry (dist/index.d.ts) and nothing in this repository imported it. It was not the mirror of the `action:group` block, which is ActionGroupBlockSchema (the spec row by reference). It disagreed with that row on six counts: it required `name` (the row refuses it; slice 1 retired it from the block's inputs), it required `label` and `actions` (optional on the row), it typed `visible` as a string only, and it lacked `location`, `variant` and `size`. Retiring the whole interface rather than only `name`: an exported type with zero consumers that mirrors nothing. Breaking for an external TypeScript consumer that imports it. Released as minor, per the fixed group's version-alignment rule (AGENTS.md). Pinned retired by action-group-retired-11168.test.ts: @ts-expect-error legs on the module and the entry, with lit controls. Claude-Session: https://claude.ai/code/session_01VhxTqosz7wn54ahqyxgERT Co-authored-by: Claude <noreply@anthropic.com>
…ActionGroup retirement Two changesets, one per released package, both minor per the fixed group's version-alignment rule: @object-ui/components for the element:definition-list / element:repeater / action:button inputs, and @object-ui/types for the removed ActionGroup interface. Claude-Session: https://claude.ai/code/session_01VhxTqosz7wn54ahqyxgERT Co-authored-by: Claude <noreply@anthropic.com>
|
changeset-claim-re-read
|
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: Isolated at-tier contract reviewer, run inside the ① Derived judgmentsThe published registration
Nothing else in the ten files moves an accept set or a public surface. ② Semver levelThe diff publishes a widening (two Two changesets, Each sentence, since both publish verbatim into the CHANGELOG. Components: the ③ Boundary flagsThe dev report's
Implemented-by: VERDICT: PASS |
Refs #11168
Clause-②: yes (narrowing) — widening:
action:button.sizenow publishesdefaultandicon(the page validator refused both), andelement:definition-list.itemsis no longer required; narrowing:element:definition-list.columnstakes the NUMBERS1/2instead of the strings,element:repeater.filter/.sortdeclareof: 'object', and the@object-ui/typesActionGroupinterface is removed. The fixed group ships it asminor(the version-alignment rule in AGENTS.md); the break is stated in both changesets.Slice 2 of objectui#11168, under objectui#11111 decision 3 = B (record
5902351047): each key decided by its own measurement through the realSchemaRenderer, the real registry and the installed@objectstack/spec17.5.0 rows. Declare what the renderer honours; refuse or retire what it does not. The card stays open for slice 3; this PR lands withRefs.What each key measured, and what moved
All rendering rows mount the block the way a page does (real
SchemaRenderer, real registry). "Validator" meansvalidateTreeover the manifestmanifestFromConfigsbuilds from the whole registry, the JSX-page compiler's and the save gate's pair.1ccb5ba7delement:definition-list.columns2drawssm:grid-cols-2;'2'drawsgrid-cols-1(the renderer comparesprops.columns === 2). The spec refuses'1'/'2'(invalid_value). The published enum was the strings, so the validator raisederror:invalid-enumoncolumns: 2, the value the designer writes, and passed'2'.{ label, value }form). The validator now accepts2and reports'2'.element:definition-list.items(required flag)error:missing-required-prop.requireddropped, declaredof: 'object'. In scope as the same block's input; see "Bounded in-place fix" below.element:definition-list.items(members)termis thedt;descriptionis shown as-is: string or number verbatim, object as JSON, omitted as an em dash.label/valueitems render a blank term and an em dash, and the spec refuses them (unrecognized_keysatitems.0).element:repeater.fields{ field }each print that field's value, in order, after the title; a missing field prints an em dash. A{ field, label }entry prints the value and never the label; the spec refuses it (invalid_unionatfields.0).label, and the internalRepeaterColumntype drops it. Noof(member union), recorded inMULTI_KIND_MEMBER_CONTRACTS.element:repeater.filteradapter.findas$filter, member for member, with{current_user_id}/{current_org_id}invalueresolved first; a token-free list arrives unchanged. The spec refuses the record form (invalid_typeatfilter).of: 'object'. The lowering to the server AST is the adapter's own contract, pinned in@object-ui/data-objectstack.element:repeater.sort$orderbyunchanged and in order. The spec refuses a bare name as a member (invalid_typeatsort.0).of: 'object'.action:button.sizedefault,sm,lgandiconreach the Button primitive as-is;mddraws the same classes asdefault, by mapping (schema.size === 'md' ? 'default' : …). The registration publishedsm/md/lg, so the validator raisederror:invalid-enumondefaultandicon. The spec row declares all five.default,sm,md,lg,icon, with a description sayingmdrenders asdefault.@object-ui/typesActionGroupdist/index.d.tsre-exports it from./ui-action.js. Zero importers:git grepover this repository and over../objectstack(the second has no@object-ui/typesimporter at all). Not the mirror ofaction:group. That isActionGroupBlockSchema(spec row by reference). It disagreed with the row on six counts: requiredname(refused), requiredlabelandactions(optional),visiblestring-only, and nolocation/variant/size.nameand the five other divergences of a published type with zero consumers.Bounded in-place fix:
element:definition-list.itemsrequiredThe claim books
columnsand theitemsmember pin on this block, and not therequiredflag. The dispatch asked whether that flag is in this slice. All four in-place conditions hold, so it is fixed here:required: true. The spec docblock names the shape.data-list.tsx).Evidence is in the table above, and ablation E below.⚠️ The seat may want the claim's file surface to name this key.
Ledger arithmetic (
registry-inputs-spec-parity.test.ts)Re-derived by a static census of the edited file. A census run on BASE first reproduced BASE's own pins as the control.
unjudgedBlocksoffSpecInputsunpublishedKeysrefusedArmsobject-form.layoutstays: objectui#11117 holds that arm this round)memberPinsobjectui#11168MEMBER_PIN_EXEMPTION_CEILINGobjectui#86520 andobjectui#86490 are untouched. The guard's ownthe objectui#11111 ledger is capped at exactly the entries it listsasserts the same figures at runtime.Ablations
Predictions were written to a file before any run. Each leg went through objectstack
scripts/ablation-replace.mjs: the anchor had to hit, and the blob change was verified. Each leg had an outertraprestoring fromHEADby absolute path. Vitest aliases@object-ui/*tosrc, so nodist/sits between a mutation and its assertion. Every restore was proven: blob == HEAD blob,git diff HEADempty,git statusempty.columnsenum back to the stringselement:definition-list declares no arm the spec refuses outright+ 2 pin rows247 passed (250); blobe54574ef408eto25d2c302c708and back$orderbyhand-offdata-list.sortKey-10664SUBJECT$filtergets the raw authored filtersizeenum back tosm/md/lg283 passed (285)itemsrequired againitemsrowActionGroup(interface + entry re-export)tscTS2578 on the 2 directive lines; vitest 2 rederror TS2578: Unused '@ts-expect-error' directiveon exactly the two@ts-expect-errordirectives ofaction-group-retired-11168.test.ts(tsc exit 2), vitest 2 of 2 redGates and tests (head
19a44d591)Heavy runs went through objectstack
os-verify-lock.sh. Exits were captured by redirect-then-$?. Each suite log's first line is19a44d591.turbo run build --filter='@object-ui/components^...'7 of 7;--filter='@object-ui/console^...'34 of 34.@object-ui/types^...is empty (no workspace deps), sotypeswas built itself.@object-ui/components(tsc --noEmit && tsc -p tsconfig.test.json) exit 0;@object-ui/console(tsc --noEmit && tsc -b tsconfig.node.json --force) exit 0;@object-ui/types(tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json) exit 0.--listFilesOnlylists both component pin files, the types pin and the guard in their projects.packages/components348 files in three batches: 155 passed; 96 passed and 1 skipped; 96 passed.packages/types302 passed (7604 tests).apps/console139 files in two batches: 70 passed, 69 passed.ActionGroup, thesdui-parsersuite,schema-catalogpageheader, react config-bag): 38 passed (991 tests).Test Files 4 passed (4),Tests 307 passed (307).check:*, all exit 0:pending-changeset-literals;control-bytes,new-line-citations(0 new),test-path-roots,action-forward-parity,handler-key-reads,component-surface-parity,element-data-source-declaration,spec-symbols;readme-exports,unreferenced-sources,phantom-deps,self-import,esm-specifiers;doc-snippets(698 of 698 block(s) judged, 0 failed),doc-types,doc-examples;prompt-keys,installed-pin-claims,designer-field-key-parity,doc-example-readers,registry-bare-names,i18n-keys.readme-exportsexited 1 anddoc-snippets/doc-examplesexited 2: unbuiltcli/plugin-ai, a prerequisite and not a verdict. They were green after the gate's own scoped--build-filterbuild.check-governed-queue-guard --teston the 10 changed paths: NOT GOVERNED.eslint(this repo'slintiseslint .) on the 8 touched TS files gave 0 errors and 28 warnings, 0 of them on an added line.--print-configreturns a rule set for each file.--format json.eslint.config.jscontains neitherprojectnorparserOptions(controls:rules13 hits,typescript-eslint7), so it is not type-aware and this diff cannot move a verdict in an untouched file.check:sdui-registration-pins: needs a console bundle, and the diff touches nosideEffectsarray.check:spec-floors: the diff touches nopackage.json.pnpm test/lint/type-check: CI's.Docs
No page in
content/docs/**, no package README and nothing underskills/**documents these keys orActionGroup(census:git grepfordefinition-list,element:repeaterandActionGroup). TheButtonSchemasize row inschema-reference.mdis thebuttonnode, notaction:button. These blocks' authoring surface is the manifest built from the registrations changed here, so no document is made false. The two changesets carry the release text.Acceptance notes (noted, not filed)
@object-ui/typesUIActionSchema.sizeis typed'sm' | 'md' | 'lg'. Measured:tscrefusessize: 'icon'andsize: 'default'(TS2322); the controllgis accepted. Theaction:buttonrow declares all five. Same family as theActionGroupbooking (the types mirror of the 17.5.0 action rows). It was not fixed here becauseUIActionSchemais also the member type of theaction:group/action:menu/action:barlists, so widening it is not a mechanical, pinned shape. For the seat to book on this card or its family closer.check:changeset-claims, report-only). Each was read; none states a fact this diff moves.Implemented by an
os-devsubagent of thedomain:spec @ objectuiseat, sessionhttps://claude.ai/code/session_01VhxTqosz7wn54ahqyxgERT.Generated by Claude Code