fix(types): rename KanbanColumn.items to cards on both published halves - #7541

Merged
os-project-manager merged 5 commits into
mainfrom
claude/issue-6939-group3-kanban-cards
Sep 3, 2026
Merged

fix(types): rename KanbanColumn.items to cards on both published halves#7541
os-project-manager merged 5 commits into
mainfrom
claude/issue-6939-group3-kanban-cards

Conversation

@os-project-manager

@os-project-manageros-project-manager commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Part of #6939 — the kanban row (group 3) only. Groups 4 (filter-builder) and 5 (chart) are not addressed here and remain open; group 2 (tree-view) is PR #7533.

Clause-②: yes — this moves a published mirror's accept/reject behaviour AND renames a member on a published type. Draft + needs:contract-review; not marked ready, no auto-merge.

What changed

KanbanColumn declared its card list as items in both halves of the published surface — packages/types/src/complex.ts and the zod mirror packages/types/src/zod/complex.zod.ts — while every board reads cards. Renamed to cards.

The ruling's own numbers, re-measured on this branch's base

The maintainer ruling (comment 5510084784) took its counts on origin/mainec0a7b84. This branch is based on 78a3cc238. All three reproduce:

ReadingRulingRe-measured on 78a3cc238
plugin-kanban/src/types.ts declares cards: KanbanCard[]line 75line 75 ✓
complex.zod.ts declares itemsline 54line 55 (one line of drift)
.cards read lines in KanbanImpl.tsx1212 ✓
.cards read lines in KanbanEnhanced.tsx88 ✓
.items read lines in either00 ✓

Control for the two zeros: a same-shaped probe (grep -c '\.title') on the same two files returns 8 and 3, so the zeros are readings and not a mis-shaped probe. A nonsense-member probe of the same shape returns 0 on both.

Addendum the ruling did not count:packages/plugin-kanban/src/index.tsx reads col.cardsthree more times — lines 64 and 89 in bucketCardsIntoColumns, and line 327 in the kanban-enhanced registration's useMemo, which has the same shape. Each is col.cards || [], and that || [] is the mechanism behind the discriminator below. (An earlier revision said "twice more (lines 64 and 89)", missing line 327; corrected on review.)

Why the rename went toward cards — measured, not asserted

Per #6318's triage, a "correction" that renders identically proves the schema was the wrong side. This row clears the stronger, opposite-polarity bar: "correcting" the fixtures toward the declaration does not merely change the render, it empties the board. Measured through the harness in the new test file, on 78a3cc238, before either declaration was touched:

Entrycards (authored)items (the declared spelling)
basic-kanban-board64 elements — To Do2 … Design new feature …45 elements — No cards3 columnsTo Do0In Progress0Done0
advanced-kanban-with-badges-and-limits86 elements — Backlog2 … User Authentication …58 elements — No cards4 columnsBacklog0 …

Validator verdicts, same run: the authored cards documents failedsafeValidateSchema (: Invalid input) and the items documents passed. After this change, exactly reversed.

What is pinned

examples/schema-catalog/test/kanban-column-cards-6939.test.tsx (11 tests):

  • both catalog entries validate;
  • the items spelling is now refused (the other half of the accept-set move — a mirror that merely widened would still accept it);
  • cards is a real declaration, not a passthrough hole — counter-probes use only the declared key, since BaseSchema is .passthrough() and an unknown key would prove nothing;
  • render identity against the pre-change readings: element count, tag census, visible text literal, and SHA-256 over the full textContent;
  • anti-vacuity — every authored column title and card title is asserted on screen, plus a guard that at least one card exists, so the identity pin cannot pass on a blank tile;
  • the items empty-board reading is itself pinned, so the direction of the rename stays a measurement.

Controls are legal in both states. The render carriers never pass through the validator, and bucketCardsIntoColumns is untouched, so both the populated and the empty board render the same before and after. The waitFor witness is a column heading, which exists in both boards — it cannot settle for one spelling and time out for the other.

Ablation (predicted before measured)

Restoring items to both declarations, renderer untouched. Predicted red: the two validates cases, the two items-refused cases, and the passthrough counter-probe — 5 of 11, with the six render/anti-vacuity cases and all 12 zod-mirror-parity cases staying green.

Measured: exactly thatTests 5 failed | 18 passed (23), and the five names match the prediction one-for-one.

The mutation was proven on disk before the run (anchored counts in both directions, plus blob hashes differing from HEAD), and the restore was proven by state, not by exit code: both worktree blob hashes equal their HEAD blobs, git diff HEAD empty, git status --porcelain empty. Both files resolve through the repo's vitest source alias (packages/types/src/...), so no dist rebuild participates in this ablation.

Notes

  • packages/types/examples/zod-validation-example.ts authored the old spelling in three places; renamed. It is covered by packages/types' type-check (which runs tsc -p tsconfig.examples.json).
  • The header of examples/schema-catalog/test/safe-validate-corpus-6318.test.ts listed this row as an open finding on the Zod union; that sentence is now stale and the kanban clause is removed. That file deliberately pins no bucket size, so nothing else there moves.
  • @object-ui/plugin-kanban is unchanged — it already declared cards.
  • An earlier revision of the test preloaded the lazy chunk via @object-ui/plugin-kanban/KanbanImpl. That shape was removed: it is not in the package's exports map and resolves only through the repo's vitest alias, which @object-ui/fields deep subpaths resolve only through the repo vitest alias — its exports map publishes none of them #4325 ruled out for @object-ui/fields. The test now settles the boundary with waitFor, the way catalog-gallery-render.test.tsx already does for these same entries.

Changeset

minor, not patch — this is a rename on a published type, not a widening. @object-ui/types only. (major is forbidden repo-wide by scripts/check-changeset-no-major.mjs; the breaking semantics are spelled out in the changeset body per repo convention.)

Verification — all at merged head fba1bfd78

CheckResult
vitest run packages/types/ packages/plugin-kanban/ examples/schema-catalog/Test Files 140 passed (140), Tests 3727 passed (3727)
zod-mirror-parity.test.ts (run explicitly)Tests 12 passed (12)
turbo run type-check --filter=@object-ui/types --filter=@object-ui/plugin-kanbanTasks: 15 successful, 15 total
turbo run type-check --filter=@object-ui/example-schema-catalogTasks: 30 successful, 30 total
eslint . --format json4254 files, 0 errors (eslint's own population, not a narrowed list)
check-changeset-presence.mjsexit 0 — 1 changeset for 1 released package
check-changeset-no-major.mjsexit 0
check-control-bytes.mjsexit 0 — 6210 tracked text files

Branch merged with origin/main47547d01a (a merge, not a rebase, per AGENTS.md); the full suite above was re-run after the merge.

Clause 2 of the ruling, and a PRIOR ruling on this exact pair

The 2026-09-02 ruling has two clauses. This PR implements clause 1 (the rename). Clause 2 — "packages/plugin-kanban/src/types.ts stops carrying its own KanbanColumn declaration and re-uses the public one" — is NOT implemented here, and two things about it belong on the record. Neither asks this PR to decide anything.

1. The public declaration is not structurally sufficient. Measured: the plugin's local KanbanCard carries four members the public @object-ui/typesKanbanCard does not declare — badges, cardSubtitle, cardFieldCells, coverImage — plus an index signature; the plugin's KanbanColumn carries className where the public one has color. All are live reads (card.coverImage, card.cardFieldCells, card.cardSubtitle, card.badges, column.className, and card[swimlaneField] at KanbanImpl.tsx 449, 672 and 692). Deleting the local declaration would type column.cards as the publicKanbanCard[] and break every one of them, so clause 2 cannot be executed without widening the published type — which the dispatch explicitly forbids doing silently.

2. Correction to an earlier revision of this PR, and the prior ruling it missed.

An earlier revision cited the comment at KanbanImpl.tsx:52 as "a landed decision pointing the other way", saying objectui#6172 / #6155 made ./types the authority because the local card carried members the public one did not. That attribution was wrong. The comment compares KanbanImpl.tsx's own former copies against the plugin's ./types — an in-package drift — and says so in as many words: "the local KanbanCard carried cardSubtitle / cardFieldCells / coverImage that ./types did not". It says nothing about @object-ui/types.

That card was explicit about not touching the cross-package question. Its changeset (.changeset/6172-markdown-kanban-one-authority.md, landed in b3d562c02):

The cross-package KanbanCard / KanbanColumn / KanbanSchema collision between @object-ui/types and @object-ui/plugin-kanban is NOT resolved here and is escalated on objectui#6172 — those are two different dialects (items vs cards, labels vs badges), and collapsing them renames a published name, which needs an authority ruling.

So :52 is in-package convergence plus an explicit escalation, not a contrary decision.

And that escalation was answered. objectui#6172 comment 5474954379 (2026-08-31, maintainer verbatim 「其他同意」, director-seat batch #14) rules option A:

plugin-kanban 保留裸名 KanbanSchema 家族;@object-ui/types 三重奏改名(如 DeclarativeKanbanSchema 族)

Under that ruling the public KanbanColumn is renamed away, so clause 2's "re-use the public one" would have nothing to re-use. It predates the 2026-09-02 ruling by two days, the two do not cite each other, and it is not yet executed (packages/types/src/complex.ts:28 still declares KanbanColumn). It also lists retiring the @object-ui/types triplet outright as escalation option D — under which this PR's member rename would travel with the renamed type, or disappear with a retired one.

I am not adjudicating which ruling governs. Both are recorded so the reviewer and the maintainer can see the conflict; the dispatching seat has escalated it as-is. Worth noting that #6172's own census agrees with this PR's measurement independently: it found the types-dialect items spelling had zero non-demo, non-known-bad uses across the bound.

Follow-up: CI red on fba1bfd78, and the fix (a3fb15e5e)

Test (shard 3/4) went red on one case — packages/cli/src/__tests__/check-validity-recogniser.test.ts, "reports a registered component type the bundled schemas do not model", expected +0 to be 1. It is a correct consequence of this repair, and it is fixed here rather than worked around.

That case wrote a kanban board authoring cards and asserted objectui check would report it as a registered type the bundled schemas cannot model. It only ever landed in that bucket because the mirror required items — the exact fork this PR repairs. Once the board validates, the count drops to 0. The defect was frozen into an assertion of expected behaviour.

Reproduced end-to-end through the real check, not inferred: a kanban board with cards now yields candidates=[]; the sibling text fixture still yields a candidate (positive control); a foreign package.json still yields Skipped 1 and no candidate (negative control).

The comment was also wrong, independently of this PR. It claimed AnyComponentSchema "has no member for" kanban. ComplexSchema has carried KanbanSchema throughout (complex.zod.ts:691-692, reached from AnyComponentSchema via the ComplexSchema arm). Corrected to the real mechanism — a required-key mismatch, not an absent member.

The replacement type was chosen by measurement. Difference set, by introspecting every literal type the union declares: 658 registered types in KNOWN_SCHEMA_TYPES, 102 modelled, 558 with no member. Probe controlled in both directions — kanban, text and tree-view all read as modelled (so it is not blind to real members), a nonsense type does not.

Picked abbr. Raw HTML primitives are the stable inhabitants of that bucket: packages/components/src/renderers/basic/html-elements.tsx registers them in bulk and they are not candidates for authorable component schemas — unlike a plugin-ish type such as dashboard-grid, which also lands there today but is a plausible future modelling target. The fixture is a well-formedabbr document, which keeps the case's original point: the file is unmodelled, not broken.

The timer is defused rather than passed on. The case now asserts its own precondition — that abbr is still refused by safeValidateSchema — with a message naming what to do. If anyone ever models abbr, this file says why it went red instead of reporting a bare expected +0 to be 1. A synthetic always-unmodelled type was considered and rejected: the registered-type universe is a generated, separately-pinned file (packages/cli/src/utils/known-schema-types.ts), so a synthetic type would have to be injected by mocking it — and that would fabricate the "registered" half, which is precisely the half this bucket is about.

⛔ The test was not skipped, disabled, isolated or deleted, and the sample was not reverted to items. The changeset level is unchanged (minor).

Re-verified at merged head a3fb15e5e (merged origin/mainf0f774b0d)

CheckResult
vitest run packages/cli/ packages/types/ packages/plugin-kanban/ examples/schema-catalog/Test Files 156 passed (156), Tests 3973 passed (3973)
check-validity-recogniser.test.ts aloneTests 10 passed (10)
turbo run type-check --filter=@object-ui/cliTasks: 10 successful, 10 total
eslint on the changed file0 errors, 0 warnings
check-changeset-presence.mjsexit 0 — 1 changeset for 2 released packages
check-changeset-no-major.mjsexit 0
check-control-bytes.mjsexit 0 — 6212 tracked text files

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

`KanbanColumn` declared its card list as `items` in `complex.ts` and in the
zod mirror `complex.zod.ts`, while every board reads `cards`. Measured on
`origin/main` 78a3cc2: `KanbanImpl.tsx` reads `.cards` on 12 lines,
`KanbanEnhanced.tsx` on 8, and `bucketCardsIntoColumns` twice more as
`col.cards || []`; `.items` has zero read sites in either board, against a
same-shaped `.title` control returning 8 and 3 on the same two files.
The result was `declared !== enforced` on a published surface: both kanban
catalog entries failed `safeValidateSchema` with ": Invalid input" while
rendering perfectly — the type's seat in objectui#6318's bucket.
Renaming the read sites instead was rejected by measurement, not preference:
under the `items` spelling `col.cards || []` buckets every column to zero, and
`basic-kanban-board` goes from 64 elements reading "To Do2 / Design new
feature" to 45 elements reading "No cards / 3 columns / To Do0" — an empty
board. The declaration was the wrong side.
Pinned in `examples/schema-catalog/test/kanban-column-cards-6939.test.tsx`:
both entries validate, the `items` spelling is now refused, the rendered DOM is
byte-identical to the pre-change measurement (elements, tag census, visible
text, SHA-256 of textContent), and the empty-board reading for `items` is
pinned so the direction of the rename stays a measurement.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-JkRWQ99M.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…s false mechanism note
The `reports a registered component type the bundled schemas do not model`
case used a kanban board authoring `cards`, and its comment claimed
`AnyComponentSchema` "has no member for" kanban.
That claim was false, and was false before this branch touched anything:
`ComplexSchema` has carried `KanbanSchema` throughout. The board landed in the
bucket for a different reason — `KanbanColumnSchema` required `items` while
every board, and that sample, writes `cards`. Renaming the mirror to `cards`
made the board validate, so the case measured 0 candidates: the defect had
been frozen into an assertion of expected behaviour.
Repointed to `abbr`, chosen by measurement rather than memory. On this tree
`KNOWN_SCHEMA_TYPES` carries 658 registered types while `AnyComponentSchema`
declares 102 distinct literal `type` values, leaving 558 with no member; the
probe was controlled in both directions (`kanban` / `text` / `tree-view` read
as modelled, a nonsense type does not). Raw HTML primitives are the stable
inhabitants of that bucket — registered in bulk by `html-elements.tsx`, never
candidates for authorable component schemas — so the fixture does not carry a
timer the way a plugin-ish type such as `dashboard-grid` would.
The case also now asserts its own precondition, so if `abbr` is ever modelled
this file reports why instead of a bare `expected +0 to be 1`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-H6WopARe.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-H6WopARe.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (select-option.js)0.20KB0.19KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@os-project-managerClaude

Copy link
Copy Markdown
CollaboratorAuthor

合约审查裁断:FAIL 三条 → 补丁轮已全修 → 放行

domain:ui 派发席,session session_01EMrWaQw3XS5DxTHxp4yRyC。本席是 opus、不在 CONTRACT_REVIEW_TIER,故本 Clause-② yes 的 PR 由隔离审查者出裁。简报只含卡片、裁决与本 PR,⛔ 不含派发指令、⛔ 不含本席结论;并明确要求审查者只判 clause 2 的事实是否准确,⛔ 不判该走 A/B/C 哪个

转录档位核验:只提取 harness 生成的 model 字段(⛔ 不搜自由文本)。转录 205 行、0 行不可解析、100 个 assistant 轮次全部 claude-fable-5-1,无 fallback ⇒ 逐字采信。

三条 finding,逐条

F1 — 本 diff 让一个受 CI 把关的测试变红,而 PR 的验证人群不含它所在的包。
packages/cli/src/__tests__/check-validity-recogniser.test.ts 在 merge-base 通过、在 PR head 失败。那个用例写一个 columns[].cards: [] 的 kanban board,断言 objectui check 把它归入「未通过校验」桶。该样本从前之所以被拒,只因镜像要 items;本 PR 让 cards 成为被接受的拼法,于是它通过校验、桶计数读为 0。用例自己的散文(「kanbanAnyComponentSchema has no member for」)是假的——kanban 是被建模的,那正是本 PR 修的缺陷——所以它的前提随修复一同死亡。PR 的受影响套件跑的是 packages/types/ packages/plugin-kanban/ examples/schema-catalog/packages/cli 在人群之外,所以 PR 不可能看见它

head fba1bfd78 : × reports a registered component type … expected +0 to be 1 (1 failed | 9 passed)
base 47547d01a : 10 passed (10)
机制 同一样本经 safeValidateSchema:head success:true / base success:false [": Invalid input"]

F2 — clause 2 的叙述指错了物件,并漏掉了唯一直接相关的在先裁决。
(a) PR 称 KanbanImpl.tsx:52 记录 #6172/#6155 定权威「precisely because the local card carried … that the public one did not」。注释原文是「that ./types did not」——包内漂移;#6172 的 changeset 更明写跨包问题「is NOT resolved here and is escalated」。
(b) 该升格问题的答案存在#6172 评论 5474954379(2026-08-31,维护者逐字「其他同意」,第 6 场总监席决裁批 #14)裁选项 A —— plugin-kanban 保留裸名、@object-ui/types 三重奏改名,并列「径直退役」为升格选项 D。⇒ 在其之下 clause 2 的「公共那个」将不复存在。两条裁决相隔两天、互不引用,且 #6172尚未执行

F3(非阻塞)— 读点补记少了一处。index.tsxcol.cards处(64、89、327),索引签名读点是 449、672、692

审查者核实通过的部分

clause-2 的结构测量正确(公共 KanbanCard 确实缺那四个成员、无索引签名;本地 KanbanColumnclassName 而公共的是 color;所有引用读点为活读点,并另找到 ObjectKanban.tsx:585);裁决数字复现(items 在 55 行不是 54;12/8/0,配同形 .title 对照 8/3 与胡诌成员对照 0);判别器在真实 base 上重测,四个读数与 PR 钉的 PRE_REPAIR/ITEMS_SPELLING 全部吻合;空洞 harness 复现(Suspense fallback,1 元素、sha=e3b0c442… 即空串哈希),并验证替换后的 h3 见证在两种状态下都在场;消融在真实 base 上一对一复现(5 failed | 18 passed);changeset minor 正确,@object-ui/plugin-kanban 确未被动;普查确认插件之外无 KanbanColumn 消费者。

NARROWINGS(收口后由审查者自行转为实测的两项)

被锁住的宽跑事后返回:140 passed (140) / 3727 passed (3727),turbo type-check 32 successful, 32 total ⇒ 三棵树内无测试钉 items 拼法、无 TS 消费者读 KanbanColumn.items。**两项都确认了 F1 的结论:红的那个测试在 PR 所验证的人群之外,而那是人群选择的问题,不是人群内部有缺陷。**其余仍列为未测:whole-population eslint .、经完整 CLI 闭包的 objectui check、PR 自身的原地消融机制、--listFiles 主张、两个 issue 线程的未读部分、shard-3 的作业日志(改以本地复现代替)。


派发席处置:放行

三条全修,逐条按内容核过:

  • F1 —— 样本从 kanban 重定向到 abbr,假机制注释已订正。⭐ 实现者否决了本席倾向的合成类型方案,并给了测量KNOWN_SCHEMA_TYPES 是从注册调用生成的文件且被 known-schema-types-derivation-5115.test.ts 单独钉住,合成类型只能靠 mock 那个模块进入——那会伪造「已注册」这一半,而这一半正是被测对象。本席的建议会掏空该测试的证据价值,采纳它的。它的差集探针两方向都点亮对照(658 注册 / 102 建模 / 558 无成员,kanban/text/tree-view 读作 modelled 即对旧注释的直接反证)。⭐ 并且它把定时器拆了:用例现在断言自己的前提,未来变红会读作「abbr 现在被建模了,换一个类型」,而不是这轮花掉一个 CI 周期的 expected +0 to be 1
  • F2 / F3 —— 散文订正。⭐ 实现者做了一个正确的切分:底层测量成立(公共 KanbanCard 确缺那四个成员),作废的只是归因。F3 它自查出比裁断更多:col.cards 三处、索引签名 449/672/692(691 差一、449 整个漏掉)。
  • ⚠️F2(a) 的错源是本席——实现者是从本席的派工/上报文本里带过来的。本席已在 #6939 订正

合约面自被审 head 起未动(这是不重跑审查的依据):

 fba1bfd78(被审)→ 2e8816b61(现)
complex.ts da06193b0f6fc5f17c8197a1ef34a3e0491fa6b7 IDENTICAL
complex.zod.ts f53db2176cc01d32ec2eb01f484835b9d20eaaa7 IDENTICAL

自被审 head 起本分支只有一个自有提交 a5c4ef4b3(CLI fixture 重定向);F2/F3 是 GitHub 上的散文编辑,仓库内容未变。

⛔ clause 2 仍未实现,且仍在维护者手上

本次放行的是 clause 1itemscards 重命名)。clause 2 与 #6172 裁决的冲突未解,已原样上报(#6939 评论 5530620525)。放行 clause 1 不预判该冲突:无论 types 三重奏最终保留、改名还是按选项 D 退役,这次的成员重命名都随之迁移或一并丢弃,都不因先落而更难。

⚠️CI 在当前 head 2e8816b61 上仍在跑(19:18 启动)。⚠️ 记一笔:CI 修复所在的 head a3fb15e5e 的运行被 merge 推送取消cancelled),从未跑完——所以修复本身尚未在 CI 上被证明,正在跑的这个才是。auto-merge 会等必需检查通过,若转红本席按 drive-to-green 处置。


Generated by Claude Code

@os-project-managerClaude

Copy link
Copy Markdown
CollaboratorAuthor

CI 已在当前 head 转绿;放行动作剩两步,被 GitHub 配额挡住

domain:ui 派发席,session session_01EMrWaQw3XS5DxTHxp4yRyC

CI 序列,按 head_sha 逐个核对

fba1bfd78 failure ← 原来的红(check-validity-recogniser)
a3fb15e5e cancelled ← CI 修复所在的 head,被 merge 推送顶掉,从未跑完
2e8816b61 success ← 当前 head:修复在 CI 上被证明

⚠️ 两处值得记的读数陷阱,本 PR 上都出现了:

  • cancelled 不是绿也不是红,是未跑完。若把 a3fb15e5ecancelled 当作「修复已验证」,就会在修复从未被 CI 跑过的情况下放行。真正证明它的是 2e8816b61 这一次。
  • **按 status=completed 过滤会同时返回旧 head 的结论。**本 PR 的三次运行全部 completed,其中一个 failure、一个 cancelled——不核对 head_sha 就会读到与当前 head 无关的结果。

放行状态

  • needs:contract-review 已剥(标签现为 package: types / examples / tests
  • ✅ 裁断已逐字张贴(评论 5530965431),档位核验 100/100 在档
  • ✅ 合约面自被审 head 起逐字节未动:complex.ts = da06193b0complex.zod.ts = f53db2176fba1bfd782e8816b61
  • ✅ CI 在当前 head 绿
  • draft:false
  • 欠 auto-merge SQUASH

后两步的 API 端点(update_pull_request / enable_pr_auto_merge,GraphQL 后端)自 19:26 起持续返回 API rate limit already exceeded,而评论与标签端点仍可用——所以这条记录发得出去、放行动作发不出去。已排定时提醒跟踪补完,⛔ 不靠记忆、⛔ 不会静默停在半完成状态。

⭐ 顺带记一条操作次序上的改进,本轮两次踩到才想明白:应当先 draft:false + auto-merge,成功后再剥 needs:contract-review。先剥标签的话,配额一断就留下「标签显示已复核、实际仍是草稿」的不自洽状态;反序则只会留下「有标签、是草稿」的自洽状态。

⛔ 仍未实现且仍在维护者手上

本次放行的是 clause 1itemscards)。clause 2 与 #6172 裁决的冲突未解,已原样上报(#6939 评论 5530620525)。放行 clause 1 不预判该冲突。


Generated by Claude Code

@os-project-manager
os-project-manager marked this pull request as ready for review September 3, 2026 19:55
@os-project-manager
os-project-manager added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 240b80fSep 3, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-6939-group3-kanban-cards branch September 3, 2026 20:10
Sign up for freeto 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

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(types): rename KanbanColumn.items to cards on both published halves - #7541

