Skip to content

fix(plugin-detail): record:history refuses a row cap the contract rejects instead of repairing it - #10093

Merged
os-tesla merged 3 commits into
mainfrom
claude/issue-10005-record-history-limit-refusal
Sep 20, 2026
Merged

os-tesla merged 3 commits into
mainfrom
claude/issue-10005-record-history-limit-refusal

Conversation

@os-tesla

Copy link
Copy Markdown
Collaborator

Fixes #10005

Clause-②: no — this PULLS BACK to the declared contract (@objectstack/spec declares the member a positive integer). It relaxes no accept set and widens no public surface; it narrows what a renderer forwards to values the contract already permits.

record:history was the one renderer in the row-cap family that neither honoured nor refused a cap the contract rejects: it turned one into a one-row window, or forwarded a fractional one. It now refuses and falls back to its own default — the answer its sibling record:activity already gives.

The measurement, re-taken here — not read back from the card

Both columns are REAL CODE, not a simulation of the expressions: the record:history column is the $top that reached DataSource.find() from the rendered renderer, and the record:activity column is that module's exported normalizeLimit called directly. One harness, run twice; the only thing that differed between the runs is the renderer's own bytes (blob verified in the same command as each run).

authored limit record:history to $top — BEFORE record:history to $top — AFTER record:activity window (untouched)
absent 50 50 20
0 50 50 20
-5 1 50 20
2.5 2.5 50 2
'lots' 50 50 20
10 10 10 10

⭐ The last row is the harness's own control: a usable cap passes through unchanged on both renderers, before and after. It does not move — so the two rows that DO move are readings, not a dead harness. The card's BEFORE column reproduced exactly, control included.

Two pre-declared STOP legs, both checked before any edit:

  • An earlier guard on schema.limit. There is none. Every limit occurrence in the unmodified renderer was the optional member on its props interface, the one derivation, the one $top, and the effect dependency list — nothing between them.
  • The spec's declaration, read at source in objectstack on origin/main (81e12e186f), not from the card. RecordHistoryProps.limit is z.number().int().positive().optional(), described there as "Maximum history entries displayed, and the $top of the self-fetch query (renderer default: 50)".

And the zero this card rests on, with a control lit by the same search: nothing in the tree pinned record:history's answer. The two test files that import the renderer assert nothing about limit or $top; the same two-step search run against the sibling lights up six files. A zero that is a reading.

What changed

One resolver — normalizeHistoryLimit — admits a positive integer and drops anything else for this block's own default of 50. The wire consumes it directly.

  • ⛔ Math.max(1, limit) is GONE rather than kept behind the resolver. It is the defect, not a belt: it REPAIRED a refused -5 into a one-row window and forwarded a fractional 2.5 untouched.
  • ⛔ The defaults did NOT move. record:history stays 50, record:activity stays 20. The pin spells 50 locally so a later drift fails instead of passing.
  • Coercion stays exactly where the sibling keeps it: a numeric string still resolves ('5' answers 5 here, as normalizeLimit('5') is pinned to 5 there). What narrows is the admitted value SET, not how a node's value is read.

The refusal is SILENT — decided by measurement, and the conflict is reported, not buried

The instruction was to match the sibling, and the sibling is silent: its normalizeLimit refuses with no diagnostic at all. So this renderer refuses silently too, and the silence is pinned.

⚠️ The same question has the OPPOSITE answer at the three read points objectui#9925 landed (object-kanban, object-timeline, and record:reference_rail — that last one in this very package): they refuse LOUDLY, naming the authored value on the developer channel. The family therefore holds two answers on loudness. This PR follows the instruction it was given and settles nothing; the pin that carries the silence says so in as many words, so whoever rules that question changes it deliberately rather than discovering it.

Evidence

RED before, GREEN after — file state verified in the SAME command as each run.

RED, pins written FIRST and run against the unmodified renderer (its blob verified equal to the base blob ed735a66…, and git diff --stat empty, in that same command):

× refuses a NEGATIVE cap — not a one-row window      AssertionError: expected 1 to be 50
× refuses a NON-INTEGER cap                          AssertionError: expected 2.5 to be 50
× the `properties` read point answers identically     AssertionError: expected 1 to be 50
× names nothing on the developer channel              AssertionError: expected 1 to be 50
Tests  4 failed | 7 passed (11)

