Skip to content

refactor(types)!: rename the declarative Kanban trio, leaving the bare names to plugin-kanban - #7643

Merged
os-warren merged 1 commit into
mainfrom
claude/issue-6172-kanban-trio-rename
Sep 4, 2026
Merged

refactor(types)!: rename the declarative Kanban trio, leaving the bare names to plugin-kanban#7643
os-warren merged 1 commit into
mainfrom
claude/issue-6172-kanban-trio-rename

Conversation

@claude

@claude claude Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Fixes #6172

Executes the 2026-08-31 maintainer ruling (comment 5474954379, director seat, 第 6 场决裁批 #14, verbatim 「其他同意」) — option A. @object-ui/plugin-kanban keeps the bare KanbanSchema / KanbanColumn / KanbanCard; the @object-ui/types trio is renamed.

Spelling chosen under the latitude the ruling grants ("执行席可在同义命名内定拼写"): the ruling's own exemplar family, DeclarativeKanbanSchema / DeclarativeKanbanColumn / DeclarativeKanbanCard, because "declarative" names what actually survives here — the authoring shape and its Zod mirror, which is the 'kanban' arm of ComplexSchemaAnyComponentSchemasafeValidateSchema.

The ruling's stop-condition: measured, and it does NOT fire

The ruling makes option D (retire the trio outright) an escalation during execution, not a choice:

若实测确认改名后的拷贝无任何保留价值(区分键 draggable/onColumnAdd/onCardAdd 零读者已测),执行席停手上报由维护者升格,⛔ 不自选。

The named discriminating keys do read zero, and that reproduces. Reader census over packages/{plugin-kanban,components,core,react,app-shell}/src, non-test, same query shape for target and control:

key read sites
.draggable 0
.onColumnAdd 0
.onCardAdd 0
.onCardMove 2
.onCardClick 1
control — .columns in plugin-kanban/src 8
control — .cards in plugin-kanban/src 23
control — .title in plugin-kanban/src 13

The instrument is lit: the same query that returns 0 for the three keys returns 8 / 23 / 13 for their neighbours, so those zeros are readings rather than a dead probe.

But the condition is "无任何保留价值" — no retained value at all — and the copy has plenty. Four measured, load-bearing consumers:

  1. It is the runtime validator for authored kanban documents. zod/complex.zod.ts's mirror is the 'kanban' arm of the ComplexSchema discriminated union, an arm of AnyComponentSchema, which is what safeValidateSchema runs — and packages/cli/src/commands/{validate,check}.ts call it. Retiring the trio would orphan or remove the only validation arm every { "type": "kanban" } document is judged against.
  2. SchemaRegistry['kanban'] (registry.ts:186) — published ComponentType keyspace.
  3. The ComplexSchema union arm — published type.
  4. onCardClick is declared only here. plugin-kanban/src/index.tsx:194 forwards schema.onCardClick, and the plugin's own KanbanSchema does not declare it — it type-checks solely through BaseSchema's index signature. The declarative copy is the only declaration of a key the live renderer reads.

⇒ Renamed, not retired. Reporting the measurement rather than the conclusion, per the ruling.

What moved

Six published names are removed, not three. The ruling's break line says "types 侧三个已发布名消失", which is the type trio; its landing-point list also names the Zod mirror, the Zod barrel and the demo — and those three are touched only if the mirror consts are renamed too. This repo's mirror convention is TypeName + Schema, so leaving KanbanSchema on a mirror of DeclarativeKanbanSchema would mint exactly the name-derived-pairing hazard zod-mirror-parity.test.ts's own header warns about. Flagging the count explicitly since it exceeds the ruled wording.

removed from old new
@object-ui/types KanbanSchema DeclarativeKanbanSchema
@object-ui/types KanbanColumn DeclarativeKanbanColumn
@object-ui/types KanbanCard DeclarativeKanbanCard
@object-ui/types/zod KanbanSchema DeclarativeKanbanSchema
@object-ui/types/zod KanbanColumnSchema DeclarativeKanbanColumnSchema
@object-ui/types/zod KanbanCardSchema DeclarativeKanbanCardSchema

Pure rename: no member, no optionality, no accept/reject behaviour moves. plugin-kanban is 0 files touched.

Landing points re-derived from the tree rather than inherited — the ruling's list plus three it did not name, found by grepping for name-keyed logic: handler-keys-json-refusal-6124.test.ts (type-level pins and the mirror labels), component-docs-retired-handler-keys-7340.test.ts (its CONTROL rows key on the doc heading), and the in-page anchor […](#kanbanschema) on schema-reference.md.

The shrink-only baseline one-authority-per-exported-name-6273.test.ts loses all three rows: 36 → 33, re-derived by counting the array, not inherited.

Verification

Exit codes captured by redirect before any pipe; every verdict quoted from the gate's own line. Union re-run on the final commit c7ea4147, tree clean.

  • Root vitest union (root-relative, per objectui#3378) over packages/types/ packages/plugin-kanban/ examples/schema-catalog/ + the baseline test + check-doc-component-types.test.tsTest Files 154 passed (154) / Tests 3980 passed (3980), exit 0.
  • turbo run type-check repo-wideTasks: 81 successful, 81 total, exit 0. This is the net that matters for removing published names, and it found no consumer of the removed six.
  • Type-level pins: named the instrument. handler-keys-json-refusal-6124.test.ts holds Expect(RetiredIsNever(DeclarativeKanbanSchema['onColumnAdd'])) and three siblings. Those are erased at runtime, so vitest's green says nothing about them — the instrument is tsc -p packages/types/tsconfig.test.json, chained from that package's type-check. Membership proved with --listFiles: the test file, src/complex.ts and src/zod/complex.zod.ts are all in the program (1 hit each), exit 0. examples/zod-validation-example.ts likewise sits in tsconfig.examples.json's program.
  • Gates: check:control-bytes exit 0 — "OK (scanned 6242 tracked text file(s); skipped 85 binary)" · check:doc-types exit 0 — "Every documented component type is registered." · check:doc-fences exit 0 (227 documents) · docs:check-links exit 0 — "Links are valid across 17 scan roots." · check:doc-snippets exit 0 — "Semantic phase: 452 of 452 block(s) judged, 0 failed." · check:readme-exports exit 0 — 421 self-imports judged, 0 wrong-path, 0 fabricated · changeset presence exit 0 — "9 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)" · check:changeset-no-major exit 0 · plus check:self-import, check:phantom-deps, check:esm-specifiers, check:spec-symbols, check:docs-route-closure, check:vi-mock-specifiers, check:vi-mock-inherit, check:side-effects-array, check:entry-guard, check:dist-completeness — all exit 0.
  • Coverage verified, not assumed: api/schema-reference.md appears 0 times in check-doc-snippet-types.mjs's declared UNGATED_DOCS, so the 452/452 green genuinely covers the page whose import line this PR rewrote.
  • Two results read as NOT MEASURED, not as red: check:sdui-registration-pins and check:eager-closure both exit 2 with their own precondition text ("No console build to weigh at apps/console/dist/assets"). They need an apps/console production build this branch never produces, and this diff is type-level only. CI runs them regardless.
  • Build before judging: turbo run build for the snippet gate's own --build-filter set reported a cache hit, so dist materialisation was verified in this worktree before anything was trusted — packages/types/dist/complex.d.ts, mtime from this run, carries DeclarativeKanban* 7 times and zero bare trio names outside my own prose.
  • eslint over changed files — exit 0, 0 errors; 17 warnings, all pre-existing no-explicit-any on lines this PR does not touch. Repo-wide pnpm lint was narrowed deliberately, and the narrowing is measured: (i) population read from eslint's own config, which reports the 5 .md/changeset paths as "File ignored because no matching configuration was supplied"; (ii) 10 of 15 files in population, counted from --format json; (iii) eslint.config.js declares no projectService / project / parserOptions, so linting is not type-aware and no untouched file's verdict can move on this diff.

Ablation — three legs, direction predicted in writing first

Each leg: predict, mutate, prove the mutation on disk (anchored count and git hash-object off the HEAD blob), observe, restore via git checkout HEAD -- ABSOLUTE_PATH under trap … EXIT INT TERM, prove the restore both ways (blob back to the HEAD value and empty git diff HEAD). No rebuild needed on any leg: the ratchet is a text scan over source and the link gate reads markdown.

  • Leg A — ratchet, stale direction. Predicted: re-adding the three deleted rows while each name has one authority reds as stale. Observed exactly — exit 1, KanbanCard / KanbanColumn / KanbanSchema — no longer collides at:, 1 failed / 10 passed.
  • Leg B — ratchet, fresh direction. Predicted: re-introducing a bare KanbanSchema declaration in complex.ts with the rows deleted reds as a new collision. Observed exactly — exit 1, KanbanSchema — a NEW colliding name, 1 failed / 10 passed.
  • Leg C — the doc anchor. ⚠️ Prediction FALSIFIED, and the falsification is the finding. Predicted check-doc-links would red on the pre-rename anchor. It exits 0. Two-arm control on the same file proves the instrument is alive and the gap is specific: a broken file-path link → exit 1 with the gate's relative: message; a broken in-page anchor (#totally-not-a-heading-xyz) → exit 0, silent. ⇒ The anchor correction in this PR is real but held by no gate; filed as a finding rather than fixed here.

Deliberately not changed

Clause-② — yes

Six published names are removed from @object-ui/types and @object-ui/types/zod: the published surface narrows. needs:contract-review is on both carriers; stays draft, not enqueued, parked for the director seat at CONTRACT_REVIEW_TIER.

@objectstack/spec resolved 17.2.0 at this SHA (what the lockfile gives; 17.3.0 is out but nothing was bumped). Nothing in this diff is spec-dependent.


🤖 Generated with Claude Code

https://claude.ai/code/session_01KbJQ1y1J12nZxYzFWhP8Q3


Generated by Claude Code

…e names to plugin-kanban (objectui#6172)

`KanbanSchema` / `KanbanColumn` / `KanbanCard` were declared twice with
disagreeing shapes — once in `@object-ui/types` and once in
`@object-ui/plugin-kanban`. The 2026-08-31 maintainer ruling (决裁批 #14,
option A) settled the authority: the plugin keeps the bare names, because all
four registered kanban renderers consume that dialect, and objectui#6086
measured that auto-importing the copy no renderer reads produces a confident
empty board rather than an abstention.

The `@object-ui/types` trio becomes `DeclarativeKanbanSchema` /
`DeclarativeKanbanColumn` / `DeclarativeKanbanCard`, and its Zod mirror follows
the package's `<TypeName>Schema` convention. Pure rename: no member, no
optionality and no accept/reject behaviour moves.

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

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3180.3 KB 3191.4 KB
Main entry chunk (gzip) 143.2 KB 350 KB
Entry file index-DGvdGsCg.js
Status PASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 15.67KB 5.75KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 5.13KB 2.35KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 510.70KB 116.21KB
core (index.js) 6.12KB 2.42KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 180.00KB 50.20KB
fields (index.js) 242.40KB 61.26KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 4.28KB 1.75KB
i18n (index.js) 3.65KB 1.47KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.98KB 10.98KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.32KB 1.64KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 11.71KB 4.29KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 5.12KB 1.74KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 15.75KB 3.80KB
plugin-calendar (index.js) 48.09KB 13.34KB
plugin-charts (index.js) 70.92KB 19.75KB
plugin-chatbot (index.js) 196.19KB 46.43KB
plugin-dashboard (index.js) 132.86KB 34.68KB
plugin-designer (index.js) 212.86KB 43.19KB
plugin-detail (index.js) 250.59KB 64.06KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 132.87KB 32.66KB
plugin-gantt (index.js) 167.40KB 41.05KB
plugin-grid (index.js) 210.75KB 56.95KB
plugin-kanban (index.js) 52.71KB 14.55KB
plugin-list (index.js) 113.28KB 27.59KB
plugin-map (index.js) 20.55KB 6.80KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 43.57KB 11.96KB
plugin-timeline (index.js) 30.84KB 8.85KB
plugin-tree (index.js) 9.38KB 3.22KB
plugin-view (index.js) 85.24KB 20.94KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 81.07KB 26.86KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 5.41KB 2.34KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 4.93KB 2.24KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 20.57KB 5.88KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 10.35KB 3.60KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.74KB 1.41KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.58KB 2.23KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

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

@os-warren
os-warren marked this pull request as ready for review September 4, 2026 14:46
@os-warren
os-warren added this pull request to the merge queue Sep 4, 2026
Merged via the queue into main with commit 2c71482 Sep 4, 2026
34 checks passed
@os-warren
os-warren deleted the claude/issue-6172-kanban-trio-rename branch September 4, 2026 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation package: types tests

Projects

None yet

2 participants