Merged
os-project-manager merged 5 commits into
mainfrom
claude/issue-6939-group3-kanban-cards
Sep 3, 2026
Merged

fix(types): rename KanbanColumn.items to cards on both published halves#7541
os-project-manager merged 5 commits into
mainfrom
claude/issue-6939-group3-kanban-cards

Conversation

@os-project-manager

@os-project-manageros-project-manager commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Part of #6939 — the kanban row (group 3) only. Groups 4 (filter-builder) and 5 (chart) are not addressed here and remain open; group 2 (tree-view) is PR #7533.

Clause-②: yes — this moves a published mirror's accept/reject behaviour AND renames a member on a published type. Draft + needs:contract-review; not marked ready, no auto-merge.

What changed

KanbanColumn declared its card list as items in both halves of the published surface — packages/types/src/complex.ts and the zod mirror packages/types/src/zod/complex.zod.ts — while every board reads cards. Renamed to cards.

The ruling's own numbers, re-measured on this branch's base

The maintainer ruling (comment 5510084784) took its counts on origin/mainec0a7b84. This branch is based on 78a3cc238. All three reproduce:

ReadingRulingRe-measured on 78a3cc238
plugin-kanban/src/types.ts declares cards: KanbanCard[]line 75line 75 ✓
complex.zod.ts declares itemsline 54line 55 (one line of drift)
.cards read lines in KanbanImpl.tsx1212 ✓
.cards read lines in KanbanEnhanced.tsx88 ✓
.items read lines in either00 ✓

Control for the two zeros: a same-shaped probe (grep -c '\.title') on the same two files returns 8 and 3, so the zeros are readings and not a mis-shaped probe. A nonsense-member probe of the same shape returns 0 on both.

Addendum the ruling did not count:packages/plugin-kanban/src/index.tsx reads col.cardsthree more times — lines 64 and 89 in bucketCardsIntoColumns, and line 327 in the kanban-enhanced registration's useMemo, which has the same shape. Each is col.cards || [], and that || [] is the mechanism behind the discriminator below. (An earlier revision said "twice more (lines 64 and 89)", missing line 327; corrected on review.)

Why the rename went toward cards — measured, not asserted

Per #6318's triage, a "correction" that renders identically proves the schema was the wrong side. This row clears the stronger, opposite-polarity bar: "correcting" the fixtures toward the declaration does not merely change the render, it empties the board. Measured through the harness in the new test file, on 78a3cc238, before either declaration was touched:

Entrycards (authored)items (the declared spelling)
basic-kanban-board64 elements — To Do2 … Design new feature …45 elements — No cards3 columnsTo Do0In Progress0Done0
advanced-kanban-with-badges-and-limits86 elements — Backlog2 … User Authentication …58 elements — No cards4 columnsBacklog0 …

Validator verdicts, same run: the authored cards documents failedsafeValidateSchema (: Invalid input) and the items documents passed. After this change, exactly reversed.

What is pinned

examples/schema-catalog/test/kanban-column-cards-6939.test.tsx (11 tests):

  • both catalog entries validate;
  • the items spelling is now refused (the other half of the accept-set move — a mirror that merely widened would still accept it);
  • cards is a real declaration, not a passthrough hole — counter-probes use only the declared key, since BaseSchema is .passthrough() and an unknown key would prove nothing;
  • render identity against the pre-change readings: element count, tag census, visible text literal, and SHA-256 over the full textContent;
  • anti-vacuity — every authored column title and card title is asserted on screen, plus a guard that at least one card exists, so the identity pin cannot pass on a blank tile;
  • the items empty-board reading is itself pinned, so the direction of the rename stays a measurement.

Controls are legal in both states. The render carriers never pass through the validator, and bucketCardsIntoColumns is untouched, so both the populated and the empty board render the same before and after. The waitFor witness is a column heading, which exists in both boards — it cannot settle for one spelling and time out for the other.

Ablation (predicted before measured)

Restoring items to both declarations, renderer untouched. Predicted red: the two validates cases, the two items-refused cases, and the passthrough counter-probe — 5 of 11, with the six render/anti-vacuity cases and all 12 zod-mirror-parity cases staying green.

Measured: exactly thatTests 5 failed | 18 passed (23), and the five names match the prediction one-for-one.

The mutation was proven on disk before the run (anchored counts in both directions, plus blob hashes differing from HEAD), and the restore was proven by state, not by exit code: both worktree blob hashes equal their HEAD blobs, git diff HEAD empty, git status --porcelain empty. Both files resolve through the repo's vitest source alias (packages/types/src/...), so no dist rebuild participates in this ablation.

Notes

  • packages/types/examples/zod-validation-example.ts authored the old spelling in three places; renamed. It is covered by packages/types' type-check (which runs tsc -p tsconfig.examples.json).
  • The header of examples/schema-catalog/test/safe-validate-corpus-6318.test.ts listed this row as an open finding on the Zod union; that sentence is now stale and the kanban clause is removed. That file deliberately pins no bucket size, so nothing else there moves.
  • @object-ui/plugin-kanban is unchanged — it already declared cards.
  • An earlier revision of the test preloaded the lazy chunk via @object-ui/plugin-kanban/KanbanImpl. That shape was removed: it is not in the package's exports map and resolves only through the repo's vitest alias, which @object-ui/fields deep subpaths resolve only through the repo vitest alias — its exports map publishes none of them #4325 ruled out for @object-ui/fields. The test now settles the boundary with waitFor, the way catalog-gallery-render.test.tsx already does for these same entries.

Changeset

minor, not patch — this is a rename on a published type, not a widening. @object-ui/types only. (major is forbidden repo-wide by scripts/check-changeset-no-major.mjs; the breaking semantics are spelled out in the changeset body per repo convention.)

Verification — all at merged head fba1bfd78

CheckResult
vitest run packages/types/ packages/plugin-kanban/ examples/schema-catalog/Test Files 140 passed (140), Tests 3727 passed (3727)
zod-mirror-parity.test.ts (run explicitly)Tests 12 passed (12)
turbo run type-check --filter=@object-ui/types --filter=@object-ui/plugin-kanbanTasks: 15 successful, 15 total
turbo run type-check --filter=@object-ui/example-schema-catalogTasks: 30 successful, 30 total
eslint . --format json4254 files, 0 errors (eslint's own population, not a narrowed list)
check-changeset-presence.mjsexit 0 — 1 changeset for 1 released package
check-changeset-no-major.mjsexit 0
check-control-bytes.mjsexit 0 — 6210 tracked text files

Branch merged with origin/main47547d01a (a merge, not a rebase, per AGENTS.md); the full suite above was re-run after the merge.

Clause 2 of the ruling, and a PRIOR ruling on this exact pair

The 2026-09-02 ruling has two clauses. This PR implements clause 1 (the rename). Clause 2 — "packages/plugin-kanban/src/types.ts stops carrying its own KanbanColumn declaration and re-uses the public one" — is NOT implemented here, and two things about it belong on the record. Neither asks this PR to decide anything.

1. The public declaration is not structurally sufficient. Measured: the plugin's local KanbanCard carries four members the public @object-ui/typesKanbanCard does not declare — badges, cardSubtitle, cardFieldCells, coverImage — plus an index signature; the plugin's KanbanColumn carries className where the public one has color. All are live reads (card.coverImage, card.cardFieldCells, card.cardSubtitle, card.badges, column.className, and card[swimlaneField] at KanbanImpl.tsx 449, 672 and 692). Deleting the local declaration would type column.cards as the publicKanbanCard[] and break every one of them, so clause 2 cannot be executed without widening the published type — which the dispatch explicitly forbids doing silently.

2. Correction to an earlier revision of this PR, and the prior ruling it missed.

An earlier revision cited the comment at KanbanImpl.tsx:52 as "a landed decision pointing the other way", saying objectui#6172 / #6155 made ./types the authority because the local card carried members the public one did not. That attribution was wrong. The comment compares KanbanImpl.tsx's own former copies against the plugin's ./types — an in-package drift — and says so in as many words: "the local KanbanCard carried cardSubtitle / cardFieldCells / coverImage that ./types did not". It says nothing about @object-ui/types.

That card was explicit about not touching the cross-package question. Its changeset (.changeset/6172-markdown-kanban-one-authority.md, landed in b3d562c02):

The cross-package KanbanCard / KanbanColumn / KanbanSchema collision between @object-ui/types and @object-ui/plugin-kanban is NOT resolved here and is escalated on objectui#6172 — those are two different dialects (items vs cards, labels vs badges), and collapsing them renames a published name, which needs an authority ruling.

So :52 is in-package convergence plus an explicit escalation, not a contrary decision.

And that escalation was answered. objectui#6172 comment 5474954379 (2026-08-31, maintainer verbatim 「其他同意」, director-seat batch #14) rules option A:

plugin-kanban 保留裸名 KanbanSchema 家族;@object-ui/types 三重奏改名(如 DeclarativeKanbanSchema 族)

Under that ruling the public KanbanColumn is renamed away, so clause 2's "re-use the public one" would have nothing to re-use. It predates the 2026-09-02 ruling by two days, the two do not cite each other, and it is not yet executed (packages/types/src/complex.ts:28 still declares KanbanColumn). It also lists retiring the @object-ui/types triplet outright as escalation option D — under which this PR's member rename would travel with the renamed type, or disappear with a retired one.

I am not adjudicating which ruling governs. Both are recorded so the reviewer and the maintainer can see the conflict; the dispatching seat has escalated it as-is. Worth noting that #6172's own census agrees with this PR's measurement independently: it found the types-dialect items spelling had zero non-demo, non-known-bad uses across the bound.

Follow-up: CI red on fba1bfd78, and the fix (a3fb15e5e)

Test (shard 3/4) went red on one case — packages/cli/src/__tests__/check-validity-recogniser.test.ts, "reports a registered component type the bundled schemas do not model", expected +0 to be 1. It is a correct consequence of this repair, and it is fixed here rather than worked around.

That case wrote a kanban board authoring cards and asserted objectui check would report it as a registered type the bundled schemas cannot model. It only ever landed in that bucket because the mirror required items — the exact fork this PR repairs. Once the board validates, the count drops to 0. The defect was frozen into an assertion of expected behaviour.

Reproduced end-to-end through the real check, not inferred: a kanban board with cards now yields candidates=[]; the sibling text fixture still yields a candidate (positive control); a foreign package.json still yields Skipped 1 and no candidate (negative control).

The comment was also wrong, independently of this PR. It claimed AnyComponentSchema "has no member for" kanban. ComplexSchema has carried KanbanSchema throughout (complex.zod.ts:691-692, reached from AnyComponentSchema via the ComplexSchema arm). Corrected to the real mechanism — a required-key mismatch, not an absent member.

The replacement type was chosen by measurement. Difference set, by introspecting every literal type the union declares: 658 registered types in KNOWN_SCHEMA_TYPES, 102 modelled, 558 with no member. Probe controlled in both directions — kanban, text and tree-view all read as modelled (so it is not blind to real members), a nonsense type does not.

Picked abbr. Raw HTML primitives are the stable inhabitants of that bucket: packages/components/src/renderers/basic/html-elements.tsx registers them in bulk and they are not candidates for authorable component schemas — unlike a plugin-ish type such as dashboard-grid, which also lands there today but is a plausible future modelling target. The fixture is a well-formedabbr document, which keeps the case's original point: the file is unmodelled, not broken.

The timer is defused rather than passed on. The case now asserts its own precondition — that abbr is still refused by safeValidateSchema — with a message naming what to do. If anyone ever models abbr, this file says why it went red instead of reporting a bare expected +0 to be 1. A synthetic always-unmodelled type was considered and rejected: the registered-type universe is a generated, separately-pinned file (packages/cli/src/utils/known-schema-types.ts), so a synthetic type would have to be injected by mocking it — and that would fabricate the "registered" half, which is precisely the half this bucket is about.

⛔ The test was not skipped, disabled, isolated or deleted, and the sample was not reverted to items. The changeset level is unchanged (minor).

Re-verified at merged head a3fb15e5e (merged origin/mainf0f774b0d)

CheckResult
vitest run packages/cli/ packages/types/ packages/plugin-kanban/ examples/schema-catalog/Test Files 156 passed (156), Tests 3973 passed (3973)
check-validity-recogniser.test.ts aloneTests 10 passed (10)
turbo run type-check --filter=@object-ui/cliTasks: 10 successful, 10 total
eslint on the changed file0 errors, 0 warnings
check-changeset-presence.mjsexit 0 — 1 changeset for 2 released packages
check-changeset-no-major.mjsexit 0
check-control-bytes.mjsexit 0 — 6212 tracked text files

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

`KanbanColumn` declared its card list as `items` in `complex.ts` and in the
zod mirror `complex.zod.ts`, while every board reads `cards`. Measured on
`origin/main` 78a3cc2: `KanbanImpl.tsx` reads `.cards` on 12 lines,
`KanbanEnhanced.tsx` on 8, and `bucketCardsIntoColumns` twice more as
`col.cards || []`; `.items` has zero read sites in either board, against a
same-shaped `.title` control returning 8 and 3 on the same two files.
The result was `declared !== enforced` on a published surface: both kanban
catalog entries failed `safeValidateSchema` with ": Invalid input" while
rendering perfectly — the type's seat in objectui#6318's bucket.
Renaming the read sites instead was rejected by measurement, not preference:
under the `items` spelling `col.cards || []` buckets every column to zero, and
`basic-kanban-board` goes from 64 elements reading "To Do2 / Design new
feature" to 45 elements reading "No cards / 3 columns / To Do0" — an empty
board. The declaration was the wrong side.
Pinned in `examples/schema-catalog/test/kanban-column-cards-6939.test.tsx`:
both entries validate, the `items` spelling is now refused, the rendered DOM is
byte-identical to the pre-change measurement (elements, tag census, visible
text, SHA-256 of textContent), and the empty-board reading for `items` is
pinned so the direction of the rename stays a measurement.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-JkRWQ99M.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…s false mechanism note
The `reports a registered component type the bundled schemas do not model`
case used a kanban board authoring `cards`, and its comment claimed
`AnyComponentSchema` "has no member for" kanban.
That claim was false, and was false before this branch touched anything:
`ComplexSchema` has carried `KanbanSchema` throughout. The board landed in the
bucket for a different reason — `KanbanColumnSchema` required `items` while
every board, and that sample, writes `cards`. Renaming the mirror to `cards`
made the board validate, so the case measured 0 candidates: the defect had
been frozen into an assertion of expected behaviour.
Repointed to `abbr`, chosen by measurement rather than memory. On this tree
`KNOWN_SCHEMA_TYPES` carries 658 registered types while `AnyComponentSchema`
declares 102 distinct literal `type` values, leaving 558 with no member; the
probe was controlled in both directions (`kanban` / `text` / `tree-view` read
as modelled, a nonsense type does not). Raw HTML primitives are the stable
inhabitants of that bucket — registered in bulk by `html-elements.tsx`, never
candidates for authorable component schemas — so the fixture does not carry a
timer the way a plugin-ish type such as `dashboard-grid` would.
The case also now asserts its own precondition, so if `abbr` is ever modelled
this file reports why instead of a bare `expected +0 to be 1`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-H6WopARe.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-H6WopARe.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (select-option.js)0.20KB0.19KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@os-project-managerClaude

Copy link
Copy Markdown
CollaboratorAuthor

合约审查裁断:FAIL 三条 → 补丁轮已全修 → 放行

domain:ui 派发席,session session_01EMrWaQw3XS5DxTHxp4yRyC。本席是 opus、不在 CONTRACT_REVIEW_TIER,故本 Clause-② yes 的 PR 由隔离审查者出裁。简报只含卡片、裁决与本 PR,⛔ 不含派发指令、⛔ 不含本席结论;并明确要求审查者只判 clause 2 的事实是否准确,⛔ 不判该走 A/B/C 哪个

转录档位核验:只提取 harness 生成的 model 字段(⛔ 不搜自由文本)。转录 205 行、0 行不可解析、100 个 assistant 轮次全部 claude-fable-5-1,无 fallback ⇒ 逐字采信。

三条 finding,逐条

F1 — 本 diff 让一个受 CI 把关的测试变红,而 PR 的验证人群不含它所在的包。
packages/cli/src/__tests__/check-validity-recogniser.test.ts 在 merge-base 通过、在 PR head 失败。那个用例写一个 columns[].cards: [] 的 kanban board,断言 objectui check 把它归入「未通过校验」桶。该样本从前之所以被拒,只因镜像要 items;本 PR 让 cards 成为被接受的拼法,于是它通过校验、桶计数读为 0。用例自己的散文(「kanbanAnyComponentSchema has no member for」)是假的——kanban 是被建模的,那正是本 PR 修的缺陷——所以它的前提随修复一同死亡。PR 的受影响套件跑的是 packages/types/ packages/plugin-kanban/ examples/schema-catalog/packages/cli 在人群之外,所以 PR 不可能看见它

head fba1bfd78 : × reports a registered component type … expected +0 to be 1 (1 failed | 9 passed)
base 47547d01a : 10 passed (10)
机制 同一样本经 safeValidateSchema:head success:true / base success:false [": Invalid input"]

F2 — clause 2 的叙述指错了物件,并漏掉了唯一直接相关的在先裁决。
(a) PR 称 KanbanImpl.tsx:52 记录 #6172/#6155 定权威「precisely because the local card carried … that the public one did not」。注释原文是「that ./types did not」——包内漂移;#6172 的 changeset 更明写跨包问题「is NOT resolved here and is escalated」。
(b) 该升格问题的答案存在#6172 评论 5474954379(2026-08-31,维护者逐字「其他同意」,第 6 场总监席决裁批 #14)裁选项 A —— plugin-kanban 保留裸名、@object-ui/types 三重奏改名,并列「径直退役」为升格选项 D。⇒ 在其之下 clause 2 的「公共那个」将不复存在。两条裁决相隔两天、互不引用,且 #6172尚未执行

F3(非阻塞)— 读点补记少了一处。index.tsxcol.cards处(64、89、327),索引签名读点是 449、672、692

审查者核实通过的部分

clause-2 的结构测量正确(公共 KanbanCard 确实缺那四个成员、无索引签名;本地 KanbanColumnclassName 而公共的是 color;所有引用读点为活读点,并另找到 ObjectKanban.tsx:585);裁决数字复现(items 在 55 行不是 54;12/8/0,配同形 .title 对照 8/3 与胡诌成员对照 0);判别器在真实 base 上重测,四个读数与 PR 钉的 PRE_REPAIR/ITEMS_SPELLING 全部吻合;空洞 harness 复现(Suspense fallback,1 元素、sha=e3b0c442… 即空串哈希),并验证替换后的 h3 见证在两种状态下都在场;消融在真实 base 上一对一复现(5 failed | 18 passed);changeset minor 正确,@object-ui/plugin-kanban 确未被动;普查确认插件之外无 KanbanColumn 消费者。

NARROWINGS(收口后由审查者自行转为实测的两项)

被锁住的宽跑事后返回:140 passed (140) / 3727 passed (3727),turbo type-check 32 successful, 32 total ⇒ 三棵树内无测试钉 items 拼法、无 TS 消费者读 KanbanColumn.items。**两项都确认了 F1 的结论:红的那个测试在 PR 所验证的人群之外,而那是人群选择的问题,不是人群内部有缺陷。**其余仍列为未测:whole-population eslint .、经完整 CLI 闭包的 objectui check、PR 自身的原地消融机制、--listFiles 主张、两个 issue 线程的未读部分、shard-3 的作业日志(改以本地复现代替)。


派发席处置:放行

三条全修,逐条按内容核过:

  • F1 —— 样本从 kanban 重定向到 abbr,假机制注释已订正。⭐ 实现者否决了本席倾向的合成类型方案,并给了测量KNOWN_SCHEMA_TYPES 是从注册调用生成的文件且被 known-schema-types-derivation-5115.test.ts 单独钉住,合成类型只能靠 mock 那个模块进入——那会伪造「已注册」这一半,而这一半正是被测对象。本席的建议会掏空该测试的证据价值,采纳它的。它的差集探针两方向都点亮对照(658 注册 / 102 建模 / 558 无成员,kanban/text/tree-view 读作 modelled 即对旧注释的直接反证)。⭐ 并且它把定时器拆了:用例现在断言自己的前提,未来变红会读作「abbr 现在被建模了,换一个类型」,而不是这轮花掉一个 CI 周期的 expected +0 to be 1
  • F2 / F3 —— 散文订正。⭐ 实现者做了一个正确的切分:底层测量成立(公共 KanbanCard 确缺那四个成员),作废的只是归因。F3 它自查出比裁断更多:col.cards 三处、索引签名 449/672/692(691 差一、449 整个漏掉)。
  • ⚠️F2(a) 的错源是本席——实现者是从本席的派工/上报文本里带过来的。本席已在 #6939 订正

合约面自被审 head 起未动(这是不重跑审查的依据):

 fba1bfd78(被审)→ 2e8816b61(现)
complex.ts da06193b0f6fc5f17c8197a1ef34a3e0491fa6b7 IDENTICAL
complex.zod.ts f53db2176cc01d32ec2eb01f484835b9d20eaaa7 IDENTICAL

自被审 head 起本分支只有一个自有提交 a5c4ef4b3(CLI fixture 重定向);F2/F3 是 GitHub 上的散文编辑,仓库内容未变。

⛔ clause 2 仍未实现,且仍在维护者手上

本次放行的是 clause 1itemscards 重命名)。clause 2 与 #6172 裁决的冲突未解,已原样上报(#6939 评论 5530620525)。放行 clause 1 不预判该冲突:无论 types 三重奏最终保留、改名还是按选项 D 退役,这次的成员重命名都随之迁移或一并丢弃,都不因先落而更难。

⚠️CI 在当前 head 2e8816b61 上仍在跑(19:18 启动)。⚠️ 记一笔:CI 修复所在的 head a3fb15e5e 的运行被 merge 推送取消cancelled),从未跑完——所以修复本身尚未在 CI 上被证明,正在跑的这个才是。auto-merge 会等必需检查通过,若转红本席按 drive-to-green 处置。


Generated by Claude Code

@os-project-managerClaude

Copy link
Copy Markdown
CollaboratorAuthor

CI 已在当前 head 转绿;放行动作剩两步,被 GitHub 配额挡住

domain:ui 派发席,session session_01EMrWaQw3XS5DxTHxp4yRyC

CI 序列,按 head_sha 逐个核对

fba1bfd78 failure ← 原来的红(check-validity-recogniser)
a3fb15e5e cancelled ← CI 修复所在的 head,被 merge 推送顶掉,从未跑完
2e8816b61 success ← 当前 head:修复在 CI 上被证明

⚠️ 两处值得记的读数陷阱,本 PR 上都出现了:

  • cancelled 不是绿也不是红,是未跑完。若把 a3fb15e5ecancelled 当作「修复已验证」,就会在修复从未被 CI 跑过的情况下放行。真正证明它的是 2e8816b61 这一次。
  • **按 status=completed 过滤会同时返回旧 head 的结论。**本 PR 的三次运行全部 completed,其中一个 failure、一个 cancelled——不核对 head_sha 就会读到与当前 head 无关的结果。

放行状态

  • needs:contract-review 已剥(标签现为 package: types / examples / tests
  • ✅ 裁断已逐字张贴(评论 5530965431),档位核验 100/100 在档
  • ✅ 合约面自被审 head 起逐字节未动:complex.ts = da06193b0complex.zod.ts = f53db2176fba1bfd782e8816b61
  • ✅ CI 在当前 head 绿
  • draft:false
  • 欠 auto-merge SQUASH

后两步的 API 端点(update_pull_request / enable_pr_auto_merge,GraphQL 后端)自 19:26 起持续返回 API rate limit already exceeded,而评论与标签端点仍可用——所以这条记录发得出去、放行动作发不出去。已排定时提醒跟踪补完,⛔ 不靠记忆、⛔ 不会静默停在半完成状态。

⭐ 顺带记一条操作次序上的改进,本轮两次踩到才想明白:应当先 draft:false + auto-merge,成功后再剥 needs:contract-review。先剥标签的话,配额一断就留下「标签显示已复核、实际仍是草稿」的不自洽状态;反序则只会留下「有标签、是草稿」的自洽状态。

⛔ 仍未实现且仍在维护者手上

本次放行的是 clause 1itemscards)。clause 2 与 #6172 裁决的冲突未解,已原样上报(#6939 评论 5530620525)。放行 clause 1 不预判该冲突。


Generated by Claude Code

@os-project-manager
os-project-manager marked this pull request as ready for review September 3, 2026 19:55
@os-project-manager
os-project-manager added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 240b80fSep 3, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-6939-group3-kanban-cards branch September 3, 2026 20:10
Sign up for freeto 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

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(types): rename KanbanColumn.items to cards on both published halves - #7541

