Skip to content

fix(core,react): a refused dataSource binding limit is not authored and yields to the view's cap (objectui#10016) - #10389

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-10016-binding-limit-not-authored
Sep 24, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-10016-binding-limit-not-authored

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #10016
Clause-②: yes

Ruling 5749674763 (batch #198 item 4, letter A) applied. A dataSource binding's own limit gets the positivity check objectui#10014 gave the saved view's operand. A refused binding cap (0, a negative, a fraction, or a non-number) is not authored: the chain falls through to savedViewLimit(view), and when that is absent too, to the consumer's own default. The rule is objectui#10009's precedent (a contract-refused value is not authored, so the other source wins), applied to the two operands of one resolver. The defect carried on the thread (5814132982) is in the same stroke: ViewDataProvider no longer reports a refused view cap when the binding's own usable limit is the cap actually used.

What changed

  • composeElementDataSource: config.limit ?? savedViewLimit(view) becomes bindingLimit(config) ?? savedViewLimit(view). bindingLimit is module-private and applies the same isUsableRowLimit predicate savedViewLimit uses. null stays absent, as ?? made it.
  • elementDataSourceRefusedLimitMessage (the channel objectui#10014 built; ⛔ no third channel): it takes two optional trailing parameters, binding and operand ('view', the default, or 'binding'). The binding operand has its own sentence, built by a module-private sibling, and that sentence names the binding (dataSource binding on OBJECT ... declares limit: VALUE). So the two refusals are told apart when both fire. For the view operand, the builder now applies the condition "the binding supplied no usable cap" itself, so both callers share one copy of it. No new export: @object-ui/core's entry list is byte-identical, and a three-argument call answers exactly as before.
  • ViewDataProvider.resolveElementDataSource asks both operands and warns once per refused operand on the existing console.warn channel.
  • ElementDataSourceGate (renderer path):
    • The view cap that takes a refused binding cap's place is a view-sourced BASELINE. A usable component cap still wins over it, and the gate's fromView for the row cap is now "the binding has no usable limit".
    • The binding refusal is reported once per declaration, from an effect, for a block that reads a row cap.
    • The view refusal's binding condition moved into the builder.
  • The objectui#9928 test's KNOWN GAP header now points at this card's test file. None of objectui#10014's or objectui#10241's assertions were rewritten.

Zone 2 readings (measured on ea02938cd, the branch base)

  1. element-data-source.ts held const limit = config.limit ?? savedViewLimit(view); in composeElementDataSource, savedViewLimit reading savedViewRawLimit through isUsableRowLimit, and elementDataSourceRefusedLimitMessage(view, viewName, object). Confirmed.

  2. The callers that reported the view refusal:

    • ViewDataProvider.resolveElementDataSource, which called elementDataSourceRefusedLimitMessage(view, config.view, config.object) and warned unconditionally;
    • the gate's describeRefusedViewRowLimit, which returned null on config.limit != null or a usable component cap, under if (limit).

    Confirmed. A third caller of the composer exists: useElementDataSource, whose consumers are the gate and element:record_picker. The record picker reports neither refusal today, so by the dispatch's rule it is out of scope. It is listed under Acceptance notes.

  3. The builder was reused through a parameter, with no new export. Confirmed feasible. The additive parameters sit on an export that has not been released yet: .changeset/9928-saved-view-limit-non-positive.md is still pending.

  4. The truth table follows.

Truth table, measured before and after on both callers

The instrument was a throwaway probe, not committed. It ran against the base blobs of the three source files, then against HEAD, and the restore was proven by blob hash. "none" = no limit reached the fetcher, or no cap was written to the node. Warnings are listed by the operand they name.

ViewDataProvider (fetcher limit):

binding view before after
absent no cap none, no warning none, no warning
absent usable 25 25 25
absent refused 0 none, view warning none, view warning
usable 3 no cap 3 3
usable 3 usable 25 3 3
usable 3 refused 0 3, view warning (false claim) 3, no warning
refused 0 no cap 0 none, binding warning
refused 0 usable 25 0 25, binding warning
refused 0 refused 0 0, view warning none, binding + view warnings

ElementDataSourceGate (pagination.pageSize written; component cap C):

C binding view before after
absent refused 0 no cap 0 none, binding warning
absent refused 0 usable 7 0 7, binding warning
absent refused 0 refused 0 0 none, view + binding warnings
usable 50 refused 0 no cap / usable 7 / refused 0 0 (over the usable 50) 50, binding warning
refused 0 refused 0 no cap 0, displaced-cap message claiming "(0) was used" 0 (the component's own, for the renderer's diagnostic), binding warning
refused 0 refused 0 usable 7 0, displaced-cap message 7, displaced-cap + binding warnings
refused 0 refused 0 refused 0 0, displaced-cap message 0, view + binding warnings

The probe covered 27 gate rows (C x binding x view, each three-valued). The 18 rows without a refused binding are identical before and after, in value and in warnings. On the gate, the carried defect's row (usable 3 x refused 0) was already silent, and it still is. Only the rows with a refused binding change resolution. Everywhere else, the one change is the carried-defect warning on ViewDataProvider. This matches Zone 2 item 4.

Tests (HEAD 22feffeb2)

  • New element-data-source.bindingLimitNotAuthored-10016.test.ts. It covers the composer's full table over refused values 0, -10, 25.5, "20", and the builder, which names each operand, stays silent under a usable binding, and gives two distinct messages when both operands are refused. It also covers every ViewDataProvider row, including the dispatch's five minimum pins.
  • A new block in ElementDataSourceGate.test.tsx has every refused-binding row, the component-cap rows, the flat limit key, a re-render guard, the carried-defect row, and CONTROL and SILENCE rows.
  • pnpm exec vitest run packages/core/src/data-scope/ packages/react/src/element-data-source/: 8 files, 260 tests passed.
  • Union on the final commit, 22feffeb2: pnpm exec vitest run over the two directories above, plus every other test file that names the binding, the gate, the hook, the composer or resolveElementDataSource (51 files across plugin-list, grid, kanban, timeline, detail, form, dashboard, map, calendar, gantt, charts, view, components, app-shell, console, types and scripts). The union also includes the two tests that read the touched sources as TEXT: injected-component-input-6950.test.ts and registry-assertion-ratchet-8316.test.ts. useResolvedDataSource.schemaRendererContextRead-7209.test.ts is already inside the gate directory. Result: 61 files, 1203 tests passed.
  • pnpm --filter @object-ui/core --filter @object-ui/react run type-check passed. Both echoed type-check: Done, after pnpm --filter '@object-ui/react^...' run build rebuilt the closure from HEAD; the rebuilt core .d.ts carries the new operand parameter. tsc -p tsconfig.test.json --listFiles counts the new core test file (1) and the gate test file (1).

Ablations (each through ablation-replace.mjs WRAP mode: the anchor had to hit x1, the landing was proven by anchor and replacement counts and a blob change, and the restore was proven by blob == HEAD and an empty git diff HEAD)

@object-ui/core is aliased to packages/core/src by the root vitest config, and no dist/ was on disk during these runs. So each mutation reached both suites without a build.

  • (a) The binding positivity check was removed (bindingLimit returns config.limit). Blob cc2aa376 went to 302d2fde and was restored to cc2aa376. 35 failed / 225 passed: every refused-binding row on the composer, ViewDataProvider and the gate. 0 of the failures carry CONTROL or SILENCE. The two gate rows with a usable component cap stayed green, because the gate's own fromView condition guards them, hence (c).
  • (b) The unconditional view warning was restored (the builder's if (isUsableRowLimit(binding?.limit)) return null; was deleted). Blob cc2aa376 went to b7c7c10a and was restored. 5 failed: the ViewDataProvider carried-defect row, the builder row, the gate's carried-defect row, and two objectui#10241 pins whose guard now lives in the builder. Those two are "the binding's own limit wins over the view" and "a binding limit displaced a refused component cap". ⚠️ The ablation caught a naming error of mine. The gate's carried-defect row was labelled CONTROL, but under this suite's convention a CONTROL passes on both sides of the ablated guard, and this row does not. It was relabelled in a follow-up commit (22feffeb2).
  • (c) The gate's fromView was reverted to presence (binding.config?.limit === undefined). Blob f2082ce4 went to c9239886 and was restored. Exactly 1 failed: "binding 0 + usable view cap + usable COMPONENT cap ⇒ the component's cap wins over the view baseline".

Gates (each exit code captured before any pipe)

  • pnpm check:control-bytes: OK (scanned 8436 tracked text file(s); skipped 85 binary).
  • pnpm check:new-line-citations: VERDICT new-cross-file-line-citations: 0 new citation(s).
  • node scripts/check-changeset-presence.mjs: 6 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s).
  • pnpm check:changeset-claims passed; it flags nothing. pnpm check:pending-changeset-literals passed. node scripts/check-changeset-no-major.mjs passed.
  • pnpm check:test-path-roots and pnpm check:element-data-source-declaration (13 gate-consuming files) passed.
  • eslint, narrowed to the diff, as a measurement:
    • ① The population, read from eslint's own config: of the 7 changed files, eslint lints 6; the changeset .md gets "File ignored because no matching configuration was supplied".
    • ② --format json returned 6 results with 0 errors and 27 warnings. The base blobs of the same files give 27 warnings too: 13 + 9 + 5 on the three pre-existing files that carry any, and 0 on the new file.
    • ③ Invariance: type-aware linting is off (eslint.config.js has no projectService, no parserOptions.project and no TypeChecked preset), and no rule under eslint-rules/ reads the filesystem. So this diff cannot move a verdict on an untouched file.
  • NOT MEASURED, check:doc-examples and check:readme-exports. Reason: PREREQUISITE NOT MET, because 32 packages are unbuilt. The diff touches no @example block (0 hits in the diff) and adds no export. The full farm and repo-wide pnpm lint are CI's.

Population, with a lit control (card item 3)

The instrument was a throwaway walk at 22feffeb2, over git ls-files: 549 strict-JSON files and 257 JSON fences in .md/.mdx (changesets and CHANGELOGs excluded), plus a literal scan of dataSource: { object: ... } object literals in source.

population bindings with a limit (CONTROL: usable) refused
authored metadata (JSON + fences) 7 5 (5) 0
source literals 124 11 (11) 0

The control is lit in both rows, so this zero is a reading, not a dark instrument. No authored binding in the tree carries a refused limit. This agrees with the ruling's facet ②, which said the change is not urgent.

Seat amendment (2026-09-24T21:40Z). Line 2 now reads Clause-②: yes. The exported elementDataSourceRefusedLimitMessage gains two optional parameters, which changes the @object-ui/core exports-map surface, so a contract review is owed before enqueue (claim 5822089217, amended). The @object-ui/react changeset level moved from patch to minor at 226994a2f.

Acceptance notes

  • The write-surface refusal (the ruling's C half): 承接者:无. It was measured that the spec contract already refuses the value: on @objectstack/spec 17.4.0, PageComponentSchema.safeParse with dataSource.limit: 0 gives too_small at dataSource.limit, and ElementDataSourceSchema refuses 0 / -10 (too_small) and 25.5 / "20" (invalid_type). Whether every write surface runs that parse before persisting was not measured.
  • The third caller of the composer, element:record_picker (through useElementDataSource). It reports neither the view's refusal nor now the binding's, so by the dispatch's rule it is out of scope. Its resolution follows the ruling for free (composed?.limit ?? props.limit ?? 50). Its registry description still states the precedence as dataSource.limit ?? limit ?? 50, which predates both objectui#9928 and this card. 承接者:无.
  • content/docs/guide/data-source.md says "sort and limit override the view's". That is still true for a usable binding limit, and it says nothing about a refused one. It is outside this claim's file surface. 承接者:无.
  • ReportView forwards dataSource.limit raw as $top, but the report contract declares that key dataSource?: never (and the spec's ReportSchema refuses it as an unrecognized key), so it is not this binding. It was noted and not pursued.
  • The objectui#10009 changeset's "an explicit cap on the dataSource binding still wins over both" now holds for a usable binding cap. This PR's changeset states that explicitly.

Changeset: .changeset/10016-binding-limit-not-authored.md. @object-ui/core is minor, following objectui#10014's level for this class, and @object-ui/react is minor since head 226994a2f (seat respin; it was patch, following objectui#10009 and objectui#10241), because the gate's precedence changes on the refused-binding rows. The changeset states the behaviour change plainly.

The implementing session is https://claude.ai/code/session_01BA3nKVUwKQJf8DBxrSVtNC (domain:ui seat 1 dispatch, mode:subagent).


Generated by Claude Code

…nd yields to the view's cap (objectui#10016)

The binding's own `limit`, the other operand of the row-cap chain, gets the
positivity check objectui#9928 gave the saved view's. A refused binding cap
(0, negative, non-integer, non-number) is not authored: the chain falls
through to the view's usable cap, then to the consumer's own default.

- composeElementDataSource: `bindingLimit(config) ?? savedViewLimit(view)`.
- elementDataSourceRefusedLimitMessage: optional `binding` and `operand`
  parameters; the binding operand has its own sentence naming the binding,
  and the view operand is silent when the binding's usable cap is used.
- ViewDataProvider reports both operands; its view warning no longer fires
  under a usable binding cap (the defect carried on the card).
- ElementDataSourceGate: the view cap that replaces a refused binding cap is
  a baseline a usable component cap wins over, and the binding refusal is
  reported once per declaration from an effect.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BA3nKVUwKQJf8DBxrSVtNC
…d is the core builder's

Ablating the builder's binding condition reddens it, so by this suite's
naming convention it is not a control. Moved into its own block.

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

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3042.9 KB 3104.5 KB
Main entry chunk (gzip) 148.4 KB 350 KB
Entry file index-CxLihquh.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) 16.68KB 6.20KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
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.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.52KB 3.45KB
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) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 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) 542.11KB 129.60KB
core (index.js) 8.94KB 3.59KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 224.12KB 62.26KB
fields (index.js) 254.86KB 64.50KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 34.99KB 11.45KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 39.28KB 11.09KB
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.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.39KB 3.10KB
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.01KB 3.93KB
plugin-calendar (index.js) 51.44KB 14.62KB
plugin-charts (index.js) 72.58KB 20.29KB
plugin-chatbot (index.js) 198.27KB 47.18KB
plugin-dashboard (index.js) 133.19KB 35.25KB
plugin-designer (index.js) 216.12KB 44.37KB
plugin-detail (index.js) 260.94KB 67.93KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 146.34KB 37.47KB
plugin-gantt (index.js) 168.31KB 41.45KB
plugin-grid (index.js) 215.22KB 58.85KB
plugin-kanban (index.js) 49.30KB 15.39KB
plugin-list (index.js) 114.17KB 28.16KB
plugin-map (index.js) 21.74KB 7.07KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.55KB 11.99KB
plugin-timeline (index.js) 30.72KB 8.96KB
plugin-tree (index.js) 10.74KB 3.76KB
plugin-view (index.js) 85.86KB 21.38KB
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.66KB 3.50KB
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) 114.58KB 37.60KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.78KB 2.09KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.78KB 2.56KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 18.27KB 6.20KB
types (ai.js) 4.11KB 2.06KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
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) 0.20KB 0.18KB
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) 4.74KB 2.25KB
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 (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
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) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 17.15KB 6.32KB
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

