Repository navigation
chore(deps): move @objectstack/* to the next prerelease ^18.0.0-next.0 and follow its contract (objectui#12030) - #12337
Conversation
…0 (objectui#12030) Every @objectstack/* range in dependencies, devDependencies and peerDependencies (40 ranges in 32 manifests) moves from ^17.x to ^18.0.0-next.0. The ranges were raised textually, so no other manifest byte moved, and pnpm-lock.yaml was regenerated by `pnpm install` only. A frozen install exits 0 and a second plain install leaves the lockfile byte-identical. Claude-Session: https://claude.ai/code/session_01CsyMRsFJBKNEMa4oPY1b5z Co-authored-by: Claude <noreply@anthropic.com>
…ectui#12030) The 22 published packages whose dependencies or peerDependencies name an @objectstack/* range take a minor, with the consumer-facing break stated in the body. No major is declared. Claude-Session: https://claude.ai/code/session_01CsyMRsFJBKNEMa4oPY1b5z Co-authored-by: Claude <noreply@anthropic.com>
…ope and its refusal of a bare unique index (objectui#12030)
@objectstack/spec 18 narrows the metadata overlay scope to 'env' (the 'org'
member is gone), so the overlay fixtures write 'env' and the scope's docblock
and type pin read the one-member enum. The zh scope label table keeps its
'org' row beside the union, unchanged, for a server still on 17.x.
Protocol 18 refuses a bare `unique: true` on an index: the index-fallback
probe now pins that refusal with a `false` control, and the validation-preview
help text names the scoped spellings ('organization', 'global') instead.
The connect lifecycle in data-objectstack's index.ts is not touched.
Claude-Session: https://claude.ai/code/session_01CsyMRsFJBKNEMa4oPY1b5z
Co-authored-by: Claude <noreply@anthropic.com>
…n, manage_org_presentation out (objectui#12030) @objectstack/spec 18 adds `manage_mailboxes` to PLATFORM_CAPABILITIES and retires `manage_org_presentation` (objectstack#15206 S3). The curated label set the spec-parity pin compares against follows, the default label and the ten locale packs swap the retired key's label for the new one. Claude-Session: https://claude.ai/code/session_01CsyMRsFJBKNEMa4oPY1b5z Co-authored-by: Claude <noreply@anthropic.com>
…ontract (objectui#12030) @objectstack/spec 18 retires the flat query keys of element:number, element:repeater and element:record_picker (object / filter / sort / limit and the record_picker display keys' query siblings, objectstack#11509) and object-grid's `defaultFilters` as tombstones that refuse by name. The number / repeater arms drop their pre-18 waiver and take the row by reference; the record_picker node and registration stop publishing the four keys; the parity, arm and harvest pins read the tombstones. The spec adds `checkPageSlotPair`, now attached to both page node schemas beside the other page checks (its siblings `checkPagePrintComposition` and `checkListViewChartBinding` read a discriminator and are listed as not attachable); ListView gains `requiredPermissions` (pinned as the one pending declaration, see the PR), ObjectSchema gains `attachedOnRead` (45 keys), record:details sections gain an experimental `count`, and three new record component types (approvals, attachments, approval_decision) stay out of the block palette, as today. Claude-Session: https://claude.ai/code/session_01CsyMRsFJBKNEMa4oPY1b5z Co-authored-by: Claude <noreply@anthropic.com>
…egistry and redirect messages (objectui#12030)
@objectstack/spec 18 (ADR-0032 §3) reads a flow text slot's `{{ }}` template
only and a value slot's string as the literal it spells, refusing a `{…}`
token there in favour of a CEL value envelope. Flow fixtures move to the
spellings the spec accepts; the value-role ledger now names six key/value
maps (screen defaults, script inputs and subflow input join), measured to
refuse a malformed envelope with the editor's own sentences; and the pins
that restated `{token}` acceptance now read the spec's refusal. The Studio
behaviour is unchanged: the editor still writes what it wrote and shows the
spec's verdict; the recipient picker's template spellings and a blank Notify
title are pinned as pending, for the decision the PR names.
Approver `position` is a registry binding in spec 18, so the spec-17
loosening of the value-source table is removed and the identity, directory
and lookup pins read the registry arm. The submit-redirect refusal pins
read the spec's message instead of a dated ruling citation it dropped, and a
url action target is a path, as the spec now requires.
Claude-Session: https://claude.ai/code/session_01CsyMRsFJBKNEMa4oPY1b5z
Co-authored-by: Claude <noreply@anthropic.com>
…e floor reader to 18.0.0-next.0 (objectui#12030) Each claim that named 17.7.0 as the installed @objectstack/spec was re-measured on 18.0.0-next.0 and restamped where the fact still holds; the one that names 17.7.0 as the release that closed a fork is ledgered as historical. The live-backend pin moves to the release the tag @objectstack/cli@18.0.0-next.0 names, QUICK_REFERENCE is re-synced by its script, the lockfile-integrity samples are re-keyed, and the declared-floor reader reads a prerelease floor by its core triple, refusing the floor's own prerelease. Claude-Session: https://claude.ai/code/session_01CsyMRsFJBKNEMa4oPY1b5z Co-authored-by: Claude <noreply@anthropic.com>
…rrors chain (objectui#12030) Attaching spec 18's checkPageSlotPair to PageNodeSchema and PageKindNodeSchema puts a raw spec read in layout.zod.ts; the import-boundary census accepts a chained check function by name, as it does checkPageRequiresKind. Claude-Session: https://claude.ai/code/session_01CsyMRsFJBKNEMa4oPY1b5z Co-authored-by: Claude <noreply@anthropic.com>
… payback the 18.0.0-next.0 bump carries (objectui#12030, objectui#11762) The fourth raise (objectui#11717) filed objectstack#22044 as its payback; the 18.0.0-next.0 release carries it, so the ceiling, BASELINE and the vendor-objectstack per-chunk rows come down by what the bump recovered, measured on two console builds in one container: cea429b (main, 17.7.0) 3,209,684 against 5488ae7 (this branch) 3,122,463, -87,221 aggregate and -86,591 on vendor-objectstack. Lowered by the amount, not re-derived as a reading plus half a regression and not rounded; the regression constant is untouched. Claude-Session: https://claude.ai/code/session_01CsyMRsFJBKNEMa4oPY1b5z Co-authored-by: Claude <noreply@anthropic.com>
…eased from Changesets pre mode on tag next (objectui#12030) The maintainer's ruling (record 6148150305 on objectui#12030): objectui's next release ships v18. This PR's changeset becomes the AGENTS.md §版本号策略 sync major, the one major that policy admits, and the repository enters Changesets pre mode on tag `next` (`pnpm changeset pre enter next`), so the release is 18.0.0-next.N on the npm `next` dist-tag and `latest` stays on 17.7.0. Claude-Session: https://claude.ai/code/session_01CsyMRsFJBKNEMa4oPY1b5z Co-authored-by: Claude <noreply@anthropic.com>
… enum (objectui#12030) Spec 18 narrows the overlay scope to 'env' (objectstack#15206 S5). The seat's judgment under the maintainer's ruling 6148150305, as break-list item 6098299437 prescribes: the zh label table keys the union alone, and an 'org' from an older server renders raw. Claude-Session: https://claude.ai/code/session_01CsyMRsFJBKNEMa4oPY1b5z Co-authored-by: Claude <noreply@anthropic.com>
…faultFilters (objectui#12030) @objectstack/spec 18 tombstones object-grid.defaultFilters (objectstack#11509) and refuses it by name; the seat's judgment under the maintainer's ruling 6148150305 is that a retirement takes effect at once. ObjectGrid drops its alias read and ObjectView drops the table.defaultFilters rung, as objectui#12093 said it would at the pin that carries the tombstone. No in-repo producer writes the key. The tests that pinned it as a working alias are flipped to pin it inert beside a canonical filter control; the plugin-view docs, the registration's filter description and the type's JSDoc say retired. Claude-Session: https://claude.ai/code/session_01CsyMRsFJBKNEMa4oPY1b5z Co-authored-by: Claude <noreply@anthropic.com>
…wo edits, not re-pinned (objectui#12030) The org label drop and the defaultFilters read removal reach bundler inputs after the 5488ae7 reading BASELINE carries. The console build of 5db13ba reads 3,122,375 (-88), inside the band, so neither constant moves; the BASELINE prose says so instead of claiming no later commit reaches a bundler input. Claude-Session: https://claude.ai/code/session_01CsyMRsFJBKNEMa4oPY1b5z Co-authored-by: Claude <noreply@anthropic.com>
… 18, released from Changesets pre mode on tag next (objectui#12030)" This reverts commit 0b942ba. The scope split recorded as 6149376719: this change is the dependency move only, so its changeset goes back to minor and .changeset/pre.json is removed. The objectui 18.x release (the sync major, pre mode on tag next, and the two gate edits of 6148150305 and 6149296149) moves to objectui#12334. Claude-Session: https://claude.ai/code/session_01CsyMRsFJBKNEMa4oPY1b5z Co-authored-by: Claude <noreply@anthropic.com>
…e suite pins, 3160.1 to 3049.3 (objectui#12030) The literal is BASELINE.gzipBytes rendered, re-taken each time the baseline moves; objectstack#22044's payback moved it. Claude-Session: https://claude.ai/code/session_01CsyMRsFJBKNEMa4oPY1b5z Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: opus — maintainer waiver 6158097279, in place of CONTRACT_REVIEW_TIER Inputs read:
Nothing was built, run or re-run. ① Derived judgmentsGate verdicts on the head.
Delta since the last record (
Accept-set and public-surface changes the whole net diff implies, judged afresh:
No accept-set or public-surface change in the diff is wrong. ② Semver level
③ Boundary flagsEscalations of record 6158813708, each re-read at this head:
Escalations of record 6158463307, still answered:
Escalations of record 6151661549, still answered:
Dev flags:
New escalation from this review, to the seat, not blocking. Before
Optionally, reword the Recorded consequences, already ruled; neither is a defect of this head:
Implemented-by: VERDICT: PASS |
✅ 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
|
Fixes #12030
Clause-②: yes — 22 published
@object-ui/*packages declare a consumer-facing@objectstack/*range that moves from^17.xto^18.0.0-next.0(21 independencies, 1 inpeerDependencies, counted from the manifests at the head), so a release would carry a published-contract change.node scripts/check-changeset-presence.mjsat0cc4e8fcc: "102 source file(s) and 1 published-contract change(s) of 18 released package(s) changed, and this change declares 3 changeset(s)"..changeset/12030-objectstack-next-18.mddeclares the 22 packagesminor, with the breaking-for-consumers note in its body; the changeset coverage of the other touched packages is below.follow-up: #12334
Scope: the
@objectstack/*move to^18.0.0-next.0and the fixes it forces. No objectui release. Releasing objectui 18.x (the AGENTS.md §版本号策略 syncmajor, Changesets pre mode onnext, and the two gate edits ruled in records 6148150305 and 6149296149) moves to the follow-up card above, per the scope split recorded as 6149376719. This branch carried the syncmajorand.changeset/pre.jsonfor a while (0b942ba); they are reverted (7ec3c2b), and neither gate script is edited.Known effect after merge, intended:
Spec Range Floors(scripts/check-spec-range-floors.mjs) cannot read^18.0.0-next.0: at the head it exits 1 with "The scan collapsed: 0 package(s) declare @objectstack/spec in a consumer-facing field". Its nightly alarm onmainturns red, andpnpm changeset:publishcancels any publish until the follow-up lands. That is the fail-safe that stops a 17.x release declaring 18 ranges. The open version PR #11600 (changeset-release/main) refreshes toward 17.8.0 and must not be merged before the follow-up.What this does
@objectstack/*range independencies,devDependenciesandpeerDependenciesmoves to^18.0.0-next.0: 40 ranges in 32 manifests (26 / 13 / 1). Raised textually;pnpm-lock.yamlregenerated bypnpm installonly, never hand-edited.pnpm install --frozen-lockfileexits 0 and a second plainpnpm installleaves the lockfile byte-identical (measured ate8e9a35; lockfile and manifests unchanged since).@objectstack/*packages objectui names (spec,client,formula,lint):next: 18.0.0-next.0,latest: 17.7.0; every18.0.0-next.0tag peels to objectstackd889448b93.nexthad not moved when the final head was pushed, so feat(spec)!: retire the view-levelapidata source — a view binds its object or static rows; an API call is the page element's binding (#23082) objectstack#23160 (1912af47ba, compare readsbehind: not an ancestor) is not in this release and the view-levelapidata source is retired in @objectstack/spec (objectstack#23082): delete theViewData.provider === 'api'readers, keep the approvals inbox's code-builtApiDataSource#12325's reader removal stays out of scope.Changeset coverage
Every published package this change touches, measured on the net diff from
72594f29e(the merge base since themainmerge; the earlier rounds measured fromcea429b98, before it, and the set is the same 32 published packages):.changeset/12030-objectstack-next-18.md: the 22 packages whose consumer-facing ranges move,minor..changeset/12030-i18n-capability-labels.md:@object-ui/i18n,minor. The ten locale packs dropcapability.label.manage_org_presentationand addcapability.label.manage_mailboxeswith spec 18's capability set. A key a consumer could read is removed, so the bump isminor, notpatch..changeset/12030-console-bundles-spec-18.md:@object-ui/consoleand@object-ui/runner,minor. In both, the@objectstack/*ranges aredevDependencies, but each is an app build whose publisheddistbundles them. The console bundles them in itsvendor-objectstackchunk, measured under chore(console): lower the eager-closure line by the objectstack#22044 payback once objectui resolves an @objectstack/spec release carrying 93125aeeb8 #11762 below. The runner is a Vite app build (vite build, nobuild.lib, noexternal) whose aliases compile@object-ui/components,core,typesand other@object-ui/*packages fromsrc; those import@objectstack/specat runtime. The runner line was added in the second patch round, after the opus re-review 6158463307 measured it.@object-ui/plugin-calendarand@object-ui/plugin-kanbanchanged only a comment, and get no line. Measured: both rebuilt from source at2c15e40cf(pnpm --filter … run build, after removingdist);grep -rFover eachdist(theirfiles[]publishdist,README.md,CHANGELOG.md,LICENSE) finds neither the changed sentence nor the unchanged comment sentence beside it, while code strings such asstartDateFieldandObjectKanbanRendererare found.@object-ui/collaboration,mobile,plugin-charts,plugin-reportandsdui-parserget no line. The test: does the package's publishedfiles[]bundle anything this change touched? In each, the only manifest change isdevDependencies["@objectstack/spec"], and the package's own sources are unchanged.collaboration,mobileandsdui-parserbuild withtsc, so theirdistholds their own sources only.plugin-chartsandplugin-reportare Vite lib builds whoserollupOptions.externalexternalises every bare import, so no other package is compiled into them. None of them imports@objectstack/specfrom non-test source.Pending changesets on
mainreworded (patch round 3)Commit
0cc4e8fcc. Eight pending.changeset/*.mdthat this change did not add carried sentences the spec-18 move makes false at release time. Each false clause is corrected in place, mostly by one clause pointing at objectui#12030; history is kept. In the quotes below, a type argument is spelled in words (PublicBlockNodeOffor'element:repeater'), because GitHub's body sanitizer eats angle-bracket fragments; the files spell it as code. The wording is all that changed: every file's frontmatter (packages and levels) is byte-identical to0d457fe1f(sha1 of each frontmatter block compared), andcheck-changeset-overwritereports "declared at base" equal to "declares now" for all eight..changeset/6152-grid-default-filters-gantt-map-filter.md(@object-ui/typesminor;core,plugin-grid,plugin-map,plugin-viewpatch)@objectstack/spechas typedComponentPropsMap['object-grid'].defaultFiltersas the sameViewFilterRulearray asfilter,[{ field, operator, value }, ...], since 17.6.0: the legacy fallbackObjectGridreads only whenfilteris absent, …"@objectstack/spectypedComponentPropsMap['object-grid'].defaultFiltersas the sameViewFilterRulearray asfilter,[{ field, operator, value }, ...], from 17.6.0 until 18 retired it (see objectui#12030): the legacy fallbackObjectGridread only whenfilterwas absent, …"table: { defaultFilters: [{ field: 'status', operator: 'equals', value: 'open' }] }now parses there, on the tolerant and the strict face and throughsafeValidateSchema."table: { defaultFilters: [{ field: 'status', operator: 'equals', value: 'open' }] }parsed there through 17.x, on the tolerant and the strict face and throughsafeValidateSchema; retired in 18, see objectui#12030: the row's tombstone refusesdefaultFiltersby name, so every value, the rule array included, is refused there now."defaultFilters: { status: 'open' }asdefaultFilters: [{ field: 'status', operator: 'equals', value: 'open' }], or, better, move it tofilter, which takes the same array and wins when both are written."filter). RespelldefaultFilters: { status: 'open' }asfilter: [{ field: 'status', operator: 'equals', value: 'open' }]; the rule-arraydefaultFiltersspelling this entry first offered is retired in 18 too."ObjectGridlowersdefaultFiltersthrough the sametoFilterNodesink asfilter, so a rule array there sends the same$filterand draws the same rows as the same array written asfilter; the sink still lowers a record or an AST that reaches the slot at runtime, …"ObjectGridlowereddefaultFiltersthrough the sametoFilterNodesink asfilter, so a rule array there sent the same$filterand drew the same rows as the same array written asfilter(retired in 18, see objectui#12030:ObjectGridandObjectViewno longer readdefaultFilters, so a view that still carries it renders unfiltered); the sink still lowers a record or an AST that reachesfilterat runtime, …"@object-ui/plugin-grida pin of the above through the real renderer."@object-ui/plugin-grida pin of the above through the real renderer (since 18 it pins thatdefaultFiltersis not read).".changeset/11880-grid-filter-handoff.md(@object-ui/plugin-viewpatch)table.filterunless it lowers to nothing (absent,[]or{}), else the deprecatedtable.defaultFilters."table.filterunless it lowers to nothing (absent,[]or{}), else the deprecatedtable.defaultFilters(a rung retired in 18, see objectui#12030:ObjectViewno longer reads it)."table.defaultFiltersrung is retired, see objectui#12030), and …"table.defaultFiltersdid before this entry's change..changeset/12056-repeater-object-waiver.md(@object-ui/typesminor)ElementRepeaterBlockSchemanow applies the sameobjectwaiver as the spec's props gate (objectui#12056)."ElementRepeaterBlockSchemanow applies the sameobjectwaiver as the spec's props gate (objectui#12056); superseded in 18, see objectui#12030: spec 18 retires the flatobject, so the arm is the row by reference, a node may omitproperties.objectwhether or not it binds one, and aproperties.objectis refused by name."ComponentPropsMap['element:repeater']requiresobject." … "a node refinement puts the requirement back wherever no binding names the object."ComponentPropsMap['element:repeater']requiredobjectthrough 17.x." … "a node refinement puts the requirement back wherever no binding names the object. Both waivers and both refinements are gone in 18 (objectui#12030): the row has no flatobjectleft to waive."properties.object. A bag with noobjectis refused when the node has no binding that names one: … The refusal is acustomissue withparams.codeELEMENT_REPEATER_OBJECT_REQUIRED, and its message names both remedies. Aproperties.objectof the wrong type is still refused by the row itself."properties.objectthrough 17.x. A bag with noobjectwas refused when the node had no binding that names one: … The refusal was acustomissue withparams.codeELEMENT_REPEATER_OBJECT_REQUIRED, and its message named both remedies; retired in 18, see objectui#12030: the refinement and its code are deleted, so such a bag is accepted. Aproperties.objectof the wrong type is still refused by the row itself, and since 18 so is anyproperties.object, by name."ElementRepeaterBlockSchematype now typesproperties.objectas optional, and so does the authoring typePublicBlockNodeOffor'element:repeater'derived from it."ElementRepeaterBlockSchematype typedproperties.objectas optional through 17.x, and so did the authoring typePublicBlockNodeOffor'element:repeater'derived from it; since 18 (objectui#12030) both follow the row, which retiresobject, so a typedproperties.object: stringno longer type-checks.".changeset/7611-approver-registry-read.md(@object-ui/app-shellpatch)databinding (user,team,department, andpositionunder the installed spec 17.7.0) still renders the record lookup … The type that admits the registry member before the installed spec declares it is marked for removal when objectui moves to spec 18."databinding (user,team,department, andpositionunder spec 17.7.0; spec 18, which objectui installs from objectui#12030, bindspositionto the registry) still renders the record lookup … The type that admitted the registry member before the installed spec declared it was marked for removal when objectui moves to spec 18; removed in 18, see objectui#12030.".changeset/11880-element-datasource-only.md(@object-ui/components,app-shell,i18npatch)@objectstack/specretires them in v18; each input's description now says it is not read and names the binding member that is."@objectstack/specretired them in 18: the record picker's four inputs left with that retirement (objectui#12030), andelement:number's two with objectui#12085.".changeset/12056-repeater-datasource.md(@object-ui/app-shellpatch)objectui validateaccepts the node the designer now writes, because@object-ui/typestakes the spec gate'sobjectwaiver for this element in the same change."objectui validateaccepts the node the designer now writes:@object-ui/typestook the spec gate'sobjectwaiver for this element in the same change, and since 18 (objectui#12030) the row has no flatobjectleft to require.".changeset/11880-repeater-datasource.md(@object-ui/typesminor,@object-ui/componentspatch), found by the grep beyond the six namedproperties.object/filter/sort/limitstay read, as the fallback, until@objectstack/specretires them in v18, so a repeater that carries only the flat keys reads exactly as before."properties.object/filter/sort/limitstay read, as the fallback (spec 18 retires them as authored keys, see objectui#12030, and the renderer keeps this read for metadata written before), so a repeater that carries only the flat keys reads exactly as before."objectstays required. Clause-②: the strict authoring face (StrictAnyComponentSchema) now ACCEPTS a repeater carryingproperties.objectplus a well-formeddataSource, which it refused as an unrecognized key; …"objectstays required (until objectui#12056's waiver, and retired in 18, see objectui#12030). Clause-②: the strict authoring face (StrictAnyComponentSchema) now ACCEPTS a repeater carryingproperties.objectplus a well-formeddataSource, which it refused as an unrecognized key (since 18 it refusesproperties.objectby name, so the accepted node carries the binding alone); …"objectis refused atproperties.objecton both faces, as before."objectis refused atproperties.objecton both faces, as before; retired in 18, see objectui#12030: such a repeater is accepted."dataSourceinput;objectstays required." after "The registration now publishes the injecteddataSourceinput;objectstays required (until objectui#12085 dropped the flat query inputs)." Evidence: theelement:repeaterregistration inpackages/components/src/renderers/basic/data-list.tsxat the head publishestitleField,fields,emptyText,dividedand noobject, and.changeset/12085-element-binding-inputs.mdstates the drop. The seat may ask for this one clause back out..changeset/12093-spec-main-compile.md(empty frontmatter, no release)main), and@object-ui/app-shell's zh-CN overlay-scope label table keysorgbeside the spec's union (objectstackmainnarrows that union toenv)."main; the read itself is retired in 18, see objectui#12030), and@object-ui/app-shell's zh-CN overlay-scope label table keysorgbeside the spec's union (objectstackmainnarrows that union toenv; theorglabel is dropped in 18, see objectui#12030)."The grep over all 438 pending
.changeset/*.md, besides this change's own three:defaultFiltershits 6152, 11880-grid-filter-handoff and 12093;ELEMENT_REPEATER_OBJECT_REQUIREDhits 12056-repeater-object-waiver only;ELEMENT_NUMBER_OBJECT_REQUIREDandmanage_org_presentationhit nothing; the overlay-scopeorghits 12093 only (12171-environment-overlay-copy names the environment overlay and stays true); the flat element query keys and the record picker hit 11880-element-datasource-only, 11880-repeater-datasource, 12056-repeater-datasource, 12056-repeater-object-waiver and 12085-element-binding-inputs. Read and left as written, each still true at release:12085-element-binding-inputs.md(the repeater renderer still reads its flat keys as the fallback; this change does not touch it),11903-record-picker-layout.md(theRecordPickerDialog, notelement:record_picker),12086-edit-inline-default-on.md,7611-capability-registry.md(names no curated capability),7611-decision-output-position-registry.md, and the "since 17.7.0" mentions elsewhere, which date a fact and do not say what is installed.Merge of
mainmainat72594f29eis merged into this branch (merge commit1c95e13af): six commits, merged cleanly, none touching a manifest or the lockfile. Files both sides changed:packages/app-shell/src/views/metadata-admin/i18n.ts,packages/plugin-grid/src/ObjectGrid.tsxand the tenpackages/i18nlocale packs. The re-run after the merge is under Gates.The break list (measured first, at
a3f41ed: the bump and changeset alone)Full vitest suite in five lock-held groups: 50 files, 159 tests red (types/core 15 files / 58 tests, app-shell 21 / 45, plugins A 6 / 20, plugins B 1 / 4, console + scripts 7 / 32).
turbo run buildand every package'stype-checkwere green at that commit (81/81). Two repo gates were red:check:eager-closure(exit 2, ceilings drifted to 1.74x / 1.21x) andcheck:installed-pin-claims(23 findings). By area, and how each is closed:envonly (objectstack#15206 S5; card comment 6098299437): data-objectstack overlay fixtures and docblock, two app-shell fixtures, and the zh scope label table drops itsorgrow (anorgfrom an older server renders raw), as the ruling's seat judgment says.unique: truerefused at protocol 18 (objectstack#22103): the index-fallback probe pins the refusal with afalsecontrol, the validation-preview help (en, zh) namesunique: 'organization'/unique: 'global', and thedata-protocol.tsdocblock says refused. These are the three sites console: three sites still teach or pin a declared index's bareunique: true, which@objectstack/specrefuses since objectstack#22103 (the help text leads a user into a save-time 422) #11864 names; its legacy-row rendering case still passes and is left as is.manage_mailboxesin,manage_org_presentationout; curated label set, default label, ten locale packs.defaultFiltersare tombstones refusing by name (objectstack#11509). The number and repeater arms take the spec row by reference; the record_picker node and registration stop publishing the four keys; the parity, arm, harvest and ratchet pins read the tombstones.ObjectGridno longer readsdefaultFiltersandObjectViewno longer readstable.defaultFilters; no in-repo producer writes the key. The tests that pinned it as a working alias are flipped to pin it inert beside a canonicalfiltercontrol; the plugin-view README and docs page, the registration'sfilterdescription and the type's JSDoc say retired. The element:repeater renderer's flatobject/filter/sort/limitfallback reads stay:apps/console/src/dev/DevLists.tsxwritesproperties.objectandproperties.limitand is routed inApp.tsx, a live in-repo producer, reported instead of deleted. element:number and element:record_picker already read the binding only.checkPageSlotPairattached to both page node schemas beside the existing page checks (and listed among the chained refinements in the import-boundary census);checkPagePrintCompositionandcheckListViewChartBindingread a discriminator and are listed as not attachable; ObjectSchema's 45th keyattachedOnRead; record:details sections' experimentalcountlisted as deferred; the three new record component types stay out of the block palette, as today.requiredPermissions: pinned as the one pending declaration; the seat files a declare-and-enforce card.{token}string in a value slot is refused by the spec and the editor shows that refusal; the recipient picker's{…}spellings and a blank Notify title are pinned as PENDING. The Studio cutover rides v18: Studio's flow text slots insert and prescribe{{ }}(the objectui half of objectstack-ai/objectstack#22110) #11824.positionis a registry binding in v18: the spec-17 loosening is removed and the identity, directory and lookup pins read the registry arm.e2e/live/ci/backend.envmoves to18.0.0-next.0;QUICK_REFERENCE.mdre-synced by its script; lockfile-integrity samples re-keyed; the declared-floor reader in core's test reads a prerelease floor by its core triple.#11762: the eager-closure line comes down by the payback
objectstack#22044 (
93125aeeb8) is an ancestor of the18.0.0-next.0tag commit (compareahead, behind 0; control: the 17.7.0 tag commit4e4e881427also readsahead). Two console builds, one container, one instrument (CI=true pnpm exec turbo run build --filter=@object-ui/console... --concurrency=2under the verify lock, readingapps/console/dist/eager-closure.json):cea429b(main, 17.7.0)5488ae7(this branch)vendor-objectstackui-componentsMAX_EAGER_CLOSURE_GZIP_BYTES3,281,467 to 3,194,246 andBASELINEonto5488ae7;vendor-objectstackceiling 1,623,000 to 1,536,409 and its baseline onto the same build. Lowered by the amount, not re-derived and not rounded;REGRESSION_THIS_GATE_MUST_CATCH_BYTESuntouched. Headroom 71,783 bytes = 0.79x on the aggregate, 23,719 = 0.26x onvendor-objectstack: whatmainhad oncea429b. The ruling's two later edits reach bundler inputs; the console build of5db13bareads 3,122,375 (-88), inside the band, recorded in theBASELINEprose and not re-pinned. The upstream figure (-226,301 on the chunk) was on an injected dist; the real release nets -86,591 here.Held cards: their Restart-when probes at the head
18.0.0-next.0)MetadataConflictErrorSchemain the spec's.d.ts@latest(17.7.0) tarball: exit 1anonymousFormIntakeCandidatesis a functionc5658133fc)d889448b93@objectstack/coreand@objectstack/objectqlcarrying4578c56e6518.0.0-next.0carries it; objectql is in no objectui manifest or lockfile, so the probe cannot be met as writtenPagePrintSchemaandPRINTABLE_PAGE_COMPONENT_TYPESef1fcb26a293125aeeb8as ancestorEmptyStateSchemalink +InterfacePageConfigSchema.emptyStateListDraftsResponseSchemareads a draft'smemberlabel, which the schema requires (drafts.0.labelinvalid_union). Withlabeladded: exit 0label, 17.7.0: exit 1SECTION_HEADING_COUNT_HOLEis a RegExpstampCommentBodyEditin@objectstack/plugin-auditdist@latest(17.7.0): exit 1. Run against@next(18.0.0-next.0): exit 0Gates (final head
0cc4e8fcc; each reading names the commit it ran on)Patch round 3 (
0cc4e8fcc: pending-changeset wording only, eight.changeset/*.md, no code, manifest or lockfile):0cc4e8fcc, one script under the verify lock,VERDICT command-exit 0(the script exits 1 if any gate does), each gate exit 0:check-changeset-presence("102 source file(s) and 1 published-contract change(s) of 18 released package(s) changed, and this change declares 3 changeset(s)"),check-changeset-no-major("No changeset declares amajorbump."),check-changeset-fixed,check-changeset-overwrite(report-only: "3 changeset(s) added, 8 modified, 0 deleted", and for each of the eight the declared packages and levels at base equal those now),check:changeset-claims("No pending changeset names a file this change touches."),check:pending-changeset-literals("No test source names a pending changeset."),check:new-line-citations(0 new),check:control-bytes("OK (scanned 8636 tracked text file(s); skipped 85 binary)"),check:installed-pin-claims(OK)..changeset/or run a changeset gate against this tree, at0cc4e8fccunder the verify lock:pnpm exec vitest run --project unit --maxWorkers=2overchangeset-polarity-census,check-changeset-no-major,body-dialect-census,dollar-dialect-alias-census,check-changeset-claims,check-pending-changeset-literals,check-control-bytes,check-changeset-presenceandcheck-changeset-overwrite: 9 files, 376 tests passed,VERDICT command-exit 0. No code moved, so no package test or type-check was re-run.Patch round 2 (
0d457fe1f: the runner changeset line, the three objectui-side moves named in the main changeset, and the lastdefaultFilters-is-read prose reworded, in theObjectGridSlotKeydocblock that ships in the published.d.ts, the zod mirror's member comment, the grid round-10 test header, the grid registration note and theObjectGridprops note):0d457fe1f, under the verify lock, each exit 0:check-changeset-presence("declares 3 changeset(s)"),check-changeset-no-major,check-changeset-fixed,check:changeset-claims,check:pending-changeset-literals,check:new-line-citations(0 new),check:control-bytes,check:spec-symbols,check:installed-pin-claims.pnpm exec turbo run type-check --filter=@object-ui/types --filter=@object-ui/plugin-grid --concurrency=2 --continue: 16/16. Thengrid-default-filters-gantt-map-filter-round10-6152,object-view-slot-key-listsandimported-defaults-8317: 3 files, 392 tests passed.git grep defaultFiltersover non-test sources (READMEs, docs and changelogs aside): what is left says retired, not read; describes history (objectui#6152, objectui#11880); or is the declaration typed by the row's tombstone.Patch round, after the
mainmerge (1c95e13af;a1ca2ad55only rewords the i18n changeset):a1ca2ad55, under the verify lock, each exit 0:check-changeset-presence(above, "declares 3 changeset(s)"),check-changeset-no-major,check-changeset-fixed,check:changeset-claims,check:pending-changeset-literals,check:i18n-keys("Every in-scope call-site key resolves against the en pack (3375 keys)"),check:i18n-drift,check:i18n-designer-parity,check:i18n-dead-keys(a report),check:control-bytes.1c95e13af:pnpm exec turbo run type-check --filter=@object-ui/app-shell --filter=@object-ui/components --filter=@object-ui/data-objectstack --filter=@object-ui/i18n --filter=@object-ui/plugin-detail --filter=@object-ui/plugin-grid --filter=@object-ui/types --concurrency=2 --continue, 36/36.1c95e13af. The set: every packagemainand this branch both changed (plugin-grid,i18n,data-objectstack,types) in full; every test filemainadded or changed, now running on spec 18; and every app-shell test that importsmetadata-admin/i18n. Result: 920 files passed, 16,446 tests passed, 13 skipped. The merge touches no manifest and no lockfile, so the whole suite was not re-run; this head's CI shards are the whole-workspace reading.Before the patch round:
pnpm install --frozen-lockfileexit 0, then a plainpnpm installleavespnpm-lock.yamlbyte-identical (sha256 compared), ate8e9a35; the lockfile and every manifest are unchanged since (git diff e8e9a35 HEADover them is empty). Lockfile diff againstcea429b: +106 / -106.CI=true pnpm exec turbo run build --filter=@object-ui/console... --concurrency=2, exit 0, 35/35 tasks, at5db13ba(the last commit touching a bundler input); the whole published set was built (43 tasks) bypnpm check:published-distate8e9a35.pnpm exec turbo run type-check --concurrency=2 --continue, 81/81, at5db13ba(later commits touch only scripts, tests and the changeset);pnpm type-check:scripts && pnpm type-check:vitest-setup && pnpm type-check:e2e && pnpm type-check:vitest-config, exit 0, at2c15e40cf.pnpm exec vitest run --maxWorkers=2, five lock-held groups):5488ae7: 1019 of 1020 files; the red one (imported-defaults-8317, from attachingcheckPageSlotPair) is fixed inef2054eand re-ran green (267 tests). Later commits touch these packages only in one JSDoc.ef2054e: 1319 passed, 1 skipped (12,730 tests). After theorglabel drop, the four overlay-scope files re-ran green at2e80824ea(21 tests).2e80824ea: 1207 passed, 2 skipped (12,292 tests).7ec3c2b: 1031 passed, 2 skipped (11,505 tests).7ec3c2b: 429 passed, 2 failed.check-eager-closure-budget.test.tspinned the renderedBASELINEliteral: re-taken in2c15e40cfand green there.date-only-zone-pins-10183.test.tsis red at2c15e40cftoo, and is NOT caused by this diff: its forked child fails one case, the suite-zone control ofFormulaFunctions.dateOnlyZone-10866, which readsAsia/Shanghai(11:00) instead of UTC (03:00). That is the zone another pin file sets last. Theunitproject runsisolate: false, and the file order comes from each worktree's vitest cache. Run alone in the same forked child at2c15e40cf, that file passes (39/39). The same driver passed 28/28 ata3f41edin a fresh worktree. This diff touches neither the pin files nor the code they exercise.2c15e40cf, exit 0 unless noted:check-changeset-presence(above),check-changeset-no-major("No changeset declares amajorbump."),check-changeset-fixed,check:changeset-claims,check:pending-changeset-literals,check:installed-pin-claims(OK),check:spec-symbols,check:phantom-deps,check:new-line-citations(0 new),check:control-bytes,check:eager-closure("3049.2 KB gzipped across 72 of 2255 chunks (budget: 3119.4 KB, headroom: 70.2 KB)", every ceiling in range).check:spec-floorsexits 1, the known effect above..changeset/pre.jsonis absent.check:lockfile-integrity,check:lockfile-dedupe,check:unused-depsandcheck:published-distwere green at2e80824ea/e8e9a35and nothing they read has changed since.Acceptance notes
orglabel, remove the retired reads.requiredPermissionsmirror: types: mirror spec 18's list-viewrequiredPermissions(the server enforces it since objectstack PR #22731) — no second client gate (the objectui half of objectstack#22611 ruling A, after #12030) #12341;record:approval_decisionregistration): app-shell: spec 18'srecord:approval_decisionpage block renders nothing —ApprovalDecisionRendereris written but never registered (the objectui half of spec 18's three record blocks, after #12030) #12342;metadataRefusedmarker: fields: a file the reader may not open arrives as{ id, metadataRefused: true }(objectstack#22593) and still shows a generic file chip — show a restricted state (the objectui half, after #12030) #12339;element:repeaterflat-key reads and theirDevLists.tsxproducer: components: the element:repeater renderer still reads the flat object/filter/sort/limit spec 18 retires, because the console's DevLists dev route still writes them — move the producer to dataSource, then delete the reads (after #12030) #12345;{{ }}(the objectui half of objectstack-ai/objectstack#22110) #11824;major, Changesets pre mode onnext, and the two gate edits (the maintainer's ruling on #12030), after #12030 lands #12334.{…}spellings; a blank Notify title, which is sent and shows the server's refusal; a{token}value-slot text cell, which commits as typed and shows the spec's refusal; the new record component types, which stay out of the palette; ListViewrequiredPermissions, still undeclared.apps/console/src/dev/DevLists.tsx(routed inApp.tsx) writesproperties.object/properties.limit, a live in-repo producer.isValueEnvelopeSlotservesKEY.*ledger paths only, as before. The ledger's whole-valuevalueslots (the record nodes'filter, loop/mapcollection, notifyrecipients) are not key/value maps, and this change leaves them alone.unique: true, which@objectstack/specrefuses since objectstack#22103 (the help text leads a user into a save-time 422) #11864's legacy-row case (EmbeddedItemEditor.indexFallback, a stored bareunique: truestill renders) passes and is left as is: an 18 server serves such a row as'global'.refusedOptionValuestill marks an unknown option value on a writable field, which the server now keeps (objectstack-ai/objectstack#22183) #11970 names@objectstack/objectql, which no objectui manifest or lockfile carries. Studio's draft panel and commit timeline address a bundle member: readmemberoff_drafts/ package commits and pass?member=(the objectui half of objectstack#23073) #12271's fixture lacks the requiredlabel.BASELINEprose inscripts/check-eager-closure-budget.mjs, cover this branch's own commits through2c15e40cf. Themainmerge (1c95e13af) bringsmain's own bundler inputs, which aremain's drift, not this change; CI'sBundle Analysisweighs them on this head. The console was not rebuilt locally after the merge.OBJECTUI_ALLOW_MAJOR=1as the sync-major switch, and nothing in.github/sets it. That is the follow-up card's to settle; this change leaves AGENTS.md alone.Generated by Claude Code