Merged
os-project-manager merged 5 commits into
mainfrom
claude/issue-6939-group3-kanban-cards
Sep 3, 2026
Merged

fix(types): rename KanbanColumn.items to cards on both published halves#7541
os-project-manager merged 5 commits into
mainfrom
claude/issue-6939-group3-kanban-cards

Conversation

@os-project-manager

@os-project-manageros-project-manager commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Part of #6939 — the kanban row (group 3) only. Groups 4 (filter-builder) and 5 (chart) are not addressed here and remain open; group 2 (tree-view) is PR #7533.

Clause-②: yes — this moves a published mirror's accept/reject behaviour AND renames a member on a published type. Draft + needs:contract-review; not marked ready, no auto-merge.

What changed

KanbanColumn declared its card list as items in both halves of the published surface — packages/types/src/complex.ts and the zod mirror packages/types/src/zod/complex.zod.ts — while every board reads cards. Renamed to cards.

The ruling's own numbers, re-measured on this branch's base

The maintainer ruling (comment 5510084784) took its counts on origin/mainec0a7b84. This branch is based on 78a3cc238. All three reproduce:

ReadingRulingRe-measured on 78a3cc238
plugin-kanban/src/types.ts declares cards: KanbanCard[]line 75line 75 ✓
complex.zod.ts declares itemsline 54line 55 (one line of drift)
.cards read lines in KanbanImpl.tsx1212 ✓
.cards read lines in KanbanEnhanced.tsx88 ✓
.items read lines in either00 ✓

Control for the two zeros: a same-shaped probe (grep -c '\.title') on the same two files returns 8 and 3, so the zeros are readings and not a mis-shaped probe. A nonsense-member probe of the same shape returns 0 on both.

Addendum the ruling did not count:packages/plugin-kanban/src/index.tsx reads col.cardsthree more times — lines 64 and 89 in bucketCardsIntoColumns, and line 327 in the kanban-enhanced registration's useMemo, which has the same shape. Each is col.cards || [], and that || [] is the mechanism behind the discriminator below. (An earlier revision said "twice more (lines 64 and 89)", missing line 327; corrected on review.)

Why the rename went toward cards — measured, not asserted

Per #6318's triage, a "correction" that renders identically proves the schema was the wrong side. This row clears the stronger, opposite-polarity bar: "correcting" the fixtures toward the declaration does not merely change the render, it empties the board. Measured through the harness in the new test file, on 78a3cc238, before either declaration was touched:

Entrycards (authored)items (the declared spelling)
basic-kanban-board64 elements — To Do2 … Design new feature …45 elements — No cards3 columnsTo Do0In Progress0Done0
advanced-kanban-with-badges-and-limits86 elements — Backlog2 … User Authentication …58 elements — No cards4 columnsBacklog0 …

Validator verdicts, same run: the authored cards documents failedsafeValidateSchema (: Invalid input) and the items documents passed. After this change, exactly reversed.

What is pinned

examples/schema-catalog/test/kanban-column-cards-6939.test.tsx (11 tests):

  • both catalog entries validate;
  • the items spelling is now refused (the other half of the accept-set move — a mirror that merely widened would still accept it);
  • cards is a real declaration, not a passthrough hole — counter-probes use only the declared key, since BaseSchema is .passthrough() and an unknown key would prove nothing;
  • render identity against the pre-change readings: element count, tag census, visible text literal, and SHA-256 over the full textContent;
  • anti-vacuity — every authored column title and card title is asserted on screen, plus a guard that at least one card exists, so the identity pin cannot pass on a blank tile;
  • the items empty-board reading is itself pinned, so the direction of the rename stays a measurement.

Controls are legal in both states. The render carriers never pass through the validator, and bucketCardsIntoColumns is untouched, so both the populated and the empty board render the same before and after. The waitFor witness is a column heading, which exists in both boards — it cannot settle for one spelling and time out for the other.

Ablation (predicted before measured)

Restoring items to both declarations, renderer untouched. Predicted red: the two validates cases, the two items-refused cases, and the passthrough counter-probe — 5 of 11, with the six render/anti-vacuity cases and all 12 zod-mirror-parity cases staying green.

Measured: exactly thatTests 5 failed | 18 passed (23), and the five names match the prediction one-for-one.

The mutation was proven on disk before the run (anchored counts in both directions, plus blob hashes differing from HEAD), and the restore was proven by state, not by exit code: both worktree blob hashes equal their HEAD blobs, git diff HEAD empty, git status --porcelain empty. Both files resolve through the repo's vitest source alias (packages/types/src/...), so no dist rebuild participates in this ablation.

Notes

  • packages/types/examples/zod-validation-example.ts authored the old spelling in three places; renamed. It is covered by packages/types' type-check (which runs tsc -p tsconfig.examples.json).
  • The header of examples/schema-catalog/test/safe-validate-corpus-6318.test.ts listed this row as an open finding on the Zod union; that sentence is now stale and the kanban clause is removed. That file deliberately pins no bucket size, so nothing else there moves.
  • @object-ui/plugin-kanban is unchanged — it already declared cards.
  • An earlier revision of the test preloaded the lazy chunk via @object-ui/plugin-kanban/KanbanImpl. That shape was removed: it is not in the package's exports map and resolves only through the repo's vitest alias, which @object-ui/fields deep subpaths resolve only through the repo vitest alias — its exports map publishes none of them #4325 ruled out for @object-ui/fields. The test now settles the boundary with waitFor, the way catalog-gallery-render.test.tsx already does for these same entries.

Changeset

minor, not patch — this is a rename on a published type, not a widening. @object-ui/types only. (major is forbidden repo-wide by scripts/check-changeset-no-major.mjs; the breaking semantics are spelled out in the changeset body per repo convention.)

Verification — all at merged head fba1bfd78

CheckResult
vitest run packages/types/ packages/plugin-kanban/ examples/schema-catalog/Test Files 140 passed (140), Tests 3727 passed (3727)
zod-mirror-parity.test.ts (run explicitly)Tests 12 passed (12)
turbo run type-check --filter=@object-ui/types --filter=@object-ui/plugin-kanbanTasks: 15 successful, 15 total
turbo run type-check --filter=@object-ui/example-schema-catalogTasks: 30 successful, 30 total
eslint . --format json4254 files, 0 errors (eslint's own population, not a narrowed list)
check-changeset-presence.mjsexit 0 — 1 changeset for 1 released package
check-changeset-no-major.mjsexit 0
check-control-bytes.mjsexit 0 — 6210 tracked text files

Branch merged with origin/main47547d01a (a merge, not a rebase, per AGENTS.md); the full suite above was re-run after the merge.

Clause 2 of the ruling, and a PRIOR ruling on this exact pair

The 2026-09-02 ruling has two clauses. This PR implements clause 1 (the rename). Clause 2 — "packages/plugin-kanban/src/types.ts stops carrying its own KanbanColumn declaration and re-uses the public one" — is NOT implemented here, and two things about it belong on the record. Neither asks this PR to decide anything.

1. The public declaration is not structurally sufficient. Measured: the plugin's local KanbanCard carries four members the public @object-ui/typesKanbanCard does not declare — badges, cardSubtitle, cardFieldCells, coverImage — plus an index signature; the plugin's KanbanColumn carries className where the public one has color. All are live reads (card.coverImage, card.cardFieldCells, card.cardSubtitle, card.badges, column.className, and card[swimlaneField] at KanbanImpl.tsx 449, 672 and 692). Deleting the local declaration would type column.cards as the publicKanbanCard[] and break every one of them, so clause 2 cannot be executed without widening the published type — which the dispatch explicitly forbids doing silently.

2. Correction to an earlier revision of this PR, and the prior ruling it missed.

An earlier revision cited the comment at KanbanImpl.tsx:52 as "a landed decision pointing the other way", saying objectui#6172 / #6155 made ./types the authority because the local card carried members the public one did not. That attribution was wrong. The comment compares KanbanImpl.tsx's own former copies against the plugin's ./types — an in-package drift — and says so in as many words: "the local KanbanCard carried cardSubtitle / cardFieldCells / coverImage that ./types did not". It says nothing about @object-ui/types.

That card was explicit about not touching the cross-package question. Its changeset (.changeset/6172-markdown-kanban-one-authority.md, landed in b3d562c02):

The cross-package KanbanCard / KanbanColumn / KanbanSchema collision between @object-ui/types and @object-ui/plugin-kanban is NOT resolved here and is escalated on objectui#6172 — those are two different dialects (items vs cards, labels vs badges), and collapsing them renames a published name, which needs an authority ruling.

So :52 is in-package convergence plus an explicit escalation, not a contrary decision.

And that escalation was answered. objectui#6172 comment 5474954379 (2026-08-31, maintainer verbatim 「其他同意」, director-seat batch #14) rules option A:

plugin-kanban 保留裸名 KanbanSchema 家族;@object-ui/types 三重奏改名(如 DeclarativeKanbanSchema 族)

Under that ruling the public KanbanColumn is renamed away, so clause 2's "re-use the public one" would have nothing to re-use. It predates the 2026-09-02 ruling by two days, the two do not cite each other, and it is not yet executed (packages/types/src/complex.ts:28 still declares KanbanColumn). It also lists retiring the @object-ui/types triplet outright as escalation option D — under which this PR's member rename would travel with the renamed type, or disappear with a retired one.

I am not adjudicating which ruling governs. Both are recorded so the reviewer and the maintainer can see the conflict; the dispatching seat has escalated it as-is. Worth noting that #6172's own census agrees with this PR's measurement independently: it found the types-dialect items spelling had zero non-demo, non-known-bad uses across the bound.

Follow-up: CI red on fba1bfd78, and the fix (a3fb15e5e)

Test (shard 3/4) went red on one case — packages/cli/src/__tests__/check-validity-recogniser.test.ts, "reports a registered component type the bundled schemas do not model", expected +0 to be 1. It is a correct consequence of this repair, and it is fixed here rather than worked around.

That case wrote a kanban board authoring cards and asserted objectui check would report it as a registered type the bundled schemas cannot model. It only ever landed in that bucket because the mirror required items — the exact fork this PR repairs. Once the board validates, the count drops to 0. The defect was frozen into an assertion of expected behaviour.

Reproduced end-to-end through the real check, not inferred: a kanban board with cards now yields candidates=[]; the sibling text fixture still yields a candidate (positive control); a foreign package.json still yields Skipped 1 and no candidate (negative control).

The comment was also wrong, independently of this PR. It claimed AnyComponentSchema "has no member for" kanban. ComplexSchema has carried KanbanSchema throughout (complex.zod.ts:691-692, reached from AnyComponentSchema via the ComplexSchema arm). Corrected to the real mechanism — a required-key mismatch, not an absent member.

The replacement type was chosen by measurement. Difference set, by introspecting every literal type the union declares: 658 registered types in KNOWN_SCHEMA_TYPES, 102 modelled, 558 with no member. Probe controlled in both directions — kanban, text and tree-view all read as modelled (so it is not blind to real members), a nonsense type does not.

Picked abbr. Raw HTML primitives are the stable inhabitants of that bucket: packages/components/src/renderers/basic/html-elements.tsx registers them in bulk and they are not candidates for authorable component schemas — unlike a plugin-ish type such as dashboard-grid, which also lands there today but is a plausible future modelling target. The fixture is a well-formedabbr document, which keeps the case's original point: the file is unmodelled, not broken.

The timer is defused rather than passed on. The case now asserts its own precondition — that abbr is still refused by safeValidateSchema — with a message naming what to do. If anyone ever models abbr, this file says why it went red instead of reporting a bare expected +0 to be 1. A synthetic always-unmodelled type was considered and rejected: the registered-type universe is a generated, separately-pinned file (packages/cli/src/utils/known-schema-types.ts), so a synthetic type would have to be injected by mocking it — and that would fabricate the "registered" half, which is precisely the half this bucket is about.

⛔ The test was not skipped, disabled, isolated or deleted, and the sample was not reverted to items. The changeset level is unchanged (minor).

Re-verified at merged head a3fb15e5e (merged origin/mainf0f774b0d)

CheckResult
vitest run packages/cli/ packages/types/ packages/plugin-kanban/ examples/schema-catalog/Test Files 156 passed (156), Tests 3973 passed (3973)
check-validity-recogniser.test.ts aloneTests 10 passed (10)
turbo run type-check --filter=@object-ui/cliTasks: 10 successful, 10 total
eslint on the changed file0 errors, 0 warnings
check-changeset-presence.mjsexit 0 — 1 changeset for 2 released packages
check-changeset-no-major.mjsexit 0
check-control-bytes.mjsexit 0 — 6212 tracked text files

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

`KanbanColumn` declared its card list as `items` in `complex.ts` and in the
zod mirror `complex.zod.ts`, while every board reads `cards`. Measured on
`origin/main` 78a3cc2: `KanbanImpl.tsx` reads `.cards` on 12 lines,
`KanbanEnhanced.tsx` on 8, and `bucketCardsIntoColumns` twice more as
`col.cards || []`; `.items` has zero read sites in either board, against a
same-shaped `.title` control returning 8 and 3 on the same two files.
The result was `declared !== enforced` on a published surface: both kanban
catalog entries failed `safeValidateSchema` with ": Invalid input" while
rendering perfectly — the type's seat in objectui#6318's bucket.
Renaming the read sites instead was rejected by measurement, not preference:
under the `items` spelling `col.cards || []` buckets every column to zero, and
`basic-kanban-board` goes from 64 elements reading "To Do2 / Design new
feature" to 45 elements reading "No cards / 3 columns / To Do0" — an empty
board. The declaration was the wrong side.
Pinned in `examples/schema-catalog/test/kanban-column-cards-6939.test.tsx`:
both entries validate, the `items` spelling is now refused, the rendered DOM is
byte-identical to the pre-change measurement (elements, tag census, visible
text, SHA-256 of textContent), and the empty-board reading for `items` is
pinned so the direction of the rename stays a measurement.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-JkRWQ99M.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…s false mechanism note
The `reports a registered component type the bundled schemas do not model`
case used a kanban board authoring `cards`, and its comment claimed
`AnyComponentSchema` "has no member for" kanban.
That claim was false, and was false before this branch touched anything:
`ComplexSchema` has carried `KanbanSchema` throughout. The board landed in the
bucket for a different reason — `KanbanColumnSchema` required `items` while
every board, and that sample, writes `cards`. Renaming the mirror to `cards`
made the board validate, so the case measured 0 candidates: the defect had
been frozen into an assertion of expected behaviour.
Repointed to `abbr`, chosen by measurement rather than memory. On this tree
`KNOWN_SCHEMA_TYPES` carries 658 registered types while `AnyComponentSchema`
declares 102 distinct literal `type` values, leaving 558 with no member; the
probe was controlled in both directions (`kanban` / `text` / `tree-view` read
as modelled, a nonsense type does not). Raw HTML primitives are the stable
inhabitants of that bucket — registered in bulk by `html-elements.tsx`, never
candidates for authorable component schemas — so the fixture does not carry a
timer the way a plugin-ish type such as `dashboard-grid` would.
The case also now asserts its own precondition, so if `abbr` is ever modelled
this file reports why instead of a bare `expected +0 to be 1`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-H6WopARe.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-H6WopARe.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (select-option.js)0.20KB0.19KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@os-project-managerClaude

Copy link
Copy Markdown
CollaboratorAuthor

合约审查裁断:FAIL 三条 → 补丁轮已全修 → 放行

domain:ui 派发席,session session_01EMrWaQw3XS5DxTHxp4yRyC。本席是 opus、不在 CONTRACT_REVIEW_TIER,故本 Clause-② yes 的 PR 由隔离审查者出裁。简报只含卡片、裁决与本 PR,⛔ 不含派发指令、⛔ 不含本席结论;并明确要求审查者只判 clause 2 的事实是否准确,⛔ 不判该走 A/B/C 哪个

转录档位核验:只提取 harness 生成的 model 字段(⛔ 不搜自由文本)。转录 205 行、0 行不可解析、100 个 assistant 轮次全部 claude-fable-5-1,无 fallback ⇒ 逐字采信。

三条 finding,逐条

F1 — 本 diff 让一个受 CI 把关的测试变红,而 PR 的验证人群不含它所在的包。
packages/cli/src/__tests__/check-validity-recogniser.test.ts 在 merge-base 通过、在 PR head 失败。那个用例写一个 columns[].cards: [] 的 kanban board,断言 objectui check 把它归入「未通过校验」桶。该样本从前之所以被拒,只因镜像要 items;本 PR 让 cards 成为被接受的拼法,于是它通过校验、桶计数读为 0。用例自己的散文(「kanbanAnyComponentSchema has no member for」)是假的——kanban 是被建模的,那正是本 PR 修的缺陷——所以它的前提随修复一同死亡。PR 的受影响套件跑的是 packages/types/ packages/plugin-kanban/ examples/schema-catalog/packages/cli 在人群之外,所以 PR 不可能看见它

head fba1bfd78 : × reports a registered component type … expected +0 to be 1 (1 failed | 9 passed)
base 47547d01a : 10 passed (10)
机制 同一样本经 safeValidateSchema:head success:true / base success:false [": Invalid input"]

F2 — clause 2 的叙述指错了物件,并漏掉了唯一直接相关的在先裁决。
(a) PR 称 KanbanImpl.tsx:52 记录 #6172/#6155 定权威「precisely because the local card carried … that the public one did not」。注释原文是「that ./types did not」——包内漂移;#6172 的 changeset 更明写跨包问题「is NOT resolved here and is escalated」。
(b) 该升格问题的答案存在#6172 评论 5474954379(2026-08-31,维护者逐字「其他同意」,第 6 场总监席决裁批 #14)裁选项 A —— plugin-kanban 保留裸名、@object-ui/types 三重奏改名,并列「径直退役」为升格选项 D。⇒ 在其之下 clause 2 的「公共那个」将不复存在。两条裁决相隔两天、互不引用,且 #6172尚未执行

F3(非阻塞)— 读点补记少了一处。index.tsxcol.cards处(64、89、327),索引签名读点是 449、672、692

审查者核实通过的部分

clause-2 的结构测量正确(公共 KanbanCard 确实缺那四个成员、无索引签名;本地 KanbanColumnclassName 而公共的是 color;所有引用读点为活读点,并另找到 ObjectKanban.tsx:585);裁决数字复现(items 在 55 行不是 54;12/8/0,配同形 .title 对照 8/3 与胡诌成员对照 0);判别器在真实 base 上重测,四个读数与 PR 钉的 PRE_REPAIR/ITEMS_SPELLING 全部吻合;空洞 harness 复现(Suspense fallback,1 元素、sha=e3b0c442… 即空串哈希),并验证替换后的 h3 见证在两种状态下都在场;消融在真实 base 上一对一复现(5 failed | 18 passed);changeset minor 正确,@object-ui/plugin-kanban 确未被动;普查确认插件之外无 KanbanColumn 消费者。

NARROWINGS(收口后由审查者自行转为实测的两项)

被锁住的宽跑事后返回:140 passed (140) / 3727 passed (3727),turbo type-check 32 successful, 32 total ⇒ 三棵树内无测试钉 items 拼法、无 TS 消费者读 KanbanColumn.items。**两项都确认了 F1 的结论:红的那个测试在 PR 所验证的人群之外,而那是人群选择的问题,不是人群内部有缺陷。**其余仍列为未测:whole-population eslint .、经完整 CLI 闭包的 objectui check、PR 自身的原地消融机制、--listFiles 主张、两个 issue 线程的未读部分、shard-3 的作业日志(改以本地复现代替)。


派发席处置:放行

三条全修,逐条按内容核过:

  • F1 —— 样本从 kanban 重定向到 abbr,假机制注释已订正。⭐ 实现者否决了本席倾向的合成类型方案,并给了测量KNOWN_SCHEMA_TYPES 是从注册调用生成的文件且被 known-schema-types-derivation-5115.test.ts 单独钉住,合成类型只能靠 mock 那个模块进入——那会伪造「已注册」这一半,而这一半正是被测对象。本席的建议会掏空该测试的证据价值,采纳它的。它的差集探针两方向都点亮对照(658 注册 / 102 建模 / 558 无成员,kanban/text/tree-view 读作 modelled 即对旧注释的直接反证)。⭐ 并且它把定时器拆了:用例现在断言自己的前提,未来变红会读作「abbr 现在被建模了,换一个类型」,而不是这轮花掉一个 CI 周期的 expected +0 to be 1
  • F2 / F3 —— 散文订正。⭐ 实现者做了一个正确的切分:底层测量成立(公共 KanbanCard 确缺那四个成员),作废的只是归因。F3 它自查出比裁断更多:col.cards 三处、索引签名 449/672/692(691 差一、449 整个漏掉)。
  • ⚠️F2(a) 的错源是本席——实现者是从本席的派工/上报文本里带过来的。本席已在 #6939 订正

合约面自被审 head 起未动(这是不重跑审查的依据):

 fba1bfd78(被审)→ 2e8816b61(现)
complex.ts da06193b0f6fc5f17c8197a1ef34a3e0491fa6b7 IDENTICAL
complex.zod.ts f53db2176cc01d32ec2eb01f484835b9d20eaaa7 IDENTICAL

自被审 head 起本分支只有一个自有提交 a5c4ef4b3(CLI fixture 重定向);F2/F3 是 GitHub 上的散文编辑,仓库内容未变。

⛔ clause 2 仍未实现,且仍在维护者手上

本次放行的是 clause 1itemscards 重命名)。clause 2 与 #6172 裁决的冲突未解,已原样上报(#6939 评论 5530620525)。放行 clause 1 不预判该冲突:无论 types 三重奏最终保留、改名还是按选项 D 退役,这次的成员重命名都随之迁移或一并丢弃,都不因先落而更难。

⚠️CI 在当前 head 2e8816b61 上仍在跑(19:18 启动)。⚠️ 记一笔:CI 修复所在的 head a3fb15e5e 的运行被 merge 推送取消cancelled),从未跑完——所以修复本身尚未在 CI 上被证明,正在跑的这个才是。auto-merge 会等必需检查通过,若转红本席按 drive-to-green 处置。


Generated by Claude Code

@os-project-managerClaude

Copy link
Copy Markdown
CollaboratorAuthor

CI 已在当前 head 转绿;放行动作剩两步,被 GitHub 配额挡住

domain:ui 派发席,session session_01EMrWaQw3XS5DxTHxp4yRyC

CI 序列,按 head_sha 逐个核对

fba1bfd78 failure ← 原来的红(check-validity-recogniser)
a3fb15e5e cancelled ← CI 修复所在的 head,被 merge 推送顶掉,从未跑完
2e8816b61 success ← 当前 head:修复在 CI 上被证明

⚠️ 两处值得记的读数陷阱,本 PR 上都出现了:

  • cancelled 不是绿也不是红,是未跑完。若把 a3fb15e5ecancelled 当作「修复已验证」,就会在修复从未被 CI 跑过的情况下放行。真正证明它的是 2e8816b61 这一次。
  • **按 status=completed 过滤会同时返回旧 head 的结论。**本 PR 的三次运行全部 completed,其中一个 failure、一个 cancelled——不核对 head_sha 就会读到与当前 head 无关的结果。

放行状态

  • needs:contract-review 已剥(标签现为 package: types / examples / tests
  • ✅ 裁断已逐字张贴(评论 5530965431),档位核验 100/100 在档
  • ✅ 合约面自被审 head 起逐字节未动:complex.ts = da06193b0complex.zod.ts = f53db2176fba1bfd782e8816b61
  • ✅ CI 在当前 head 绿
  • draft:false
  • 欠 auto-merge SQUASH

后两步的 API 端点(update_pull_request / enable_pr_auto_merge,GraphQL 后端)自 19:26 起持续返回 API rate limit already exceeded,而评论与标签端点仍可用——所以这条记录发得出去、放行动作发不出去。已排定时提醒跟踪补完,⛔ 不靠记忆、⛔ 不会静默停在半完成状态。

⭐ 顺带记一条操作次序上的改进,本轮两次踩到才想明白:应当先 draft:false + auto-merge,成功后再剥 needs:contract-review。先剥标签的话,配额一断就留下「标签显示已复核、实际仍是草稿」的不自洽状态;反序则只会留下「有标签、是草稿」的自洽状态。

⛔ 仍未实现且仍在维护者手上

本次放行的是 clause 1itemscards)。clause 2 与 #6172 裁决的冲突未解,已原样上报(#6939 评论 5530620525)。放行 clause 1 不预判该冲突。


Generated by Claude Code

@os-project-manager
os-project-manager marked this pull request as ready for review September 3, 2026 19:55
@os-project-manager
os-project-manager added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 240b80fSep 3, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-6939-group3-kanban-cards branch September 3, 2026 20:10
Sign up for freeto 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

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(types): rename KanbanColumn.items to cards on both published halves - #7541

Merged
os-project-manager merged 5 commits into
mainfrom
claude/issue-6939-group3-kanban-cards
Sep 3, 2026
Merged

fix(types): rename KanbanColumn.items to cards on both published halves#7541
os-project-manager merged 5 commits into
mainfrom
claude/issue-6939-group3-kanban-cards

Conversation

@os-project-manager

@os-project-manageros-project-manager commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Part of #6939 — the kanban row (group 3) only. Groups 4 (filter-builder) and 5 (chart) are not addressed here and remain open; group 2 (tree-view) is PR #7533.

Clause-②: yes — this moves a published mirror's accept/reject behaviour AND renames a member on a published type. Draft + needs:contract-review; not marked ready, no auto-merge.

What changed

KanbanColumn declared its card list as items in both halves of the published surface — packages/types/src/complex.ts and the zod mirror packages/types/src/zod/complex.zod.ts — while every board reads cards. Renamed to cards.

The ruling's own numbers, re-measured on this branch's base

The maintainer ruling (comment 5510084784) took its counts on origin/mainec0a7b84. This branch is based on 78a3cc238. All three reproduce:

ReadingRulingRe-measured on 78a3cc238
plugin-kanban/src/types.ts declares cards: KanbanCard[]line 75line 75 ✓
complex.zod.ts declares itemsline 54line 55 (one line of drift)
.cards read lines in KanbanImpl.tsx1212 ✓
.cards read lines in KanbanEnhanced.tsx88 ✓
.items read lines in either00 ✓

Control for the two zeros: a same-shaped probe (grep -c '\.title') on the same two files returns 8 and 3, so the zeros are readings and not a mis-shaped probe. A nonsense-member probe of the same shape returns 0 on both.

Addendum the ruling did not count:packages/plugin-kanban/src/index.tsx reads col.cardsthree more times — lines 64 and 89 in bucketCardsIntoColumns, and line 327 in the kanban-enhanced registration's useMemo, which has the same shape. Each is col.cards || [], and that || [] is the mechanism behind the discriminator below. (An earlier revision said "twice more (lines 64 and 89)", missing line 327; corrected on review.)

Why the rename went toward cards — measured, not asserted

Per #6318's triage, a "correction" that renders identically proves the schema was the wrong side. This row clears the stronger, opposite-polarity bar: "correcting" the fixtures toward the declaration does not merely change the render, it empties the board. Measured through the harness in the new test file, on 78a3cc238, before either declaration was touched:

Entrycards (authored)items (the declared spelling)
basic-kanban-board64 elements — To Do2 … Design new feature …45 elements — No cards3 columnsTo Do0In Progress0Done0
advanced-kanban-with-badges-and-limits86 elements — Backlog2 … User Authentication …58 elements — No cards4 columnsBacklog0 …

Validator verdicts, same run: the authored cards documents failedsafeValidateSchema (: Invalid input) and the items documents passed. After this change, exactly reversed.

What is pinned

examples/schema-catalog/test/kanban-column-cards-6939.test.tsx (11 tests):

  • both catalog entries validate;
  • the items spelling is now refused (the other half of the accept-set move — a mirror that merely widened would still accept it);
  • cards is a real declaration, not a passthrough hole — counter-probes use only the declared key, since BaseSchema is .passthrough() and an unknown key would prove nothing;
  • render identity against the pre-change readings: element count, tag census, visible text literal, and SHA-256 over the full textContent;
  • anti-vacuity — every authored column title and card title is asserted on screen, plus a guard that at least one card exists, so the identity pin cannot pass on a blank tile;
  • the items empty-board reading is itself pinned, so the direction of the rename stays a measurement.

Controls are legal in both states. The render carriers never pass through the validator, and bucketCardsIntoColumns is untouched, so both the populated and the empty board render the same before and after. The waitFor witness is a column heading, which exists in both boards — it cannot settle for one spelling and time out for the other.

Ablation (predicted before measured)

Restoring items to both declarations, renderer untouched. Predicted red: the two validates cases, the two items-refused cases, and the passthrough counter-probe — 5 of 11, with the six render/anti-vacuity cases and all 12 zod-mirror-parity cases staying green.

Measured: exactly thatTests 5 failed | 18 passed (23), and the five names match the prediction one-for-one.

The mutation was proven on disk before the run (anchored counts in both directions, plus blob hashes differing from HEAD), and the restore was proven by state, not by exit code: both worktree blob hashes equal their HEAD blobs, git diff HEAD empty, git status --porcelain empty. Both files resolve through the repo's vitest source alias (packages/types/src/...), so no dist rebuild participates in this ablation.

Notes

  • packages/types/examples/zod-validation-example.ts authored the old spelling in three places; renamed. It is covered by packages/types' type-check (which runs tsc -p tsconfig.examples.json).
  • The header of examples/schema-catalog/test/safe-validate-corpus-6318.test.ts listed this row as an open finding on the Zod union; that sentence is now stale and the kanban clause is removed. That file deliberately pins no bucket size, so nothing else there moves.
  • @object-ui/plugin-kanban is unchanged — it already declared cards.
  • An earlier revision of the test preloaded the lazy chunk via @object-ui/plugin-kanban/KanbanImpl. That shape was removed: it is not in the package's exports map and resolves only through the repo's vitest alias, which @object-ui/fields deep subpaths resolve only through the repo vitest alias — its exports map publishes none of them #4325 ruled out for @object-ui/fields. The test now settles the boundary with waitFor, the way catalog-gallery-render.test.tsx already does for these same entries.

Changeset

minor, not patch — this is a rename on a published type, not a widening. @object-ui/types only. (major is forbidden repo-wide by scripts/check-changeset-no-major.mjs; the breaking semantics are spelled out in the changeset body per repo convention.)

Verification — all at merged head fba1bfd78

CheckResult
vitest run packages/types/ packages/plugin-kanban/ examples/schema-catalog/Test Files 140 passed (140), Tests 3727 passed (3727)
zod-mirror-parity.test.ts (run explicitly)Tests 12 passed (12)
turbo run type-check --filter=@object-ui/types --filter=@object-ui/plugin-kanbanTasks: 15 successful, 15 total
turbo run type-check --filter=@object-ui/example-schema-catalogTasks: 30 successful, 30 total
eslint . --format json4254 files, 0 errors (eslint's own population, not a narrowed list)
check-changeset-presence.mjsexit 0 — 1 changeset for 1 released package
check-changeset-no-major.mjsexit 0
check-control-bytes.mjsexit 0 — 6210 tracked text files

Branch merged with origin/main47547d01a (a merge, not a rebase, per AGENTS.md); the full suite above was re-run after the merge.

Clause 2 of the ruling, and a PRIOR ruling on this exact pair

The 2026-09-02 ruling has two clauses. This PR implements clause 1 (the rename). Clause 2 — "packages/plugin-kanban/src/types.ts stops carrying its own KanbanColumn declaration and re-uses the public one" — is NOT implemented here, and two things about it belong on the record. Neither asks this PR to decide anything.

1. The public declaration is not structurally sufficient. Measured: the plugin's local KanbanCard carries four members the public @object-ui/typesKanbanCard does not declare — badges, cardSubtitle, cardFieldCells, coverImage — plus an index signature; the plugin's KanbanColumn carries className where the public one has color. All are live reads (card.coverImage, card.cardFieldCells, card.cardSubtitle, card.badges, column.className, and card[swimlaneField] at KanbanImpl.tsx 449, 672 and 692). Deleting the local declaration would type column.cards as the publicKanbanCard[] and break every one of them, so clause 2 cannot be executed without widening the published type — which the dispatch explicitly forbids doing silently.

2. Correction to an earlier revision of this PR, and the prior ruling it missed.

An earlier revision cited the comment at KanbanImpl.tsx:52 as "a landed decision pointing the other way", saying objectui#6172 / #6155 made ./types the authority because the local card carried members the public one did not. That attribution was wrong. The comment compares KanbanImpl.tsx's own former copies against the plugin's ./types — an in-package drift — and says so in as many words: "the local KanbanCard carried cardSubtitle / cardFieldCells / coverImage that ./types did not". It says nothing about @object-ui/types.

That card was explicit about not touching the cross-package question. Its changeset (.changeset/6172-markdown-kanban-one-authority.md, landed in b3d562c02):

The cross-package KanbanCard / KanbanColumn / KanbanSchema collision between @object-ui/types and @object-ui/plugin-kanban is NOT resolved here and is escalated on objectui#6172 — those are two different dialects (items vs cards, labels vs badges), and collapsing them renames a published name, which needs an authority ruling.

So :52 is in-package convergence plus an explicit escalation, not a contrary decision.

And that escalation was answered. objectui#6172 comment 5474954379 (2026-08-31, maintainer verbatim 「其他同意」, director-seat batch #14) rules option A:

plugin-kanban 保留裸名 KanbanSchema 家族;@object-ui/types 三重奏改名(如 DeclarativeKanbanSchema 族)

Under that ruling the public KanbanColumn is renamed away, so clause 2's "re-use the public one" would have nothing to re-use. It predates the 2026-09-02 ruling by two days, the two do not cite each other, and it is not yet executed (packages/types/src/complex.ts:28 still declares KanbanColumn). It also lists retiring the @object-ui/types triplet outright as escalation option D — under which this PR's member rename would travel with the renamed type, or disappear with a retired one.

I am not adjudicating which ruling governs. Both are recorded so the reviewer and the maintainer can see the conflict; the dispatching seat has escalated it as-is. Worth noting that #6172's own census agrees with this PR's measurement independently: it found the types-dialect items spelling had zero non-demo, non-known-bad uses across the bound.

Follow-up: CI red on fba1bfd78, and the fix (a3fb15e5e)

Test (shard 3/4) went red on one case — packages/cli/src/__tests__/check-validity-recogniser.test.ts, "reports a registered component type the bundled schemas do not model", expected +0 to be 1. It is a correct consequence of this repair, and it is fixed here rather than worked around.

That case wrote a kanban board authoring cards and asserted objectui check would report it as a registered type the bundled schemas cannot model. It only ever landed in that bucket because the mirror required items — the exact fork this PR repairs. Once the board validates, the count drops to 0. The defect was frozen into an assertion of expected behaviour.

Reproduced end-to-end through the real check, not inferred: a kanban board with cards now yields candidates=[]; the sibling text fixture still yields a candidate (positive control); a foreign package.json still yields Skipped 1 and no candidate (negative control).

The comment was also wrong, independently of this PR. It claimed AnyComponentSchema "has no member for" kanban. ComplexSchema has carried KanbanSchema throughout (complex.zod.ts:691-692, reached from AnyComponentSchema via the ComplexSchema arm). Corrected to the real mechanism — a required-key mismatch, not an absent member.

The replacement type was chosen by measurement. Difference set, by introspecting every literal type the union declares: 658 registered types in KNOWN_SCHEMA_TYPES, 102 modelled, 558 with no member. Probe controlled in both directions — kanban, text and tree-view all read as modelled (so it is not blind to real members), a nonsense type does not.

Picked abbr. Raw HTML primitives are the stable inhabitants of that bucket: packages/components/src/renderers/basic/html-elements.tsx registers them in bulk and they are not candidates for authorable component schemas — unlike a plugin-ish type such as dashboard-grid, which also lands there today but is a plausible future modelling target. The fixture is a well-formedabbr document, which keeps the case's original point: the file is unmodelled, not broken.

The timer is defused rather than passed on. The case now asserts its own precondition — that abbr is still refused by safeValidateSchema — with a message naming what to do. If anyone ever models abbr, this file says why it went red instead of reporting a bare expected +0 to be 1. A synthetic always-unmodelled type was considered and rejected: the registered-type universe is a generated, separately-pinned file (packages/cli/src/utils/known-schema-types.ts), so a synthetic type would have to be injected by mocking it — and that would fabricate the "registered" half, which is precisely the half this bucket is about.

⛔ The test was not skipped, disabled, isolated or deleted, and the sample was not reverted to items. The changeset level is unchanged (minor).

Re-verified at merged head a3fb15e5e (merged origin/mainf0f774b0d)

CheckResult
vitest run packages/cli/ packages/types/ packages/plugin-kanban/ examples/schema-catalog/Test Files 156 passed (156), Tests 3973 passed (3973)
check-validity-recogniser.test.ts aloneTests 10 passed (10)
turbo run type-check --filter=@object-ui/cliTasks: 10 successful, 10 total
eslint on the changed file0 errors, 0 warnings
check-changeset-presence.mjsexit 0 — 1 changeset for 2 released packages
check-changeset-no-major.mjsexit 0
check-control-bytes.mjsexit 0 — 6212 tracked text files

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

`KanbanColumn` declared its card list as `items` in `complex.ts` and in the
zod mirror `complex.zod.ts`, while every board reads `cards`. Measured on
`origin/main` 78a3cc2: `KanbanImpl.tsx` reads `.cards` on 12 lines,
`KanbanEnhanced.tsx` on 8, and `bucketCardsIntoColumns` twice more as
`col.cards || []`; `.items` has zero read sites in either board, against a
same-shaped `.title` control returning 8 and 3 on the same two files.
The result was `declared !== enforced` on a published surface: both kanban
catalog entries failed `safeValidateSchema` with ": Invalid input" while
rendering perfectly — the type's seat in objectui#6318's bucket.
Renaming the read sites instead was rejected by measurement, not preference:
under the `items` spelling `col.cards || []` buckets every column to zero, and
`basic-kanban-board` goes from 64 elements reading "To Do2 / Design new
feature" to 45 elements reading "No cards / 3 columns / To Do0" — an empty
board. The declaration was the wrong side.
Pinned in `examples/schema-catalog/test/kanban-column-cards-6939.test.tsx`:
both entries validate, the `items` spelling is now refused, the rendered DOM is
byte-identical to the pre-change measurement (elements, tag census, visible
text, SHA-256 of textContent), and the empty-board reading for `items` is
pinned so the direction of the rename stays a measurement.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-JkRWQ99M.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…s false mechanism note
The `reports a registered component type the bundled schemas do not model`
case used a kanban board authoring `cards`, and its comment claimed
`AnyComponentSchema` "has no member for" kanban.
That claim was false, and was false before this branch touched anything:
`ComplexSchema` has carried `KanbanSchema` throughout. The board landed in the
bucket for a different reason — `KanbanColumnSchema` required `items` while
every board, and that sample, writes `cards`. Renaming the mirror to `cards`
made the board validate, so the case measured 0 candidates: the defect had
been frozen into an assertion of expected behaviour.
Repointed to `abbr`, chosen by measurement rather than memory. On this tree
`KNOWN_SCHEMA_TYPES` carries 658 registered types while `AnyComponentSchema`
declares 102 distinct literal `type` values, leaving 558 with no member; the
probe was controlled in both directions (`kanban` / `text` / `tree-view` read
as modelled, a nonsense type does not). Raw HTML primitives are the stable
inhabitants of that bucket — registered in bulk by `html-elements.tsx`, never
candidates for authorable component schemas — so the fixture does not carry a
timer the way a plugin-ish type such as `dashboard-grid` would.
The case also now asserts its own precondition, so if `abbr` is ever modelled
this file reports why instead of a bare `expected +0 to be 1`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-H6WopARe.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-H6WopARe.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (select-option.js)0.20KB0.19KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@os-project-managerClaude

Copy link
Copy Markdown
CollaboratorAuthor

合约审查裁断:FAIL 三条 → 补丁轮已全修 → 放行

domain:ui 派发席,session session_01EMrWaQw3XS5DxTHxp4yRyC。本席是 opus、不在 CONTRACT_REVIEW_TIER,故本 Clause-② yes 的 PR 由隔离审查者出裁。简报只含卡片、裁决与本 PR,⛔ 不含派发指令、⛔ 不含本席结论;并明确要求审查者只判 clause 2 的事实是否准确,⛔ 不判该走 A/B/C 哪个

转录档位核验:只提取 harness 生成的 model 字段(⛔ 不搜自由文本)。转录 205 行、0 行不可解析、100 个 assistant 轮次全部 claude-fable-5-1,无 fallback ⇒ 逐字采信。

三条 finding,逐条

F1 — 本 diff 让一个受 CI 把关的测试变红,而 PR 的验证人群不含它所在的包。
packages/cli/src/__tests__/check-validity-recogniser.test.ts 在 merge-base 通过、在 PR head 失败。那个用例写一个 columns[].cards: [] 的 kanban board,断言 objectui check 把它归入「未通过校验」桶。该样本从前之所以被拒,只因镜像要 items;本 PR 让 cards 成为被接受的拼法,于是它通过校验、桶计数读为 0。用例自己的散文(「kanbanAnyComponentSchema has no member for」)是假的——kanban 是被建模的,那正是本 PR 修的缺陷——所以它的前提随修复一同死亡。PR 的受影响套件跑的是 packages/types/ packages/plugin-kanban/ examples/schema-catalog/packages/cli 在人群之外,所以 PR 不可能看见它

head fba1bfd78 : × reports a registered component type … expected +0 to be 1 (1 failed | 9 passed)
base 47547d01a : 10 passed (10)
机制 同一样本经 safeValidateSchema:head success:true / base success:false [": Invalid input"]

F2 — clause 2 的叙述指错了物件,并漏掉了唯一直接相关的在先裁决。
(a) PR 称 KanbanImpl.tsx:52 记录 #6172/#6155 定权威「precisely because the local card carried … that the public one did not」。注释原文是「that ./types did not」——包内漂移;#6172 的 changeset 更明写跨包问题「is NOT resolved here and is escalated」。
(b) 该升格问题的答案存在#6172 评论 5474954379(2026-08-31,维护者逐字「其他同意」,第 6 场总监席决裁批 #14)裁选项 A —— plugin-kanban 保留裸名、@object-ui/types 三重奏改名,并列「径直退役」为升格选项 D。⇒ 在其之下 clause 2 的「公共那个」将不复存在。两条裁决相隔两天、互不引用,且 #6172尚未执行

F3(非阻塞)— 读点补记少了一处。index.tsxcol.cards处(64、89、327),索引签名读点是 449、672、692

审查者核实通过的部分

clause-2 的结构测量正确(公共 KanbanCard 确实缺那四个成员、无索引签名;本地 KanbanColumnclassName 而公共的是 color;所有引用读点为活读点,并另找到 ObjectKanban.tsx:585);裁决数字复现(items 在 55 行不是 54;12/8/0,配同形 .title 对照 8/3 与胡诌成员对照 0);判别器在真实 base 上重测,四个读数与 PR 钉的 PRE_REPAIR/ITEMS_SPELLING 全部吻合;空洞 harness 复现(Suspense fallback,1 元素、sha=e3b0c442… 即空串哈希),并验证替换后的 h3 见证在两种状态下都在场;消融在真实 base 上一对一复现(5 failed | 18 passed);changeset minor 正确,@object-ui/plugin-kanban 确未被动;普查确认插件之外无 KanbanColumn 消费者。

NARROWINGS(收口后由审查者自行转为实测的两项)

被锁住的宽跑事后返回:140 passed (140) / 3727 passed (3727),turbo type-check 32 successful, 32 total ⇒ 三棵树内无测试钉 items 拼法、无 TS 消费者读 KanbanColumn.items。**两项都确认了 F1 的结论:红的那个测试在 PR 所验证的人群之外,而那是人群选择的问题,不是人群内部有缺陷。**其余仍列为未测:whole-population eslint .、经完整 CLI 闭包的 objectui check、PR 自身的原地消融机制、--listFiles 主张、两个 issue 线程的未读部分、shard-3 的作业日志(改以本地复现代替)。


派发席处置:放行

三条全修,逐条按内容核过:

  • F1 —— 样本从 kanban 重定向到 abbr,假机制注释已订正。⭐ 实现者否决了本席倾向的合成类型方案,并给了测量KNOWN_SCHEMA_TYPES 是从注册调用生成的文件且被 known-schema-types-derivation-5115.test.ts 单独钉住,合成类型只能靠 mock 那个模块进入——那会伪造「已注册」这一半,而这一半正是被测对象。本席的建议会掏空该测试的证据价值,采纳它的。它的差集探针两方向都点亮对照(658 注册 / 102 建模 / 558 无成员,kanban/text/tree-view 读作 modelled 即对旧注释的直接反证)。⭐ 并且它把定时器拆了:用例现在断言自己的前提,未来变红会读作「abbr 现在被建模了,换一个类型」,而不是这轮花掉一个 CI 周期的 expected +0 to be 1
  • F2 / F3 —— 散文订正。⭐ 实现者做了一个正确的切分:底层测量成立(公共 KanbanCard 确缺那四个成员),作废的只是归因。F3 它自查出比裁断更多:col.cards 三处、索引签名 449/672/692(691 差一、449 整个漏掉)。
  • ⚠️F2(a) 的错源是本席——实现者是从本席的派工/上报文本里带过来的。本席已在 #6939 订正

合约面自被审 head 起未动(这是不重跑审查的依据):

 fba1bfd78(被审)→ 2e8816b61(现)
complex.ts da06193b0f6fc5f17c8197a1ef34a3e0491fa6b7 IDENTICAL
complex.zod.ts f53db2176cc01d32ec2eb01f484835b9d20eaaa7 IDENTICAL

自被审 head 起本分支只有一个自有提交 a5c4ef4b3(CLI fixture 重定向);F2/F3 是 GitHub 上的散文编辑,仓库内容未变。

⛔ clause 2 仍未实现,且仍在维护者手上

本次放行的是 clause 1itemscards 重命名)。clause 2 与 #6172 裁决的冲突未解,已原样上报(#6939 评论 5530620525)。放行 clause 1 不预判该冲突:无论 types 三重奏最终保留、改名还是按选项 D 退役,这次的成员重命名都随之迁移或一并丢弃,都不因先落而更难。

⚠️CI 在当前 head 2e8816b61 上仍在跑(19:18 启动)。⚠️ 记一笔:CI 修复所在的 head a3fb15e5e 的运行被 merge 推送取消cancelled),从未跑完——所以修复本身尚未在 CI 上被证明,正在跑的这个才是。auto-merge 会等必需检查通过,若转红本席按 drive-to-green 处置。


Generated by Claude Code

@os-project-managerClaude

Copy link
Copy Markdown
CollaboratorAuthor

CI 已在当前 head 转绿;放行动作剩两步,被 GitHub 配额挡住

domain:ui 派发席,session session_01EMrWaQw3XS5DxTHxp4yRyC

CI 序列,按 head_sha 逐个核对

fba1bfd78 failure ← 原来的红(check-validity-recogniser)
a3fb15e5e cancelled ← CI 修复所在的 head,被 merge 推送顶掉,从未跑完
2e8816b61 success ← 当前 head:修复在 CI 上被证明

⚠️ 两处值得记的读数陷阱,本 PR 上都出现了:

  • cancelled 不是绿也不是红,是未跑完。若把 a3fb15e5ecancelled 当作「修复已验证」,就会在修复从未被 CI 跑过的情况下放行。真正证明它的是 2e8816b61 这一次。
  • **按 status=completed 过滤会同时返回旧 head 的结论。**本 PR 的三次运行全部 completed,其中一个 failure、一个 cancelled——不核对 head_sha 就会读到与当前 head 无关的结果。

放行状态

  • needs:contract-review 已剥(标签现为 package: types / examples / tests
  • ✅ 裁断已逐字张贴(评论 5530965431),档位核验 100/100 在档
  • ✅ 合约面自被审 head 起逐字节未动:complex.ts = da06193b0complex.zod.ts = f53db2176fba1bfd782e8816b61
  • ✅ CI 在当前 head 绿
  • draft:false
  • 欠 auto-merge SQUASH

后两步的 API 端点(update_pull_request / enable_pr_auto_merge,GraphQL 后端)自 19:26 起持续返回 API rate limit already exceeded,而评论与标签端点仍可用——所以这条记录发得出去、放行动作发不出去。已排定时提醒跟踪补完,⛔ 不靠记忆、⛔ 不会静默停在半完成状态。

⭐ 顺带记一条操作次序上的改进,本轮两次踩到才想明白:应当先 draft:false + auto-merge,成功后再剥 needs:contract-review。先剥标签的话,配额一断就留下「标签显示已复核、实际仍是草稿」的不自洽状态;反序则只会留下「有标签、是草稿」的自洽状态。

⛔ 仍未实现且仍在维护者手上

本次放行的是 clause 1itemscards)。clause 2 与 #6172 裁决的冲突未解,已原样上报(#6939 评论 5530620525)。放行 clause 1 不预判该冲突。


Generated by Claude Code

@os-project-manager
os-project-manager marked this pull request as ready for review September 3, 2026 19:55
@os-project-manager
os-project-manager added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 240b80fSep 3, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-6939-group3-kanban-cards branch September 3, 2026 20:10
Sign up for freeto 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

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(types): rename KanbanColumn.items to cards on both published halves - #7541

Merged
os-project-manager merged 5 commits into
mainfrom
claude/issue-6939-group3-kanban-cards
Sep 3, 2026
Merged

fix(types): rename KanbanColumn.items to cards on both published halves#7541
os-project-manager merged 5 commits into
mainfrom
claude/issue-6939-group3-kanban-cards

Conversation

@os-project-manager

@os-project-manageros-project-manager commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Part of #6939 — the kanban row (group 3) only. Groups 4 (filter-builder) and 5 (chart) are not addressed here and remain open; group 2 (tree-view) is PR #7533.

Clause-②: yes — this moves a published mirror's accept/reject behaviour AND renames a member on a published type. Draft + needs:contract-review; not marked ready, no auto-merge.

What changed

KanbanColumn declared its card list as items in both halves of the published surface — packages/types/src/complex.ts and the zod mirror packages/types/src/zod/complex.zod.ts — while every board reads cards. Renamed to cards.

The ruling's own numbers, re-measured on this branch's base

The maintainer ruling (comment 5510084784) took its counts on origin/mainec0a7b84. This branch is based on 78a3cc238. All three reproduce:

ReadingRulingRe-measured on 78a3cc238
plugin-kanban/src/types.ts declares cards: KanbanCard[]line 75line 75 ✓
complex.zod.ts declares itemsline 54line 55 (one line of drift)
.cards read lines in KanbanImpl.tsx1212 ✓
.cards read lines in KanbanEnhanced.tsx88 ✓
.items read lines in either00 ✓

Control for the two zeros: a same-shaped probe (grep -c '\.title') on the same two files returns 8 and 3, so the zeros are readings and not a mis-shaped probe. A nonsense-member probe of the same shape returns 0 on both.

Addendum the ruling did not count:packages/plugin-kanban/src/index.tsx reads col.cardsthree more times — lines 64 and 89 in bucketCardsIntoColumns, and line 327 in the kanban-enhanced registration's useMemo, which has the same shape. Each is col.cards || [], and that || [] is the mechanism behind the discriminator below. (An earlier revision said "twice more (lines 64 and 89)", missing line 327; corrected on review.)

Why the rename went toward cards — measured, not asserted

Per #6318's triage, a "correction" that renders identically proves the schema was the wrong side. This row clears the stronger, opposite-polarity bar: "correcting" the fixtures toward the declaration does not merely change the render, it empties the board. Measured through the harness in the new test file, on 78a3cc238, before either declaration was touched:

Entrycards (authored)items (the declared spelling)
basic-kanban-board64 elements — To Do2 … Design new feature …45 elements — No cards3 columnsTo Do0In Progress0Done0
advanced-kanban-with-badges-and-limits86 elements — Backlog2 … User Authentication …58 elements — No cards4 columnsBacklog0 …

Validator verdicts, same run: the authored cards documents failedsafeValidateSchema (: Invalid input) and the items documents passed. After this change, exactly reversed.

What is pinned

examples/schema-catalog/test/kanban-column-cards-6939.test.tsx (11 tests):

  • both catalog entries validate;
  • the items spelling is now refused (the other half of the accept-set move — a mirror that merely widened would still accept it);
  • cards is a real declaration, not a passthrough hole — counter-probes use only the declared key, since BaseSchema is .passthrough() and an unknown key would prove nothing;
  • render identity against the pre-change readings: element count, tag census, visible text literal, and SHA-256 over the full textContent;
  • anti-vacuity — every authored column title and card title is asserted on screen, plus a guard that at least one card exists, so the identity pin cannot pass on a blank tile;
  • the items empty-board reading is itself pinned, so the direction of the rename stays a measurement.

Controls are legal in both states. The render carriers never pass through the validator, and bucketCardsIntoColumns is untouched, so both the populated and the empty board render the same before and after. The waitFor witness is a column heading, which exists in both boards — it cannot settle for one spelling and time out for the other.

Ablation (predicted before measured)

Restoring items to both declarations, renderer untouched. Predicted red: the two validates cases, the two items-refused cases, and the passthrough counter-probe — 5 of 11, with the six render/anti-vacuity cases and all 12 zod-mirror-parity cases staying green.

Measured: exactly thatTests 5 failed | 18 passed (23), and the five names match the prediction one-for-one.

The mutation was proven on disk before the run (anchored counts in both directions, plus blob hashes differing from HEAD), and the restore was proven by state, not by exit code: both worktree blob hashes equal their HEAD blobs, git diff HEAD empty, git status --porcelain empty. Both files resolve through the repo's vitest source alias (packages/types/src/...), so no dist rebuild participates in this ablation.

Notes

  • packages/types/examples/zod-validation-example.ts authored the old spelling in three places; renamed. It is covered by packages/types' type-check (which runs tsc -p tsconfig.examples.json).
  • The header of examples/schema-catalog/test/safe-validate-corpus-6318.test.ts listed this row as an open finding on the Zod union; that sentence is now stale and the kanban clause is removed. That file deliberately pins no bucket size, so nothing else there moves.
  • @object-ui/plugin-kanban is unchanged — it already declared cards.
  • An earlier revision of the test preloaded the lazy chunk via @object-ui/plugin-kanban/KanbanImpl. That shape was removed: it is not in the package's exports map and resolves only through the repo's vitest alias, which @object-ui/fields deep subpaths resolve only through the repo vitest alias — its exports map publishes none of them #4325 ruled out for @object-ui/fields. The test now settles the boundary with waitFor, the way catalog-gallery-render.test.tsx already does for these same entries.

Changeset

minor, not patch — this is a rename on a published type, not a widening. @object-ui/types only. (major is forbidden repo-wide by scripts/check-changeset-no-major.mjs; the breaking semantics are spelled out in the changeset body per repo convention.)

Verification — all at merged head fba1bfd78

CheckResult
vitest run packages/types/ packages/plugin-kanban/ examples/schema-catalog/Test Files 140 passed (140), Tests 3727 passed (3727)
zod-mirror-parity.test.ts (run explicitly)Tests 12 passed (12)
turbo run type-check --filter=@object-ui/types --filter=@object-ui/plugin-kanbanTasks: 15 successful, 15 total
turbo run type-check --filter=@object-ui/example-schema-catalogTasks: 30 successful, 30 total
eslint . --format json4254 files, 0 errors (eslint's own population, not a narrowed list)
check-changeset-presence.mjsexit 0 — 1 changeset for 1 released package
check-changeset-no-major.mjsexit 0
check-control-bytes.mjsexit 0 — 6210 tracked text files

Branch merged with origin/main47547d01a (a merge, not a rebase, per AGENTS.md); the full suite above was re-run after the merge.

Clause 2 of the ruling, and a PRIOR ruling on this exact pair

The 2026-09-02 ruling has two clauses. This PR implements clause 1 (the rename). Clause 2 — "packages/plugin-kanban/src/types.ts stops carrying its own KanbanColumn declaration and re-uses the public one" — is NOT implemented here, and two things about it belong on the record. Neither asks this PR to decide anything.

1. The public declaration is not structurally sufficient. Measured: the plugin's local KanbanCard carries four members the public @object-ui/typesKanbanCard does not declare — badges, cardSubtitle, cardFieldCells, coverImage — plus an index signature; the plugin's KanbanColumn carries className where the public one has color. All are live reads (card.coverImage, card.cardFieldCells, card.cardSubtitle, card.badges, column.className, and card[swimlaneField] at KanbanImpl.tsx 449, 672 and 692). Deleting the local declaration would type column.cards as the publicKanbanCard[] and break every one of them, so clause 2 cannot be executed without widening the published type — which the dispatch explicitly forbids doing silently.

2. Correction to an earlier revision of this PR, and the prior ruling it missed.

An earlier revision cited the comment at KanbanImpl.tsx:52 as "a landed decision pointing the other way", saying objectui#6172 / #6155 made ./types the authority because the local card carried members the public one did not. That attribution was wrong. The comment compares KanbanImpl.tsx's own former copies against the plugin's ./types — an in-package drift — and says so in as many words: "the local KanbanCard carried cardSubtitle / cardFieldCells / coverImage that ./types did not". It says nothing about @object-ui/types.

That card was explicit about not touching the cross-package question. Its changeset (.changeset/6172-markdown-kanban-one-authority.md, landed in b3d562c02):

The cross-package KanbanCard / KanbanColumn / KanbanSchema collision between @object-ui/types and @object-ui/plugin-kanban is NOT resolved here and is escalated on objectui#6172 — those are two different dialects (items vs cards, labels vs badges), and collapsing them renames a published name, which needs an authority ruling.

So :52 is in-package convergence plus an explicit escalation, not a contrary decision.

And that escalation was answered. objectui#6172 comment 5474954379 (2026-08-31, maintainer verbatim 「其他同意」, director-seat batch #14) rules option A:

plugin-kanban 保留裸名 KanbanSchema 家族;@object-ui/types 三重奏改名(如 DeclarativeKanbanSchema 族)

Under that ruling the public KanbanColumn is renamed away, so clause 2's "re-use the public one" would have nothing to re-use. It predates the 2026-09-02 ruling by two days, the two do not cite each other, and it is not yet executed (packages/types/src/complex.ts:28 still declares KanbanColumn). It also lists retiring the @object-ui/types triplet outright as escalation option D — under which this PR's member rename would travel with the renamed type, or disappear with a retired one.

I am not adjudicating which ruling governs. Both are recorded so the reviewer and the maintainer can see the conflict; the dispatching seat has escalated it as-is. Worth noting that #6172's own census agrees with this PR's measurement independently: it found the types-dialect items spelling had zero non-demo, non-known-bad uses across the bound.

Follow-up: CI red on fba1bfd78, and the fix (a3fb15e5e)

Test (shard 3/4) went red on one case — packages/cli/src/__tests__/check-validity-recogniser.test.ts, "reports a registered component type the bundled schemas do not model", expected +0 to be 1. It is a correct consequence of this repair, and it is fixed here rather than worked around.

That case wrote a kanban board authoring cards and asserted objectui check would report it as a registered type the bundled schemas cannot model. It only ever landed in that bucket because the mirror required items — the exact fork this PR repairs. Once the board validates, the count drops to 0. The defect was frozen into an assertion of expected behaviour.

Reproduced end-to-end through the real check, not inferred: a kanban board with cards now yields candidates=[]; the sibling text fixture still yields a candidate (positive control); a foreign package.json still yields Skipped 1 and no candidate (negative control).

The comment was also wrong, independently of this PR. It claimed AnyComponentSchema "has no member for" kanban. ComplexSchema has carried KanbanSchema throughout (complex.zod.ts:691-692, reached from AnyComponentSchema via the ComplexSchema arm). Corrected to the real mechanism — a required-key mismatch, not an absent member.

The replacement type was chosen by measurement. Difference set, by introspecting every literal type the union declares: 658 registered types in KNOWN_SCHEMA_TYPES, 102 modelled, 558 with no member. Probe controlled in both directions — kanban, text and tree-view all read as modelled (so it is not blind to real members), a nonsense type does not.

Picked abbr. Raw HTML primitives are the stable inhabitants of that bucket: packages/components/src/renderers/basic/html-elements.tsx registers them in bulk and they are not candidates for authorable component schemas — unlike a plugin-ish type such as dashboard-grid, which also lands there today but is a plausible future modelling target. The fixture is a well-formedabbr document, which keeps the case's original point: the file is unmodelled, not broken.

The timer is defused rather than passed on. The case now asserts its own precondition — that abbr is still refused by safeValidateSchema — with a message naming what to do. If anyone ever models abbr, this file says why it went red instead of reporting a bare expected +0 to be 1. A synthetic always-unmodelled type was considered and rejected: the registered-type universe is a generated, separately-pinned file (packages/cli/src/utils/known-schema-types.ts), so a synthetic type would have to be injected by mocking it — and that would fabricate the "registered" half, which is precisely the half this bucket is about.

⛔ The test was not skipped, disabled, isolated or deleted, and the sample was not reverted to items. The changeset level is unchanged (minor).

Re-verified at merged head a3fb15e5e (merged origin/mainf0f774b0d)

CheckResult
vitest run packages/cli/ packages/types/ packages/plugin-kanban/ examples/schema-catalog/Test Files 156 passed (156), Tests 3973 passed (3973)
check-validity-recogniser.test.ts aloneTests 10 passed (10)
turbo run type-check --filter=@object-ui/cliTasks: 10 successful, 10 total
eslint on the changed file0 errors, 0 warnings
check-changeset-presence.mjsexit 0 — 1 changeset for 2 released packages
check-changeset-no-major.mjsexit 0
check-control-bytes.mjsexit 0 — 6212 tracked text files

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

`KanbanColumn` declared its card list as `items` in `complex.ts` and in the
zod mirror `complex.zod.ts`, while every board reads `cards`. Measured on
`origin/main` 78a3cc2: `KanbanImpl.tsx` reads `.cards` on 12 lines,
`KanbanEnhanced.tsx` on 8, and `bucketCardsIntoColumns` twice more as
`col.cards || []`; `.items` has zero read sites in either board, against a
same-shaped `.title` control returning 8 and 3 on the same two files.
The result was `declared !== enforced` on a published surface: both kanban
catalog entries failed `safeValidateSchema` with ": Invalid input" while
rendering perfectly — the type's seat in objectui#6318's bucket.
Renaming the read sites instead was rejected by measurement, not preference:
under the `items` spelling `col.cards || []` buckets every column to zero, and
`basic-kanban-board` goes from 64 elements reading "To Do2 / Design new
feature" to 45 elements reading "No cards / 3 columns / To Do0" — an empty
board. The declaration was the wrong side.
Pinned in `examples/schema-catalog/test/kanban-column-cards-6939.test.tsx`:
both entries validate, the `items` spelling is now refused, the rendered DOM is
byte-identical to the pre-change measurement (elements, tag census, visible
text, SHA-256 of textContent), and the empty-board reading for `items` is
pinned so the direction of the rename stays a measurement.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-JkRWQ99M.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…s false mechanism note
The `reports a registered component type the bundled schemas do not model`
case used a kanban board authoring `cards`, and its comment claimed
`AnyComponentSchema` "has no member for" kanban.
That claim was false, and was false before this branch touched anything:
`ComplexSchema` has carried `KanbanSchema` throughout. The board landed in the
bucket for a different reason — `KanbanColumnSchema` required `items` while
every board, and that sample, writes `cards`. Renaming the mirror to `cards`
made the board validate, so the case measured 0 candidates: the defect had
been frozen into an assertion of expected behaviour.
Repointed to `abbr`, chosen by measurement rather than memory. On this tree
`KNOWN_SCHEMA_TYPES` carries 658 registered types while `AnyComponentSchema`
declares 102 distinct literal `type` values, leaving 558 with no member; the
probe was controlled in both directions (`kanban` / `text` / `tree-view` read
as modelled, a nonsense type does not). Raw HTML primitives are the stable
inhabitants of that bucket — registered in bulk by `html-elements.tsx`, never
candidates for authorable component schemas — so the fixture does not carry a
timer the way a plugin-ish type such as `dashboard-grid` would.
The case also now asserts its own precondition, so if `abbr` is ever modelled
this file reports why instead of a bare `expected +0 to be 1`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-H6WopARe.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-H6WopARe.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (select-option.js)0.20KB0.19KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@os-project-managerClaude

Copy link
Copy Markdown
CollaboratorAuthor

合约审查裁断:FAIL 三条 → 补丁轮已全修 → 放行

domain:ui 派发席,session session_01EMrWaQw3XS5DxTHxp4yRyC。本席是 opus、不在 CONTRACT_REVIEW_TIER,故本 Clause-② yes 的 PR 由隔离审查者出裁。简报只含卡片、裁决与本 PR,⛔ 不含派发指令、⛔ 不含本席结论;并明确要求审查者只判 clause 2 的事实是否准确,⛔ 不判该走 A/B/C 哪个

转录档位核验:只提取 harness 生成的 model 字段(⛔ 不搜自由文本)。转录 205 行、0 行不可解析、100 个 assistant 轮次全部 claude-fable-5-1,无 fallback ⇒ 逐字采信。

三条 finding,逐条

F1 — 本 diff 让一个受 CI 把关的测试变红,而 PR 的验证人群不含它所在的包。
packages/cli/src/__tests__/check-validity-recogniser.test.ts 在 merge-base 通过、在 PR head 失败。那个用例写一个 columns[].cards: [] 的 kanban board,断言 objectui check 把它归入「未通过校验」桶。该样本从前之所以被拒,只因镜像要 items;本 PR 让 cards 成为被接受的拼法,于是它通过校验、桶计数读为 0。用例自己的散文(「kanbanAnyComponentSchema has no member for」)是假的——kanban 是被建模的,那正是本 PR 修的缺陷——所以它的前提随修复一同死亡。PR 的受影响套件跑的是 packages/types/ packages/plugin-kanban/ examples/schema-catalog/packages/cli 在人群之外,所以 PR 不可能看见它

head fba1bfd78 : × reports a registered component type … expected +0 to be 1 (1 failed | 9 passed)
base 47547d01a : 10 passed (10)
机制 同一样本经 safeValidateSchema:head success:true / base success:false [": Invalid input"]

F2 — clause 2 的叙述指错了物件,并漏掉了唯一直接相关的在先裁决。
(a) PR 称 KanbanImpl.tsx:52 记录 #6172/#6155 定权威「precisely because the local card carried … that the public one did not」。注释原文是「that ./types did not」——包内漂移;#6172 的 changeset 更明写跨包问题「is NOT resolved here and is escalated」。
(b) 该升格问题的答案存在#6172 评论 5474954379(2026-08-31,维护者逐字「其他同意」,第 6 场总监席决裁批 #14)裁选项 A —— plugin-kanban 保留裸名、@object-ui/types 三重奏改名,并列「径直退役」为升格选项 D。⇒ 在其之下 clause 2 的「公共那个」将不复存在。两条裁决相隔两天、互不引用,且 #6172尚未执行

F3(非阻塞)— 读点补记少了一处。index.tsxcol.cards处(64、89、327),索引签名读点是 449、672、692

审查者核实通过的部分

clause-2 的结构测量正确(公共 KanbanCard 确实缺那四个成员、无索引签名;本地 KanbanColumnclassName 而公共的是 color;所有引用读点为活读点,并另找到 ObjectKanban.tsx:585);裁决数字复现(items 在 55 行不是 54;12/8/0,配同形 .title 对照 8/3 与胡诌成员对照 0);判别器在真实 base 上重测,四个读数与 PR 钉的 PRE_REPAIR/ITEMS_SPELLING 全部吻合;空洞 harness 复现(Suspense fallback,1 元素、sha=e3b0c442… 即空串哈希),并验证替换后的 h3 见证在两种状态下都在场;消融在真实 base 上一对一复现(5 failed | 18 passed);changeset minor 正确,@object-ui/plugin-kanban 确未被动;普查确认插件之外无 KanbanColumn 消费者。

NARROWINGS(收口后由审查者自行转为实测的两项)

被锁住的宽跑事后返回:140 passed (140) / 3727 passed (3727),turbo type-check 32 successful, 32 total ⇒ 三棵树内无测试钉 items 拼法、无 TS 消费者读 KanbanColumn.items。**两项都确认了 F1 的结论:红的那个测试在 PR 所验证的人群之外,而那是人群选择的问题,不是人群内部有缺陷。**其余仍列为未测:whole-population eslint .、经完整 CLI 闭包的 objectui check、PR 自身的原地消融机制、--listFiles 主张、两个 issue 线程的未读部分、shard-3 的作业日志(改以本地复现代替)。


派发席处置:放行

三条全修,逐条按内容核过:

  • F1 —— 样本从 kanban 重定向到 abbr,假机制注释已订正。⭐ 实现者否决了本席倾向的合成类型方案,并给了测量KNOWN_SCHEMA_TYPES 是从注册调用生成的文件且被 known-schema-types-derivation-5115.test.ts 单独钉住,合成类型只能靠 mock 那个模块进入——那会伪造「已注册」这一半,而这一半正是被测对象。本席的建议会掏空该测试的证据价值,采纳它的。它的差集探针两方向都点亮对照(658 注册 / 102 建模 / 558 无成员,kanban/text/tree-view 读作 modelled 即对旧注释的直接反证)。⭐ 并且它把定时器拆了:用例现在断言自己的前提,未来变红会读作「abbr 现在被建模了,换一个类型」,而不是这轮花掉一个 CI 周期的 expected +0 to be 1
  • F2 / F3 —— 散文订正。⭐ 实现者做了一个正确的切分:底层测量成立(公共 KanbanCard 确缺那四个成员),作废的只是归因。F3 它自查出比裁断更多:col.cards 三处、索引签名 449/672/692(691 差一、449 整个漏掉)。
  • ⚠️F2(a) 的错源是本席——实现者是从本席的派工/上报文本里带过来的。本席已在 #6939 订正

合约面自被审 head 起未动(这是不重跑审查的依据):

 fba1bfd78(被审)→ 2e8816b61(现)
complex.ts da06193b0f6fc5f17c8197a1ef34a3e0491fa6b7 IDENTICAL
complex.zod.ts f53db2176cc01d32ec2eb01f484835b9d20eaaa7 IDENTICAL

自被审 head 起本分支只有一个自有提交 a5c4ef4b3(CLI fixture 重定向);F2/F3 是 GitHub 上的散文编辑,仓库内容未变。

⛔ clause 2 仍未实现,且仍在维护者手上

本次放行的是 clause 1itemscards 重命名)。clause 2 与 #6172 裁决的冲突未解,已原样上报(#6939 评论 5530620525)。放行 clause 1 不预判该冲突:无论 types 三重奏最终保留、改名还是按选项 D 退役,这次的成员重命名都随之迁移或一并丢弃,都不因先落而更难。

⚠️CI 在当前 head 2e8816b61 上仍在跑(19:18 启动)。⚠️ 记一笔:CI 修复所在的 head a3fb15e5e 的运行被 merge 推送取消cancelled),从未跑完——所以修复本身尚未在 CI 上被证明,正在跑的这个才是。auto-merge 会等必需检查通过,若转红本席按 drive-to-green 处置。


Generated by Claude Code

@os-project-managerClaude

Copy link
Copy Markdown
CollaboratorAuthor

CI 已在当前 head 转绿;放行动作剩两步,被 GitHub 配额挡住

domain:ui 派发席,session session_01EMrWaQw3XS5DxTHxp4yRyC

CI 序列,按 head_sha 逐个核对

fba1bfd78 failure ← 原来的红(check-validity-recogniser)
a3fb15e5e cancelled ← CI 修复所在的 head,被 merge 推送顶掉,从未跑完
2e8816b61 success ← 当前 head:修复在 CI 上被证明

⚠️ 两处值得记的读数陷阱,本 PR 上都出现了:

  • cancelled 不是绿也不是红,是未跑完。若把 a3fb15e5ecancelled 当作「修复已验证」,就会在修复从未被 CI 跑过的情况下放行。真正证明它的是 2e8816b61 这一次。
  • **按 status=completed 过滤会同时返回旧 head 的结论。**本 PR 的三次运行全部 completed,其中一个 failure、一个 cancelled——不核对 head_sha 就会读到与当前 head 无关的结果。

放行状态

  • needs:contract-review 已剥(标签现为 package: types / examples / tests
  • ✅ 裁断已逐字张贴(评论 5530965431),档位核验 100/100 在档
  • ✅ 合约面自被审 head 起逐字节未动:complex.ts = da06193b0complex.zod.ts = f53db2176fba1bfd782e8816b61
  • ✅ CI 在当前 head 绿
  • draft:false
  • 欠 auto-merge SQUASH

后两步的 API 端点(update_pull_request / enable_pr_auto_merge,GraphQL 后端)自 19:26 起持续返回 API rate limit already exceeded,而评论与标签端点仍可用——所以这条记录发得出去、放行动作发不出去。已排定时提醒跟踪补完,⛔ 不靠记忆、⛔ 不会静默停在半完成状态。

⭐ 顺带记一条操作次序上的改进,本轮两次踩到才想明白:应当先 draft:false + auto-merge,成功后再剥 needs:contract-review。先剥标签的话,配额一断就留下「标签显示已复核、实际仍是草稿」的不自洽状态;反序则只会留下「有标签、是草稿」的自洽状态。

⛔ 仍未实现且仍在维护者手上

本次放行的是 clause 1itemscards)。clause 2 与 #6172 裁决的冲突未解,已原样上报(#6939 评论 5530620525)。放行 clause 1 不预判该冲突。


Generated by Claude Code

@os-project-manager
os-project-manager marked this pull request as ready for review September 3, 2026 19:55
@os-project-manager
os-project-manager added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 240b80fSep 3, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-6939-group3-kanban-cards branch September 3, 2026 20:10
Sign up for freeto 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

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(types): rename KanbanColumn.items to cards on both published halves - #7541

Merged
os-project-manager merged 5 commits into
mainfrom
claude/issue-6939-group3-kanban-cards
Sep 3, 2026
Merged

