Skip to content

feat(types)!: retire object-grid's resizableColumns on both faces and stop ObjectGrid reading it (part of objectui#6152, round 7) - #11955

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-6152-resizable-columns-retire
Oct 8, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-6152-resizable-columns-retire

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #6152 (round 7)

The card stays open for its later rounds, which triage booked as separate PRs: the 17.7.0 member moves (operations, conditionalFormatting, filter) and ObjectCalendarSchema.calendar's .passthrough(). Neither is in this PR.

Clause-②: no

This round narrows and widens nothing. It retires object-grid's resizableColumns, which @objectstack/spec 17.7.0 already refuses, so it owes one at-tier contract review before the queue.

What changed: the four strokes the seat scoped

The seat answered (card comment 5957903936) that resizable is canonical and resizableColumns retires with no window, once the spec half was installable. @objectstack/spec 17.7.0 retired the key in ComponentPropsMap['object-grid'] (objectstack#21445), and objectui resolves 17.7.0 since objectui#11717.

  1. TypeScript face. ObjectGridSchema.resizableColumns is ?: never, following the package's convention for a retired member (the defaultSort precedent on the same interface). The @deprecated tag points at resizable, which is properties.resizable on an authored node.
  2. Flat zod mirror. The flat ObjectGridSchema in @object-ui/types/zod declares resizableColumns: retirementTombstone(...). Its one-string message, the OBJECT_GRID_RESIZABLE_COLUMNS_RETIRED constant beside the objectui#11068 constants, names properties.resizable. It sits next to defaultSort's tombstone. The object-view table slot keeps its own refusal, which .extends over this member, just as it does for the five keys objectui#11068 retired on the grid.
  3. Renderer. ObjectGrid hands DataTable resizableColumns: schema.resizable ?? true. The ?? schema.resizableColumns fallback is gone. The object-grid registration's resizable input description no longer calls the old spelling a fallback. The registration's header comment now names resizableColumns beside defaultSort as a spelling that left by tombstone, not by exemption.
  4. Ledger. The objectql.zod.ts#ObjectGridSchema entry leaves UnmirroredDeclared. Its one key was retired, and a tombstone is a mirrored member, so the entry went with it, as PaginationSchema's did. The entry's docblock is rewritten as the departed-entry comment its neighbours use and keeps the entry's history. Every pinned prose figure moved and gained its history sentence: the header bullet, the split's SPEC-DERIVED line, the totals line and its narrative, both ledger docstrings, and the cross-ledger union sentence. The objectui#7279, finding(types): zod-mirror-parity's three LEDGER entry counts are still hand-written prose — the half of #6141 that #7433's scope deliberately left behind #7733, finding(types): zod-mirror-parity's header says KnownDrift holds 62 keys; two instruments measure 63 — wrong since objectui#7664, and the sibling half of #7733 #8222 and finding(types): zod-mirror-parity's two ledger docstrings say UnmirroredDeclared records 94 keys; two instruments measure 87 — unmoved since objectui#7779, and outside every pin in the file #8243 pins derive the new figures and are green: UnmirroredDeclared 4 entries / 5 keys, 2 / 3 spec-derived and 2 / 2 local, with a union of 9. No KnownDrift, RuntimeOnlyDeclared, WiderThanDeclared or MirroredUndeclared row moved. SPEC_DERIVED_PAIRS keeps ObjectGridSchema, because its membership comes from the mirror's spec references, which did not change.

What moves for a reader of the published packages

  • Did not move: the authored door. { "type": "object-grid", "properties": { "resizableColumns": false } } and the flat spelling on the node were already refused by name before this change, through the spec row and flatPropRefusals. That holds on the tolerant face, the strict face and safeValidateSchema, and the round-7 pin re-measures all three.
  • Narrowed: @object-ui/types. The TypeScript member now refuses any value. The exported flat ObjectGridSchema mirror refuses the key at the key with invalid_type, where BaseSchema's .passthrough() used to keep it unexamined.
  • Changed behaviour: @object-ui/plugin-grid. A grid node that still carries resizableColumns gets the default, resizable columns. resizableColumns: false no longer removes the resize handles. A tree-scoped search found no producer that writes the key on an object-grid (see Measurements).
  • Changeset. .changeset/6152-resizable-columns-retired.md bumps @object-ui/types and @object-ui/plugin-grid minor (the fixed group's version policy) and states the break.

Measurements before editing (the dispatch's mechanism assumptions)

  • H1, the sites: held, on base 19a7348, which is the dispatch's f1781be plus one app-shell commit. The one renderer read is the ?? schema.resizableColumns fallback in ObjectGrid. The registration names the spelling in the resizable input's description and in the header comment. The flat mirror did not carry the key, and the table slot refused it by name.

  • H2, the install surface already refuses it: held on the installed @objectstack/spec 17.7.0. ComponentPropsMap['object-grid'].safeParse({ resizableColumns: true }) fails with invalid_type at resizableColumns and the retired-key message naming resizable. The lit control { resizable: true } parses, and the strictness control (an unknown key) fails with unrecognized_keys. So the local tombstone refuses nothing the installed protocol accepts. The round-7 pin re-reads this against the installed package.

  • H3, the pins that flip: partly held. The round-6 test "resizableColumns is NOT mirrored: its route is open, and the parity ledger keeps it" flips in place into the retired assertion: the key is a member, and true and false are each refused at the key. Two other pins do not flip, because they pin the table slot's own refusal, which this round leaves standing:

    • the round-6 test "table.navigation and table.resizableColumns stay withheld, refused by name";
    • object-view-slot-key-lists.test.ts's alias row.

    Their docstrings now record that the grid itself tombstones the key since round 7. No assertion was deleted.

  • Fixture sweep, by the rule's consumer radius (the whole repository). Zero tracked JSON, Markdown or MDX documents write resizableColumns on an object-grid; a control search for resizable finds 11. The one consumer test that writes the key past the type is plugin-view's table-relay test, which writes it to prove it is withheld; it is green. DataTableSchema.resizableColumns is a different block's own key and is untouched, as the claim requires.

Tests and gates

Run from the worktree root with repo-relative paths. Every build, suite, type-check and ablation went through os-verify-lock.sh. Each exit code was captured before any pipe.

  • Build. turbo run build --concurrency=2 over check-doc-snippet-types --build-filter: Tasks: 35 successful, 35 total. The dist was checked after the build:

    • packages/types/dist/objectql.d.ts carries resizableColumns?: never;
    • the plugin-grid bundle reads resizableColumns: e.resizable ?? !0 and has 0 hits for the old fallback.
  • Type-checks, both scripts echoed in the log, exit 0, 0 error TS:

    • pnpm --filter @object-ui/types type-check (tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json);
    • pnpm --filter @object-ui/plugin-grid type-check (tsc --noEmit && tsc -p tsconfig.test.json).

    --listFilesOnly shows both test projects include the touched and new test files.

  • Suites, with --maxWorkers=2:

    • vitest run packages/types/: Test Files 360 passed (360), Tests 9624 passed (9624).
    • vitest run packages/plugin-grid/ apps/console/src/__tests__/registry-inputs-spec-parity.test.ts: Test Files 195 passed (195), Tests 2077 passed (2077). A verbose re-run of the two named files read 255 console-parity tests and the 4 new grid tests, each passing.
    • plugin-view's ObjectView.tableSlotRelay-10976.test.tsx: 7 passed.
  • Gates at the final head 06db65a6, all exit 0:

    • check-changeset-presence ("9 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)"), changeset:check, check:changeset-claims ("No pending changeset names a file this change touches"; a search of pending changesets for resizableColumns and for ledger figures also found nothing), check:pending-changeset-literals;
    • check:new-line-citations ("0 new citation(s)"), check:control-bytes, check:spec-symbols, check:test-path-roots, check:unreferenced-sources, check:handler-key-reads, check:vi-mock-specifiers, check-type-check-coverage ("43/43");
    • check-governed-queue-guard --test over the 10 paths: NOT GOVERNED.
  • Doc and skill gates, run on the built closure at 4a1feb41, all exit 0:

    • check:skill-examples;
    • check:doc-types;
    • check:doc-snippets ("784 of 784 block(s) judged, 0 failed");
    • check:doc-examples;
    • check:readme-exports;
    • check:component-surface-parity (report-only);
    • check:prompt-keys;
    • check:designer-field-key-parity.

    06db65a6 changes only the plugin-grid pin's cast, which no doc gate reads.

  • Lint, a declared narrowing. eslint --no-inline-config --format json judged all 9 changed TS files and ignored none: 1 error and 261 warnings. No message sits on an added line once the pin's any was replaced by a cast through unknown (06db65a6). The one error is the inline-disabled react-hooks/static-components line in ObjectGrid's empty-state icon, which this diff does not touch. Invariance: eslint.config.js declares no parserOptions.project or projectService (no type-aware linting), so this diff cannot move a verdict in an untouched file. The repo-wide pnpm lint is CI's.

Reverse verification

Predictions were written to scratch before each run. Each mutation ran through objectstack's scripts/ablation-replace.mjs (wrap mode) on committed HEAD 06db65a6, inside a harness with a trap restore on absolute paths. Every leg was restored and proven: blob equal to the HEAD blob, git diff HEAD 0 bytes, porcelain 0 lines. No leg needed a dist step: every subject resolves to source through relative imports.

  • A1, put the renderer's fallback read back (anchor x1 to x0, blob 2ec85adb to ed7482d6). The plugin-grid pin read 1 failed | 3 passed, exactly the predicted row: "resizableColumns: false alone is not read", expected +0 to be 2.

  • A2, delete the mirror's tombstone member (blob 59edcee7 to ece13ddb).

    • tsc -p tsconfig.test.json exited 2 with exactly one TS2322, "objectql.zod.ts#ObjectGridSchema" not assignable to never, at assertionUnmirroredMatchesLedger.
    • vitest read 4 failed | 159 passed, as predicted: the three mirror rows of the round-7 pin and the flipped round-6 test. Every authored-door and slot row stayed green, and so did object-view-slot-key-lists and the parity runtime pins.
  • A3, re-declare the TypeScript member as boolean (blob b1d0a398 to 1caaa5d4). tsc -p tsconfig.test.json exited 2 with the three predicted errors:

    • TS2578, the round-7 @ts-expect-error now unused;
    • TS2344 at assertionResizableColumnsIsRetiredOnTheInterface;
    • TS2322 at assertionDriftMatchesLedger (the mirror's never against a declared boolean).

    The first A3 attempt timed out in the lock queue (exit 99) before tsc ran. Its restore was proven, and it was re-run under the same slot.

NOT MEASURED

  • check:sdui-registration-pins. It weighs registrations in a built console, and this diff adds and removes no registration; only one input's description text changed.
  • The full pnpm test farm and the repo-wide pnpm lint. Both are CI's.
  • The plugin-view and plugin-list suites beyond the relay test. No producer passes resizableColumns to ObjectGrid (the tree-scoped search above), and ObjectView withholds it by construction.
  • The at-tier contract record. The seat owes it on the landing head.

Acceptance notes

  • Prose repair inside the claimed file. zod-mirror-parity.test.ts's paragraph listing which cross-ledger figures are pinned spelled their values as digits (13, both 8s). Those digits had gone stale before this round, while the pinned ones moved. Because this round moves the same figures, the paragraph now names them by role, not by digit.
  • The registry-parity comment is now historical. apps/console's registry-inputs-spec-parity.test.ts comment on the harvested object-grid.resizableColumns row ends "Retiring the renderer's own read of the old spelling is objectui#6152's." That read is retired here, so the sentence is now history. It is outside this round's surface and was left as is. Carrier: the next PR that touches that file.
  • Slot-scoped docs stay accurate. content/docs/plugins/plugin-view.mdx, packages/plugin-view/README.md and the ObjectView relay comment still call resizableColumns a legacy alias the table slot withholds (write resizable). That stays true, because the slot's own refusal is unchanged.

Deviations, declared

  • Commit trailers are AGENTS.md's model-free pair (Claude-Session plus Co-authored-by: Claude), not the harness reminder's model-named line.
  • This footer is the dispatch contract's session-URL form.

Session: https://claude.ai/code/session_01DBZ9bntPZ7VKyQNtJeNsgw


Generated by Claude Code

claude added 2 commits October 8, 2026 09:02
…d stop ObjectGrid reading it

objectui#6152 round 7, the four strokes the seat scoped once @objectstack/spec
17.7.0 refused the key in the object-grid row:

- ObjectGridSchema.resizableColumns is `?: never` on the interface;
- the flat zod ObjectGridSchema declares it as a retirementTombstone() whose
  message names properties.resizable;
- ObjectGrid reads `resizable` alone (the `?? schema.resizableColumns`
  fallback is dropped), and the registration's `resizable` description stops
  naming the old spelling;
- the UnmirroredDeclared entry leaves the parity ledger (4 entries / 5 keys),
  with every pinned prose figure and its history sentence moved.

The round-6 pin that read "is NOT mirrored" is flipped into the retired
assertion; a round-7 pin file covers the protocol precondition, the mirror,
every authored door and the TS face, and a plugin-grid pin counts the column
resize handles.

Claude-Session: https://claude.ai/code/session_01DBZ9bntPZ7VKyQNtJeNsgw
Co-authored-by: Claude <noreply@anthropic.com>
…nown instead of any

The pin writes the retired spelling on purpose, so it needs a cast; a cast
through `unknown` to ObjectGridSchema does that without adding an explicit
`any` (the only lint warning the round's diff added).

Claude-Session: https://claude.ai/code/session_01DBZ9bntPZ7VKyQNtJeNsgw
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

❌ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 336 chunks) 3307.5 KB 3307.0 KB
Main entry chunk (gzip) 71.3 KB 350 KB
Entry file index-DSfCSKR1.js —
Status FAIL —

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.

Which half objected:

Eager-closure half Verdict
Aggregate closure ceiling ❌ over its ceiling
Per-chunk ceilings ✅ pass
Per-chunk membership (declared packages) ✅ pass
Ceiling sensitivity (headroom) ✅ pass
Ceiling freshness (checkout vs. base branch) ✅ pass

📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 17.82KB 6.58KB
app-shell (runtime-config.js) 22.59KB 7.89KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.11KB 7.97KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.28KB 2.60KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.50KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 586.28KB 141.14KB
core (index.js) 10.00KB 3.96KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 240.39KB 67.09KB
fields (index.js) 266.92KB 67.47KB
i18n (LocalizationContext.js) 2.92KB 1.42KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.52KB 2.39KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.35KB 12.88KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 38.37KB 10.31KB
i18n (useSafeTranslation.js) 7.14KB 2.92KB
layout (index.js) 41.50KB 11.82KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.86KB 5.00KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.52KB 2.26KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.04KB 3.92KB
plugin-calendar (index.js) 53.39KB 15.52KB
plugin-charts (index.js) 84.71KB 23.25KB
plugin-chatbot (index.js) 199.63KB 47.46KB
plugin-dashboard (index.js) 144.82KB 39.17KB
plugin-designer (index.js) 231.46KB 48.87KB
plugin-detail (index.js) 248.57KB 65.47KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 176.62KB 45.75KB
plugin-gantt (index.js) 179.17KB 45.07KB
plugin-grid (index.js) 248.06KB 68.79KB
plugin-kanban (index.js) 52.17KB 16.37KB
plugin-list (index.js) 117.45KB 29.33KB
plugin-map (index.js) 27.24KB 9.03KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.12KB 12.29KB
plugin-timeline (index.js) 39.10KB 11.81KB
plugin-tree (index.js) 15.07KB 5.33KB
plugin-view (index.js) 91.07KB 22.93KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.81KB 3.58KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 120.63KB 39.56KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.50KB 2.06KB
react (schema-input.js) 4.31KB 2.07KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.50KB 1.99KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 7.30KB 3.12KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 23.87KB 7.83KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (authoring-nodes.js) 0.20KB 0.19KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (cloud.js) 0.20KB 0.18KB
types (complex.js) 4.44KB 2.07KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (dashboard-widget-layout.js) 2.06KB 0.96KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 1.13KB 0.65KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 5.78KB 2.70KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (node-slots.js) 7.18KB 2.34KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 4.99KB 1.96KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 19.93KB 7.25KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Bundle Analysis is red on this head (06db65a6) because main is red on it. From the domain:spec @ objectui seat (objectui#10217), session session_01DBZ9bntPZ7VKyQNtJeNsgw, 2026-10-08T10:00Z. ⛔ Not a review verdict.

  • Not this PR's red: the check fails on main's own pushes (19a7348, job 113226826039; f3a0488, job 113232900960). The anchor card is objectui#11937 (p0, domain:ui, claimed). The fixes in flight are PR objectui#11956 (a revert) and PR objectui#11949 (a ceiling raise), with decision card objectui#11942 open. Nothing is ported here: that fix is the anchor's, and its candidates are still being decided. A re-run would fail the same way, so none is spent.
  • This PR's own share:
    • This merge ref reads 3307.5 KB (bot comment 6057399473).
    • PR objectui#11949, with no app-code change, read 3307.4 KB. So this PR adds roughly 0.1 KB gzip.
    • On PR objectui#11956's base (3306.6 KB), this PR would sit near 3306.7 KB, under the 3307.0 KB ceiling.
    • The seat re-reads this check once main's fix lands.

Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 06db65a6f115da1f95576d98541f2182f599f791
Local-runs: none

PR objectui#11955, round 7 of card objectui#6152 (draft, not ready, no auto-merge). Inputs, and nothing else: the card body and all 54 comments (the scope comments 5957903936, 5958557260, 6020652401 and 6029312212; the claim 6056162668; the dev report 6057365466; the round-6 report 5957803718 and its ACCEPT 5958245046 for the stop condition this round releases), the PR body, its 10-file list, the net diff against main at the merge base 19a7348 (10 files, +365 / −75, the same 10 paths as the file list), and the check-runs on this head (status at the final poll in ③). Gate verdicts are read off those check-runs; nothing was built, run or re-run here. Context was read with git show origin/main:PATH in the existing checkout (the slot composition, flatPropRefusals, ObjectGridSlotKey, the ledgers, the console parity test, the lockfile). The dev's censuses, probes, ablations and dist checks are read as declared, not as verdicts.

① Derived judgments

Published TypeScript face (@object-ui/types):

  1. ObjectGridSchema.resizableColumns: ?: boolean to ?: never — RIGHT. Stroke 1 of the four scoped in 5958557260 and 6029312212, on the seat's answer 5957903936 (resizable is canonical; the alias retires with no window once the spec half is installable). The precondition holds on main: pnpm-lock.yaml resolves @objectstack/spec at 17.7.0 and nothing else, packages/types/package.json declares ^17.7.0, and main's own console parity pin already records 17.7.0's object-grid tombstone for this key. A tombstone rather than a deletion is the package's convention (defaultSort beside it) and keeps the member in keyof ObjectGridSchema, so the object-view-slot-key-lists pin's withheld alias row still classifies it; a deletion would have left that row stale. Pinned by a @ts-expect-error in a file tsconfig.test.json compiles (its include is src/**/*.test.ts) and by an Equal assertion reading the member as undefined, so a re-declared boolean reds Type Check on both.
  2. ObjectViewSchema.table, a Partial Pick of ObjectGridSchema over ObjectGridSlotKey: unchanged — RIGHT. ObjectGridSlotKey is an explicit list that never carried resizableColumns (it sits in the withheld alias set), so the never does not reach the slot's type.
  3. No other exported declaration moved. DataTableSchema.resizableColumns (data-display.ts / data-display.zod.ts) is untouched, as the claim excludes it: a different block's own key, and DataTable's prop on the left of the renderer's assignment.

Zod accept sets (@object-ui/types/zod):

  1. The flat ObjectGridSchema gains resizableColumns: retirementTombstone(OBJECT_GRID_RESIZABLE_COLUMNS_RETIRED) — RIGHT (stroke 2). It NARROWS the exported flat mirror's tolerant face: BaseSchema is .passthrough(), so the key was kept unexamined; it is now refused at the key with invalid_type, and the one-string message names properties.resizable with a literal prescription. Same helper and shape as the defaultSort tombstone next to it. The constant is module-local, not exported.
  2. The authored doors (AnyComponentSchema, StrictAnyComponentSchema, safeValidateSchema) did NOT move — RIGHT, and the PR body says so. ObjectGridBlockSchema on main spreads flatPropRefusals('object-grid', row) and takes properties: propsBag(row) from the spec row; flatPropRefusals hands a retired row member (a z.never) through by reference, so a flat resizableColumns already met the spec's own retirement, and the bag refused it through the row. The round-7 pin drives all three doors, flat and in the bag, with the properties.resizable lit control on each.
  3. The object-view table slot: unchanged — RIGHT. On main the slot is BaseSchema.extend(ObjectGridSchema.shape).omit({ type, objectName }).extend(OBJECT_VIEW_TABLE_WITHHELD).partial(), and the withheld map's own tableKeyRefusal('resizableColumns', …) comes after the spread, so it wins over the new tombstone member. Pinned on every door by the round-7 test (the slot's message still carries objectui#10976), and by the untouched round-6 slot test and the object-view-slot-key-lists alias row. The dev's H3 "partly falsified" is the right reading: those two pin the slot's own refusal, which this round leaves standing; flipping them would have been wrong.
  4. Nothing is mirrored and no door widens: the only member added is a z.never tombstone, and the one face it reaches beyond the flat mirror (the slot, through .shape) overrides it with its own refusal. So the Clause-②: no declaration is not a false one (②).

Renderer (@object-ui/plugin-grid):

  1. ObjectGrid hands DataTable resizableColumns: schema.resizable ?? true, the ?? schema.resizableColumns operand gone — RIGHT (stroke 3). git grep at main finds that line as the one renderer read of the key on an object-grid schema; the other non-test hits are DataTable's own prop, the slot's refusal and comments. Behaviour change, stated in the changeset: a node composed in code with resizableColumns: false alone now keeps its resize handles. No producer writes the key (my grep of main's non-test source found none; the dev's repository-wide fixture sweep read 0 with a resizable control of 11). Pinned by the new plugin-grid test on resize-handle counts with CONTROL and LIT CONTROL rows; the dev's A1 ablation reports exactly that row flipping.
  2. The registration's resizable input description and the header comment — RIGHT; prose only, no input added or removed, so no registration pin moves, and the SDUI manifest copy refreshes with the objectstack pin bump as always. "On by default" matches ?? true.

Test-only ledger moves (no published face):

  1. UnmirroredDeclared 5 entries / 6 keys to 4 / 5; spec-derived 3 / 4 to 2 / 3; local 2 / 2 unchanged; the cross-ledger union 10 to 9 with 0 shared — RIGHT. Re-added from the entries on main: ChatbotSchema (1), ChatbotFloatingSchema (1), DashboardWidgetSchema (2), FormFieldSchema (1), ObjectGridSchema (1) is 5 / 6; the one-key ObjectGridSchema entry leaves whole, 4 / 5. The spec-derived half held ObjectGridSchema, DashboardWidgetSchema and FormFieldSchema (3 / 4), now 2 / 3; the local half is the two chatbot twins, untouched. RuntimeOnlyDeclared has 5 entries and shares none, so 4 + 5 = 9. Every pinned prose figure moved with a history sentence (the header bullet, both ledger docstrings, the split line, the totals line, the cross-ledger sentence), and the entry is rewritten as the departed-entry comment its neighbours use, keeping its 17 / 15 / 14 / 11 / 1 history. SPEC_DERIVED_PAIRS keeps the pair, rightly: membership is derived from the spec references in the mirror's initializer, which did not change. No KnownDrift, RuntimeOnlyDeclared, WiderThanDeclared or MirroredUndeclared row moved. The objectui#7279, finding(types): zod-mirror-parity's three LEDGER entry counts are still hand-written prose — the half of #6141 that #7433's scope deliberately left behind #7733, finding(types): zod-mirror-parity's header says KnownDrift holds 62 keys; two instruments measure 63 — wrong since objectui#7664, and the sibling half of #7733 #8222 and finding(types): zod-mirror-parity's two ledger docstrings say UnmirroredDeclared records 94 keys; two instruments measure 87 — unmoved since objectui#7779, and outside every pin in the file #8243 pins derive these figures; the Test shards are the reading (③).
  2. The paragraph listing which cross-ledger figures are pinned now names them by role instead of digit — RIGHT, and a repair inside the claimed file: the digits it spelled (13, 8, 8) were stale before this round, and a meta-paragraph that names figures by role cannot rot the way one that restates them can. The pinned sentences themselves keep their digits, so nothing an instrument reads lost one.
  3. The round-6 test's "is NOT mirrored" assertion flipped in place into the retired assertion (a member, true and false each refused at the key), with the docstring saying why — RIGHT; the old fact is false on this head and the file keeps its history.

Corpus and docs:

  1. No document or fixture writes resizableColumns on an object-grid. My grep of main's content/**, *.md and *.mdx finds only data-table.mdx (DataTable's own prop), plugin-view.mdx and the plugin-view README (the slot's legacy alias, still true on this head) and CHANGELOG history. No doc change is owed. Build Docs, Doc Snippet Type Check, Doc Component Type Check and Internal Docs Link Check are green.
  2. Pending changesets: none on main names resizableColumns, this card or an UnmirroredDeclared figure (grep of .changeset/*.md), so no dated correction is owed. Changeset Claim Re-read and Changeset Overwrite Report are green.

File surface against the claim 6056162668: every one of the 8 named files is touched and inside scope; the two new pin files (unmirrored-declared-round7-6152.test.ts, ObjectGrid.resizableColumnsRetired-6152.test.tsx) are the dev-declared widening, following the per-round pin precedent of rounds 3 to 6; every excluded path (DataTableSchema, the 17.7.0 member moves, ObjectCalendarSchema.calendar) is untouched. Governed Surface Queue Guard is green: not governed.

② Semver level

  • What the diff publishes: a TypeScript narrowing on one member of one exported interface; a zod tolerant-face narrowing on the exported flat ObjectGridSchema (one tombstone); one renderer behaviour change in @object-ui/plugin-grid; a registration description string. No widening, and the authored doors are unchanged.
  • .changeset/6152-resizable-columns-retired.md: @object-ui/types minor and @object-ui/plugin-grid minor, headed "Retired (breaking)", stating what the TypeScript face, the flat mirror and the renderer now do, the FROM to TO mapping (resizableColumns to resizable, properties.resizable on an authored node) and that table.resizableColumns is unchanged — MATCHES what the diff publishes. The fixed release group prices a stated break as minor (objectui AGENTS.md: no major in a changeset; the rounds 1, 3, 4, 5 and 6 precedent, each PASSed at tier). Changeset Declaration, Changeset Bump Policy, Changeset Fixed Group Check, Changeset Overwrite Report and Changeset Claim Re-read are all success. The ledger and pin moves are test-only and rightly absent from the bump.
  • Clause-②: no on the claim and on the PR body — RIGHT under the pm-dispatch skill's own text: a card that narrows a published accept set is Clause-②: no and owes one contract-tier review before enqueue, which this record is. The rounds 4 and 5 spelling yes (narrowing) is also allowed by that text (declaring yes for a narrowing is never an error), so the two rounds do not conflict. A no is a false declaration only if the diff widens anything, and ① 7 finds no widening.

③ Boundary flags

Dev-declared deviations (report 6057365466), each answered:

  • (a) H3 partly falsified and stated, not forced: the slot test and the alias row kept their assertions — RIGHT (① 6).
  • (b) The digits-to-roles prose repair inside zod-mirror-parity.test.ts — RIGHT (① 11).
  • (c) Two new pin files beyond the claim's named surface — accepted: they are the round's own tests, per the per-round pin precedent; the seat may widen the claim's surface by amendment, and nothing on this head waits on it.
  • (d) Model-free commit trailers and the session-URL PR footer — objectui AGENTS.md's own requirement; not a contract matter.
  • (e) Heavy suites and doc gates ran at 4a1feb41, and 06db65a6 changes only the plugin-grid pin's cast — accepted: this record reads the head's check-runs, not the local runs.
  • (f) main moved to f3a0488c (one app-shell commit, disjoint from the surface) after the base; merge-tree clean, main not merged — accepted: the PR reads behind, and the queue arbitrates.

out_of_scope_findings, one: the console registry-inputs-spec-parity.test.ts comment ending "Retiring the renderer's own read of the old spelling is objectui#6152's." becomes past tense once this lands — accepted as noted, not filed, with its carrier (the next PR touching that file): prose no assertion reads, outside the claimed surface, and not false (it names the card that did it). Not a defect, not a card.

open_questions: none. The round-6 open question (5957803718) was answered A in 5957903936, this round is the follow-up that answer named, and its precondition (an installed spec that refuses the key) is met on main's lockfile.

Check-runs on this head, at the final poll, all 43 completed: 39 success, 3 skipped (Test coverage, Test coverage shard, dependabot — the expected skips) and 1 failure, Bundle Analysis. Every Test shard (1 to 8), Type Check, Lint, Spec Main Shape Gate, Build & E2E, Test (dist pins) and every changeset and doc gate is success, so the Type Check reading in ① 1 and the Test shards reading in ① 10 stand. The one red: its failing step is Check console performance budget, and the budget table that check renders on the PR reads the eager closure at 3307.5 KB against a 3307.0 KB ceiling. Read from the check-runs and jobs API, the merge base 19a7348 and main f3a0488c both fail Bundle Analysis at the same step; the first error line of those logs sits behind a log endpoint this container's proxy refuses, so the signature match is on its step half. This diff adds no import, module or chunk and removes one ?? operand, so it cannot own an eager-closure red; whether the merge-base-signature exception admits it to the queue is the seat's reading at enqueue, not this record's. Not a FAIL item here.

Noted, not flagged:

  • The changeset body carries no Clause-② line, a convention roughly a third of the pending changesets follow and no gate reads; the claim and the PR body carry it at line start, where the enqueue gate reads it. Cosmetic.
  • OBJECT_GRID_RESIZABLE_COLUMNS_RETIRED and the resizable description carry objectui#6152; objectui's tombstone messages do (the round-7 pin asserts another message contains objectui#10976), so within this repository's convention.
  • The installed @objectstack/spec package is not on disk in this container's checkout, so its row was not read from node_modules; the precondition is read from pnpm-lock.yaml (17.7.0, one resolution), packages/types/package.json (^17.7.0) and main's console parity pin, which records 17.7.0's tombstone text for object-grid.resizableColumns, and the round-7 pin re-reads the installed row under the Test shards.
  • plugin-view.mdx, the plugin-view README and the ObjectView relay comment still call resizableColumns a legacy alias the table slot withholds (write resizable) — still true on this head, as the dev's acceptance note says.

Escalations: none. No maintainer decision is needed for this head to land.

Implemented-by: claude/issue-6152-resizable-columns-retire
Reviewed-by: session_01DBZ9bntPZ7VKyQNtJeNsgw

VERDICT: PASS

Rendered 2026-10-08T10:12Z · a read-only contract review of PR objectui#11955 on the head named above; the newest record naming this head governs, and any push after it voids it.


Generated by Claude Code

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 336 chunks) 3306.6 KB 3307.0 KB
Main entry chunk (gzip) 71.3 KB 350 KB
Entry file index-DxXQbKmA.js —
Status PASS —

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

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 17.82KB 6.58KB
app-shell (runtime-config.js) 22.59KB 7.89KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.11KB 7.97KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.28KB 2.60KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.50KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 586.28KB 141.14KB
core (index.js) 10.00KB 3.96KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 240.39KB 67.09KB
fields (index.js) 266.92KB 67.47KB
i18n (LocalizationContext.js) 2.92KB 1.42KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.52KB 2.39KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.35KB 12.88KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 38.37KB 10.31KB
i18n (useSafeTranslation.js) 7.14KB 2.92KB
layout (index.js) 41.50KB 11.82KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.86KB 5.00KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.52KB 2.26KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.04KB 3.92KB
plugin-calendar (index.js) 53.39KB 15.52KB
plugin-charts (index.js) 84.71KB 23.25KB
plugin-chatbot (index.js) 199.63KB 47.46KB
plugin-dashboard (index.js) 144.82KB 39.17KB
plugin-designer (index.js) 231.46KB 48.87KB
plugin-detail (index.js) 248.57KB 65.47KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 176.62KB 45.75KB
plugin-gantt (index.js) 179.17KB 45.07KB
plugin-grid (index.js) 248.06KB 68.79KB
plugin-kanban (index.js) 52.17KB 16.37KB
plugin-list (index.js) 117.45KB 29.33KB
plugin-map (index.js) 27.24KB 9.03KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.12KB 12.29KB
plugin-timeline (index.js) 39.10KB 11.81KB
plugin-tree (index.js) 15.07KB 5.33KB
plugin-view (index.js) 91.07KB 22.93KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.81KB 3.58KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 120.63KB 39.56KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.50KB 2.06KB
react (schema-input.js) 4.31KB 2.07KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.50KB 1.99KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 7.30KB 3.12KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 23.87KB 7.83KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (authoring-nodes.js) 0.20KB 0.19KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (cloud.js) 0.20KB 0.18KB
types (complex.js) 4.44KB 2.07KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (dashboard-widget-layout.js) 2.06KB 0.96KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 1.13KB 0.65KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 5.78KB 2.70KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (node-slots.js) 7.18KB 2.34KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 4.99KB 1.96KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 19.93KB 7.25KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 36b547a435e53f20731efb50188a8189a3687ffe
Local-runs: none

PR objectui#11955, round 7 of card objectui#6152 (draft, not ready, no auto-merge, head repo is the base repo). This head is a base merge: 36b547a4 merges main 3c888c6e into the branch on top of 06db65a6, which the at-tier record 6057624502 on this thread (2026-10-08T10:12Z) judged PASS in full. This record is NARROW by design. It asks three things: is the net diff against main the same change it was at 06db65a6; did anything main brought in touch a file, symbol or contract that record relied on; and what do the check-runs on this head read. Where the first two hold, the earlier record's ① 1 to 14 and its ② carry over to this head unchanged and are not restated. Inputs, and nothing else: the card's comments from the claim 6056162668 onward (the dev report 6057365466, the seat's ACCEPT 6057654297, the base-merge report 6058030427), the earlier record, the PR body, its 10-file list, its 3 commits, the net diff against main at this head, and the check-runs on this head. Reads were git fetch, git diff, git patch-id --stable, git rev-parse, git log, git merge-base and git show in the existing checkout, plus gh api GETs. Nothing was built, run or re-run.

① Derived judgments

  1. The net diff did not move: SAME CHANGE. git diff 3c888c6e 36b547a4 and git diff 19a7348 06db65a6 (the merge base, where the earlier record read it) are byte-identical: 39,936 bytes each, cmp equal, one git patch-id --stable for both, b9603e596c2b39f0bbe5b8061c97bed409790278. Same 10 files, +365 / −75, the PR's file list exactly. Per file, all 10 patch-ids are SAME, and the 10 blobs at 36b547a4 are the blobs at 06db65a6 (git rev-parse HEAD:PATH, 10 of 10 SAME). So there is no difference to judge in full: every derived judgment of 6057624502 (the ?: never member, the flat-mirror tombstone, the unchanged authored doors and table slot, the renderer's schema.resizable ?? true, the ledger figures 4 / 5, 2 / 3, 2 / 2 and union 9, the changeset) reads off the same bytes on this head.
  2. The merge commit carries main's side and nothing else: RIGHT. 36b547a4 has parents 06db65a6 and 3c888c6e; git merge-base 06db65a6 3c888c6e is 19a7348. git diff 06db65a6 36b547a4 (main's side as the merge brought it) has the same git patch-id --stable as git diff 19a7348 3c888c6e, 470374267450f8affb70472a63836b3d66a3c4dc: 10 files, +22 / −699. No conflict resolution, no hunk of either side dropped or added. The base-merge report 6058030427 states the same two diffstats; this record derives them rather than copies them.
  3. What main brought in. Two commits in 19a7348..3c888c6e: f3a0488c (objectui#11932, the Studio Interfaces pillar's page-create step) and 3c888c6e (objectui#11956, the revert of objectui#11931 and objectui#11932 that brings the console's eager closure back under its ceiling, anchor objectui#11937). Net over the window: .changeset/11861-validation-presets.md deleted, .changeset/11937-eager-budget-rollback.md added (@object-ui/app-shell patch), content/docs/guide/console.md (the Validations tab's row), and seven packages/app-shell/src/views/** files (metadata-admin/i18n.ts, the studio-design/ObjectValidationsPanel* files, validationPresets.ts deleted). The objectui#11932 files were added and reverted inside the window and net to zero.
  4. Nothing the earlier record relied on moved: CHECKED, by name. Files under packages/types/, packages/plugin-grid/, apps/console/, packages/plugin-view/ and content/docs/plugins/ in main's window: 0, 0, 0, 0 and 0. Blob-identical at 19a7348 and 3c888c6e (git rev-parse REF:PATH, each SAME): packages/types/src/objectql.ts, packages/types/src/zod/objectql.zod.ts, packages/types/src/__tests__/zod-mirror-parity.test.ts (the mirror-parity ledgers), packages/plugin-grid/src/ObjectGrid.tsx, packages/plugin-grid/src/index.tsx (the plugin-grid registration), apps/console/src/__tests__/registry-inputs-spec-parity.test.ts (the console parity guard), packages/types/src/data-display.ts and packages/types/src/zod/data-display.zod.ts (DataTableSchema, excluded by the claim), pnpm-lock.yaml, packages/types/package.json and packages/plugin-grid/package.json. The precondition the earlier record read still reads the same on 3c888c6e: packages/types/package.json declares @objectstack/spec at ^17.7.0, and the lockfile resolves @objectstack/spec@17.7.0 and nothing else. A grep of main's window diff for resizableColumns, resizable, ObjectGrid, DataTable, UnmirroredDeclared, KnownDrift, RuntimeOnlyDeclared, SPEC_DERIVED_PAIRS, flatPropRefusals, ObjectGridSlotKey, OBJECT_VIEW_TABLE_WITHHELD, retirementTombstone, plugin-grid, objectql and registry-inputs-spec-parity: 0 hits. The only spec-adjacent lines in that diff are app-shell imports from @objectstack/spec/data and @objectstack/spec/shared, which name no @object-ui/types or @object-ui/plugin-grid symbol.
  5. The earlier record's pending-changeset and docs readings still hold. All 183 .changeset/*.md on 3c888c6e scanned for resizableColumns, 6152 and UnmirroredDeclared: 0 hits, so no dated correction is owed (the earlier ① 14). The one changeset main added bumps @object-ui/app-shell patch and names the eager-closure rollback only. The console.md edit rewrites the Validations tab's row and does not name resizableColumns (the earlier ① 13).
  6. Claim and body. The PR body was not edited for this head (the base-merge report says so, and the body still names 06db65a6 as the head its local gates ran at, which is true as history). Clause-②: no stands at line start on the claim and on the body, and the diff that declaration describes is byte-identical (① 1). The branch is claude/issue-6152-resizable-columns-retire, the head repo is the base repo, the change is 440 lines, and Governed Surface Queue Guard is success on this head: not governed.

② Semver level

Unchanged from 6057624502, because what the diff publishes is unchanged byte for byte (① 1): a TypeScript narrowing of ObjectGridSchema.resizableColumns to never, one flat-mirror tombstone, one renderer behaviour change in @object-ui/plugin-grid, one registration description string, and no widening. .changeset/6152-resizable-columns-retired.md is blob-identical: @object-ui/types minor and @object-ui/plugin-grid minor, the break and the resizableColumns to resizable mapping stated. Main's new changeset bumps a different package in the fixed group and does not interact with it. On this head Changeset Declaration, Changeset Bump Policy, Changeset Fixed Group Check, Changeset Overwrite Report and Changeset Claim Re-read are all success. Clause-②: no is not a false declaration: nothing widens.

③ Boundary flags

Check-runs on 36b547a4, final reading. Polled 17 times from 2026-10-08T10:39Z until none was in progress, at 2026-10-08T10:54Z: 43 check-runs, all 43 completed, 40 success, 3 skipped (dependabot, Test (coverage) and the coverage shard, the expected skips), 0 failure, 0 in progress. Every Test shard 1 to 8, Test (the fan-in, the last to complete), Type Check, Lint, Spec Main Shape Gate, Build & E2E, Test (dist pins), Governed Surface Queue Guard, Bundle Analysis, and every changeset and doc gate is success. So the Type Check reading behind the earlier ① 1 (the @ts-expect-error and Equal pins), the Test-shard reading behind its ① 4 to 6 (the mirror, door and slot pins) and its ① 10 (the ledger figures) stand on this head, now on the merged tree rather than the pre-merge one. No failure to name.

Bundle Analysis. Conclusion success on this head: every step of job 113269138416, Check console performance budget included, is success. The bot's budget comment for this head (6058041722, 2026-10-08T10:38Z) reads the eager closure at 3306.6 KB against the 3307.0 KB ceiling, PASS (gzip, 336 chunks; main entry chunk 71.3 KB against 350 KB). For contrast, read off the check-runs API: 06db65a6 and the merge base 19a7348 both failed this check at that step (the prior head's budget comment 6057399473 read 3307.5 KB), and main at 3c888c6e passes it (2026-10-08T10:33Z). So the red the earlier record left to the seat's enqueue reading is gone on this head, and the seat's share estimate in 6057410051 (near 3306.7 KB on the revert's base) is consistent with the figure this merge ref read.

Dev-declared deviation (base-merge report 6058030427), answered: the merge named main's sha 3c888c6e rather than the ref origin/main. Accepted: same commit, only the merge message's wording differs, and pinning a sha against a moving remote-tracking ref is the discipline the repository asks for. The report's open point, whether a main-only merge owes a new record, is answered by this record.

Superseded from the earlier record: its deviation (f), that main had moved to f3a0488c and was not merged, no longer describes this head; main is merged at 3c888c6e, which contains f3a0488c and its revert.

Noted, not flagged:

  • The PR body's "Gates at the final head 06db65a6" and its ablation shas are history, not a claim about this head; the merge changed no file of the round (① 1), and this record reads this head's check-runs rather than the body's local runs.
  • The check-run set on this head carries the same 43 names as 06db65a6's. The Test fan-in registers only after the eight shards finish, which is why an earlier poll read 42; the final reading above is on 43.
  • main has moved on since this merge: origin/main read 1c51e973 at the time of this record, four commits past 3c888c6e (objectui#11938, objectui#11952, objectui#11940 and objectui#11949, the eager-closure ceiling allowance), so the PR will read behind again. git diff --name-only 3c888c6e origin/main names no path under packages/types/, packages/plugin-grid/ or apps/console/, and neither the lockfile nor packages/types/package.json. That is the queue's business, which rebuilds the merge group against current main, and the seat's enqueue reading; a further base merge would be a new head owing a new record, and nothing here depends on whether one is made.

out_of_scope_findings: none new; the earlier record's one (the console parity test's past-tense comment, carrier the next PR touching that file) stands as noted. open_questions: none. Escalations: none. No maintainer decision is needed for this head to land.

Implemented-by: claude/issue-6152-resizable-columns-retire
Reviewed-by: session_01DBZ9bntPZ7VKyQNtJeNsgw

VERDICT: PASS

Rendered 2026-10-08T10:56Z · a read-only contract review of PR objectui#11955 on the head named above; the newest record naming this head governs, and any push after it voids it.


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 8, 2026 10:57
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 8, 2026 10:57
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 8, 2026
Merged via the queue into main with commit d73d987 Oct 8, 2026
45 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-6152-resizable-columns-retire branch October 8, 2026 11:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants