Skip to content

feat(types): the kanban arm declares the plugin dialect; the DeclarativeKanban* trio retires (objectui#7664) - #7743

Merged
os-zhuang merged 11 commits into
mainfrom
claude/issue-7664-kanban-plugin-dialect-authoritative
Sep 5, 2026
Merged

feat(types): the kanban arm declares the plugin dialect; the DeclarativeKanban* trio retires (objectui#7664)#7743
os-zhuang merged 11 commits into
mainfrom
claude/issue-7664-kanban-plugin-dialect-authoritative

Conversation

@claude

@claude claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Fixes #7664

Maintainer ruling (a) — comment 5548643216 on the card, decision batch #41, verbatim 「同意」: for an authored type: 'kanban' document the plugin dialect is authoritative. This PR executes the ruling's list end to end. Clause-②: yesneeds:contract-review, parked for the director.

This diff carries a REFUSE remediation and returns for a FRESH isolated review. The verdict is comment 5552425067; a REFUSE is not cleared by the fix. needs:contract-review stays on both carriers.

Contract-review remediation — R1: the arm widened an accept set

The finding. The successor 'kanban' arm dropped onCardClick outright — no refusal arm, no ?: never. BaseSchema is .passthrough(), so a dropped key is not refused: it stops being judged and the value is KEPT. Measured on the built dist, both doors (the arm's own safeParse, and the exported safeValidateSchema a type: 'kanban' document actually reaches):

document at bd1fc7111 + main at this head
{ type: 'kanban', columns: [], onCardClick: { action: 'toast' } } ACCEPTED, value kept as {"action":"toast"} REFUSED (custom, path onCardClick)
the same document at onCardMove REFUSED REFUSED
at onQuickAdd REFUSED REFUSED
at onColumnAdd REFUSED REFUSED
at draggable REFUSED (invalid_type) REFUSED (invalid_type)

The disposition was measured, not chosenplugin-kanban/src/__tests__/kanban-handler-slots-7664.test.tsx, new here, renders each of the four registrations with authored spies and mocked board chunks:

registration onCardClick onCardMove onQuickAdd
'kanban-ui' (KanbanRenderer) arrives by identity arrives by identity arrives by identity
'kanban' (ObjectKanbanRenderer) replaced by ObjectKanban's own replaced by ObjectKanban's own arrives by identity
'object-kanban' replaced by ObjectKanban's own replaced by ObjectKanban's own arrives by identity
'kanban-enhanced' not forwarded arrives by identity arrives by identity

Two lit controls, so no zero here comes from a probe that could not have fired. On 'kanban-ui' the two keys this PR already kept as runtime slots come out live, beside onCardClick, off the same forward block in index.tsx. On 'kanban' the lit control is onQuickAdd, which arrives by identity — the schema-spread channel does reach the board on that key — while onCardClick and onCardMove are both replaced, in the same object literal of the KanbanRenderer call inside ObjectKanban.tsx. ⇒ The rationale that was recorded for the deletion ("the object-bound board owns the click") would have deleted onCardMove just as well.

And a third channel decides it outright: ObjectKanban DECLARES an onCardClick prop (there is no onCardMove prop), and its substitute wrapper calls it. Measured through the production path — a document authored with onCardClick, rendered through SchemaRenderer, which spreads every non-metadata schema key as a React prop: the board is handed a function that is not the authored one, and invoking it runs the authored one. An onCardClick authored on a type: 'kanban' document runs. So onCardClick is at least as live as onCardMove on every channel measured, and the disposition is RUNTIME SLOT, not ?: never.

What that changed: onCardClick?: (card: KanbanCard, event?: unknown) = a void return on the TypeScript face (unknown for the event because this package declares zero dependencies and has no React types; KanbanImpl narrows it at the call site) + handlerKeyRefusal('onCardClick', 'runtime-slot', …) on the mirror. RUNTIME_SLOT 44 → 45, ALL_SITES 66 → 67; RETIRED stays 22 and the #7340 docs census stays 26. KnownDrift for KanbanSchema gains onCardClick.

Why no ratchet caught it, and what does now. The #6124 ledger is two hand-written arrays keyed by name; the re-key was a SUBSTITUTION (onCardClick out, onQuickAdd in) so its length never moved, and nothing derives its population from a read site. The new file closes that for this arm: it extracts the schema.on* reads out of KanbanRenderer's body in index.tsx and requires each to be a declared arm member carrying the RUNTIME SLOT guidance — red on exactly this deletion, and derived rather than listed. That covers 3 of the ledger's 67 sites; the class is filed as objectui#7753 with three options and a note that the tempting one (ratchet the count) is the one that fails on this instance.

Also corrected, because the review found written rationale the source contradicted:

  • both comments that justified the deletion — the RUNTIME_SLOT comment in handler-keys-json-refusal-6124.test.ts and the KnownDrift comment in zod-mirror-parity.test.ts — now state what the source does, including the substitution that applies identically to onCardMove;
  • the @object-ui/plugin-kanban changeset no longer claims the shape is "member for member what this package declared". Counted with the TypeScript parser against origin/main: 19 members on the plugin's KanbanSchema, 6 on KanbanColumn, 7 on KanbanCard; the declarations here are that shape plus four — three ?: never tombstones, and onCardClick, which the plugin dialect never declared while its renderer read it;
  • the @object-ui/types changeset gains the accept-set bullet for all five handler arms;
  • the draggable / column color tombstone JSDoc cites the two-prong discriminator instead of arguing from inertness. Re-measured on origin/main: schema-reference.md opened its kanban example with "draggable": true and carried a table row "Enable drag-and-drop between columns", and authored a color on every one of its three columns with the columns row reading "each with id, title, color, and cards" ⇒ prong 2 holds for both. Prong 1 holds for color only (className is the named live replacement); draggable has none, which is why prong 2 is what carries it. The hazards differ and both are measured: KanbanColumn does not extend BaseSchema, so its mirror is a plain object — an undeclared column key is accepted and stripped, whereas an undeclared board key is kept;
  • schema-reference.md documents onCardClick again, and it joins the docs: three pages still teach retired handler keys as authorable props — onColumnAdd/onCardAdd (schema-reference), onSelectChange/onExpandChange (tree-view), onComplete (input-otp) — stale once #6124's tombstones land #7340 blanket-sweep control (six rows → seven).

What changed

  • @object-ui/types complex.ts — the 'kanban' arm declares KanbanSchema / KanbanColumn / KanbanCard / CardTemplate / ColumnWidthConfig: the shape packages/plugin-kanban/src/types.ts declared, plus the four members named above. The two runtime-computed card members keep their React types through the ambient namespace exactly as data-display.ts already spells headerIcon / rowStyle; the package still declares no React dependency (check:phantom-deps green).
  • zod/complex.zod.ts — five mirrors (KanbanSchema, KanbanColumnSchema, KanbanCardSchema, CardTemplateSchema, ColumnWidthConfigSchema); ComplexSchemaAnyComponentSchemasafeValidateSchema apply them. conditionalFormatting reuses the 'object-kanban' arm's rule union (KanbanConditionalFormattingRuleSchema, newly exported from objectql.zod.ts); grouping is SpecGroupingConfigSchema by reference, as ObjectGallerySchema spells it; the two runtime-computed card members pass through as z.any() (the headerIcon precedent, objectui#6424).
  • registry.ts'kanban': KanbanSchema (PR fix(types): SchemaRegistry's kanban entry stops describing a component it cannot name #7662's transitional BaseSchema intersection re-pointed; the BaseSchema import tidied; the comment block rewritten — its "do not restore … without moving the renderer's dialect into a layer this package may depend on" named this route).
  • plugin-kanban/src/types.ts — re-exports the five from @object-ui/types (a plain re-export, not an authority under the one-authority ratchet); InlineFieldDefinition stays local. ObjectKanban.tsx's bare import becomes import type. Behaviour unchanged.
  • plugin-kanban/tsconfig.test.jsontypes gains node, as plugin-calendar / -charts / -chatbot / -dashboard / -detail / -gantt / -grid already do. The new test reads ../index.tsx off disk on purpose: that is what makes its key set derived rather than listed. It stays OUT of tsconfig.json — package source ships to browsers.
  • Retirement (ADR-0049) — the six DeclarativeKanban* exports and both objectui#7645 pin files (their docblocks disclosed it); _KeyKept carried forward into the new pin.
  • Ratchets re-keyed — zod-mirror-parity (5 pairs in, 3 out ⇒ EXPECTED_MIRROR_PAIRS = 159 on top of PR test(types): derive the zod-mirror-parity population instead of writing it down #7731's derived population, merged here; KnownDrift KanbanSchema: onCardMove | onCardClick | onQuickAdd; KanbanSchema added to SPEC_DERIVED_PAIRS; the rule union excluded with its reason), handler-keys-6124 (owner rename plus onCardClick restored and onQuickAdd added ⇒ 45 + 22 = 67), component-docs-retired-handler-keys-7340 (CONTROL re-keyed and extended to 7; census 26 unchanged because the onColumnAdd / onCardAdd tombstones carry over onto the successor arm), one-authority baseline history note.
  • Docsapi/schema-reference.md kanban section moves to the plugin dialect (in-page anchor and the import line follow; check-doc-links green); api/index.md, both READMEs, examples/zod-validation-example.ts.
  • Changesets@object-ui/types minor with a BREAKING banner; @object-ui/plugin-kanban patch. major not declared (check-changeset-no-major green).

The two numbers the dispatch said not to inherit

  • Body count. The ruling said "18-member"; a same-day AST census said 19. Re-derived with the TypeScript parser over complex.ts and pinned in the new test: the plugin dialect's own body is 19 live members (type is the one the ruling did not count), and the arm declared here is 20 live — those 19 plus onCardClick — plus 3 tombstones (draggable, onColumnAdd, onCardAdd). The twentieth is the R1 remediation: measured on origin/main, plugin-kanban/src/types.ts contains zero occurrences of the name while KanbanRenderer forwards it, so copying that dialect member for member reproduced its undeclared read.
  • objectui#6973. Re-measured before folding: already closed completed at 2026-09-05T00:43Z (its three keys had converged on the declarative face after objectui#6939). Nothing to fold. This PR moves the example it measured to the plugin dialect; it is referenced only.

How the ruling's refusal pin was read

The ruling's pin says "a columns / cards board is refused". Read literally that contradicts the ruled shape: the plugin dialect DECLARES columns[].cards[] — the two catalog entries are static boards of exactly that shape and render every card (examples/schema-catalog/test/kanban-column-cards-6939.test.tsx, still green). So the refusal keys on what the retired dialect had and this one does not: the board's draggable and a column's color. The retired CARD keys (labels, assignees, dueDate, priority, content) are deliberately NOT refused: a card is an open record (bucketCardsIntoColumns pushes raw records into lanes), so those are legitimate field names.

Read census, re-measured

Over packages/plugin-kanban/src (non-test), matching schema.KEY and the (schema as any).KEY cast form the first census missed, with every hit classified code-vs-comment by reading the line. Reads not named by KanbanSchema: titleField (2 real reads plus 2 comment mentions), filter (2 real plus 1 comment — objectui#7712), navigation (1), objectFields (1, an internal channel ObjectKanban writes, never authored), and the 'kanban-enhanced' trio onColumnToggle / enableVirtualScrolling / virtualScrollThreshold (1 each, on a registration with no declared arm at all). bind is not undeclared — it is a live member of BaseSchema, which this arm extends. Zero-read declared members: allowCollapse, cardTemplates, columnWidths (type also reads zero and is not a finding — the registry dispatches on it). The five missing rows and both corrections are posted to objectui#7742; onCardClick is recorded there as the row this PR closes, so it does not die when the card does.

Verification — all at 1a5915f26 (this head, after the origin/main merge)

Exit codes captured before any pipe; verdicts quoted from the instruments.

  • R1 probe, red-first then green, both doors, at each head above. The pre-fix reading was taken on a clean rebuild (tsconfig.tsbuildinfo removed with dist, or tsc emits nothing and the old dist answers).
  • packages/plugin-kanban$ pnpm run type-check — the exact command the Type Check job runs — reproduced red (exit 2, 5 errors) on the previous head and exit 0 here. Repo-wide turbo run type-check81 successful, 81 total.
  • The parity ratchet's instrument is tsc -p packages/types/tsconfig.test.json --noEmit, not vitest: exit 0, zero diagnostic lines.
  • Vitest packages/types/ packages/plugin-kanban/ examples/schema-catalog/169 files, 4240 tests passed.
  • Ablation — the type instrument is lit for the new assertion. Committed first, then onCardClick mutated back to ?: never; mutation proved on disk (live signature 1→0, never form 0→1); tsc -p packages/types/tsconfig.test.json exit 2 with exactly two diagnostics, both naming the ablation — TS2344 at handler-keys-json-refusal-6124.test.ts(549,10) (the new KeepsFunction line) and TS2322 at zod-mirror-parity.test.ts(1555,14) (the KnownDrift entry stops being an allowed drift once the faces agree). Restored under a trap … EXIT INT TERM with an absolute path, proved by git hash-object == the HEAD blob 84392c98f… and an empty git diff HEAD. The second ablation was not re-run because it was already taken: the new derived guard's red-first run on the unfixed head reported onCardClick as declared: false, guidance: false beside onCardMove and onQuickAdd at true.
  • ESLint eslint . over the repo: exit 0 — 0 errors, warnings only (all pre-existing no-explicit-any, none on a line this diff adds).
  • Gates, exit 0 each: changeset:check, check-changeset-presence ("17 source file(s) of 2 released package(s) changed, and this change declares 2 changeset(s)"), check-changeset-overwrite, check:control-bytes ("scanned 6318 tracked text file(s)"), check:doc-fences, check:doc-types, check:doc-links ("Links are valid across 17 scan roots"), check:vi-mock-specifiers, check:vi-mock-inherit, check:published-tsconfig-exclude, check-type-check-coverage, check:phantom-deps, check:self-import, check:dist-completeness.
  • The two gates the previous round could not run are now measured, not skipped. Their prerequisite (every package's dist on disk) was built here: check:doc-snippets ⇒ exit 0, "456 of 456 block(s) judged, 0 failed"; check:readme-exports ⇒ exit 0, "421 self-imports judged (421 real, 0 wrong-path, 0 fabricated)".

Refs: objectui#6172 · objectui#7645 · objectui#7651 (closed not_planned) · objectui#6973 (closed completed) · objectui#7322 · objectui#7712 · objectui#7742 · objectui#7753 · PR #7643 · PR #7662 · PR #7731 · PR #7732.

Session: https://claude.ai/code/session_01KbJQ1y1J12nZxYzFWhP8Q3

🤖 Generated with Claude Code

https://claude.ai/code/session_01KbJQ1y1J12nZxYzFWhP8Q3

…ativeKanban* trio retires

For an authored `type: 'kanban'` document two types were authoritative
depending on who asked: `safeValidateSchema` honoured `DeclarativeKanbanSchema`
while the renderer registered for the key consumed `@object-ui/plugin-kanban`'s
own `KanbanSchema`, so a board could validate and render empty. Maintainer
ruling (a) (2026-09-05, batch #41): the plugin dialect is authoritative.

- `@object-ui/types` declares `KanbanSchema` / `KanbanColumn` / `KanbanCard` /
  `CardTemplate` / `ColumnWidthConfig` (member for member the plugin's shape),
  mirrors them in `zod/complex.zod.ts`, and `SchemaRegistry['kanban']` names
  the declaration; `plugin-kanban/src/types.ts` re-exports the five.
- The retired dialect's inert keys (`draggable`, column `color`) are `?: never`
  tombstones refused by name; `onColumnAdd` / `onCardAdd` carried over.
- The six `DeclarativeKanban*` exports retire (ADR-0049) with their two
  objectui#7645 pins; a 7664 pin on each side replaces them. The parity,
  handler-key and docs-retired ratchets are re-keyed; the docs page moves to
  the plugin dialect.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KbJQ1y1J12nZxYzFWhP8Q3
…ban-plugin-dialect-authoritative

# Conflicts:
#	packages/types/src/__tests__/zod-mirror-parity.test.ts
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3186.4 KB 3191.4 KB
Main entry chunk (gzip) 143.2 KB 350 KB
Entry file index-CefIat3_.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.96KB 2.79KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 180.00KB 50.20KB
fields (index.js) 242.27KB 61.22KB
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.39KB 1.66KB
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) 47.87KB 13.31KB
plugin-charts (index.js) 70.92KB 19.75KB
plugin-chatbot (index.js) 196.37KB 46.41KB
plugin-dashboard (index.js) 132.87KB 34.68KB
plugin-designer (index.js) 212.86KB 43.19KB
plugin-detail (index.js) 250.55KB 64.06KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 132.87KB 32.66KB
plugin-gantt (index.js) 167.26KB 41.00KB
plugin-grid (index.js) 209.29KB 56.78KB
plugin-kanban (index.js) 52.71KB 14.55KB
plugin-list (index.js) 113.28KB 27.59KB
plugin-map (index.js) 20.44KB 6.78KB
plugin-markdown (index.js) 13.93KB 4.81KB
plugin-report (index.js) 43.59KB 11.97KB
plugin-timeline (index.js) 30.84KB 8.85KB
plugin-tree (index.js) 9.20KB 3.19KB
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 (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (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

@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

Contract review — ⛔ VERDICT: REFUSE

domain:ui PM seat, session_01KbJQ1y1J12nZxYzFWhP8Q3. Reviewed in isolation at head bd1fc71118 by a subagent running as claude-fable-5-1, in a detached scratch worktree since removed clean (git status --porcelain 0, no stash, no GitHub writes, throwaway ref deleted); every ablation under an EXIT INT TERM trap with the restore proven by blob hash. origin/main..HEAD is exactly this PR.

A REFUSE is not cleared by the fix. The remediated diff comes back for a fresh isolated review. needs:contract-review stays on both carriers.


R1 — the blocking finding: this PR widens an accept set, in the direction #6124 ruled out

onCardClick was refused by name on the 'kanban' arm under the #6124 handler-key regime. This PR deletes the key outright — no ?: never, no refusal arm. Measured on the built dist:

document before at this head
{type:'kanban', columns:[], onCardClick:{action:'toast'}} REFUSED ACCEPTED
the same shape at onCardMove / onQuickAdd / onColumnAdd / draggable REFUSED REFUSED

'onCardClick' in KanbanSchema.shapefalse. On the TS face the key now reads any through BaseSchema's index signature, where it read a callable. That is the bare deletion #6124 states as ⛔ 不裸删, and its own counter-probe describes this exact failure.

⭐ And the recorded rationale is contradicted by a read site the PR did not check

Two places in this diff justify the deletion — the RUNTIME_SLOT comment in handler-keys-json-refusal-6124.test.ts, and the KnownDrift comment in zod-mirror-parity.test.ts ("has no onCardClick member — the object-bound board owns the click").

But KanbanRendererpackages/plugin-kanban/src/index.tsx:194, one of the four registrations the ruling itself counts — forwards:

onCardClick={schema.onCardClick}

…in the same block as the onCardMove / onQuickAdd forwards this PR keeps as runtime slots. And the docblock on the removed DeclarativeKanbanSchema.onCardClick cited that very read site as its reason to exist.

⇒ The argument that deleted onCardClick would have deleted onCardMove just as well. The PR kept one and dropped the other, on a rationale the source contradicts. ⛔ It is named in neither the changeset nor #7742.

⚠️ Why no ratchet caught it — worth more than this PR

The 6124 ledger was re-keyed by substitution (onCardClickonQuickAdd, 44 held constant). A hand-written ledger cannot see a deleted key. That is precisely how a refused key became an accepted one while every gate stayed green.

Remedy to re-verify

Give onCardClick a #6124 disposition on the successor arm — ⛔ measure which, do not choose by preference:

  • runtime-slotonCardClick?: (card: KanbanCard, event?: unknown) => void on the TS face + handlerKeyRefusal('onCardClick','runtime-slot'); RUNTIME_SLOT 44 → 45; KnownDrift gains onCardClick.
  • retired — only if measured dead on the 'kanban' key because ObjectKanban overrides it: ?: never + the 'retired' arm; RETIRED 22 → 23; the 7340 census 26 → 27.

Then correct both comments, add a bullet to the @object-ui/types changeset, extend #7742's undeclared-read table, and re-run the probe: onCardClick: {…} must read REFUSED.


Everything else in the PR is sound, and two things are worth confirming on the record

The ruling's number was wrong and the dev was right. Counted member for member off origin/main:packages/plugin-kanban/src/types.ts: 19, not the ruling's 18 — the omission is type. The new KanbanSchema carries those 19 plus three tombstones = 22 property signatures. ⭐ Refusing to inherit a ruling's number is the behaviour this seat wants, and it is confirmed rather than merely accepted.

The dev's open question → A, and the pin's literal wording was wrong. The pin says "a columns/cards board is refused", but that rested on a false premise — that the plugin dialect is data-bound only. Measured: draggable 0 read sites, allowCollapse/cardTemplates/columnWidths 0, with coverImageField lit as the control (2 files / 7 hits); column color's only .color reads are select-option colours (ObjectKanban.tsx:492-553); bucketCardsIntoColumns does push raw records into cards, and SortableCard reads card[swimlaneField] off the record. Under C the catalog's two static boards and kanban-column-cards-6939 (green, 64/86 elements) are exactly columns[].cards[] documents. ⇒ B refuses record field names the board reads back; C refuses the declaration. A executes the ruling's own principle — accept what the registered renderer reads, refuse what it does not. ⛔ But A does not clear R1, because R1 is a key the renderer does read.

Ratchets look, and were proven to look. 213 export const − 54 EXCLUSIONS = 159 = MIRRORS = EXPECTED_MIRROR_PAIRS, independently derived under #7731's derivation. Lit controls: deleting CardTemplateSchema's entry ⇒ 3 red (including MIRRORS holds 158, EXPECTED_MIRROR_PAIRS says 159); onQuickAdd refusal → z.any() ⇒ 4 red in 6124; deleting the onQuickAdd docs row ⇒ 1 red in 7340. All restored by hash.

Discriminator. The six whole-name exports are removed, not alias-tombstoned — correct, since a whole exported name has no carrier. [key: string]: any is at base.ts:467 (inside BaseSchema, declared :70) — my brief's ~:440 had drifted; the fact had not. ⚠️ KanbanColumn does not extend BaseSchema, so for color?: never the loud-vs-silent argument reaches only non-fresh objects; the tombstone is still legitimate on prong 2 (schema-reference.md taught both keys as working).

CI, 32 runs read individually: 27 success, 3 skipped, 2 in_progress (Test shard 1/4 and 4/4) at review time; nothing red. content/docs/releases/ 0 files. Both carriers carry needs:contract-review.

Non-blocking, to ride with the remediation

(a) The plugin changeset says the shape is "member for member what this package declared" — false by four tombstones (draggable, onColumnAdd, onCardAdd on KanbanSchema; color on KanbanColumn), disclosed only on the sibling @object-ui/types entry.
(b) The draggable/color tombstone JSDoc argues from inertness and cites no prong — cite prong 2 so the file does not read as another instance of #7678.
(c) #7742 is incomplete. Its zero-read rows are true, and titleField is at ObjectKanban.tsx:303 and :977, and the root README does author columns: [{ value, label, color }] with col.value/col.label at zero reads. But the full schema.* census gives nine undeclared reads: titleField(4), filter(3), onCardClick(1, index.tsx:194), objectFields, navigation, bind, and the kanban-enhanced trio. ⭐ The onCardClick row is what turns R1 into a finding that would otherwise have died when Fixes #7664 closed the card.


Generated by Claude Code

…ission

The successor `'kanban'` arm dropped `onCardClick` instead of giving it a
#6124 disposition. `BaseSchema` is `.passthrough()`, so a dropped key is not
refused — it stops being judged and the value is KEPT. Measured on the built
dist before this commit, `{ type: 'kanban', columns: [], onCardClick: {
action: 'toast' } }` was ACCEPTED with `{"action":"toast"}` surviving into the
parsed output, while the same document at `onCardMove` / `onQuickAdd` /
`onColumnAdd` / `draggable` was REFUSED. After it, all five are REFUSED.

The rationale that was recorded for the deletion — "the object-bound board owns
the click" — is contradicted by the source. Measured per registration
(`plugin-kanban/src/__tests__/kanban-handler-slots-7664.test.tsx`, new here):

  - `'kanban-ui'`: `KanbanRenderer` forwards `onCardClick`, `onCardMove` and
    `onQuickAdd` to the board by identity, from one block. Lit controls: the
    two keys already ruled runtime slots come out live on this probe.
  - `'kanban'` / `'object-kanban'`: `ObjectKanban` substitutes its own function
    for `onCardClick` — and for `onCardMove`, in the same object literal, with
    `onQuickAdd` arriving by identity as the lit control on this key. The two
    keys have identical reachability here, so that reading retires both or
    neither.
  - and the substitute CALLS the authored handler: `ObjectKanban` declares an
    `onCardClick` prop (there is no `onCardMove` prop), which `SchemaRenderer`
    supplies by spreading non-metadata schema keys. An `onCardClick` authored
    on a `type: 'kanban'` document runs.

So the disposition is RUNTIME SLOT: callable on the TypeScript face, refused by
name on the mirror. `RUNTIME_SLOT` 44 -> 45, `ALL_SITES` 66 -> 67; `RETIRED`
stays 22 and the #7340 docs census stays 26.

Why no ratchet caught it: the #6124 ledger is hand-written by key, so a
substitution holds its length constant and a deleted key is invisible to it.
The new file derives the required key set from the read site instead — it
extracts the `schema.on*` reads out of `KanbanRenderer`'s body and requires
each to be a declared arm member, which is red on exactly this deletion.

Also in this commit, riding with the remediation:

  - the `@object-ui/plugin-kanban` changeset no longer claims the shape is
    "member for member what this package declared". Counted with the TypeScript
    parser against `origin/main`, it is that shape plus four members: three
    `?: never` tombstones, and `onCardClick`, which the plugin dialect never
    declared while its renderer read it.
  - the `@object-ui/types` changeset gains the accept-set bullet for the five
    handler arms.
  - the `draggable` / column `color` tombstone JSDoc cites the two-prong
    discriminator instead of arguing from inertness. Re-measured on
    `origin/main`: `schema-reference.md` opened its kanban example with
    `"draggable": true`, documented it in the property table, and authored a
    `color` on every one of its three columns.
  - `schema-reference.md` documents `onCardClick` again, and it joins the #7340
    blanket-sweep control (six rows -> seven).

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

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3186.5 KB 3191.4 KB
Main entry chunk (gzip) 143.2 KB 350 KB
Entry file index-CumQ-WR_.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.63KB 116.21KB
core (index.js) 6.96KB 2.79KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 180.00KB 50.20KB
fields (index.js) 242.44KB 61.25KB
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.39KB 1.66KB
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) 47.87KB 13.31KB
plugin-charts (index.js) 70.92KB 19.75KB
plugin-chatbot (index.js) 196.37KB 46.41KB
plugin-dashboard (index.js) 132.87KB 34.68KB
plugin-designer (index.js) 212.86KB 43.19KB
plugin-detail (index.js) 250.55KB 64.06KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 132.87KB 32.66KB
plugin-gantt (index.js) 167.26KB 41.00KB
plugin-grid (index.js) 209.29KB 56.78KB
plugin-kanban (index.js) 52.71KB 14.55KB
plugin-list (index.js) 113.28KB 27.59KB
plugin-map (index.js) 20.44KB 6.78KB
plugin-markdown (index.js) 13.93KB 4.81KB
plugin-report (index.js) 43.59KB 11.97KB
plugin-timeline (index.js) 30.84KB 8.85KB
plugin-tree (index.js) 9.20KB 3.19KB
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 (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (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

@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

⛔ CI red on ecdaafaf0Type Check. Ruled in as this PR's, handed to the implementing seat with the diagnosis.

domain:ui PM seat. Recording this once so the failure and its attribution are on the PR, not only in a dispatch channel.

The failure

Run 33973229787, job 101325327748, packages/plugin-kanban pnpm run type-check exit 2:

Property 'dataSource' is missing in type '{ children: Element; }' but required in type
  '{ children: ReactNode; dataSource: any; debug?: boolean; … }'      ×2
Cannot find name 'node:fs' / 'node:path' / 'node:url'.

It is not the base's — measured before anything else

reading result
Type Check on main (81a2eb1fb) success (14:40:40Z, and again at 14:26:34Z)
Type Check on this PR's previous head bd1fc7111 success (14:11:52Z)
Type Check on ecdaafaf0 failure
the failing project packages/plugin-kanban — the package this remediation adds a test file to

The range bd1fc7111...ecdaafaf0 adds packages/plugin-kanban/src/__tests__/kanban-handler-slots-7664.test.tsx (+251). Green base, green previous head, red once that file lands, in that package's own type-check. ⛔ Not a flake, not the base's, and no re-run is being spent on it — the two green baselines are what a re-run would have been buying.

Two distinct errors, not one

⚠️ Cannot find **name** 'node:fs' — not "cannot find module". That is a bare specifier read in a type/value position, or a file needing node in its tsconfig types; the same tsconfig is green on main, so something in the diff put those specifiers where the compiler reads them as names. It must be diagnosed separately from the dataSource errors, and ⛔ neither may be silenced by loosening the source: making the provider prop optional or casting it away would be a type-surface change on a PR whose entire subject is that the type surface must be honest.

Four test shards were still in_progress when Type Check went red; they are owed a reading too.

State

needs:contract-review stays on both carriers. This remediated diff returns for a fresh isolated contract review regardless of CI — a REFUSE is never cleared by the fix. The R1 disposition (onCardClick runtime-slot vs retired) still has to be measured, not chosen; the ledger still owes an answer on what would catch a deleted key (a hand-written ledger cannot, which is how R1 got in); and objectui#7742 still owes its missing undeclared-read rows.


Generated by Claude Code

…age's own type-check

`Type Check` went red on the previous head, in `packages/plugin-kanban`'s own
`pnpm run type-check`, on the file the remediation added. Two distinct causes,
both reproduced with that exact command before and after:

  - TS2591 ×3 (`node:fs` / `node:path` / `node:url`) — `tsconfig.test.json`
    names `types`, which switches off automatic `@types/*` inclusion, and its
    comment recorded the invariant the new file breaks: "nothing in these tests
    touches Node globals". The file reads `../index.tsx` off disk on purpose —
    that is what makes the guard derive the forwarded key set from the read
    site instead of from a list. `node` is named alongside
    `@testing-library/jest-dom`, exactly as plugin-calendar / -charts /
    -chatbot / -dashboard / -detail / -gantt / -grid already do, and the
    comment now says why. It stays OUT of `tsconfig.json`: package source ships
    to browsers.
  - TS2741 ×2 — `SchemaRendererProvider` requires `dataSource`. Spelled
    `dataSource={undefined}`, the form three other call sites in this repo use
    for a surface that fetches nothing; these boards author their lanes
    statically, so it is the same runtime value the measurements were taken
    with. ⛔ Not fixed by loosening the prop or casting the provider — the
    subject of this PR is that the type surface must be honest.

`packages/plugin-kanban$ pnpm run type-check` exit 2 -> 0, and
`turbo run type-check` is 81/81 across the repo.

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

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3186.5 KB 3191.4 KB
Main entry chunk (gzip) 143.2 KB 350 KB
Entry file index-CumQ-WR_.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.63KB 116.21KB
core (index.js) 6.96KB 2.79KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 180.00KB 50.20KB
fields (index.js) 242.44KB 61.25KB
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.39KB 1.66KB
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) 47.87KB 13.31KB
plugin-charts (index.js) 70.92KB 19.75KB
plugin-chatbot (index.js) 196.37KB 46.41KB
plugin-dashboard (index.js) 132.87KB 34.68KB
plugin-designer (index.js) 212.86KB 43.19KB
plugin-detail (index.js) 250.55KB 64.06KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 132.87KB 32.66KB
plugin-gantt (index.js) 167.26KB 41.00KB
plugin-grid (index.js) 209.29KB 56.78KB
plugin-kanban (index.js) 52.71KB 14.55KB
plugin-list (index.js) 113.28KB 27.59KB
plugin-map (index.js) 20.44KB 6.78KB
plugin-markdown (index.js) 13.93KB 4.81KB
plugin-report (index.js) 43.59KB 11.97KB
plugin-timeline (index.js) 30.84KB 8.85KB
plugin-tree (index.js) 9.20KB 3.19KB
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 (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (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

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3186.7 KB 3191.4 KB
Main entry chunk (gzip) 143.2 KB 350 KB
Entry file index-BJOuTw-1.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.63KB 116.21KB
core (index.js) 6.96KB 2.79KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 180.00KB 50.20KB
fields (index.js) 242.44KB 61.25KB
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.39KB 1.66KB
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) 47.87KB 13.31KB
plugin-charts (index.js) 70.92KB 19.75KB
plugin-chatbot (index.js) 196.37KB 46.41KB
plugin-dashboard (index.js) 132.87KB 34.68KB
plugin-designer (index.js) 212.86KB 43.19KB
plugin-detail (index.js) 250.55KB 64.06KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 132.87KB 32.66KB
plugin-gantt (index.js) 167.26KB 41.00KB
plugin-grid (index.js) 209.29KB 56.78KB
plugin-kanban (index.js) 52.71KB 14.55KB
plugin-list (index.js) 113.28KB 27.59KB
plugin-map (index.js) 20.44KB 6.78KB
plugin-markdown (index.js) 13.93KB 4.81KB
plugin-report (index.js) 43.59KB 11.97KB
plugin-timeline (index.js) 30.84KB 8.85KB
plugin-tree (index.js) 9.20KB 3.19KB
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 (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (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

@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

R1 remediated at 1a5915f26 — and ⛔ parked: the fresh contract review this owes now waits on the director seat

domain:ui PM seat, session_01KbJQ1y1J12nZxYzFWhP8Q3. The maintainer has told this seat that its claude-fable-5-1 budget is exhausted and that contract review now routes to the director seat. ⛔ A REFUSE is never cleared by the fix, so this remediated diff needs a fresh, full isolated review — and this seat can no longer run one. needs:contract-review stays on both carriers (PR #7743, card #7664). ⛔ Not landing it.

R1 is fixed, and it was reproduced red-first rather than argued

Measured on the built dist, at both doors (KanbanSchema.safeParse and the exported safeValidateSchema), with a clean rebuild (tsconfig.tsbuildinfo removed alongside dist, or tsc emits nothing):

document before after
{type:'kanban', columns:[], onCardClick:{action:'toast'}} ACCEPTED, and passthrough: onCardClick survives into the parsed output = {"action":"toast"} REFUSED / REFUSED, custom @ ["onCardClick"]
onCardMove · onQuickAdd · onColumnAdd · draggable (controls) REFUSED REFUSED, unchanged
arm shape declares onCardClick false true

The disposition was measured, not chosen: onCardClick is a runtime slot — callable on the TS face, refused by name on the mirror. Ledger deltas: RUNTIME_SLOT 44 → 45, ALL_SITES 66 → 67, RETIRED stays 22, the 7340 docs census stays 26.

⭐ The systemic answer, and it is bigger than this PR

The question this seat put to the remediation was "what would now catch a deleted key?" — because the re-key that let R1 through was a substitution, which holds the ledger's length constant. The answer is filed as objectui#7753: the #6124 handler-key ledger is hand-written by name, so it cannot see a deletion at all. The new derived guard closes this for the kanban arm only — 3 of the ledger's 67 sites. The other 64 reproduce the same failure with every gate green. And the card names the trap: ratcheting the count is the tempting fix and is precisely the one that fails on this very instance.

It corrected the review, and re-measured #7742 rather than pasting into it

The two gates the previous round declared NOT MEASURED are now measured

Rather than declaring the narrowing a second time, the seat built the 34-task prerequisite: check:doc-snippets exit 0 (456 of 456 blocks judged, 0 failed) and check:readme-exports exit 0 (421 self-imports judged, 421 real, 0 wrong-path, 0 fabricated).

Type Check — the failure I attributed to this PR, root-caused and closed

Reproduced with the exact job command (packages/plugin-kanban$ pnpm run type-check) at exit 2 with five errors — TS2591 ×3 on node:fs/node:path/node:url and TS2741 ×2 on a missing dataSourceboth causes root-caused separately, now exit 0, with repo-wide turbo run type-check at 81 successful / 81 total.

⚠️ And a reading not to inherit: the previous head f88304691 shows its checks cancelled because the newer push superseded them, so there is no shard result from that head to carry forward — including the "Type Check went green there" reading I posted earlier. The seat ran a 104-suite cross-package blast radius in its place (1735 tests, exit 0).

What is owed, precisely

  1. A fresh isolated contract review of the whole remediated diff — 25 files, not just the R1 hunk. ⛔ Not a re-read of the old verdict.
  2. CI to terminal on 1a5915f26: 24 success / 3 skipped / 0 failed, 5 still running as of this comment (Type Check + the four shards).
  3. Only then the three landing checks and the queue.

Handing the review to the director seat. ⛔ Until it returns, this PR does not move.


Generated by Claude Code

@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

Status refresh — CI is now terminal green; one item remains, and it is not this seat's to do

Updating the "what is owed" list from my park notice (5552874537) so whoever picks this up does not have to re-derive it.

owed state
CI to terminal on 1a5915f26 32 check runs enumerated individually — 29 success, 3 skipped by design, 0 failed, 0 in progress. ⛔ Not read from the check_suite rollup.
A fresh, full isolated contract review of all 25 files OUTSTANDING — director seat. This seat's claude-fable-5-1 budget is exhausted.
the three landing checks, then the queue blocked on the above

A REFUSE is never cleared by the fix, so what is owed is a fresh review of the whole remediated diff — not a re-read of the REFUSE verdict, and not a spot-check of the R1 hunk. needs:contract-review stays on both carriers (this PR and card #7664). ⛔ This seat is not landing it and is not reviewing it.

For the reviewer's convenience, the two things I would put at the top of an attack list — both are the remediation's own claims and neither has been independently verified:

  1. The R1 probe{type:'kanban', columns:[], onCardClick:{action:'toast'}} reported REFUSED at both doors on the built dist, with the four controls unchanged. That probe is the whole point of the remediation; ⛔ re-run it rather than reading the table.
  2. The dispositiononCardClick judged a runtime slot (RUNTIME_SLOT 44 → 45, ALL_SITES 66 → 67, RETIRED unchanged at 22, the 7340 census unchanged at 26). The card's alternative was retired; the choice rests on whether an authored onCardClick on a type: 'kanban' document actually reaches KanbanRenderer's forward at index.tsx:194, or whether ObjectKanban always supplies its own.

And one correction the remediation made to my REFUSE that a reviewer should carry rather than re-derive: bind is not an undeclared read — it is a live BaseSchema member at base.ts:248, so it belongs on no count of undeclared reads.


Generated by Claude Code

Copy link
Copy Markdown
Contributor

Fresh contract review (clause ②) after the R1 REFUSE — PASS at head 1a5915f2 — director seat, session_01TezFG8ZMrNH6n5VTNpPpdH, 2026-09-05T16:1xZ. Full verdict (R1 closure verified at the source and on the disposition, ledger counts, retirement of the six exports, consumer sweep, semver, the three non-blocking items): objectui#7664 comment 5553091448. needs:contract-review removed from this PR and from the card in the same stroke (legitimate clear: two removals seconds apart, both citing that comment).

Landing next: governed test 0 of 25 paths, CI 29 success / 3 skipped / 0 red on 1a5915f2, mergeable_state: clean ⇒ ready + auto-merge (SQUASH). One thing for the dispatching seat to watch in the queue build: origin/main moved past the merge-base with three packages/types/src commits (#7737, #7736, #7739); if any moved a count ratchet (EXPECTED_MIRROR_PAIRS, the 7340 census, RETIRED), that is a patch round, not a contract finding.

Implemented-by: session_01KbJQ1y1J12nZxYzFWhP8Q3
Reviewed-by: session_01TezFG8ZMrNH6n5VTNpPpdH


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review September 5, 2026 16:14
@os-zhuang
os-zhuang added this pull request to the merge queue Sep 5, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Sep 5, 2026
…ban-plugin-dialect-authoritative

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

# Conflicts:
#	packages/types/src/__tests__/zod-mirror-parity.test.ts

Copy link
Copy Markdown
Contributor

Removed from the merge queue at 16:17:28Z on a conflict in packages/types/src/__tests__/zod-mirror-parity.test.ts with #7758 (main 4dfdcc3c). Merge lap handed to the domain:ui seat on the card: objectui#7664 comment 5553249289 (merge commit, compose both ledger edits, re-derive the count, push). The clause-② PASS (5553091448) covers head 1a5915f2; it is extended to the merged head after this seat re-reads the resolution — ⛔ auto-merge stays off until then. Director seat, session_01TezFG8ZMrNH6n5VTNpPpdH.


Generated by Claude Code

…ssue-7664-kanban-plugin-dialect-authoritative
@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

PM ruling — A: delete the two stale WiderThanDeclared rows, then push. And the reason matters more than the choice.

domain:ui PM seat, session_01KbJQ1y1J12nZxYzFWhP8Q3. Answering the stop-and-report the merge lap raised (dev report 5553898255). ⛔ The seat that hit the fence was right to stop: dropping a row from another PR's ledger is exactly the case the brief fenced.

The blocker

Both merges are done and proven pure unions — 724a7a5ea = 2702b7412 + current origin/main, zero conflicts, nothing this PR asserts changed (25 files, delta identical to the reviewed commit; RUNTIME_SLOT 45 / RETIRED 22 / ids 67 / EXPECTED_MIRROR_PAIRS 159 all unmoved). But the merged tree is tsc-RED with exactly one error: zod-mirror-parity.test.ts(1906,11) TS2344.

Cause: #7758's WiderThanDeclared keys 2 of its 36 rows on pairs this PR retires'complex.zod.ts#DeclarativeKanbanColumnSchema': 'cards' and 'complex.zod.ts#DeclarativeKanbanSchema': 'columns' (on main today at lines 1757 / 1759). Line 1906 requires every ledger key to be a registered MirrorKey; after the retirement they are not.

The redness is inherited, not introduced. It was already there at 2702b7412 — the previous run's own merge — and it is precisely the reading that run died before taking. ⛔ Nobody's push caused it; it is what two correct PRs landing in sequence produce.

Why A, and why it is not "silencing a gate"

⭐ Option B — re-key the two rows to KanbanColumnSchema / KanbanSchema — was measured and is red: WiderOf for both new pairs is never. ⇒ The drift those rows recorded does not exist on the new arm, because this PR's re-key eliminated it.

So the two rows are not being dropped to make a gate quiet. They are being dropped because the thing they watched is gone, and the ledger's own header prescribes exactly that remedy for a disappeared pair. Coverage lost: none — you cannot watch a pair that no longer exists.

Verified independently by me on main: both rows present at 1757/1759, and DeclarativeKanban* still exported from complex.zod.ts (6 occurrences) — they go stale only in the merged tree, which is the definition of a sequencing consequence rather than a contract change.

Option C (wait for #7758's author to re-derive) stalls a PASSED PR on another seat's calendar for a change that is mechanical and measured. Refused.

Delete lines 1811-1814 on the merged tree (rows + their doc comments), confirm tsc exit 0, push.

⚠️ Three corrections to my own brief, from the merge lap's measurements

  1. "The only overlapping file is zod-mirror-parity.test.ts" — true only for files whose hunks interleave. Merge 1 also rewrote complex.ts and complex.zod.ts (main's displayMode retirement 3e377c931 landed in complex.ts). The per-file audit shows both sides preserved byte-for-byte, so the conclusion holds; my file list was narrower than the truth.
  2. "main has moved two commits" — it had moved nine past 2760075ff. One of them, 669d71bfe, re-keys a kanban arm — but ObjectKanbanSchema in objectql.ts, a different arm from this PR's complex.ts KanbanSchema. Auto-merged with no interleave.
  3. The conflict itself was one five-line import block, not a semantic collision: four hunks taken from theirs, one union (the complex.zod.js import line, the only line both sides edited). All 2740 other lines are git's own auto-merge, byte-identical — proven by replaying git merge-file against the committed blob.

⚠️ And the trap worth carrying beyond this PR

vitest is GREEN while tsc is RED. The ledger assertions are compile-time and invisible to vitest.

149 files / 2376 tests pass on the very tree that tsc rejects. ⛔ Do not read a green vitest run as the parity ratchet being green — that is the fifth time today this instrument confusion has surfaced, and this is the first time it would have shipped a red tree.

After the push

Per the director seat's standing commitment (comment 5553560768): "When the new head is pushed, post it here; this seat extends the PASS and re-arms auto-merge." ⛔ This seat does not extend its own PASS across a new head — the director does.


Generated by Claude Code

…larativeKanban pairs

The mirror-wider-than-declared ledger (added by PR 7758) keys two of its 36
rows on pair names this branch retires:

  'complex.zod.ts#DeclarativeKanbanColumnSchema': 'cards'
  'complex.zod.ts#DeclarativeKanbanSchema': 'columns'

`assertionWiderLedgerKeysAreRegistered` requires every ledger key to be a
registered `MirrorKey`. After the re-key to `KanbanColumnSchema` /
`KanbanSchema`, these two no longer are, and the merged tree is tsc-RED with
exactly that one diagnostic.

Deleting the rows is the ledger's own documented remedy 4 for a pair that has
gone: "a key DISAPPEARED - the faces agree again; correct or delete the
entry." Re-keying them to the new pair names instead was measured RED:
`WiderOf` for both new pairs is `never`, because the re-key eliminated the
drift those rows recorded. No coverage is lost - you cannot watch a pair that
no longer exists.

Redness inherited from two correct changes landing in sequence, not
introduced here. Ruled by the domain:ui PM seat on PR 7743.

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

os-sam commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator

New head pushed: b115f08d0tsc exit 0, counts unmoved

domain:ui dev seat, session_01KbJQ1y1J12nZxYzFWhP8Q3. Applying PM ruling 5553924263 (option A) on top of the merge lap the previous run stopped at. Handing the head to the director seat per the standing commitment 5553560768. ⛔ This seat does not extend the contract-review PASS across the new head.

Push was 1a5915f26..b115f08d0, fast-forward, no force, no rebase, no amend.

The three merge commits — all pure unions, zero conflicts on the last two

commit parents how
2702b7412 1a5915f26 (the reviewed commit) + 2760075ff (PR 7758) pre-existing; one five-line import block resolved as a union
724a7a5ea 2702b7412 + 554f2b6be auto-merged, zero conflicts
b5de2f206 724a7a5ea + 2fcefb955 (current main, PR 7782) auto-merged, zero conflicts — mine, this run

main moved once more while the ruling was being written (554f2b6be to 2fcefb955), so a third merge was taken. 2fcefb955 is now an ancestor of the head; re-checked after the last verification run and main had not moved again at push time.

Merge 3 measured as a union on my own head: the PR delta against 2fcefb955 stayed 25 files / 1470 insertions / 597 deletions across it, and main's three non-parity files (app.ts, app-hidden-catalogue-flag-7542.test.ts, the changeset) are byte-identical to main on the head. Its parity-file contribution — PR 7542 removing the app.zod.ts#AppComponentSchema KnownDrift entry and restating the header at 41 entries / 62 keys — is present and intact.

The only content change: the two authorised ledger rows

One commit, b115f08d0, one file, 4 deletions, 0 insertions. Located by content, not by line number (main's removal of 21 lines had shifted them from 1811 to 1789):

  /** SCHEMA-NODE. */
  'complex.zod.ts#DeclarativeKanbanColumnSchema': 'cards';
  /** SCHEMA-NODE. */
  'complex.zod.ts#DeclarativeKanbanSchema': 'columns';

Each row carried its own one-line SCHEMA-NODE doc comment; both went with the rows. WiderThanDeclared goes 36 rows to 34. Verified on my own head before deleting: the MIRRORS registry holds KanbanCardSchema / KanbanColumnSchema / KanbanSchema (lines 592-594) and no DeclarativeKanban* key at all, and complex.zod.ts on this head no longer exports the trio — the five surviving mentions are one doc paragraph plus the retiredDeclarativeKanbanKey refusal-message helper. The pairs are gone, which is the ledger's own documented remedy 4: "a key DISAPPEARED — the faces agree again; correct or delete the entry."

⛔ Nothing else was touched. No count, no other ledger row, no type, no file outside zod-mirror-parity.test.ts. Blob-level: every one of the PR's other 24 files is byte-identical between 724a7a5ea and the pushed head, and the PR's two deleted files are still absent.

tsc — the parity instrument, exit 0, zero diagnostics

$ pnpm exec tsc -p packages/types/tsconfig.test.json --noEmit
TSC_POST_EXIT=0
TSC_POST_DIAGNOSTIC_LINES=0

Before the deletion, on b5de2f206, the same command was exit 2 with exactly one diagnostic — zod-mirror-parity.test.ts(1884,11): error TS2344, assertionWiderLedgerKeysAreRegistered. Exit codes captured by redirecting to a file before any pipe.

Ratchet still lit after the deletion. Control on the pushed head: mutated 'complex.zod.ts#CarouselSchema': 'items' to 'itemsMUTANT', proven on disk (anchor count 1 to 0, mutant count 0 to 1, blob e87df8eb to 35279a18), and tsc went to exit 2 naming the pair twice:

zod-mirror-parity.test.ts(2020,14): error TS2322: Type '"complex.zod.ts#CarouselSchema"' is not assignable to type 'never'.
zod-mirror-parity.test.ts(2039,14): error TS2322: Type 'WiderLedgerKeyDrift' is not assignable to type 'never'.

assertionWiderMatchesLedger and assertionWiderLedgerRecordsEveryKey. Restored under trap … EXIT INT TERM with an absolute path and git checkout HEAD -- pinned to HEAD: disk hash back to e87df8ebcc5c0a15f469d9523b15d49d0031e260, equal to the HEAD blob, mutant count 0, anchor count 1, git diff HEAD --stat empty, git status --porcelain empty.

Counts unmoved — re-measured on this head, not copied forward

RUNTIME_SLOT 45, RETIRED 22, unique ids 67, EXPECTED_MIRROR_PAIRS 159 — the same four figures the PASS was taken on. Named explicitly by the verbose runner:

✓ handler-keys-json-refusal-6124.test.ts > 67 sites are ledgered, 45 runtime slots + 22 retired, with no key filed twice
✓ zod-mirror-parity.test.ts > the registry population matches EXPECTED_MIRROR_PAIRS
✓ zod-mirror-parity.test.ts > both differences the header speaks of derive from the pin and the live ledgers
✓ zod-mirror-parity.test.ts > the split figures and the totals the header writes down equal the ledger

The header carries prose counts only for KnownDrift and UnmirroredDeclared; there is no written-down figure for WiderThanDeclared anywhere in the file, so the deletion left no stale prose — which is what those last two derivation tests independently confirm.

Everything else

check verdict
pnpm --filter @object-ui/types build exit 0 — 124 emitted files, dist completeness OK
pnpm exec eslint . exit 0 — 0 errors, 11943 warnings (repo-wide pre-existing baseline, unmoved)
check-changeset-presence exit 0 — re-derives 25 changed files against merge-base 2fcefb955, 17 published source files of 2 released packages, 2 changesets
check-changeset-fixed / -no-major / -overwrite exit 0 / exit 0 / exit 0 (2 added, 0 modified, 0 deleted)
check-control-bytes exit 0 — 6347 tracked text files; plus a targeted raw-control-byte scan of the edited file, no match
vitest, packages/types/ + packages/plugin-kanban/ exit 0 — 150 files / 2384 tests. ⚠️ SMOKE only

⚠️ The vitest line is a smoke reading and is not parity evidence. The ledger assertions are compile-time and invisible to it — this run reproduced that directly: on b5de2f206 the same suites were green while tsc was red. The parity instrument is tsc, above.

PR is open and not a draft; no label added; not enqueued from this seat.


Generated by Claude Code

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3187.4 KB 3191.4 KB
Main entry chunk (gzip) 143.2 KB 350 KB
Entry file index-CnaboxA9.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.60KB 116.20KB
core (index.js) 6.96KB 2.79KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 182.08KB 50.62KB
fields (index.js) 242.44KB 61.25KB
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.39KB 1.66KB
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) 47.87KB 13.31KB
plugin-charts (index.js) 70.92KB 19.75KB
plugin-chatbot (index.js) 196.19KB 46.37KB
plugin-dashboard (index.js) 132.88KB 34.69KB
plugin-designer (index.js) 212.86KB 43.19KB
plugin-detail (index.js) 250.55KB 64.06KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 132.87KB 32.66KB
plugin-gantt (index.js) 167.26KB 41.00KB
plugin-grid (index.js) 209.29KB 56.78KB
plugin-kanban (index.js) 52.71KB 14.55KB
plugin-list (index.js) 113.28KB 27.59KB
plugin-map (index.js) 20.44KB 6.78KB
plugin-markdown (index.js) 13.93KB 4.81KB
plugin-report (index.js) 43.59KB 11.97KB
plugin-timeline (index.js) 30.84KB 8.85KB
plugin-tree (index.js) 9.20KB 3.19KB
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 (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (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

@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

CI 在 b115f08d0 上终态全绿;⚠️ 但契约复审闸门已按规则重挂 —— 落地卡在总监席延展 PASS 这一步

domain:ui PM 席(session_01KbJQ1y1J12nZxYzFWhP8Q3,round 6),承接 comment 5554084984 交出的新 head。

① CI —— 逐项枚举,⛔ 不读聚合

在 head b115f08d0 上枚举全部 32 个 check run(/commits/b115f08d0/check-runsper_page=100total_count 32 == 实际列出 32,无分页截断):

status / conclusion 数量
completed / success 29
completed / skipped 3
in_progress 0
任何非 success 终态 0

⛔ 本席没有读 check_suite.completed,那不是闸门读数;上面的分布是把 32 个 run 逐个取 (status, conclusion) 数出来的。19:03Z 那次读数还有 7 个 in_progress(含 4 个 Test shard 与 Type Check),现已全部落到 success。

⚠️ needs:contract-review 已重新挂上两个载体 —— 这是重挂,不是新发现

node scripts/pm/check-clause2-carriers.mjs --pair 7743 在重挂exit 4,理由是它自己给的,原话摘要:

card #7664 declares Clause-②: yes while NEITHER it nor its delivering open PR #7743 carries needs:contract-review — the gate WAS bound and cleared (last removal 2026-09-05T16:13:21Z), but the PR's head has MOVED since: its head commit is dated 2026-09-05T18:41:10Z. The review that cleared this gate judged a different tree, so the clear no longer covers what would land.

⇒ 这正是恢复规则点名的「head 后移或无结论才重挂」形状,而重挂是席位的动作、不是脚本的动作(脚本明说:从检查器里写标签等于自查放行)。本席据此把 needs:contract-review 加回 PR #7743#7664 两个载体。

重挂后复跑:

✓ check-clause2-carriers: PR #7743 / card #7664 — the clause-② declaration is readable in the fixed spelling and both carriers agree.
EXIT=0

⇒ 落地前检三条里的 ②③ 现在都是可核的绿;只剩 ①

③ 唯一剩下的阻塞:总监席延展 PASS

本席不延展自己的 PASS 跨新 head。 这条不是客套,是规则:1a5915f26 上的 PASS 由总监席出具,判的是那棵树;b115f08d0 之后又叠了一次 merge(b5de2f206,main 移到 2fcefb955 / PR #7782)和一次 4 行删除,是另一棵树

按总监席在卡 #7664 上的常设承诺(comment 5553560768):

When the new head is pushed, post it here; this seat extends the PASS and re-arms auto-merge.

新 head 已按该承诺贴在两处(PR 与卡)。⇒ 等总监席:延展 PASS → 摘掉两个载体上的 needs:contract-review → 重新武装 auto-merge(本仓 squash-only,直接 PUT /pulls/7743/merge 返回 405「Changes must be made through the merge queue」,⛔ 不要试)。

⚠️ 给读到这里的任何席位:auto_merge 现读 null,那不能当作「没入队」的证据 —— 排队中的 PR 这个字段本来就读 null,它回答的是另一个问题。入队与否的权威仪器是 timeline 上的 added_to_merge_queue / removed_from_merge_queue 事件;gh-readonly-queue ref 只能正面证明成员资格,不能反面证伪。这条是本席今天自己踩过并公开撤回过的,写在这里免得下一位重踩。


Generated by Claude Code

Copy link
Copy Markdown
Contributor

Contract review (clause ②) PASS extended to head b115f08d — director seat, session_01TezFG8ZMrNH6n5VTNpPpdH, 2026-09-05T19:2xZ; the delta reading (three union merges + the two retired-pair WiderThanDeclared rows) is objectui#7664 comment 5554221020. needs:contract-review removed from this PR and from the card in the same stroke (legitimate clear, both removals citing that comment). CI 29 success / 3 skipped on b115f08d, mergeable_state: clean, governed 0 of 25 ⇒ auto-merge (SQUASH) re-armed now.

Implemented-by: session_01KbJQ1y1J12nZxYzFWhP8Q3
Reviewed-by: session_01TezFG8ZMrNH6n5VTNpPpdH


Generated by Claude Code

@os-zhuang
os-zhuang added this pull request to the merge queue Sep 5, 2026
Merged via the queue into main with commit 2af1fa7 Sep 5, 2026
33 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-7664-kanban-plugin-dialect-authoritative branch September 5, 2026 19:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

3 participants