The 7 that passed RED are the values the old derivation already answered correctly (absent, 0, NaN, a non-numeric string, the pass-through control, a numeric string, and the honoured properties path) — stated rather than hidden, because a pin set whose every member fails is usually measuring the harness.

GREEN, after the fix — renderer blob 0f97ccb4… (differs from base), sibling blob verified UNMOVED at 5ab2ef32… in the same command:

  • the new pin file plus the pre-existing record-history envelope pin: Test Files 2 passed (2) · Tests 13 passed (13)
  • the whole @object-ui/plugin-detail suite: Test Files 191 passed (191) · Tests 1889 passed (1889)
  • pnpm --filter @object-ui/plugin-detail run type-check (it echoes tsc --noEmit && tsc -p tsconfig.test.json, so the pin file is type-checked too): shared-lock VERDICT command-exit 0
  • pnpm --filter @object-ui/plugin-detail run lint: exit 0, 0 errors

Ablation, on the committed state — mutation AND restore proven by object hash, never by an exit code. A console.warn naming the authored value was injected into the refusal branch through an anchored replace that asserts its anchor matched (a zero-hit edit would otherwise exit 0 and read as a no-op), behind an EXIT INT TERM trap restoring with git checkout HEAD -- at an absolute path:

  • marker count before 0, after 1; on-disk blob moved 0f97ccb4… to db578e0d…, and the run stops if it did not
  • under the mutation the silence pin is RED, and the reported value is the INJECTED call
  • after restore: blob back to 0f97ccb4… = the HEAD blob, marker count 0, git diff HEAD empty

That ablation found a defect in my own pin. The silence control began as a blanket expect(warn).not.toHaveBeenCalled(). The ablation's output showed the spy ALSO catching an unrelated react-i18next NO_I18NEXT_INSTANCE warning — so whether it passed depended on which other tests in the file had rendered first: green for the whole file, red for anyone running that one test alone, and pinning test ORDER rather than this renderer's silence. The control now filters the spy down to calls about this renderer's row cap, and all three legs were re-measured: green in file order, green alone, and still red under the injected diagnostic with the injected call as the reported value.

Gates

