Skip to content

docs(core): withdraw the vacuous entry-surface justification on the SchemaNode re-export - #5915

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-5673-vacuous-dts-justification
Aug 24, 2026
Merged

docs(core): withdraw the vacuous entry-surface justification on the SchemaNode re-export#5915
os-zhuang merged 1 commit into
mainfrom
claude/issue-5673-vacuous-dts-justification

Conversation

@claude

@claude claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Fixes #5673

A defect in a proof, not in behaviour. packages/core/src/types/index.ts justified
the #4580 re-export convergence with:

core's own entry surface is unchanged (dist/index.d.ts is byte-identical across the
change — measured, both rounds)

True, and it certified nothing. That block now withdraws the sentence, states the
mechanism, and carries a gauge that can fail — with its failure mode written down, so the
next reader inherits a check instead of a claim.

Why the reading is vacuous — measured, not argued

core/dist/index.d.ts is emitted from a barrel that only forwards the symbol, and
forwarding never restates a shape: neither export * nor the export type { … } line
that names this one. Only the module that declares the symbol can move.

Probe calibration on this tree — one additive optional key on BaseSchema (the shape
SchemaNode publishes), each leg built from a cleared dist/ and a cleared
tsconfig.tsbuildinfo, both packages rebuilt every leg:

emitted file base with probe probe dropped
@object-ui/types dist/base.d.ts — declares the shape 31b5a01d… 8487500e… moved 31b5a01d…
@object-ui/core dist/types/index.d.ts — forwards it 0e64c8c6… 0e64c8c6… 0e64c8c6…
@object-ui/core dist/index.d.ts — entry barrel, names the symbol 5cca207a… 5cca207a… 5cca207a…

Two things this pins beyond the card's own control leg:

The mutation was proven on disk before any build was believed: anchor count 1 → 1, marker
count 0 → 1, the injected line printed from the file, git diff --stat showing
1 insertion(+); then marker_count=1 in types/dist/base.d.ts and 0 in
core/dist/index.d.ts after the rebuild. The restore leg is symmetric — marker count back
to 0 in source and in dist/, and all three hashes back to base. The script carried
trap '<restore>' EXIT INT TERM, so a mid-run kill could not leave a mutated tree behind.

No ablation is available for this card and none was staged: the change is prose. What
replaces it is the calibration above, which is the same discipline applied to the thing
actually under test.

Where else the sentence propagated

Search scope: git grep -nI over all 5001 tracked files, patterns index\.d\.ts
(144 hits, each classified), byte.identical, entry (type )?surface, and the exact
#4580 sentence.

Controls, searched the same way: is byte-identical across the change (known present) →
6 files; SchemaNode.reconciliation.test.ts (known present in the edited file) → 2 files;
a known-absent string → git grep exit 1, zero lines, with the exit code captured
before any pipe. So an empty result here is distinguishable from a broken search.

Result — the vacuous class has exactly six instances, one live and five released:

Citations that are sound and were left alone, because the gauge can fail for their
claim: packages/app-shell/CHANGELOG.md:2694 and packages/plugin-grid/CHANGELOG.md:863
(a claim about which names the entry publishes — adding or removing a forwarded name
does move the barrel); packages/fields/CHANGELOG.md:1033 and
packages/plugin-editor/CHANGELOG.md:96 (whole-tree sha256 manifests);
packages/types/CHANGELOG.md:652 and packages/data-objectstack/CHANGELOG.md:299 (the
gauge firing positively in a declaring package);
.changeset/app-shell-page-header-subtitle-4761.md (checker-resolved export census with
controls); .changeset/plugin-component-input-deprecate-5674.md (the calibrated one).
.changeset/componentinput-reexport-4972.md already reports the gauge only with its
control
— the card's "it propagated once" instance has self-corrected; its stated reason
is narrower than the mechanism, which is recorded in the report rather than edited, since
it is another card's pending release note.

The one bounded in-place correction

The ComponentRendererProps block in the same file reached the right verdict already but
gave a narrower reason: "core/src/index.ts is a 95-line export * barrel". Two
defects, same class as this card: the count was stale (that file is 101 lines today), and
the reason is wrong for ComponentRendererProps specifically — the barrel names it on
line 9. The measurement above is what settles the correct form, so it is mechanical. It
now states the forwarding rule, and its cross-reference to the SchemaNode block above
had to move anyway, since that block no longer merely omits the sentence — it withdraws it.

No new gate

Per this card's ruling, no CI check is added here. The shape one could take, and the
reason a naive phrase-ban would be wrong, is filed as #5914 (finding, unassigned).

Verification

Gate union re-run after the final commit, at 738390cc1 (clean tree), quoting each
gate's own verdict line; exit codes captured before any pipe:

check-changeset-presence  EXIT=0  ✅  1 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s): .changeset/vacuous-dts-justification-5673.md.
check-changeset-no-major  EXIT=0  ✅  No changeset declares a `major` bump.
check-changeset-fixed     EXIT=0  ✅  All workspace packages are in the changeset fixed group.
check-control-bytes       EXIT=0  ✅  check-control-bytes: OK (scanned 4917 tracked text file(s); skipped 85 binary).
> @object-ui/core@17.6.0 type-check   (tsc --noEmit && tsc -p tsconfig.test.json)
 Test Files  100 passed (100)
      Tests  2014 passed (2014)
os-verify-lock: VERDICT command-exit 0 · held the lock 23s · waited 18s

