Skip to content

docs(types): bring every statement of the tombstone discriminator to the amended form - #9682

Merged
os-justin merged 4 commits into
mainfrom
claude/issue-7678-tombstone-discriminator-agreement
Sep 17, 2026
Merged

os-justin merged 4 commits into
mainfrom
claude/issue-7678-tombstone-discriminator-agreement

Conversation

@os-justin

Copy link
Copy Markdown
Collaborator

Part of #7678

Prose only. No member added, removed, renamed or retyped in any file; no ?: never tombstone touched; no accept set moved; nothing newly exported.

Clause-②: no, re-measured at delivery on dce4a74a1: git diff 72f55c9ec..HEAD -U0 | grep -c '^+export' scores 0, and the same diff filtered to non-comment source lines scores 0 lines — every added and removed line in packages/types/** is a comment line.


Two premises of the dispatch falsified

1. The item-1 ask was NOT already discharged

The dispatch recorded the card's item-1 ask — "make the complex.ts JSDoc cite prong 2 as the reason this key earns a tombstone" — as already done, measured at the KanbanColumn.color block. That block does state both prongs with a worked example for each. It states them for a different retirement.

The triggerIcon block — the site this card was filed about — mentions neither prong, nor the discriminator, nor the carrier precondition. Measured on 72f55c9ec over that whole docblock: grep -c "prong|discriminator|carrier|5941|7526" returns 0. It argues from the tsc deleted-vs-tombstoned contrast alone, which is exactly the rationale the card names as the cause of the contradiction, since that contrast applied equally to objectui#4919 and #5942 and both were removed outright.

Commit dce4a74a1 takes that site too. It is separable on purpose — drop it and the other three sites still agree.

2. The floatingConfig tripwire is alive, and it is not the displayMode one

Address: packages/types/src/__tests__/floating-chatbot-trigger-icon-retired.test.ts, the TRIPWIRE comment on the parse-green assertion inside the there is NO zod refusal on a %s node block. The displayMode tripwire in chatbot-display-mode-retired.test.ts is a separate, already-corrected one and was not touched — displayMode stays out of scope.


Measurement behind the tripwire rewrite

Injected a minted floatingConfig arm onto both twins in packages/types/src/zod/complex.zod.ts, ran the tripwire file, restored under a trap ... EXIT INT TERM. Both legs verified on disk: marker count 0 to 3, blob 656fc015 to the mutated blob and back to 656fc015, git diff HEAD empty afterwards.

tree result
baseline 72f55c9ec 11 passed / 11
house-style non-strict z.object mirror 2 failed / 9 passed — both failures are the shape pin, one per twin. The parse-green line the comment sat on stays GREEN.
z.strictObject mirror 4 failed / 7 passed — shape pin and parse-green line, one of each per twin

This reproduces triage's table (triage counted per-key; the file's describe.each doubles each reading). The comment now names the shape pin as the assertion that fires and records both readings; the shape pin gained a back-pointer.


Before / after at each site

complex.tsKanbanColumn.color

before:

A tombstone rather than a plain removal on BOTH prongs of the discriminator the precedent changesets state (objectui#5941, #7526; the one-line form is under correction as objectui#7678) — a tombstone exists (1) to steer authors to a named live replacement KEY, or (2) to keep loud a key the docs taught as working:

after:

A tombstone rather than a plain removal on BOTH prongs of the discriminator the precedent changesets state (objectui#5941, #7526), in the form objectui#7678 amended it to: a ?: never tombstone is available only on a SURVIVING CARRIER — KanbanColumn survives this retirement, while a whole exported type name has no carrier and is removed outright — and on such a carrier it is used when either prong holds: (1) it steers authors to a named live replacement KEY, or (2) it keeps loud a key the docs taught as working. Both hold here:

The site's own parenthetical named this card as its open correction; that parenthetical is now discharged rather than repeated.

complex.ts — the ChatbotSchema dark-keys block

before:

(mobile.ts, objectui#5941 / #7526 / #7678: a tombstone exists to steer authors to a named live replacement KEY, or to keep loud a key the docs taught as working)

after:

(mobile.ts, objectui#5941 / #7526 / #7678: a ?: never tombstone is available only on a SURVIVING CARRIER — ChatbotSchema survives, while a whole exported type name has no carrier and is removed outright — and on such a carrier it is used when either prong holds: it steers authors to a named live replacement KEY, or it keeps loud a key the docs taught as working)

complex.ts — the triggerIcon tombstone (the separable commit)

before: the Why a tombstone and not a deletion section ended at the deleted-vs-tombstoned table and went straight to Pinned in .... No prong, no discriminator, no carrier.

after, added between them:

⚠️ That tsc contrast is the MECHANISM, not the discriminator. It applied equally to objectui#4919 and #5942, which were removed outright, so it cannot be what separates the routes. What decides the route is this package's retire-vs-remove discriminator in its amended form (objectui#7678, the same wording the chatbot tombstones above carry): a ?: never tombstone is available only on a SURVIVING CARRIER — FloatingChatbotConfig survives this retirement, while a whole exported type name has no carrier and is removed outright — and on such a carrier it is used when either prong holds. PRONG 2 is the one that holds here: the key was advertised in the 3.3.0 release record (2026-04-17, the "New ChatbotSchema floating fields" entry, which names triggerIcon among FloatingChatbotConfig's options) and its published JSDoc promised @default 'MessageCircle' — the docs taught it as working. Prong 1 does NOT hold: there is no replacement key, which is why the guidance below names the trigger's own markup instead.

complex.ts — the displayMode tombstone

⛔ Unchanged. It is the site that already carried the precondition and it was the model every other site was matched to.

mobile.ts — the MobileOverrides retirement note

The prong-1 argument is kept verbatim — the removal is settled and is not re-argued. Added after it:

That one line states prong 1 alone. The discriminator's full, amended form (objectui#7678) is stated in complex.ts beside the chatbot tombstones: a ?: never tombstone is available only on a SURVIVING CARRIER, and on one it is used when EITHER prong holds — a named live replacement KEY, or keeping loud a key the docs taught as working. Neither branch reaches this retirement: an exported type name that goes whole has no carrier to host a ?: never member at all, and where a member did have one, prong 1 fails (above) and prong 2 has nothing to guard — this module has never had a zod/ twin, so there is no mirror that could accept an undeclared key and strip it silently, which is the hazard prong 2 guards where a mirror does exist. ⛔ The route itself is settled (objectui#4919); this note states the rule it followed and does not reopen it.

the tripwire comment

before:

⚠️ TRIPWIRE: if objectui#6152 ever mints a FloatingChatbotConfigSchema, this goes RED. That is the intended signal, not a nuisance — whoever lands the mirror must add the retirementTombstone() half for triggerIcon at the same time, and flip this control rather than delete it into a vacuum.

after:

⚠️ TRIPWIRE: if objectui#6152 ever mints a FloatingChatbotConfigSchema and wires it onto these twins as the floatingConfig arm, the assertion that fires is the SHAPE PIN at the foot of this block — the one reading shape.floatingConfig — and NOT this line. Measured on objectui#7678's base, arm injected on both twins and restored under a trap: a house-style non-strict z.object mirror reds the shape pin ONLY (2 failures, one per twin) and leaves this parse-green line GREEN, because a non-strict object accepts triggerIcon and strips it, so success stays true; a z.strictObject mirror reds both (4 failures). Either shape trips the file — that is the intended signal, not a nuisance: whoever lands the mirror must add the retirementTombstone() half for triggerIcon at the same time, and flip these controls rather than delete them into a vacuum.


Stale addresses, reported and NOT repaired

This card is scope-pinned, so AGENTS.md #11's opportunistic citation repair does not apply.

  • The card body and comment 5548730153 both address the triggerIcon rationale as packages/types/src/complex.ts:967. On 72f55c9ec that line is ChatToolInvocation.state prose, unrelated. The block is roughly 850 lines further down. ⛔ Not repaired here.
  • Every address the dispatch itself gave resolved correctly on 72f55c9ec, including base.ts:499 inside a BaseSchema body running :70 to :500 — verified by reading the interface's true extent (^export interface at :70, closing } at :500), not a context window.

Verification

Run through the shared verify lock where it is a package suite.

what result
pnpm --filter @object-ui/types run type-check (tsc --noEmit + examples + tsconfig.test.json) exit 0
pnpm --filter @object-ui/types run test 198 files / 4656 tests passed
node scripts/check-changeset-presence.mjs exit 0 — 3 published source files changed, 1 changeset, empty frontmatter, "declared as releasing nothing, which is the explicit exemption and a complete answer to this gate"
check-changeset-claims / -no-major / -fixed / -overwrite / check-pending-changeset-literals exit 0
node scripts/check-new-cross-file-line-citations.mjs exit 0 — 0 new cross-file line citations
node scripts/check-control-bytes.mjs exit 0
node scripts/check-governed-queue-guard.mjs --test ... NOT GOVERNED, 4 paths checked against 5 governed surfaces
eslint . --no-inline-config --format json (whole repo, 5038 files) 95 errors / 13202 warnings, none in any file this branch touches; the three changed files lint to 0 errors

The 95 repo-wide eslint errors are pre-existing on origin/main (react-hooks/static-components, no-console and friends in apps/console and e2e/), untouched by a comment-only diff.

Changeset

Empty frontmatter, following the repo's own precedent for comment-only changes in published source. Comments do reach the emitted .d.ts here — the base tsconfig sets removeComments: false, verified — and the changeset says so explicitly, but nothing a consumer can execute or type-check against moves.


Generated by Claude Code

…r to the amended form

The retire-vs-remove discriminator is stated at three sites in
`packages/types/src/complex.ts` at two different levels of amendment: the
`KanbanColumn.color` block and the `ChatbotSchema` dark-keys block gave the two
prongs without their precondition, while the `displayMode` tombstone already
carried it. The first two now state the amended rule in the wording the third
already uses, so a reader landing on any of the three gets the same rule. The
`KanbanColumn.color` site's own parenthetical had named objectui#7678 as its
open correction; that parenthetical is discharged rather than repeated.

`mobile.ts`'s `MobileOverrides` retirement note keeps its prong-1 argument,
which is settled, and gains a pointer to the amended rule and to the reason
prong 2 has nothing to guard there: the module has never had a `zod/` twin.

The objectui#6152 tripwire comment in
`floating-chatbot-trigger-icon-retired.test.ts` claimed the parse-green
assertion it sits on would go red once a `FloatingChatbotConfigSchema` is
minted. Measured by injecting the arm on both twins and restoring under a trap:
a non-strict `z.object` mirror reds the shape pin only (2 failures, one per
twin) and leaves that parse-green line green; a `z.strictObject` mirror reds
both (4 failures). The comment now names the shape pin and records both
readings.

Comment-only. No member added, removed, renamed or retyped, no accept set
moved, no export added.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EpHzwH4wTy5sd7ibkD2yq
…a bare keyword

The clause-2 mechanical floor for this card is `^\+export` scoring 0 in the
diff. The previous wrapping put "export added." at the head of a line inside
the changeset prose, which scored 1 against a floor meant to catch an added
declaration. Reflowed; the sentence is unchanged in meaning.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EpHzwH4wTy5sd7ibkD2yq
…erIcon tombstone

⚠️ This commit is separable on purpose. The dispatch for objectui#7678 recorded
the card's item-1 ask — "make the `complex.ts` JSDoc cite prong 2 as the reason
this key earns a tombstone" — as already discharged, measured at the
`KanbanColumn.color` block. That block does state both prongs, but for a
DIFFERENT retirement. The `triggerIcon` block, which is the site the card was
filed about, mentions neither prong, the discriminator, nor the carrier
precondition: it argues from the `tsc` deleted-vs-tombstoned contrast alone,
which is exactly the rationale the card names as the cause of the
contradiction, since that contrast applied equally to objectui#4919 and #5942
and both were removed outright.

The block now carries the amended discriminator in the same wording as the
other sites and names prong 2 — the 3.3.0 release record advertised the key and
its published JSDoc promised a default — as the reason it earns a tombstone,
with prong 1 recorded as not holding. The route is untouched: no member, no
`?: never`, no accept set, nothing newly exported. The tombstone is not
re-litigated; only its recorded reason is completed.

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

github-actions Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

changeset-claim-re-read

⚠️ 10 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/6687-chatbot-surface-authorable.md

  • names packages/types/src/complex.tspackages/types/src/complex.ts — edited by this change

    Measured on both declaration faces before the fix, each with a control that had to hit: schema.surface appeared 0 times in renderer.tsx against schema.placeholder at 3 (one per registration) and schema.processVisibility at 1; and ChatbotSchema (packages/types/src/complex.ts) declared 34 keys, not this one. Two faces agreeing is what made the zero a reading rather than a bad query.

.changeset/6939-kanban-column-cards.md

  • names complex.tspackages/types/src/complex.ts — edited by this change

    Breaking, deliberately. KanbanColumn declared its card list as items in complex.ts and in the zod mirror complex.zod.ts. Every board reads cards. Measured on origin/main 78a3cc238: KanbanImpl.tsx reads .cards on 12 lines, KanbanEnhanced.tsx on 8, and bucketCardsIntoColumns twice more as col.cards || []; .items had zero read sites in either board (a same-shaped .title control on the same two files returns 8 and 3, so those zeros are readings and not a mis-shaped probe). Both catalog entries, the plugin docs and content/docs/api/schema-reference.md all author cards.

.changeset/7295-chat-message-avatar-keys.md

  • names packages/types/src/complex.tspackages/types/src/complex.ts — edited by this change

    packages/plugin-chatbot/src/index.tsx:173–178 reads message.avatar || userAvatarUrl and message.avatarFallback || userAvatarFallback (and the assistant twins), the authoring-to-runtime seam spreads every unlisted key through (chatMessageAdapter.ts, ...passthrough), and the SDUI renderer feeds the authored messages[] straight in — a per-message avatar override renders, is documented, and no authoring-facing type declared it. ChatMessage in packages/types/src/complex.ts has no index signature (objectui#5155, deliberately — none is added here), so an author annotating ChatbotSchema.messages was told a value that renders is an error (TS2353); the zod mirror ChatMessageSchema is a plain strip-mode z.object, so the value parsed green and was silently DROPPED from the parsed output.

.changeset/7580-responsive-vocabulary-rehome.md

  • names mobile.tspackages/types/src/mobile.ts — edited by this change

    • BreakpointName (xs2xl) is now declared in @object-ui/types (mobile.ts) instead of re-exported from the spec. No consumer change: same name, same six members, same export sites on @object-ui/types and @object-ui/mobile. Only its provenance moved. - BreakpointColumnMap is now declared in @object-ui/layout (ResponsiveGrid.tsx), verbatim from the retired $strict schema: six optional column counts, no index signature. responsive-grid's columns input and its resolver are unchanged.

.changeset/7654-floating-chatbot-trigger-icon-tombstone.md

  • names packages/types/src/__tests__/floating-chatbot-trigger-icon-retired.test.tspackages/types/src/__tests__/floating-chatbot-trigger-icon-retired.test.ts — edited by this change

    Excess-property checking only reaches a fresh literal, so deletion would have left the widened path — const raw = { triggerIcon: 'Sparkles' }; const cfg: FloatingChatbotConfig = raw; — silently accepting a key nothing reads. The declared never makes the assignment itself ill-typed, so freshness stops mattering. Both rows are pinned in packages/types/src/__tests__/floating-chatbot-trigger-icon-retired.test.ts, the "deleted" row as a live control on a genuinely undeclared key rather than as prose, so the contrast cannot rot.

.changeset/7655-chatbot-registration-authoring-faces.md

  • names complex.tspackages/types/src/complex.ts — edited by this change

    New published symbol: ChatbotSharedKey, the string-literal union of the twenty keys all three registrations read. It is exported from complex.ts because an exported interface may not extend a Pick over a private name (TS4022), so it is emitted into dist/complex.d.ts and is reachable through the published @object-ui/types/complex subpath (it is not re-exported from the package entry). It is a census, not an authoring face.

.changeset/7703-chatbot-dark-keys-retired.md

  • names packages/types/src/complex.tspackages/types/src/complex.ts — edited by this change

    Each member goes to ?: never on packages/types/src/complex.ts and to retirementTombstone(...) on packages/types/src/zod/complex.zod.ts — both halves, in lockstep, the convention MarkdownSchema.sanitize (objectui#6972), TimelineSchema.timeScale (objectui#6355) and ObjectViewSchema.viewTabBar (objectui#7779) already carry. Each refusal names the key, says why it is retired, and points at what to write instead; one string feeds both the parse-time message and the .describe() metadata, so the two cannot drift.

  • names mobile.tspackages/types/src/mobile.ts — edited by this change

    All six have a Zod arm, and that is what decides the route here. BaseSchema is .passthrough() on the Zod side and carries a [key: string]: any index signature on the TS side, so an UNDECLARED key is not refused — it is KEPT. Deleting the members would hand the authored spelling exactly the silent no-op this card exists to close, on both faces at once. The two-prong discriminator (mobile.ts, objectui#5941 / feat(types,mobile)!: retire the MobileComponentConfig published type #7526 / types: the triggerIcon tombstone's rationale contradicts mobile.ts's own retire-vs-remove discriminator, and its tripwire comment overclaims #7678) leaves that structural hazard to the carrier: where there is no mirror there is "no silent-strip hazard for prong 2 to guard". Here there is a mirror to host the refusal, and prong 1 holds by the letter for four of the six. The "deleted" row is pinned live as a control in packages/types/src/__tests__/chatbot-dark-keys-retired-7703.test.ts, so the contrast cannot rot into prose.

.changeset/8415-filter-builder-condition-id.md

  • names complex.tspackages/types/src/complex.ts — edited by this change

    Breaking for authored metadata: a filter-builder CONDITION must now declare id (objectui#8415). It is declared on both published faces — the TypeScript interface FilterBuilderCondition in complex.ts and the Zod mirror FilterBuilderConditionSchema in zod/complex.zod.ts — so a key the renderer has always required is finally validated instead of silently discarded.

.changeset/8802-8257-8008-kanban-gantt-family-retirement.md

  • names complex.tspackages/types/src/complex.ts — edited by this change

    What each retirement was, measured. Three of the four were registration-only: no schema face in @object-ui/types ever declared kanban-ui, kanban-enhanced or gantt as a component node type, so unregistering is the whole retirement. The bare kanban key was the exception — it had a declared arm on both faces (KanbanSchema in complex.ts and its Zod mirror), and a plain deletion there would have been the objectui#7664 failure: BaseSchema is .passthrough(), so a document naming a dropped key validates green and renders nothing. It therefore retires as a named refusal: the Zod union keeps an arm claiming the literal and answers a { "type": "kanban" } document with a message naming object-kanban as the remedy, while the TypeScript half is the absence of the arm from ComplexSchema and of the key from SchemaRegistry, so tsc refuses it at the authoring site.

.changeset/calendar-readme-schema-keys-5045.md

  • names packages/types/src/complex.tspackages/types/src/complex.ts — edited by this change

    README.md's "Schema API / CalendarView" block described a CalendarViewSchema that does not exist. Measured against the interface itself (packages/types/src/complex.ts) and its zod mirror: events — the schema's only required key besides type — was published as events?, so a reader following the README omits it and TypeScript rejects the node; defaultDate was string where the schema says string | Date; and onDateClick was listed as a schema key when it is a CalendarViewProps component prop, sending readers to a different package's surface for a key calendar-view does not have (the schema's key is onDateChange). The block also listed 6 of the schema's 13 keys with nothing saying it was a summary (objectui#5045).

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 claim that was born false (a changeset this change adds is excluded by construction), 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 72f55c9ec (merge-base with origin/main): 3 file(s) changed outside .changeset/, read against 1119 pending declaration(s) that publish a body (1624 pending in total). · run

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3048.9 KB 3104.5 KB
Main entry chunk (gzip) 145.7 KB 350 KB
Entry file index-Ckww2Jo5.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.84KB 130.66KB
core (index.js) 8.94KB 3.59KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 215.98KB 59.97KB
fields (index.js) 249.27KB 62.92KB
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.83KB 10.95KB
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) 4.39KB 1.66KB
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) 49.92KB 14.22KB
plugin-charts (index.js) 71.33KB 19.90KB
plugin-chatbot (index.js) 195.34KB 46.51KB
plugin-dashboard (index.js) 131.44KB 34.65KB
plugin-designer (index.js) 215.94KB 44.33KB
plugin-detail (index.js) 253.29KB 65.88KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 136.71KB 34.16KB
plugin-gantt (index.js) 167.62KB 41.26KB
plugin-grid (index.js) 212.64KB 57.91KB
plugin-kanban (index.js) 46.41KB 14.49KB
plugin-list (index.js) 112.73KB 27.69KB
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.07KB 8.74KB
plugin-tree (index.js) 10.58KB 3.72KB
plugin-view (index.js) 85.04KB 21.01KB
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) 104.82KB 34.67KB
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 (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.66KB 2.50KB
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) 14.82KB 4.99KB
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) 4.73KB 2.28KB
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

…irement note

The sixth and last site in this package that states the retire-vs-remove
discriminator. It gave the two prongs in full and without the precondition —
in `mobile.ts`, which is the file whose disagreement with `complex.ts` is why
objectui#7678 exists.

It now carries the amended form in the same wording as the other five: a
`?: never` tombstone is available only on a SURVIVING CARRIER, and on such a
carrier it is used when either prong holds. `GestureConfig` is a whole exported
type name, so it has no carrier at all and the precondition settles the route
on its own; the per-prong measurement that follows it is kept as the record
rather than dropped.

Every existing clause survives verbatim: the prong-1 zero-hit reading, the
prong-2 CHANGELOG reading, the referral of "does a reclaim note count as taught
as working" to objectui#7519, the structural no-silent-strip note, the missing
`zod/` twin, the TS2724 reading and the residue pin. The removal is not
re-argued and the objectui#7519 referral is untouched.

Census after this commit: six statements of the prong-1 phrase across
`complex.ts` and `mobile.ts`, every one of them now reached by the
precondition, plus the `triggerIcon` block that states the rule without
restating the prongs. The duplication itself is filed as objectui#9684 and is
deliberately NOT restructured here.

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

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3048.9 KB 3104.5 KB
Main entry chunk (gzip) 145.7 KB 350 KB
Entry file index-Ckww2Jo5.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.84KB 130.66KB
core (index.js) 8.94KB 3.59KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 215.98KB 59.97KB
fields (index.js) 249.27KB 62.92KB
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.83KB 10.95KB
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) 4.39KB 1.66KB
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) 49.92KB 14.22KB
plugin-charts (index.js) 71.33KB 19.90KB
plugin-chatbot (index.js) 195.34KB 46.51KB
plugin-dashboard (index.js) 131.44KB 34.65KB
plugin-designer (index.js) 215.94KB 44.33KB
plugin-detail (index.js) 253.29KB 65.88KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 136.71KB 34.16KB
plugin-gantt (index.js) 167.62KB 41.26KB
plugin-grid (index.js) 212.64KB 57.91KB
plugin-kanban (index.js) 46.41KB 14.49KB
plugin-list (index.js) 112.73KB 27.69KB
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.07KB 8.74KB
plugin-tree (index.js) 10.58KB 3.72KB
plugin-view (index.js) 85.04KB 21.01KB
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) 104.82KB 34.67KB
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 (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.66KB 2.50KB
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) 14.82KB 4.99KB
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) 4.73KB 2.28KB
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

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