Green here: check-changeset-presence (its own verdict line; a real patch bump, decided by RUNNING the gate — it was red before the changeset and names the file after), check-control-bytes, check-new-cross-file-line-citations (0 added by this branch, with that gate's six internal controls passing, so the zero is a reading), check-component-surface-parity (report-only, exit 0, names nothing in this diff), plus the package test / type-check / lint above.

⚠️ NOT A VERDICT, recorded as such:

  • the FIRST type-check attempt exited 2 with Cannot find module '@object-ui/components' across the package — a PRECONDITION NOT MET (the dependency closure was unbuilt), not a failure. Re-run properly after pnpm --filter '@object-ui/plugin-detail^...' build; the green above is that second run.
  • check-sdui-registration-pins exits 2 with No console build to weigh at apps/console/dist/assets — EXCLUDED, precondition not met: it needs an apps/console build, which CI's performance-budget workflow does. This diff registers nothing and adds no import.

Declared narrowing. Repo-wide pnpm lint, pnpm test and pnpm check are CI's runs, not this branch's. What makes the lint narrowing a measurement rather than a skipped step: the population comes from eslint's own config (249 files in the affected package, counted from its --format json output, 0 errors), and no type-aware linting is configured — the root flat config sets no parserOptions.project and no projectService, and the package carries no local config — so this diff cannot move the verdict on a file it did not touch. On the test side the package's public surface is byte-identical (the resolver is module-private, no export moved), so import-side packages owe nothing beyond CI's full sharded run.

Acceptance notes

Found while measuring, NOT fixed here, no label applied, no card opened by me — for the landing seat to dispose of:

  1. To file. record:activity's normalizeLimit FLOORS a non-integer instead of refusing it: normalizeLimit(2.5) answers 2, and the same member is declared z.number().int().positive().optional(). That is the same "repair a value the contract refused" shape this PR removed from record:history, one renderer over, and its pinned set (0, -3, undefined, 'lots') does not cover a non-integer — which is exactly how this one survived. Named probe: its own exported function. Untouched here because recordActivityFeed.ts is read-only under this order. Dedupe words: normalizeLimit non-integer floor · record:activity fractional limit · Math.floor refused row cap · plugin-detail limit int parity.
  2. To file. The family now holds two answers on LOUDNESS: silent at record:history (this PR) and record:activity, loud at objectui#9925's three read points. One ruling settles both; until it exists the pin here records the choice instead of leaving it to be discovered. Dedupe words: row cap refusal loudness family · describeRefusedRowLimit parity · record:history silent refusal · refuse-and-warn family answer.
  3. Noted, not filed. The two blocks still default differently on the same record page (50 and 20). Not mine to file: this card's own triage seat already raised it and reserved it as possibly intentional per-renderer product behaviour, and this order forbids unifying them. Who meets it next: the seat landing this PR, which is where that note already sits.

Session, in prose so it survives a body rewrite: this branch was implemented in session_018HrVaotisyhgmot9o2MLRq.


Generated by Claude Code

…d of repairing it

`@objectstack/spec` declares `RecordHistoryProps.limit` a positive integer
(`z.number().int().positive().optional()`). The renderer derived its cap with
`Number(...) || 50` and consumed it as `Math.max(1, limit)`: `||` caught `0`,
`NaN` and `''`, but a negative is truthy and survived it, so `Math.max` REPAIRED
an authored `-5` into a one-row window, and a fractional `2.5` went to the
adapter untouched as `$top`. Neither named a cause anywhere.

One resolver now answers the question — `normalizeHistoryLimit` admits only a
positive integer and drops anything else for this block's own default of 50 —
and the wire consumes it directly. That is the answer the sibling
`record:activity` already gives through `normalizeLimit`, silence included; the
two blocks' differing defaults (50 and 20) are untouched.

Pinned over the sibling's whole value set plus the two it does not cover, a
non-integer and the pass-through control, at the `$top` that reaches
`DataSource.find()` rather than at a helper — a correct normalizer is defeated
by a `Math.max(1, …)` reappearing at the call site, and only the wire sees both.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018HrVaotisyhgmot9o2MLRq
The blanket `expect(warn).not.toHaveBeenCalled()` pinned test ORDER rather than
this renderer's silence. MEASURED: rendering the timeline emits an unrelated
`react-i18next` `NO_I18NEXT_INSTANCE` warning, and whether it lands inside the
spy's window depends on which other tests in the file ran first — the assertion
was green for the whole file and red for anyone running that one test alone.

The control now filters the spy's calls down to ones ABOUT this renderer's row
cap. Both legs re-measured: the pin is green run alone as well as in file order,
and an injected `console.warn` on the refusal branch still turns it red with the
injected call — not the i18next noise — as the reported value.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018HrVaotisyhgmot9o2MLRq
@github-actions

github-actions Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

changeset-claim-re-read

⚠️ 1 pending changeset(s) describe a file this change touches

Their bodies publish verbatim into the CHANGELOG at the next release, so this is a request to re-read them against your diff — addressed here because you are the one seat that can answer it without re-deriving anything.

⛔ Nothing here blocks, and nothing here is a verdict on your change. This gate exits 0, is not a required context, and judges name resolution, never meaning: it asked whether a pending body names a file you touched. "Is this sentence still true?" is the one question it will not answer, and the one you are being asked to answer.

.changeset/6726-find-envelope-records-arms.md

  • names plugin-detail/src/renderers/record-history.tsx → packages/plugin-detail/src/renderers/record-history.tsx — edited by this change

    | module | what it does | | --- | --- | | components/src/hooks/related-count-store.ts | related-list tab badge count | | components/src/renderers/basic/data-list.tsx | element:repeater rows | | components/src/renderers/basic/elements.tsx | element:number client-side aggregate | | components/src/renderers/basic/record-picker.tsx | element:record_picker options | | plugin-detail/src/renderers/record-activity.tsx | record:activity self-fetch | | plugin-detail/src/renderers/record-history.tsx | record:history self-fetch | | plugin-view/src/ObjectView.tsx | non-grid (kanban / calendar / gallery / timeline) fetch |

Read the paragraph, not the line: both false halves of the objectui#8617 claim sat in one paragraph, and correcting either alone would have left it asserting the same wrong thing.

If a claim did go false, correct the body. That is precedented and prose-only, frontmatter untouched; check-changeset-overwrite.mjs will report the correction as its own case 2 ("correcting a declaration on purpose … legitimate"), which is the intended shape — one gate asks for the read, the other records the write.

Not covered, stated so nobody reads this as more: a born-false claim that spells no line address at all (objectui#9495 coordinated one by ORDINAL — "a grep finds that member first" — and deciding that means reading what the sentence means), a claim spelled as a symbol or a package rather than a backticked file name, and a file named ambiguously.

Compared the checked-out tree with cbda340f0 (merge-base with origin/main): 2 file(s) changed outside .changeset/, read against 1236 pending declaration(s) that publish a body (1801 pending in total). · run

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3058.7 KB 3104.5 KB
Main entry chunk (gzip) 146.9 KB 350 KB
Entry file index-BCfD865g.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.69KB 6.21KB
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) 25.05KB 9.16KB
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.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
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) 545.92KB 130.72KB
core (index.js) 8.94KB 3.59KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 221.99KB 61.72KB
fields (index.js) 251.67KB 63.42KB
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.22KB 2.26KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 32.15KB 10.49KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.90KB 10.97KB
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) 2.53KB 0.85KB
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) 14.81KB 3.63KB
plugin-calendar (index.js) 50.26KB 14.36KB
plugin-charts (index.js) 71.73KB 20.08KB
plugin-chatbot (index.js) 198.20KB 47.14KB
plugin-dashboard (index.js) 132.96KB 35.17KB
plugin-designer (index.js) 215.94KB 44.33KB
plugin-detail (index.js) 255.24KB 66.50KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 139.56KB 35.40KB
plugin-gantt (index.js) 167.62KB 41.26KB
plugin-grid (index.js) 213.44KB 58.21KB
plugin-kanban (index.js) 48.71KB 15.17KB
plugin-list (index.js) 113.53KB 27.99KB
plugin-map (index.js) 21.48KB 6.99KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.41KB 11.93KB
plugin-timeline (index.js) 30.68KB 8.95KB
plugin-tree (index.js) 10.58KB 3.72KB
plugin-view (index.js) 85.18KB 21.05KB
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) 109.04KB 36.08KB
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.38KB 1.98KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.74KB 2.54KB
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) 15.71KB 5.30KB
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) 14.04KB 5.36KB
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