vitest ran from the repo root with path filters — packages/core/, both
*.reconciliation.test.ts pins the docstrings name, and
scripts/__tests__/doc-version-claims.test.ts (the version-literal ratchet; this PR adds
no version literal to prose). The dependency closure was built first
(pnpm --workspace-concurrency=2 --filter '@object-ui/core^...' build), so nothing was
judged against a stale dist/. All heavy legs went through the shared verify lock.

Lint, narrowed — with the three pieces of evidence:

  1. Population from eslint's own config, not a guess: eslint . inside packages/core
    and the repo's own root-scope invocation (lint:root's ignore patterns), letting
    eslint resolve the file set.
  2. Counts read from --format json: 191 files in the core scope, 161 at root scope,
    0 errors in both (510 and 26 pre-existing warnings, none on the edited file). The
    edited file is present in the core population; 0 markdown files are in eslint's
    population at all, so the new changeset is outside eslint's reach by configuration.
  3. Invariance for untouched files: eslint.config.js declares no projectService and
    no parserOptions.project — type-aware linting is off — so a comment-only edit inside
    one file cannot move the verdict on any file it does not contain. turbo.json's lint
    task has no ^build dependency either, so no other package's lint result reads core's
    build output.

The repo-wide eslint farm is CI's run either way; the above is a measurement of this
diff's reach, not a skip.

Published surface

Documentation only — but it does ship. These docblocks sit on export specifiers, so they
land in the published declaration: core/dist/types/index.d.ts moved
0e64c8c6…76f769ed… for this commit, while core/dist/index.d.ts held 5cca207a…
— the same insensitivity, demonstrated a third time on this very change. That is why the
changeset declares a patch rather than an empty frontmatter. No type moves; no runtime
behaviour changes.


Generated by Claude Code

…chemaNode re-export

`packages/core/src/types/index.ts` justified objectui#4580's re-export convergence
with "core's own entry surface is unchanged (`dist/index.d.ts` is byte-identical
across the change — measured, both rounds)". The reading was real and it certified
nothing: that file is emitted from a barrel that only forwards the symbol, and
forwarding never restates a shape — not `export *`, and not the `export type { … }`
line that names this one. Only the module that declares the symbol can move.

The block now withdraws the sentence, states the mechanism, and carries the gauge
that can fail — the emitted `.d.ts` of the declaring module, over a cleared `dist/`
and a cleared `tsconfig.tsbuildinfo`, with a probe calibration and its failure mode
spelled out. Measured for this change: a probe key on `BaseSchema` moved
`@object-ui/types`' `dist/base.d.ts` and came back, while `core/dist/index.d.ts` and
`core/dist/types/index.d.ts` held one hash across all three legs.

The `ComponentRendererProps` block below reached the right verdict already but gave a
narrower reason for it — that core's entry is an `export *` barrel — which is not the
mechanism and is wrong for a symbol the barrel names; it now states the forwarding
rule instead.

Documentation only, in a published declaration file. Refs objectui#5673.

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

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 52 chunks) 3230.4 KB 3990.2 KB
Main entry chunk (gzip) 153.6 KB 350 KB
Entry file index-CXxmOL5G.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) 10.13KB 3.77KB
app-shell (runtime-config.js) 13.57KB 4.78KB
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) 5.13KB 2.35KB
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) 504.18KB 114.10KB
core (index.js) 4.92KB 1.97KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 164.55KB 45.67KB
fields (index.js) 238.40KB 59.89KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (i18n.js) 4.28KB 1.75KB
i18n (index.js) 3.44KB 1.39KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 23.13KB 7.63KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 33.40KB 8.71KB
i18n (useSafeTranslation.js) 7.77KB 3.13KB
layout (index.js) 38.95KB 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.55KB 0.62KB
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 (useResponsiveConfig.js) 1.37KB 0.63KB
mobile (useSpecGesture.js) 4.32KB 1.64KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 9.53KB 3.38KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 4.64KB 1.50KB
permissions (evaluator.js) 5.12KB 1.74KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 1.93KB 0.88KB
plugin-ai (index.js) 15.75KB 3.80KB
plugin-calendar (index.js) 46.62KB 12.83KB
plugin-charts (index.js) 64.66KB 18.32KB
plugin-chatbot (index.js) 187.32KB 44.31KB
plugin-dashboard (index.js) 133.32KB 34.42KB
plugin-designer (index.js) 212.30KB 42.80KB
plugin-detail (index.js) 244.01KB 61.72KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 125.63KB 30.64KB
plugin-gantt (index.js) 164.15KB 39.88KB
plugin-grid (index.js) 200.79KB 54.26KB
plugin-kanban (index.js) 52.93KB 14.60KB
plugin-list (index.js) 111.86KB 27.22KB
plugin-map (index.js) 20.06KB 6.62KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 43.49KB 11.93KB
plugin-timeline (index.js) 26.49KB 7.59KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 84.57KB 20.74KB
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) 3.77KB 1.33KB
react (SchemaRenderer.js) 52.40KB 17.45KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.35KB 0.70KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 5.41KB 2.34KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 4.93KB 2.24KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 12.13KB 3.65KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 7.54KB 2.63KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 0.99KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 0.20KB 0.18KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 0.20KB 0.18KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.87KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
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 (index.js) 3.88KB 1.85KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 2.59KB 1.31KB
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 (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 3.40KB 1.71KB
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-zhuang
os-zhuang marked this pull request as ready for review August 24, 2026 00:51
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 24, 2026
Merged via the queue into main with commit ed71d9e Aug 24, 2026
23 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-5673-vacuous-dts-justification branch August 24, 2026 00:51
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] #4580's "dist/index.d.ts is byte-identical" justification is a vacuous measurement, and it is written into the repo as evidence

2 participants