fix(types): rename KanbanColumn.items to cards on both published halves#7541
os-project-manager merged 5 commits into
mainfrom
claude/issue-6939-group3-kanban-cards

Conversation

@os-project-manager

@os-project-manageros-project-manager commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Part of #6939 — the kanban row (group 3) only. Groups 4 (filter-builder) and 5 (chart) are not addressed here and remain open; group 2 (tree-view) is PR #7533.

Clause-②: yes — this moves a published mirror's accept/reject behaviour AND renames a member on a published type. Draft + needs:contract-review; not marked ready, no auto-merge.

What changed

KanbanColumn declared its card list as items in both halves of the published surface — packages/types/src/complex.ts and the zod mirror packages/types/src/zod/complex.zod.ts — while every board reads cards. Renamed to cards.

The ruling's own numbers, re-measured on this branch's base

The maintainer ruling (comment 5510084784) took its counts on origin/mainec0a7b84. This branch is based on 78a3cc238. All three reproduce:

ReadingRulingRe-measured on 78a3cc238
plugin-kanban/src/types.ts declares cards: KanbanCard[]line 75line 75 ✓
complex.zod.ts declares itemsline 54line 55 (one line of drift)
.cards read lines in KanbanImpl.tsx1212 ✓
.cards read lines in KanbanEnhanced.tsx88 ✓
.items read lines in either00 ✓

Control for the two zeros: a same-shaped probe (grep -c '\.title') on the same two files returns 8 and 3, so the zeros are readings and not a mis-shaped probe. A nonsense-member probe of the same shape returns 0 on both.

Addendum the ruling did not count:packages/plugin-kanban/src/index.tsx reads col.cardsthree more times — lines 64 and 89 in bucketCardsIntoColumns, and line 327 in the kanban-enhanced registration's useMemo, which has the same shape. Each is col.cards || [], and that || [] is the mechanism behind the discriminator below. (An earlier revision said "twice more (lines 64 and 89)", missing line 327; corrected on review.)

Why the rename went toward cards — measured, not asserted

Per #6318's triage, a "correction" that renders identically proves the schema was the wrong side. This row clears the stronger, opposite-polarity bar: "correcting" the fixtures toward the declaration does not merely change the render, it empties the board. Measured through the harness in the new test file, on 78a3cc238, before either declaration was touched:

Entrycards (authored)items (the declared spelling)
basic-kanban-board64 elements — To Do2 … Design new feature …45 elements — No cards3 columnsTo Do0In Progress0Done0
advanced-kanban-with-badges-and-limits86 elements — Backlog2 … User Authentication …58 elements — No cards4 columnsBacklog0 …

Validator verdicts, same run: the authored cards documents failedsafeValidateSchema (: Invalid input) and the items documents passed. After this change, exactly reversed.

What is pinned

examples/schema-catalog/test/kanban-column-cards-6939.test.tsx (11 tests):

  • both catalog entries validate;
  • the items spelling is now refused (the other half of the accept-set move — a mirror that merely widened would still accept it);
  • cards is a real declaration, not a passthrough hole — counter-probes use only the declared key, since BaseSchema is .passthrough() and an unknown key would prove nothing;
  • render identity against the pre-change readings: element count, tag census, visible text literal, and SHA-256 over the full textContent;
  • anti-vacuity — every authored column title and card title is asserted on screen, plus a guard that at least one card exists, so the identity pin cannot pass on a blank tile;
  • the items empty-board reading is itself pinned, so the direction of the rename stays a measurement.

Controls are legal in both states. The render carriers never pass through the validator, and bucketCardsIntoColumns is untouched, so both the populated and the empty board render the same before and after. The waitFor witness is a column heading, which exists in both boards — it cannot settle for one spelling and time out for the other.

Ablation (predicted before measured)

Restoring items to both declarations, renderer untouched. Predicted red: the two validates cases, the two items-refused cases, and the passthrough counter-probe — 5 of 11, with the six render/anti-vacuity cases and all 12 zod-mirror-parity cases staying green.

Measured: exactly thatTests 5 failed | 18 passed (23), and the five names match the prediction one-for-one.

The mutation was proven on disk before the run (anchored counts in both directions, plus blob hashes differing from HEAD), and the restore was proven by state, not by exit code: both worktree blob hashes equal their HEAD blobs, git diff HEAD empty, git status --porcelain empty. Both files resolve through the repo's vitest source alias (packages/types/src/...), so no dist rebuild participates in this ablation.

Notes

  • packages/types/examples/zod-validation-example.ts authored the old spelling in three places; renamed. It is covered by packages/types' type-check (which runs tsc -p tsconfig.examples.json).
  • The header of examples/schema-catalog/test/safe-validate-corpus-6318.test.ts listed this row as an open finding on the Zod union; that sentence is now stale and the kanban clause is removed. That file deliberately pins no bucket size, so nothing else there moves.
  • @object-ui/plugin-kanban is unchanged — it already declared cards.
  • An earlier revision of the test preloaded the lazy chunk via @object-ui/plugin-kanban/KanbanImpl. That shape was removed: it is not in the package's exports map and resolves only through the repo's vitest alias, which @object-ui/fields deep subpaths resolve only through the repo vitest alias — its exports map publishes none of them #4325 ruled out for @object-ui/fields. The test now settles the boundary with waitFor, the way catalog-gallery-render.test.tsx already does for these same entries.

Changeset

minor, not patch — this is a rename on a published type, not a widening. @object-ui/types only. (major is forbidden repo-wide by scripts/check-changeset-no-major.mjs; the breaking semantics are spelled out in the changeset body per repo convention.)

Verification — all at merged head fba1bfd78

CheckResult
vitest run packages/types/ packages/plugin-kanban/ examples/schema-catalog/Test Files 140 passed (140), Tests 3727 passed (3727)
zod-mirror-parity.test.ts (run explicitly)Tests 12 passed (12)
turbo run type-check --filter=@object-ui/types --filter=@object-ui/plugin-kanbanTasks: 15 successful, 15 total
turbo run type-check --filter=@object-ui/example-schema-catalogTasks: 30 successful, 30 total
eslint . --format json4254 files, 0 errors (eslint's own population, not a narrowed list)
check-changeset-presence.mjsexit 0 — 1 changeset for 1 released package
check-changeset-no-major.mjsexit 0
check-control-bytes.mjsexit 0 — 6210 tracked text files

Branch merged with origin/main47547d01a (a merge, not a rebase, per AGENTS.md); the full suite above was re-run after the merge.

Clause 2 of the ruling, and a PRIOR ruling on this exact pair

The 2026-09-02 ruling has two clauses. This PR implements clause 1 (the rename). Clause 2 — "packages/plugin-kanban/src/types.ts stops carrying its own KanbanColumn declaration and re-uses the public one" — is NOT implemented here, and two things about it belong on the record. Neither asks this PR to decide anything.

1. The public declaration is not structurally sufficient. Measured: the plugin's local KanbanCard carries four members the public @object-ui/typesKanbanCard does not declare — badges, cardSubtitle, cardFieldCells, coverImage — plus an index signature; the plugin's KanbanColumn carries className where the public one has color. All are live reads (card.coverImage, card.cardFieldCells, card.cardSubtitle, card.badges, column.className, and card[swimlaneField] at KanbanImpl.tsx 449, 672 and 692). Deleting the local declaration would type column.cards as the publicKanbanCard[] and break every one of them, so clause 2 cannot be executed without widening the published type — which the dispatch explicitly forbids doing silently.

2. Correction to an earlier revision of this PR, and the prior ruling it missed.

An earlier revision cited the comment at KanbanImpl.tsx:52 as "a landed decision pointing the other way", saying objectui#6172 / #6155 made ./types the authority because the local card carried members the public one did not. That attribution was wrong. The comment compares KanbanImpl.tsx's own former copies against the plugin's ./types — an in-package drift — and says so in as many words: "the local KanbanCard carried cardSubtitle / cardFieldCells / coverImage that ./types did not". It says nothing about @object-ui/types.

That card was explicit about not touching the cross-package question. Its changeset (.changeset/6172-markdown-kanban-one-authority.md, landed in b3d562c02):

The cross-package KanbanCard / KanbanColumn / KanbanSchema collision between @object-ui/types and @object-ui/plugin-kanban is NOT resolved here and is escalated on objectui#6172 — those are two different dialects (items vs cards, labels vs badges), and collapsing them renames a published name, which needs an authority ruling.

So :52 is in-package convergence plus an explicit escalation, not a contrary decision.

And that escalation was answered. objectui#6172 comment 5474954379 (2026-08-31, maintainer verbatim 「其他同意」, director-seat batch #14) rules option A:

plugin-kanban 保留裸名 KanbanSchema 家族;@object-ui/types 三重奏改名(如 DeclarativeKanbanSchema 族)

Under that ruling the public KanbanColumn is renamed away, so clause 2's "re-use the public one" would have nothing to re-use. It predates the 2026-09-02 ruling by two days, the two do not cite each other, and it is not yet executed (packages/types/src/complex.ts:28 still declares KanbanColumn). It also lists retiring the @object-ui/types triplet outright as escalation option D — under which this PR's member rename would travel with the renamed type, or disappear with a retired one.

I am not adjudicating which ruling governs. Both are recorded so the reviewer and the maintainer can see the conflict; the dispatching seat has escalated it as-is. Worth noting that #6172's own census agrees with this PR's measurement independently: it found the types-dialect items spelling had zero non-demo, non-known-bad uses across the bound.

Follow-up: CI red on fba1bfd78, and the fix (a3fb15e5e)

Test (shard 3/4) went red on one case — packages/cli/src/__tests__/check-validity-recogniser.test.ts, "reports a registered component type the bundled schemas do not model", expected +0 to be 1. It is a correct consequence of this repair, and it is fixed here rather than worked around.

That case wrote a kanban board authoring cards and asserted objectui check would report it as a registered type the bundled schemas cannot model. It only ever landed in that bucket because the mirror required items — the exact fork this PR repairs. Once the board validates, the count drops to 0. The defect was frozen into an assertion of expected behaviour.

Reproduced end-to-end through the real check, not inferred: a kanban board with cards now yields candidates=[]; the sibling text fixture still yields a candidate (positive control); a foreign package.json still yields Skipped 1 and no candidate (negative control).

The comment was also wrong, independently of this PR. It claimed AnyComponentSchema "has no member for" kanban. ComplexSchema has carried KanbanSchema throughout (complex.zod.ts:691-692, reached from AnyComponentSchema via the ComplexSchema arm). Corrected to the real mechanism — a required-key mismatch, not an absent member.

The replacement type was chosen by measurement. Difference set, by introspecting every literal type the union declares: 658 registered types in KNOWN_SCHEMA_TYPES, 102 modelled, 558 with no member. Probe controlled in both directions — kanban, text and tree-view all read as modelled (so it is not blind to real members), a nonsense type does not.

Picked abbr. Raw HTML primitives are the stable inhabitants of that bucket: packages/components/src/renderers/basic/html-elements.tsx registers them in bulk and they are not candidates for authorable component schemas — unlike a plugin-ish type such as dashboard-grid, which also lands there today but is a plausible future modelling target. The fixture is a well-formedabbr document, which keeps the case's original point: the file is unmodelled, not broken.

The timer is defused rather than passed on. The case now asserts its own precondition — that abbr is still refused by safeValidateSchema — with a message naming what to do. If anyone ever models abbr, this file says why it went red instead of reporting a bare expected +0 to be 1. A synthetic always-unmodelled type was considered and rejected: the registered-type universe is a generated, separately-pinned file (packages/cli/src/utils/known-schema-types.ts), so a synthetic type would have to be injected by mocking it — and that would fabricate the "registered" half, which is precisely the half this bucket is about.

⛔ The test was not skipped, disabled, isolated or deleted, and the sample was not reverted to items. The changeset level is unchanged (minor).

Re-verified at merged head a3fb15e5e (merged origin/mainf0f774b0d)

CheckResult
vitest run packages/cli/ packages/types/ packages/plugin-kanban/ examples/schema-catalog/Test Files 156 passed (156), Tests 3973 passed (3973)
check-validity-recogniser.test.ts aloneTests 10 passed (10)
turbo run type-check --filter=@object-ui/cliTasks: 10 successful, 10 total
eslint on the changed file0 errors, 0 warnings
check-changeset-presence.mjsexit 0 — 1 changeset for 2 released packages
check-changeset-no-major.mjsexit 0
check-control-bytes.mjsexit 0 — 6212 tracked text files

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

`KanbanColumn` declared its card list as `items` in `complex.ts` and in the
zod mirror `complex.zod.ts`, while every board reads `cards`. Measured on
`origin/main` 78a3cc2: `KanbanImpl.tsx` reads `.cards` on 12 lines,
`KanbanEnhanced.tsx` on 8, and `bucketCardsIntoColumns` twice more as
`col.cards || []`; `.items` has zero read sites in either board, against a
same-shaped `.title` control returning 8 and 3 on the same two files.
The result was `declared !== enforced` on a published surface: both kanban
catalog entries failed `safeValidateSchema` with ": Invalid input" while
rendering perfectly — the type's seat in objectui#6318's bucket.
Renaming the read sites instead was rejected by measurement, not preference:
under the `items` spelling `col.cards || []` buckets every column to zero, and
`basic-kanban-board` goes from 64 elements reading "To Do2 / Design new
feature" to 45 elements reading "No cards / 3 columns / To Do0" — an empty
board. The declaration was the wrong side.
Pinned in `examples/schema-catalog/test/kanban-column-cards-6939.test.tsx`:
both entries validate, the `items` spelling is now refused, the rendered DOM is
byte-identical to the pre-change measurement (elements, tag census, visible
text, SHA-256 of textContent), and the empty-board reading for `items` is
pinned so the direction of the rename stays a measurement.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-JkRWQ99M.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…s false mechanism note
The `reports a registered component type the bundled schemas do not model`
case used a kanban board authoring `cards`, and its comment claimed
`AnyComponentSchema` "has no member for" kanban.
That claim was false, and was false before this branch touched anything:
`ComplexSchema` has carried `KanbanSchema` throughout. The board landed in the
bucket for a different reason — `KanbanColumnSchema` required `items` while
every board, and that sample, writes `cards`. Renaming the mirror to `cards`
made the board validate, so the case measured 0 candidates: the defect had
been frozen into an assertion of expected behaviour.
Repointed to `abbr`, chosen by measurement rather than memory. On this tree
`KNOWN_SCHEMA_TYPES` carries 658 registered types while `AnyComponentSchema`
declares 102 distinct literal `type` values, leaving 558 with no member; the
probe was controlled in both directions (`kanban` / `text` / `tree-view` read
as modelled, a nonsense type does not). Raw HTML primitives are the stable
inhabitants of that bucket — registered in bulk by `html-elements.tsx`, never
candidates for authorable component schemas — so the fixture does not carry a
timer the way a plugin-ish type such as `dashboard-grid` would.
The case also now asserts its own precondition, so if `abbr` is ever modelled
this file reports why instead of a bare `expected +0 to be 1`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-H6WopARe.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-H6WopARe.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (select-option.js)0.20KB0.19KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@os-project-managerClaude

Copy link
Copy Markdown
CollaboratorAuthor

合约审查裁断:FAIL 三条 → 补丁轮已全修 → 放行

domain:ui 派发席,session session_01EMrWaQw3XS5DxTHxp4yRyC。本席是 opus、不在 CONTRACT_REVIEW_TIER,故本 Clause-② yes 的 PR 由隔离审查者出裁。简报只含卡片、裁决与本 PR,⛔ 不含派发指令、⛔ 不含本席结论;并明确要求审查者只判 clause 2 的事实是否准确,⛔ 不判该走 A/B/C 哪个

转录档位核验:只提取 harness 生成的 model 字段(⛔ 不搜自由文本)。转录 205 行、0 行不可解析、100 个 assistant 轮次全部 claude-fable-5-1,无 fallback ⇒ 逐字采信。

三条 finding,逐条

F1 — 本 diff 让一个受 CI 把关的测试变红,而 PR 的验证人群不含它所在的包。
packages/cli/src/__tests__/check-validity-recogniser.test.ts 在 merge-base 通过、在 PR head 失败。那个用例写一个 columns[].cards: [] 的 kanban board,断言 objectui check 把它归入「未通过校验」桶。该样本从前之所以被拒,只因镜像要 items;本 PR 让 cards 成为被接受的拼法,于是它通过校验、桶计数读为 0。用例自己的散文(「kanbanAnyComponentSchema has no member for」)是假的——kanban 是被建模的,那正是本 PR 修的缺陷——所以它的前提随修复一同死亡。PR 的受影响套件跑的是 packages/types/ packages/plugin-kanban/ examples/schema-catalog/packages/cli 在人群之外,所以 PR 不可能看见它

head fba1bfd78 : × reports a registered component type … expected +0 to be 1 (1 failed | 9 passed)
base 47547d01a : 10 passed (10)
机制 同一样本经 safeValidateSchema:head success:true / base success:false [": Invalid input"]

F2 — clause 2 的叙述指错了物件,并漏掉了唯一直接相关的在先裁决。
(a) PR 称 KanbanImpl.tsx:52 记录 #6172/#6155 定权威「precisely because the local card carried … that the public one did not」。注释原文是「that ./types did not」——包内漂移;#6172 的 changeset 更明写跨包问题「is NOT resolved here and is escalated」。
(b) 该升格问题的答案存在#6172 评论 5474954379(2026-08-31,维护者逐字「其他同意」,第 6 场总监席决裁批 #14)裁选项 A —— plugin-kanban 保留裸名、@object-ui/types 三重奏改名,并列「径直退役」为升格选项 D。⇒ 在其之下 clause 2 的「公共那个」将不复存在。两条裁决相隔两天、互不引用,且 #6172尚未执行

F3(非阻塞)— 读点补记少了一处。index.tsxcol.cards处(64、89、327),索引签名读点是 449、672、692

审查者核实通过的部分

clause-2 的结构测量正确(公共 KanbanCard 确实缺那四个成员、无索引签名;本地 KanbanColumnclassName 而公共的是 color;所有引用读点为活读点,并另找到 ObjectKanban.tsx:585);裁决数字复现(items 在 55 行不是 54;12/8/0,配同形 .title 对照 8/3 与胡诌成员对照 0);判别器在真实 base 上重测,四个读数与 PR 钉的 PRE_REPAIR/ITEMS_SPELLING 全部吻合;空洞 harness 复现(Suspense fallback,1 元素、sha=e3b0c442… 即空串哈希),并验证替换后的 h3 见证在两种状态下都在场;消融在真实 base 上一对一复现(5 failed | 18 passed);changeset minor 正确,@object-ui/plugin-kanban 确未被动;普查确认插件之外无 KanbanColumn 消费者。

NARROWINGS(收口后由审查者自行转为实测的两项)

被锁住的宽跑事后返回:140 passed (140) / 3727 passed (3727),turbo type-check 32 successful, 32 total ⇒ 三棵树内无测试钉 items 拼法、无 TS 消费者读 KanbanColumn.items。**两项都确认了 F1 的结论:红的那个测试在 PR 所验证的人群之外,而那是人群选择的问题,不是人群内部有缺陷。**其余仍列为未测:whole-population eslint .、经完整 CLI 闭包的 objectui check、PR 自身的原地消融机制、--listFiles 主张、两个 issue 线程的未读部分、shard-3 的作业日志(改以本地复现代替)。


派发席处置:放行

三条全修,逐条按内容核过:

  • F1 —— 样本从 kanban 重定向到 abbr,假机制注释已订正。⭐ 实现者否决了本席倾向的合成类型方案,并给了测量KNOWN_SCHEMA_TYPES 是从注册调用生成的文件且被 known-schema-types-derivation-5115.test.ts 单独钉住,合成类型只能靠 mock 那个模块进入——那会伪造「已注册」这一半,而这一半正是被测对象。本席的建议会掏空该测试的证据价值,采纳它的。它的差集探针两方向都点亮对照(658 注册 / 102 建模 / 558 无成员,kanban/text/tree-view 读作 modelled 即对旧注释的直接反证)。⭐ 并且它把定时器拆了:用例现在断言自己的前提,未来变红会读作「abbr 现在被建模了,换一个类型」,而不是这轮花掉一个 CI 周期的 expected +0 to be 1
  • F2 / F3 —— 散文订正。⭐ 实现者做了一个正确的切分:底层测量成立(公共 KanbanCard 确缺那四个成员),作废的只是归因。F3 它自查出比裁断更多:col.cards 三处、索引签名 449/672/692(691 差一、449 整个漏掉)。
  • ⚠️F2(a) 的错源是本席——实现者是从本席的派工/上报文本里带过来的。本席已在 #6939 订正

合约面自被审 head 起未动(这是不重跑审查的依据):

 fba1bfd78(被审)→ 2e8816b61(现)
complex.ts da06193b0f6fc5f17c8197a1ef34a3e0491fa6b7 IDENTICAL
complex.zod.ts f53db2176cc01d32ec2eb01f484835b9d20eaaa7 IDENTICAL

自被审 head 起本分支只有一个自有提交 a5c4ef4b3(CLI fixture 重定向);F2/F3 是 GitHub 上的散文编辑,仓库内容未变。

⛔ clause 2 仍未实现,且仍在维护者手上

本次放行的是 clause 1itemscards 重命名)。clause 2 与 #6172 裁决的冲突未解,已原样上报(#6939 评论 5530620525)。放行 clause 1 不预判该冲突:无论 types 三重奏最终保留、改名还是按选项 D 退役,这次的成员重命名都随之迁移或一并丢弃,都不因先落而更难。

⚠️CI 在当前 head 2e8816b61 上仍在跑(19:18 启动)。⚠️ 记一笔:CI 修复所在的 head a3fb15e5e 的运行被 merge 推送取消cancelled),从未跑完——所以修复本身尚未在 CI 上被证明,正在跑的这个才是。auto-merge 会等必需检查通过,若转红本席按 drive-to-green 处置。


Generated by Claude Code

@os-project-managerClaude

Copy link
Copy Markdown
CollaboratorAuthor

CI 已在当前 head 转绿;放行动作剩两步,被 GitHub 配额挡住

domain:ui 派发席,session session_01EMrWaQw3XS5DxTHxp4yRyC

CI 序列,按 head_sha 逐个核对

fba1bfd78 failure ← 原来的红(check-validity-recogniser)
a3fb15e5e cancelled ← CI 修复所在的 head,被 merge 推送顶掉,从未跑完
2e8816b61 success ← 当前 head:修复在 CI 上被证明

⚠️ 两处值得记的读数陷阱,本 PR 上都出现了:

  • cancelled 不是绿也不是红,是未跑完。若把 a3fb15e5ecancelled 当作「修复已验证」,就会在修复从未被 CI 跑过的情况下放行。真正证明它的是 2e8816b61 这一次。
  • **按 status=completed 过滤会同时返回旧 head 的结论。**本 PR 的三次运行全部 completed,其中一个 failure、一个 cancelled——不核对 head_sha 就会读到与当前 head 无关的结果。

放行状态

  • needs:contract-review 已剥(标签现为 package: types / examples / tests
  • ✅ 裁断已逐字张贴(评论 5530965431),档位核验 100/100 在档
  • ✅ 合约面自被审 head 起逐字节未动:complex.ts = da06193b0complex.zod.ts = f53db2176fba1bfd782e8816b61
  • ✅ CI 在当前 head 绿
  • draft:false
  • 欠 auto-merge SQUASH

后两步的 API 端点(update_pull_request / enable_pr_auto_merge,GraphQL 后端)自 19:26 起持续返回 API rate limit already exceeded,而评论与标签端点仍可用——所以这条记录发得出去、放行动作发不出去。已排定时提醒跟踪补完,⛔ 不靠记忆、⛔ 不会静默停在半完成状态。

⭐ 顺带记一条操作次序上的改进,本轮两次踩到才想明白:应当先 draft:false + auto-merge,成功后再剥 needs:contract-review。先剥标签的话,配额一断就留下「标签显示已复核、实际仍是草稿」的不自洽状态;反序则只会留下「有标签、是草稿」的自洽状态。

⛔ 仍未实现且仍在维护者手上

本次放行的是 clause 1itemscards)。clause 2 与 #6172 裁决的冲突未解,已原样上报(#6939 评论 5530620525)。放行 clause 1 不预判该冲突。


Generated by Claude Code

@os-project-manager
os-project-manager marked this pull request as ready for review September 3, 2026 19:55
@os-project-manager
os-project-manager added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 240b80fSep 3, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-6939-group3-kanban-cards branch September 3, 2026 20:10
Sign up for freeto 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

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(types): rename KanbanColumn.items to cards on both published halves - #7541

Merged
os-project-manager merged 5 commits into
mainfrom
claude/issue-6939-group3-kanban-cards
Sep 3, 2026
Merged