…ed row-cap precedence (objectui#10016)

The gate's observable precedence changes: when the binding cap is refused,
a usable component cap now wins over the view cap, and the gate reports a
new refusal. Behaviour-changing work is minor in this repo; major is banned.

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

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3042.9 KB 3104.5 KB
Main entry chunk (gzip) 148.4 KB 350 KB
Entry file index-CxLihquh.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) 16.68KB 6.20KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
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.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.52KB 3.45KB
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) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 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) 542.11KB 129.60KB
core (index.js) 8.94KB 3.59KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 224.12KB 62.26KB
fields (index.js) 254.86KB 64.50KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 34.99KB 11.45KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 39.28KB 11.09KB
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.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.39KB 3.10KB
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.01KB 3.93KB
plugin-calendar (index.js) 51.44KB 14.62KB
plugin-charts (index.js) 72.58KB 20.29KB
plugin-chatbot (index.js) 198.27KB 47.18KB
plugin-dashboard (index.js) 133.19KB 35.25KB
plugin-designer (index.js) 216.12KB 44.37KB
plugin-detail (index.js) 260.94KB 67.93KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 146.34KB 37.47KB
plugin-gantt (index.js) 168.31KB 41.45KB
plugin-grid (index.js) 215.22KB 58.85KB
plugin-kanban (index.js) 49.30KB 15.39KB
plugin-list (index.js) 114.17KB 28.16KB
plugin-map (index.js) 21.74KB 7.07KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.55KB 11.99KB
plugin-timeline (index.js) 30.72KB 8.96KB
plugin-tree (index.js) 10.74KB 3.76KB
plugin-view (index.js) 85.86KB 21.38KB
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.66KB 3.50KB
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) 114.58KB 37.60KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.78KB 2.09KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.78KB 2.56KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 18.27KB 6.20KB
types (ai.js) 4.11KB 2.06KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
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) 0.20KB 0.18KB
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) 4.74KB 2.25KB
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 (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
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) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 17.15KB 6.32KB
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