@os-tesla
os-tesla marked this pull request as ready for review September 20, 2026 12:09
@os-tesla
os-tesla enabled auto-merge September 20, 2026 12:09
@os-tesla
os-tesla added this pull request to the merge queue Sep 20, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 20, 2026
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3059.0 KB 3104.5 KB
Main entry chunk (gzip) 146.9 KB 350 KB
Entry file index-DZiTaVvY.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) 25.05KB 9.16KB
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.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
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) 545.92KB 130.72KB
core (index.js) 8.94KB 3.59KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 221.99KB 61.72KB
fields (index.js) 251.81KB 63.47KB
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.22KB 2.26KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 32.15KB 10.49KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.90KB 10.97KB
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) 2.53KB 0.85KB
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) 14.81KB 3.63KB
plugin-calendar (index.js) 51.08KB 14.50KB
plugin-charts (index.js) 71.73KB 20.08KB
plugin-chatbot (index.js) 198.20KB 47.14KB
plugin-dashboard (index.js) 132.96KB 35.17KB
plugin-designer (index.js) 215.94KB 44.33KB
plugin-detail (index.js) 255.23KB 66.49KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 139.56KB 35.40KB
plugin-gantt (index.js) 167.99KB 41.37KB
plugin-grid (index.js) 213.40KB 58.19KB
plugin-kanban (index.js) 48.71KB 15.17KB
plugin-list (index.js) 113.53KB 27.99KB
plugin-map (index.js) 21.48KB 6.99KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.49KB 11.97KB
plugin-timeline (index.js) 30.68KB 8.95KB
plugin-tree (index.js) 10.58KB 3.72KB
plugin-view (index.js) 85.18KB 21.05KB
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) 109.04KB 36.08KB
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.38KB 1.98KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.74KB 2.54KB
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) 15.71KB 5.30KB
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

@os-tesla
os-tesla added this pull request to the merge queue Sep 20, 2026
Merged via the queue into main with commit cd2cb41 Sep 20, 2026
43 checks passed
@os-tesla
os-tesla deleted the claude/issue-10005-record-history-limit-refusal branch September 20, 2026 16:23
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.

finding(plugin-detail): record:history turns a refused row cap into $top: 1 or a fractional window, while record:activity already refuses it

2 participants