fix(types): rename KanbanColumn.items to cards on both published halves#7541
os-project-manager merged 5 commits into
mainfrom
claude/issue-6939-group3-kanban-cards

Conversation

@os-project-manager

@os-project-manageros-project-manager commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Part of #6939 — the kanban row (group 3) only. Groups 4 (filter-builder) and 5 (chart) are not addressed here and remain open; group 2 (tree-view) is PR #7533.

Clause-②: yes — this moves a published mirror's accept/reject behaviour AND renames a member on a published type. Draft + needs:contract-review; not marked ready, no auto-merge.

What changed

KanbanColumn declared its card list as items in both halves of the published surface — packages/types/src/complex.ts and the zod mirror packages/types/src/zod/complex.zod.ts — while every board reads cards. Renamed to cards.

The ruling's own numbers, re-measured on this branch's base

The maintainer ruling (comment 5510084784) took its counts on origin/mainec0a7b84. This branch is based on 78a3cc238. All three reproduce:

ReadingRulingRe-measured on 78a3cc238
plugin-kanban/src/types.ts declares cards: KanbanCard[]line 75line 75 ✓
complex.zod.ts declares itemsline 54line 55 (one line of drift)
.cards read lines in KanbanImpl.tsx1212 ✓
.cards read lines in KanbanEnhanced.tsx88 ✓
.items read lines in either00 ✓

Control for the two zeros: a same-shaped probe (grep -c '\.title') on the same two files returns 8 and 3, so the zeros are readings and not a mis-shaped probe. A nonsense-member probe of the same shape returns 0 on both.

Addendum the ruling did not count:packages/plugin-kanban/src/index.tsx reads col.cardsthree more times — lines 64 and 89 in bucketCardsIntoColumns, and line 327 in the kanban-enhanced registration's useMemo, which has the same shape. Each is col.cards || [], and that || [] is the mechanism behind the discriminator below. (An earlier revision said "twice more (lines 64 and 89)", missing line 327; corrected on review.)

Why the rename went toward cards — measured, not asserted

Per #6318's triage, a "correction" that renders identically proves the schema was the wrong side. This row clears the stronger, opposite-polarity bar: "correcting" the fixtures toward the declaration does not merely change the render, it empties the board. Measured through the harness in the new test file, on 78a3cc238, before either declaration was touched:

Entrycards (authored)items (the declared spelling)
basic-kanban-board64 elements — To Do2 … Design new feature …45 elements — No cards3 columnsTo Do0In Progress0Done0
advanced-kanban-with-badges-and-limits86 elements — Backlog2 … User Authentication …58 elements — No cards4 columnsBacklog0 …

Validator verdicts, same run: the authored cards documents failedsafeValidateSchema (: Invalid input) and the items documents passed. After this change, exactly reversed.

What is pinned

examples/schema-catalog/test/kanban-column-cards-6939.test.tsx (11 tests):

  • both catalog entries validate;
  • the items spelling is now refused (the other half of the accept-set move — a mirror that merely widened would still accept it);
  • cards is a real declaration, not a passthrough hole — counter-probes use only the declared key, since BaseSchema is .passthrough() and an unknown key would prove nothing;
  • render identity against the pre-change readings: element count, tag census, visible text literal, and SHA-256 over the full textContent;
  • anti-vacuity — every authored column title and card title is asserted on screen, plus a guard that at least one card exists, so the identity pin cannot pass on a blank tile;
  • the items empty-board reading is itself pinned, so the direction of the rename stays a measurement.

Controls are legal in both states. The render carriers never pass through the validator, and bucketCardsIntoColumns is untouched, so both the populated and the empty board render the same before and after. The waitFor witness is a column heading, which exists in both boards — it cannot settle for one spelling and time out for the other.

Ablation (predicted before measured)

Restoring items to both declarations, renderer untouched. Predicted red: the two validates cases, the two items-refused cases, and the passthrough counter-probe — 5 of 11, with the six render/anti-vacuity cases and all 12 zod-mirror-parity cases staying green.

Measured: exactly thatTests 5 failed | 18 passed (23), and the five names match the prediction one-for-one.

The mutation was proven on disk before the run (anchored counts in both directions, plus blob hashes differing from HEAD), and the restore was proven by state, not by exit code: both worktree blob hashes equal their HEAD blobs, git diff HEAD empty, git status --porcelain empty. Both files resolve through the repo's vitest source alias (packages/types/src/...), so no dist rebuild participates in this ablation.

Notes

  • packages/types/examples/zod-validation-example.ts authored the old spelling in three places; renamed. It is covered by packages/types' type-check (which runs tsc -p tsconfig.examples.json).
  • The header of examples/schema-catalog/test/safe-validate-corpus-6318.test.ts listed this row as an open finding on the Zod union; that sentence is now stale and the kanban clause is removed. That file deliberately pins no bucket size, so nothing else there moves.
  • @object-ui/plugin-kanban is unchanged — it already declared cards.
  • An earlier revision of the test preloaded the lazy chunk via @object-ui/plugin-kanban/KanbanImpl. That shape was removed: it is not in the package's exports map and resolves only through the repo's vitest alias, which @object-ui/fields deep subpaths resolve only through the repo vitest alias — its exports map publishes none of them #4325 ruled out for @object-ui/fields. The test now settles the boundary with waitFor, the way catalog-gallery-render.test.tsx already does for these same entries.

Changeset

minor, not patch — this is a rename on a published type, not a widening. @object-ui/types only. (major is forbidden repo-wide by scripts/check-changeset-no-major.mjs; the breaking semantics are spelled out in the changeset body per repo convention.)

Verification — all at merged head fba1bfd78

CheckResult
vitest run packages/types/ packages/plugin-kanban/ examples/schema-catalog/Test Files 140 passed (140), Tests 3727 passed (3727)
zod-mirror-parity.test.ts (run explicitly)Tests 12 passed (12)
turbo run type-check --filter=@object-ui/types --filter=@object-ui/plugin-kanbanTasks: 15 successful, 15 total
turbo run type-check --filter=@object-ui/example-schema-catalogTasks: 30 successful, 30 total
eslint . --format json4254 files, 0 errors (eslint's own population, not a narrowed list)
check-changeset-presence.mjsexit 0 — 1 changeset for 1 released package
check-changeset-no-major.mjsexit 0
check-control-bytes.mjsexit 0 — 6210 tracked text files

Branch merged with origin/main47547d01a (a merge, not a rebase, per AGENTS.md); the full suite above was re-run after the merge.

Clause 2 of the ruling, and a PRIOR ruling on this exact pair

The 2026-09-02 ruling has two clauses. This PR implements clause 1 (the rename). Clause 2 — "packages/plugin-kanban/src/types.ts stops carrying its own KanbanColumn declaration and re-uses the public one" — is NOT implemented here, and two things about it belong on the record. Neither asks this PR to decide anything.

1. The public declaration is not structurally sufficient. Measured: the plugin's local KanbanCard carries four members the public @object-ui/typesKanbanCard does not declare — badges, cardSubtitle, cardFieldCells, coverImage — plus an index signature; the plugin's KanbanColumn carries className where the public one has color. All are live reads (card.coverImage, card.cardFieldCells, card.cardSubtitle, card.badges, column.className, and card[swimlaneField] at KanbanImpl.tsx 449, 672 and 692). Deleting the local declaration would type column.cards as the publicKanbanCard[] and break every one of them, so clause 2 cannot be executed without widening the published type — which the dispatch explicitly forbids doing silently.

2. Correction to an earlier revision of this PR, and the prior ruling it missed.

An earlier revision cited the comment at KanbanImpl.tsx:52 as "a landed decision pointing the other way", saying objectui#6172 / #6155 made ./types the authority because the local card carried members the public one did not. That attribution was wrong. The comment compares KanbanImpl.tsx's own former copies against the plugin's ./types — an in-package drift — and says so in as many words: "the local KanbanCard carried cardSubtitle / cardFieldCells / coverImage that ./types did not". It says nothing about @object-ui/types.

That card was explicit about not touching the cross-package question. Its changeset (.changeset/6172-markdown-kanban-one-authority.md, landed in b3d562c02):

The cross-package KanbanCard / KanbanColumn / KanbanSchema collision between @object-ui/types and @object-ui/plugin-kanban is NOT resolved here and is escalated on objectui#6172 — those are two different dialects (items vs cards, labels vs badges), and collapsing them renames a published name, which needs an authority ruling.

So :52 is in-package convergence plus an explicit escalation, not a contrary decision.

And that escalation was answered. objectui#6172 comment 5474954379 (2026-08-31, maintainer verbatim 「其他同意」, director-seat batch #14) rules option A:

plugin-kanban 保留裸名 KanbanSchema 家族;@object-ui/types 三重奏改名(如 DeclarativeKanbanSchema 族)

Under that ruling the public KanbanColumn is renamed away, so clause 2's "re-use the public one" would have nothing to re-use. It predates the 2026-09-02 ruling by two days, the two do not cite each other, and it is not yet executed (packages/types/src/complex.ts:28 still declares KanbanColumn). It also lists retiring the @object-ui/types triplet outright as escalation option D — under which this PR's member rename would travel with the renamed type, or disappear with a retired one.

I am not adjudicating which ruling governs. Both are recorded so the reviewer and the maintainer can see the conflict; the dispatching seat has escalated it as-is. Worth noting that #6172's own census agrees with this PR's measurement independently: it found the types-dialect items spelling had zero non-demo, non-known-bad uses across the bound.

Follow-up: CI red on fba1bfd78, and the fix (a3fb15e5e)

Test (shard 3/4) went red on one case — packages/cli/src/__tests__/check-validity-recogniser.test.ts, "reports a registered component type the bundled schemas do not model", expected +0 to be 1. It is a correct consequence of this repair, and it is fixed here rather than worked around.

That case wrote a kanban board authoring cards and asserted objectui check would report it as a registered type the bundled schemas cannot model. It only ever landed in that bucket because the mirror required items — the exact fork this PR repairs. Once the board validates, the count drops to 0. The defect was frozen into an assertion of expected behaviour.

Reproduced end-to-end through the real check, not inferred: a kanban board with cards now yields candidates=[]; the sibling text fixture still yields a candidate (positive control); a foreign package.json still yields Skipped 1 and no candidate (negative control).

The comment was also wrong, independently of this PR. It claimed AnyComponentSchema "has no member for" kanban. ComplexSchema has carried KanbanSchema throughout (complex.zod.ts:691-692, reached from AnyComponentSchema via the ComplexSchema arm). Corrected to the real mechanism — a required-key mismatch, not an absent member.

The replacement type was chosen by measurement. Difference set, by introspecting every literal type the union declares: 658 registered types in KNOWN_SCHEMA_TYPES, 102 modelled, 558 with no member. Probe controlled in both directions — kanban, text and tree-view all read as modelled (so it is not blind to real members), a nonsense type does not.

Picked abbr. Raw HTML primitives are the stable inhabitants of that bucket: packages/components/src/renderers/basic/html-elements.tsx registers them in bulk and they are not candidates for authorable component schemas — unlike a plugin-ish type such as dashboard-grid, which also lands there today but is a plausible future modelling target. The fixture is a well-formedabbr document, which keeps the case's original point: the file is unmodelled, not broken.

The timer is defused rather than passed on. The case now asserts its own precondition — that abbr is still refused by safeValidateSchema — with a message naming what to do. If anyone ever models abbr, this file says why it went red instead of reporting a bare expected +0 to be 1. A synthetic always-unmodelled type was considered and rejected: the registered-type universe is a generated, separately-pinned file (packages/cli/src/utils/known-schema-types.ts), so a synthetic type would have to be injected by mocking it — and that would fabricate the "registered" half, which is precisely the half this bucket is about.

⛔ The test was not skipped, disabled, isolated or deleted, and the sample was not reverted to items. The changeset level is unchanged (minor).

Re-verified at merged head a3fb15e5e (merged origin/mainf0f774b0d)

CheckResult
vitest run packages/cli/ packages/types/ packages/plugin-kanban/ examples/schema-catalog/Test Files 156 passed (156), Tests 3973 passed (3973)
check-validity-recogniser.test.ts aloneTests 10 passed (10)
turbo run type-check --filter=@object-ui/cliTasks: 10 successful, 10 total
eslint on the changed file0 errors, 0 warnings
check-changeset-presence.mjsexit 0 — 1 changeset for 2 released packages
check-changeset-no-major.mjsexit 0
check-control-bytes.mjsexit 0 — 6212 tracked text files

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

`KanbanColumn` declared its card list as `items` in `complex.ts` and in the
zod mirror `complex.zod.ts`, while every board reads `cards`. Measured on
`origin/main` 78a3cc2: `KanbanImpl.tsx` reads `.cards` on 12 lines,
`KanbanEnhanced.tsx` on 8, and `bucketCardsIntoColumns` twice more as
`col.cards || []`; `.items` has zero read sites in either board, against a
same-shaped `.title` control returning 8 and 3 on the same two files.
The result was `declared !== enforced` on a published surface: both kanban
catalog entries failed `safeValidateSchema` with ": Invalid input" while
rendering perfectly — the type's seat in objectui#6318's bucket.
Renaming the read sites instead was rejected by measurement, not preference:
under the `items` spelling `col.cards || []` buckets every column to zero, and
`basic-kanban-board` goes from 64 elements reading "To Do2 / Design new
feature" to 45 elements reading "No cards / 3 columns / To Do0" — an empty
board. The declaration was the wrong side.
Pinned in `examples/schema-catalog/test/kanban-column-cards-6939.test.tsx`:
both entries validate, the `items` spelling is now refused, the rendered DOM is
byte-identical to the pre-change measurement (elements, tag census, visible
text, SHA-256 of textContent), and the empty-board reading for `items` is
pinned so the direction of the rename stays a measurement.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-JkRWQ99M.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…s false mechanism note
The `reports a registered component type the bundled schemas do not model`
case used a kanban board authoring `cards`, and its comment claimed
`AnyComponentSchema` "has no member for" kanban.
That claim was false, and was false before this branch touched anything:
`ComplexSchema` has carried `KanbanSchema` throughout. The board landed in the
bucket for a different reason — `KanbanColumnSchema` required `items` while
every board, and that sample, writes `cards`. Renaming the mirror to `cards`
made the board validate, so the case measured 0 candidates: the defect had
been frozen into an assertion of expected behaviour.
Repointed to `abbr`, chosen by measurement rather than memory. On this tree
`KNOWN_SCHEMA_TYPES` carries 658 registered types while `AnyComponentSchema`
declares 102 distinct literal `type` values, leaving 558 with no member; the
probe was controlled in both directions (`kanban` / `text` / `tree-view` read
as modelled, a nonsense type does not). Raw HTML primitives are the stable
inhabitants of that bucket — registered in bulk by `html-elements.tsx`, never
candidates for authorable component schemas — so the fixture does not carry a
timer the way a plugin-ish type such as `dashboard-grid` would.
The case also now asserts its own precondition, so if `abbr` is ever modelled
this file reports why instead of a bare `expected +0 to be 1`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-H6WopARe.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-H6WopARe.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (select-option.js)0.20KB0.19KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@os-project-managerClaude

Copy link
Copy Markdown
CollaboratorAuthor

合约审查裁断:FAIL 三条 → 补丁轮已全修 → 放行

domain:ui 派发席,session session_01EMrWaQw3XS5DxTHxp4yRyC。本席是 opus、不在 CONTRACT_REVIEW_TIER,故本 Clause-② yes 的 PR 由隔离审查者出裁。简报只含卡片、裁决与本 PR,⛔ 不含派发指令、⛔ 不含本席结论;并明确要求审查者只判 clause 2 的事实是否准确,⛔ 不判该走 A/B/C 哪个

转录档位核验:只提取 harness 生成的 model 字段(⛔ 不搜自由文本)。转录 205 行、0 行不可解析、100 个 assistant 轮次全部 claude-fable-5-1,无 fallback ⇒ 逐字采信。

三条 finding,逐条

F1 — 本 diff 让一个受 CI 把关的测试变红,而 PR 的验证人群不含它所在的包。
packages/cli/src/__tests__/check-validity-recogniser.test.ts 在 merge-base 通过、在 PR head 失败。那个用例写一个 columns[].cards: [] 的 kanban board,断言 objectui check 把它归入「未通过校验」桶。该样本从前之所以被拒,只因镜像要 items;本 PR 让 cards 成为被接受的拼法,于是它通过校验、桶计数读为 0。用例自己的散文(「kanbanAnyComponentSchema has no member for」)是假的——kanban 是被建模的,那正是本 PR 修的缺陷——所以它的前提随修复一同死亡。PR 的受影响套件跑的是 packages/types/ packages/plugin-kanban/ examples/schema-catalog/packages/cli 在人群之外,所以 PR 不可能看见它

head fba1bfd78 : × reports a registered component type … expected +0 to be 1 (1 failed | 9 passed)
base 47547d01a : 10 passed (10)
机制 同一样本经 safeValidateSchema:head success:true / base success:false [": Invalid input"]

F2 — clause 2 的叙述指错了物件,并漏掉了唯一直接相关的在先裁决。
(a) PR 称 KanbanImpl.tsx:52 记录 #6172/#6155 定权威「precisely because the local card carried … that the public one did not」。注释原文是「that ./types did not」——包内漂移;#6172 的 changeset 更明写跨包问题「is NOT resolved here and is escalated」。
(b) 该升格问题的答案存在#6172 评论 5474954379(2026-08-31,维护者逐字「其他同意」,第 6 场总监席决裁批 #14)裁选项 A —— plugin-kanban 保留裸名、@object-ui/types 三重奏改名,并列「径直退役」为升格选项 D。⇒ 在其之下 clause 2 的「公共那个」将不复存在。两条裁决相隔两天、互不引用,且 #6172尚未执行

F3(非阻塞)— 读点补记少了一处。index.tsxcol.cards处(64、89、327),索引签名读点是 449、672、692

审查者核实通过的部分

clause-2 的结构测量正确(公共 KanbanCard 确实缺那四个成员、无索引签名;本地 KanbanColumnclassName 而公共的是 color;所有引用读点为活读点,并另找到 ObjectKanban.tsx:585);裁决数字复现(items 在 55 行不是 54;12/8/0,配同形 .title 对照 8/3 与胡诌成员对照 0);判别器在真实 base 上重测,四个读数与 PR 钉的 PRE_REPAIR/ITEMS_SPELLING 全部吻合;空洞 harness 复现(Suspense fallback,1 元素、sha=e3b0c442… 即空串哈希),并验证替换后的 h3 见证在两种状态下都在场;消融在真实 base 上一对一复现(5 failed | 18 passed);changeset minor 正确,@object-ui/plugin-kanban 确未被动;普查确认插件之外无 KanbanColumn 消费者。

NARROWINGS(收口后由审查者自行转为实测的两项)

被锁住的宽跑事后返回:140 passed (140) / 3727 passed (3727),turbo type-check 32 successful, 32 total ⇒ 三棵树内无测试钉 items 拼法、无 TS 消费者读 KanbanColumn.items。**两项都确认了 F1 的结论:红的那个测试在 PR 所验证的人群之外,而那是人群选择的问题,不是人群内部有缺陷。**其余仍列为未测:whole-population eslint .、经完整 CLI 闭包的 objectui check、PR 自身的原地消融机制、--listFiles 主张、两个 issue 线程的未读部分、shard-3 的作业日志(改以本地复现代替)。


派发席处置:放行

三条全修,逐条按内容核过:

  • F1 —— 样本从 kanban 重定向到 abbr,假机制注释已订正。⭐ 实现者否决了本席倾向的合成类型方案,并给了测量KNOWN_SCHEMA_TYPES 是从注册调用生成的文件且被 known-schema-types-derivation-5115.test.ts 单独钉住,合成类型只能靠 mock 那个模块进入——那会伪造「已注册」这一半,而这一半正是被测对象。本席的建议会掏空该测试的证据价值,采纳它的。它的差集探针两方向都点亮对照(658 注册 / 102 建模 / 558 无成员,kanban/text/tree-view 读作 modelled 即对旧注释的直接反证)。⭐ 并且它把定时器拆了:用例现在断言自己的前提,未来变红会读作「abbr 现在被建模了,换一个类型」,而不是这轮花掉一个 CI 周期的 expected +0 to be 1
  • F2 / F3 —— 散文订正。⭐ 实现者做了一个正确的切分:底层测量成立(公共 KanbanCard 确缺那四个成员),作废的只是归因。F3 它自查出比裁断更多:col.cards 三处、索引签名 449/672/692(691 差一、449 整个漏掉)。
  • ⚠️F2(a) 的错源是本席——实现者是从本席的派工/上报文本里带过来的。本席已在 #6939 订正

合约面自被审 head 起未动(这是不重跑审查的依据):

 fba1bfd78(被审)→ 2e8816b61(现)
complex.ts da06193b0f6fc5f17c8197a1ef34a3e0491fa6b7 IDENTICAL
complex.zod.ts f53db2176cc01d32ec2eb01f484835b9d20eaaa7 IDENTICAL

自被审 head 起本分支只有一个自有提交 a5c4ef4b3(CLI fixture 重定向);F2/F3 是 GitHub 上的散文编辑,仓库内容未变。

⛔ clause 2 仍未实现,且仍在维护者手上

本次放行的是 clause 1itemscards 重命名)。clause 2 与 #6172 裁决的冲突未解,已原样上报(#6939 评论 5530620525)。放行 clause 1 不预判该冲突:无论 types 三重奏最终保留、改名还是按选项 D 退役,这次的成员重命名都随之迁移或一并丢弃,都不因先落而更难。

⚠️CI 在当前 head 2e8816b61 上仍在跑(19:18 启动)。⚠️ 记一笔:CI 修复所在的 head a3fb15e5e 的运行被 merge 推送取消cancelled),从未跑完——所以修复本身尚未在 CI 上被证明,正在跑的这个才是。auto-merge 会等必需检查通过,若转红本席按 drive-to-green 处置。


Generated by Claude Code

@os-project-managerClaude

Copy link
Copy Markdown
CollaboratorAuthor

CI 已在当前 head 转绿;放行动作剩两步,被 GitHub 配额挡住

domain:ui 派发席,session session_01EMrWaQw3XS5DxTHxp4yRyC

CI 序列,按 head_sha 逐个核对

fba1bfd78 failure ← 原来的红(check-validity-recogniser)
a3fb15e5e cancelled ← CI 修复所在的 head,被 merge 推送顶掉,从未跑完
2e8816b61 success ← 当前 head:修复在 CI 上被证明

⚠️ 两处值得记的读数陷阱,本 PR 上都出现了:

  • cancelled 不是绿也不是红,是未跑完。若把 a3fb15e5ecancelled 当作「修复已验证」,就会在修复从未被 CI 跑过的情况下放行。真正证明它的是 2e8816b61 这一次。
  • **按 status=completed 过滤会同时返回旧 head 的结论。**本 PR 的三次运行全部 completed,其中一个 failure、一个 cancelled——不核对 head_sha 就会读到与当前 head 无关的结果。

放行状态

  • needs:contract-review 已剥(标签现为 package: types / examples / tests
  • ✅ 裁断已逐字张贴(评论 5530965431),档位核验 100/100 在档
  • ✅ 合约面自被审 head 起逐字节未动:complex.ts = da06193b0complex.zod.ts = f53db2176fba1bfd782e8816b61
  • ✅ CI 在当前 head 绿
  • draft:false
  • 欠 auto-merge SQUASH

后两步的 API 端点(update_pull_request / enable_pr_auto_merge,GraphQL 后端)自 19:26 起持续返回 API rate limit already exceeded,而评论与标签端点仍可用——所以这条记录发得出去、放行动作发不出去。已排定时提醒跟踪补完,⛔ 不靠记忆、⛔ 不会静默停在半完成状态。

⭐ 顺带记一条操作次序上的改进,本轮两次踩到才想明白:应当先 draft:false + auto-merge,成功后再剥 needs:contract-review。先剥标签的话,配额一断就留下「标签显示已复核、实际仍是草稿」的不自洽状态;反序则只会留下「有标签、是草稿」的自洽状态。

⛔ 仍未实现且仍在维护者手上

本次放行的是 clause 1itemscards)。clause 2 与 #6172 裁决的冲突未解,已原样上报(#6939 评论 5530620525)。放行 clause 1 不预判该冲突。


Generated by Claude Code

@os-project-manager
os-project-manager marked this pull request as ready for review September 3, 2026 19:55
@os-project-manager
os-project-manager added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 240b80fSep 3, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-6939-group3-kanban-cards branch September 3, 2026 20:10
Sign up for freeto 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

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(types): rename KanbanColumn.items to cards on both published halves - #7541

Merged
os-project-manager merged 5 commits into
mainfrom
claude/issue-6939-group3-kanban-cards
Sep 3, 2026
Merged