…claimed but no test held (objectui#10016)

Component cap 50 + binding 0 + refused view cap; component cap 0 + binding
0 + view with no cap; component cap 0 + binding 0 + refused view cap. Each
asserts the written cap and the exact warnings the PR's truth table states.
Tests only.

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

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3042.9 KB 3104.5 KB
Main entry chunk (gzip) 148.4 KB 350 KB
Entry file index-OWkOButJ.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) 16.68KB 6.20KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
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.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.52KB 3.45KB
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) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 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) 542.11KB 129.60KB
core (index.js) 8.94KB 3.59KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 224.12KB 62.26KB
fields (index.js) 254.86KB 64.50KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 34.99KB 11.45KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 39.28KB 11.09KB
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.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.39KB 3.10KB
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.01KB 3.93KB
plugin-calendar (index.js) 51.44KB 14.62KB
plugin-charts (index.js) 72.58KB 20.29KB
plugin-chatbot (index.js) 198.27KB 47.18KB
plugin-dashboard (index.js) 133.19KB 35.25KB
plugin-designer (index.js) 216.12KB 44.37KB
plugin-detail (index.js) 260.94KB 67.93KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 146.34KB 37.47KB
plugin-gantt (index.js) 168.31KB 41.45KB
plugin-grid (index.js) 215.22KB 58.85KB
plugin-kanban (index.js) 49.30KB 15.39KB
plugin-list (index.js) 114.17KB 28.16KB
plugin-map (index.js) 21.74KB 7.07KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.55KB 11.99KB
plugin-timeline (index.js) 30.72KB 8.96KB
plugin-tree (index.js) 10.74KB 3.76KB
plugin-view (index.js) 85.86KB 21.38KB
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.66KB 3.50KB
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) 114.58KB 37.60KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.78KB 2.09KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.78KB 2.56KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 18.27KB 6.20KB
types (ai.js) 4.11KB 2.06KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
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) 0.20KB 0.18KB
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) 4.74KB 2.25KB
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 (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
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) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 17.15KB 6.32KB
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
objectstack-fleet Bot marked this pull request as ready for review September 24, 2026 22:14
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Sep 24, 2026
Merged via the queue into main with commit 97abedc Sep 24, 2026
45 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-10016-binding-limit-not-authored branch September 24, 2026 22:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

1 participant