fix(types): rename KanbanColumn.items to cards on both published halves#7541
os-project-manager merged 5 commits into
mainfrom
claude/issue-6939-group3-kanban-cards

Conversation

@os-project-manager

@os-project-manageros-project-manager commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Part of #6939 — the kanban row (group 3) only. Groups 4 (filter-builder) and 5 (chart) are not addressed here and remain open; group 2 (tree-view) is PR #7533.

Clause-②: yes — this moves a published mirror's accept/reject behaviour AND renames a member on a published type. Draft + needs:contract-review; not marked ready, no auto-merge.

What changed

KanbanColumn declared its card list as items in both halves of the published surface — packages/types/src/complex.ts and the zod mirror packages/types/src/zod/complex.zod.ts — while every board reads cards. Renamed to cards.

The ruling's own numbers, re-measured on this branch's base

The maintainer ruling (comment 5510084784) took its counts on origin/mainec0a7b84. This branch is based on 78a3cc238. All three reproduce:

ReadingRulingRe-measured on 78a3cc238
plugin-kanban/src/types.ts declares cards: KanbanCard[]line 75line 75 ✓
complex.zod.ts declares itemsline 54line 55 (one line of drift)
.cards read lines in KanbanImpl.tsx1212 ✓
.cards read lines in KanbanEnhanced.tsx88 ✓
.items read lines in either00 ✓

Control for the two zeros: a same-shaped probe (grep -c '\.title') on the same two files returns 8 and 3, so the zeros are readings and not a mis-shaped probe. A nonsense-member probe of the same shape returns 0 on both.

Addendum the ruling did not count:packages/plugin-kanban/src/index.tsx reads col.cardsthree more times — lines 64 and 89 in bucketCardsIntoColumns, and line 327 in the kanban-enhanced registration's useMemo, which has the same shape. Each is col.cards || [], and that || [] is the mechanism behind the discriminator below. (An earlier revision said "twice more (lines 64 and 89)", missing line 327; corrected on review.)

Why the rename went toward cards — measured, not asserted

Per #6318's triage, a "correction" that renders identically proves the schema was the wrong side. This row clears the stronger, opposite-polarity bar: "correcting" the fixtures toward the declaration does not merely change the render, it empties the board. Measured through the harness in the new test file, on 78a3cc238, before either declaration was touched:

Entrycards (authored)items (the declared spelling)
basic-kanban-board64 elements — To Do2 … Design new feature …45 elements — No cards3 columnsTo Do0In Progress0Done0
advanced-kanban-with-badges-and-limits86 elements — Backlog2 … User Authentication …58 elements — No cards4 columnsBacklog0 …

Validator verdicts, same run: the authored cards documents failedsafeValidateSchema (: Invalid input) and the items documents passed. After this change, exactly reversed.

What is pinned

examples/schema-catalog/test/kanban-column-cards-6939.test.tsx (11 tests):

  • both catalog entries validate;
  • the items spelling is now refused (the other half of the accept-set move — a mirror that merely widened would still accept it);
  • cards is a real declaration, not a passthrough hole — counter-probes use only the declared key, since BaseSchema is .passthrough() and an unknown key would prove nothing;
  • render identity against the pre-change readings: element count, tag census, visible text literal, and SHA-256 over the full textContent;
  • anti-vacuity — every authored column title and card title is asserted on screen, plus a guard that at least one card exists, so the identity pin cannot pass on a blank tile;
  • the items empty-board reading is itself pinned, so the direction of the rename stays a measurement.

Controls are legal in both states. The render carriers never pass through the validator, and bucketCardsIntoColumns is untouched, so both the populated and the empty board render the same before and after. The waitFor witness is a column heading, which exists in both boards — it cannot settle for one spelling and time out for the other.

Ablation (predicted before measured)

Restoring items to both declarations, renderer untouched. Predicted red: the two validates cases, the two items-refused cases, and the passthrough counter-probe — 5 of 11, with the six render/anti-vacuity cases and all 12 zod-mirror-parity cases staying green.

Measured: exactly thatTests 5 failed | 18 passed (23), and the five names match the prediction one-for-one.

The mutation was proven on disk before the run (anchored counts in both directions, plus blob hashes differing from HEAD), and the restore was proven by state, not by exit code: both worktree blob hashes equal their HEAD blobs, git diff HEAD empty, git status --porcelain empty. Both files resolve through the repo's vitest source alias (packages/types/src/...), so no dist rebuild participates in this ablation.

Notes

  • packages/types/examples/zod-validation-example.ts authored the old spelling in three places; renamed. It is covered by packages/types' type-check (which runs tsc -p tsconfig.examples.json).
  • The header of examples/schema-catalog/test/safe-validate-corpus-6318.test.ts listed this row as an open finding on the Zod union; that sentence is now stale and the kanban clause is removed. That file deliberately pins no bucket size, so nothing else there moves.
  • @object-ui/plugin-kanban is unchanged — it already declared cards.
  • An earlier revision of the test preloaded the lazy chunk via @object-ui/plugin-kanban/KanbanImpl. That shape was removed: it is not in the package's exports map and resolves only through the repo's vitest alias, which @object-ui/fields deep subpaths resolve only through the repo vitest alias — its exports map publishes none of them #4325 ruled out for @object-ui/fields. The test now settles the boundary with waitFor, the way catalog-gallery-render.test.tsx already does for these same entries.

Changeset

minor, not patch — this is a rename on a published type, not a widening. @object-ui/types only. (major is forbidden repo-wide by scripts/check-changeset-no-major.mjs; the breaking semantics are spelled out in the changeset body per repo convention.)

Verification — all at merged head fba1bfd78

CheckResult
vitest run packages/types/ packages/plugin-kanban/ examples/schema-catalog/Test Files 140 passed (140), Tests 3727 passed (3727)
zod-mirror-parity.test.ts (run explicitly)Tests 12 passed (12)
turbo run type-check --filter=@object-ui/types --filter=@object-ui/plugin-kanbanTasks: 15 successful, 15 total
turbo run type-check --filter=@object-ui/example-schema-catalogTasks: 30 successful, 30 total
eslint . --format json4254 files, 0 errors (eslint's own population, not a narrowed list)
check-changeset-presence.mjsexit 0 — 1 changeset for 1 released package
check-changeset-no-major.mjsexit 0
check-control-bytes.mjsexit 0 — 6210 tracked text files

Branch merged with origin/main47547d01a (a merge, not a rebase, per AGENTS.md); the full suite above was re-run after the merge.

Clause 2 of the ruling, and a PRIOR ruling on this exact pair

The 2026-09-02 ruling has two clauses. This PR implements clause 1 (the rename). Clause 2 — "packages/plugin-kanban/src/types.ts stops carrying its own KanbanColumn declaration and re-uses the public one" — is NOT implemented here, and two things about it belong on the record. Neither asks this PR to decide anything.

1. The public declaration is not structurally sufficient. Measured: the plugin's local KanbanCard carries four members the public @object-ui/typesKanbanCard does not declare — badges, cardSubtitle, cardFieldCells, coverImage — plus an index signature; the plugin's KanbanColumn carries className where the public one has color. All are live reads (card.coverImage, card.cardFieldCells, card.cardSubtitle, card.badges, column.className, and card[swimlaneField] at KanbanImpl.tsx 449, 672 and 692). Deleting the local declaration would type column.cards as the publicKanbanCard[] and break every one of them, so clause 2 cannot be executed without widening the published type — which the dispatch explicitly forbids doing silently.

2. Correction to an earlier revision of this PR, and the prior ruling it missed.

An earlier revision cited the comment at KanbanImpl.tsx:52 as "a landed decision pointing the other way", saying objectui#6172 / #6155 made ./types the authority because the local card carried members the public one did not. That attribution was wrong. The comment compares KanbanImpl.tsx's own former copies against the plugin's ./types — an in-package drift — and says so in as many words: "the local KanbanCard carried cardSubtitle / cardFieldCells / coverImage that ./types did not". It says nothing about @object-ui/types.

That card was explicit about not touching the cross-package question. Its changeset (.changeset/6172-markdown-kanban-one-authority.md, landed in b3d562c02):

The cross-package KanbanCard / KanbanColumn / KanbanSchema collision between @object-ui/types and @object-ui/plugin-kanban is NOT resolved here and is escalated on objectui#6172 — those are two different dialects (items vs cards, labels vs badges), and collapsing them renames a published name, which needs an authority ruling.

So :52 is in-package convergence plus an explicit escalation, not a contrary decision.

And that escalation was answered. objectui#6172 comment 5474954379 (2026-08-31, maintainer verbatim 「其他同意」, director-seat batch #14) rules option A:

plugin-kanban 保留裸名 KanbanSchema 家族;@object-ui/types 三重奏改名(如 DeclarativeKanbanSchema 族)

Under that ruling the public KanbanColumn is renamed away, so clause 2's "re-use the public one" would have nothing to re-use. It predates the 2026-09-02 ruling by two days, the two do not cite each other, and it is not yet executed (packages/types/src/complex.ts:28 still declares KanbanColumn). It also lists retiring the @object-ui/types triplet outright as escalation option D — under which this PR's member rename would travel with the renamed type, or disappear with a retired one.

I am not adjudicating which ruling governs. Both are recorded so the reviewer and the maintainer can see the conflict; the dispatching seat has escalated it as-is. Worth noting that #6172's own census agrees with this PR's measurement independently: it found the types-dialect items spelling had zero non-demo, non-known-bad uses across the bound.

Follow-up: CI red on fba1bfd78, and the fix (a3fb15e5e)

Test (shard 3/4) went red on one case — packages/cli/src/__tests__/check-validity-recogniser.test.ts, "reports a registered component type the bundled schemas do not model", expected +0 to be 1. It is a correct consequence of this repair, and it is fixed here rather than worked around.

That case wrote a kanban board authoring cards and asserted objectui check would report it as a registered type the bundled schemas cannot model. It only ever landed in that bucket because the mirror required items — the exact fork this PR repairs. Once the board validates, the count drops to 0. The defect was frozen into an assertion of expected behaviour.

Reproduced end-to-end through the real check, not inferred: a kanban board with cards now yields candidates=[]; the sibling text fixture still yields a candidate (positive control); a foreign package.json still yields Skipped 1 and no candidate (negative control).

The comment was also wrong, independently of this PR. It claimed AnyComponentSchema "has no member for" kanban. ComplexSchema has carried KanbanSchema throughout (complex.zod.ts:691-692, reached from AnyComponentSchema via the ComplexSchema arm). Corrected to the real mechanism — a required-key mismatch, not an absent member.

The replacement type was chosen by measurement. Difference set, by introspecting every literal type the union declares: 658 registered types in KNOWN_SCHEMA_TYPES, 102 modelled, 558 with no member. Probe controlled in both directions — kanban, text and tree-view all read as modelled (so it is not blind to real members), a nonsense type does not.

Picked abbr. Raw HTML primitives are the stable inhabitants of that bucket: packages/components/src/renderers/basic/html-elements.tsx registers them in bulk and they are not candidates for authorable component schemas — unlike a plugin-ish type such as dashboard-grid, which also lands there today but is a plausible future modelling target. The fixture is a well-formedabbr document, which keeps the case's original point: the file is unmodelled, not broken.

The timer is defused rather than passed on. The case now asserts its own precondition — that abbr is still refused by safeValidateSchema — with a message naming what to do. If anyone ever models abbr, this file says why it went red instead of reporting a bare expected +0 to be 1. A synthetic always-unmodelled type was considered and rejected: the registered-type universe is a generated, separately-pinned file (packages/cli/src/utils/known-schema-types.ts), so a synthetic type would have to be injected by mocking it — and that would fabricate the "registered" half, which is precisely the half this bucket is about.

⛔ The test was not skipped, disabled, isolated or deleted, and the sample was not reverted to items. The changeset level is unchanged (minor).

Re-verified at merged head a3fb15e5e (merged origin/mainf0f774b0d)

CheckResult
vitest run packages/cli/ packages/types/ packages/plugin-kanban/ examples/schema-catalog/Test Files 156 passed (156), Tests 3973 passed (3973)
check-validity-recogniser.test.ts aloneTests 10 passed (10)
turbo run type-check --filter=@object-ui/cliTasks: 10 successful, 10 total
eslint on the changed file0 errors, 0 warnings
check-changeset-presence.mjsexit 0 — 1 changeset for 2 released packages
check-changeset-no-major.mjsexit 0
check-control-bytes.mjsexit 0 — 6212 tracked text files

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

`KanbanColumn` declared its card list as `items` in `complex.ts` and in the
zod mirror `complex.zod.ts`, while every board reads `cards`. Measured on
`origin/main` 78a3cc2: `KanbanImpl.tsx` reads `.cards` on 12 lines,
`KanbanEnhanced.tsx` on 8, and `bucketCardsIntoColumns` twice more as
`col.cards || []`; `.items` has zero read sites in either board, against a
same-shaped `.title` control returning 8 and 3 on the same two files.
The result was `declared !== enforced` on a published surface: both kanban
catalog entries failed `safeValidateSchema` with ": Invalid input" while
rendering perfectly — the type's seat in objectui#6318's bucket.
Renaming the read sites instead was rejected by measurement, not preference:
under the `items` spelling `col.cards || []` buckets every column to zero, and
`basic-kanban-board` goes from 64 elements reading "To Do2 / Design new
feature" to 45 elements reading "No cards / 3 columns / To Do0" — an empty
board. The declaration was the wrong side.
Pinned in `examples/schema-catalog/test/kanban-column-cards-6939.test.tsx`:
both entries validate, the `items` spelling is now refused, the rendered DOM is
byte-identical to the pre-change measurement (elements, tag census, visible
text, SHA-256 of textContent), and the empty-board reading for `items` is
pinned so the direction of the rename stays a measurement.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-JkRWQ99M.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

…s false mechanism note
The `reports a registered component type the bundled schemas do not model`
case used a kanban board authoring `cards`, and its comment claimed
`AnyComponentSchema` "has no member for" kanban.
That claim was false, and was false before this branch touched anything:
`ComplexSchema` has carried `KanbanSchema` throughout. The board landed in the
bucket for a different reason — `KanbanColumnSchema` required `items` while
every board, and that sample, writes `cards`. Renaming the mirror to `cards`
made the board validate, so the case measured 0 candidates: the defect had
been frozen into an assertion of expected behaviour.
Repointed to `abbr`, chosen by measurement rather than memory. On this tree
`KNOWN_SCHEMA_TYPES` carries 658 registered types while `AnyComponentSchema`
declares 102 distinct literal `type` values, leaving 558 with no member; the
probe was controlled in both directions (`kanban` / `text` / `tree-view` read
as modelled, a nonsense type does not). Raw HTML primitives are the stable
inhabitants of that bucket — registered in bulk by `html-elements.tsx`, never
candidates for authorable component schemas — so the fixture does not carry a
timer the way a plugin-ish type such as `dashboard-grid` would.
The case also now asserts its own precondition, so if `abbr` is ever modelled
this file reports why instead of a bare `expected +0 to be 1`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-H6WopARe.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3182.2 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-H6WopARe.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (builtinAggregateLabels.js)0.86KB0.49KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.65KB1.47KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.15KB13.35KB
plugin-charts (index.js)70.94KB19.75KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.89KB34.68KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.57KB11.96KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)4.63KB2.18KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)4.58KB2.23KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (select-option.js)0.20KB0.19KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@os-project-managerClaude

Copy link
Copy Markdown
CollaboratorAuthor

合约审查裁断:FAIL 三条 → 补丁轮已全修 → 放行

domain:ui 派发席,session session_01EMrWaQw3XS5DxTHxp4yRyC。本席是 opus、不在 CONTRACT_REVIEW_TIER,故本 Clause-② yes 的 PR 由隔离审查者出裁。简报只含卡片、裁决与本 PR,⛔ 不含派发指令、⛔ 不含本席结论;并明确要求审查者只判 clause 2 的事实是否准确,⛔ 不判该走 A/B/C 哪个

转录档位核验:只提取 harness 生成的 model 字段(⛔ 不搜自由文本)。转录 205 行、0 行不可解析、100 个 assistant 轮次全部 claude-fable-5-1,无 fallback ⇒ 逐字采信。

三条 finding,逐条

F1 — 本 diff 让一个受 CI 把关的测试变红,而 PR 的验证人群不含它所在的包。
packages/cli/src/__tests__/check-validity-recogniser.test.ts 在 merge-base 通过、在 PR head 失败。那个用例写一个 columns[].cards: [] 的 kanban board,断言 objectui check 把它归入「未通过校验」桶。该样本从前之所以被拒,只因镜像要 items;本 PR 让 cards 成为被接受的拼法,于是它通过校验、桶计数读为 0。用例自己的散文(「kanbanAnyComponentSchema has no member for」)是假的——kanban 是被建模的,那正是本 PR 修的缺陷——所以它的前提随修复一同死亡。PR 的受影响套件跑的是 packages/types/ packages/plugin-kanban/ examples/schema-catalog/packages/cli 在人群之外,所以 PR 不可能看见它

head fba1bfd78 : × reports a registered component type … expected +0 to be 1 (1 failed | 9 passed)
base 47547d01a : 10 passed (10)
机制 同一样本经 safeValidateSchema:head success:true / base success:false [": Invalid input"]

F2 — clause 2 的叙述指错了物件,并漏掉了唯一直接相关的在先裁决。
(a) PR 称 KanbanImpl.tsx:52 记录 #6172/#6155 定权威「precisely because the local card carried … that the public one did not」。注释原文是「that ./types did not」——包内漂移;#6172 的 changeset 更明写跨包问题「is NOT resolved here and is escalated」。
(b) 该升格问题的答案存在#6172 评论 5474954379(2026-08-31,维护者逐字「其他同意」,第 6 场总监席决裁批 #14)裁选项 A —— plugin-kanban 保留裸名、@object-ui/types 三重奏改名,并列「径直退役」为升格选项 D。⇒ 在其之下 clause 2 的「公共那个」将不复存在。两条裁决相隔两天、互不引用,且 #6172尚未执行

F3(非阻塞)— 读点补记少了一处。index.tsxcol.cards处(64、89、327),索引签名读点是 449、672、692

审查者核实通过的部分

clause-2 的结构测量正确(公共 KanbanCard 确实缺那四个成员、无索引签名;本地 KanbanColumnclassName 而公共的是 color;所有引用读点为活读点,并另找到 ObjectKanban.tsx:585);裁决数字复现(items 在 55 行不是 54;12/8/0,配同形 .title 对照 8/3 与胡诌成员对照 0);判别器在真实 base 上重测,四个读数与 PR 钉的 PRE_REPAIR/ITEMS_SPELLING 全部吻合;空洞 harness 复现(Suspense fallback,1 元素、sha=e3b0c442… 即空串哈希),并验证替换后的 h3 见证在两种状态下都在场;消融在真实 base 上一对一复现(5 failed | 18 passed);changeset minor 正确,@object-ui/plugin-kanban 确未被动;普查确认插件之外无 KanbanColumn 消费者。

NARROWINGS(收口后由审查者自行转为实测的两项)

被锁住的宽跑事后返回:140 passed (140) / 3727 passed (3727),turbo type-check 32 successful, 32 total ⇒ 三棵树内无测试钉 items 拼法、无 TS 消费者读 KanbanColumn.items。**两项都确认了 F1 的结论:红的那个测试在 PR 所验证的人群之外,而那是人群选择的问题,不是人群内部有缺陷。**其余仍列为未测:whole-population eslint .、经完整 CLI 闭包的 objectui check、PR 自身的原地消融机制、--listFiles 主张、两个 issue 线程的未读部分、shard-3 的作业日志(改以本地复现代替)。


派发席处置:放行

三条全修,逐条按内容核过:

  • F1 —— 样本从 kanban 重定向到 abbr,假机制注释已订正。⭐ 实现者否决了本席倾向的合成类型方案,并给了测量KNOWN_SCHEMA_TYPES 是从注册调用生成的文件且被 known-schema-types-derivation-5115.test.ts 单独钉住,合成类型只能靠 mock 那个模块进入——那会伪造「已注册」这一半,而这一半正是被测对象。本席的建议会掏空该测试的证据价值,采纳它的。它的差集探针两方向都点亮对照(658 注册 / 102 建模 / 558 无成员,kanban/text/tree-view 读作 modelled 即对旧注释的直接反证)。⭐ 并且它把定时器拆了:用例现在断言自己的前提,未来变红会读作「abbr 现在被建模了,换一个类型」,而不是这轮花掉一个 CI 周期的 expected +0 to be 1
  • F2 / F3 —— 散文订正。⭐ 实现者做了一个正确的切分:底层测量成立(公共 KanbanCard 确缺那四个成员),作废的只是归因。F3 它自查出比裁断更多:col.cards 三处、索引签名 449/672/692(691 差一、449 整个漏掉)。
  • ⚠️F2(a) 的错源是本席——实现者是从本席的派工/上报文本里带过来的。本席已在 #6939 订正

合约面自被审 head 起未动(这是不重跑审查的依据):

 fba1bfd78(被审)→ 2e8816b61(现)
complex.ts da06193b0f6fc5f17c8197a1ef34a3e0491fa6b7 IDENTICAL
complex.zod.ts f53db2176cc01d32ec2eb01f484835b9d20eaaa7 IDENTICAL

自被审 head 起本分支只有一个自有提交 a5c4ef4b3(CLI fixture 重定向);F2/F3 是 GitHub 上的散文编辑,仓库内容未变。

⛔ clause 2 仍未实现,且仍在维护者手上

本次放行的是 clause 1itemscards 重命名)。clause 2 与 #6172 裁决的冲突未解,已原样上报(#6939 评论 5530620525)。放行 clause 1 不预判该冲突:无论 types 三重奏最终保留、改名还是按选项 D 退役,这次的成员重命名都随之迁移或一并丢弃,都不因先落而更难。

⚠️CI 在当前 head 2e8816b61 上仍在跑(19:18 启动)。⚠️ 记一笔:CI 修复所在的 head a3fb15e5e 的运行被 merge 推送取消cancelled),从未跑完——所以修复本身尚未在 CI 上被证明,正在跑的这个才是。auto-merge 会等必需检查通过,若转红本席按 drive-to-green 处置。


Generated by Claude Code

@os-project-managerClaude

Copy link
Copy Markdown
CollaboratorAuthor

CI 已在当前 head 转绿;放行动作剩两步,被 GitHub 配额挡住

domain:ui 派发席,session session_01EMrWaQw3XS5DxTHxp4yRyC

CI 序列,按 head_sha 逐个核对

fba1bfd78 failure ← 原来的红(check-validity-recogniser)
a3fb15e5e cancelled ← CI 修复所在的 head,被 merge 推送顶掉,从未跑完
2e8816b61 success ← 当前 head:修复在 CI 上被证明

⚠️ 两处值得记的读数陷阱,本 PR 上都出现了:

  • cancelled 不是绿也不是红,是未跑完。若把 a3fb15e5ecancelled 当作「修复已验证」,就会在修复从未被 CI 跑过的情况下放行。真正证明它的是 2e8816b61 这一次。
  • **按 status=completed 过滤会同时返回旧 head 的结论。**本 PR 的三次运行全部 completed,其中一个 failure、一个 cancelled——不核对 head_sha 就会读到与当前 head 无关的结果。

放行状态

  • needs:contract-review 已剥(标签现为 package: types / examples / tests
  • ✅ 裁断已逐字张贴(评论 5530965431),档位核验 100/100 在档
  • ✅ 合约面自被审 head 起逐字节未动:complex.ts = da06193b0complex.zod.ts = f53db2176fba1bfd782e8816b61
  • ✅ CI 在当前 head 绿
  • draft:false
  • 欠 auto-merge SQUASH

后两步的 API 端点(update_pull_request / enable_pr_auto_merge,GraphQL 后端)自 19:26 起持续返回 API rate limit already exceeded,而评论与标签端点仍可用——所以这条记录发得出去、放行动作发不出去。已排定时提醒跟踪补完,⛔ 不靠记忆、⛔ 不会静默停在半完成状态。

⭐ 顺带记一条操作次序上的改进,本轮两次踩到才想明白:应当先 draft:false + auto-merge,成功后再剥 needs:contract-review。先剥标签的话,配额一断就留下「标签显示已复核、实际仍是草稿」的不自洽状态;反序则只会留下「有标签、是草稿」的自洽状态。

⛔ 仍未实现且仍在维护者手上

本次放行的是 clause 1itemscards)。clause 2 与 #6172 裁决的冲突未解,已原样上报(#6939 评论 5530620525)。放行 clause 1 不预判该冲突。


Generated by Claude Code

@os-project-manager
os-project-manager marked this pull request as ready for review September 3, 2026 19:55
@os-project-manager
os-project-manager added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 240b80fSep 3, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-6939-group3-kanban-cards branch September 3, 2026 20:10
Sign up for freeto 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

@os-project-manager@claude