Skip to content

fix(plugin-calendar, plugin-map, plugin-gantt): registration inputs agree with the record-source rule - #10508

Merged
objectstack-fleet[bot] merged 7 commits into
mainfrom
claude/issue-10392-registration-record-source-inputs
Sep 25, 2026
Merged

objectstack-fleet[bot] merged 7 commits into
mainfrom
claude/issue-10392-registration-record-source-inputs

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #10392
Fixes #10394
Clause-②: no — registration metadata stops contradicting a schema rule that has already landed, and the registrations declare two inputs the schema already accepts. No schema, export or accept set moves.

Folded family. Each commit belongs to one card, and the commit subject names its package: objectui#10392 (chain head, calendar) and objectui#10394 (map and gantt). Dispatched by the domain:ui seat 2 PM; this run's session is https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN.

What changed

objectui#10392, calendar. OBJECT_CALENDAR_INPUTS (spread into both object-calendar and calendar) declared { name: 'objectName', type: 'string', required: true }, while ObjectCalendarSchema carries requireRecordSource('object-calendar'). The flag is gone and the description states the rule, in the exact form PR objectui#10390 used for map and gantt: "ObjectQL object name. The record source is one of data, staticData and objectName; the object-calendar schema refuses a block that declares none of them." One edit covers both tags because the list is shared.

objectui#10394, map and gantt. object-map, map and object-gantt now declare data and staticData, on the schema's own arms:

  • data is type: 'object'. ObjectMapSchema.data / ObjectGanttSchema.data are ViewDataSchema, a { provider, … } object, and both renderers call the ladder on the view-data arm. So a bare array under data now draws type-mismatch in the html tier, which matches what the schema and the renderer already do with it.
  • staticData is type: 'array'.

Each description says only what the renderer was measured to do (see the behaviour rows below). One map-specific limitation is published: the api provider is not implemented in ObjectMap and plots nothing.

map is declared exactly like object-map, and both keys spell the list inline. objectui#10393 is serial after this PR and may retire the bare map key. That is not decided here.

Measured before writing the prose (hypotheses)

  • H1. The flagged line is in the shared OBJECT_CALENDAR_INPUTS, so both calendar tags had it. There is no second copy. data / staticData were already declared there.
  • H2. Both renderers read data, then staticData, then objectName through resolveRecordSourceConfig(schema, 'view-data'). This was probed through the real SchemaRenderer on all three keys, and the probe results are now committed as behaviour rows. Differences from the calendar:
    • map/gantt data is a provider configuration, not a record array.
    • On the map, { provider: 'api' } plots nothing and logs API provider not yet implemented for ObjectMap. With staticData beside it, staticData is still not reached.
    • On the gantt, api reads through its request.
    • The descriptions were written from these readings.
  • H3. Pins exist for both cards and are shown red on the base (below).
  • H4. map has not been retired or re-armed.

Tests

New pins:

  • packages/plugin-calendar/src/__tests__/recordSourceInput-10392.test.ts
  • packages/plugin-map/src/index.recordSourceInputs-10394.test.tsx
  • packages/plugin-gantt/src/__tests__/recordSourceInputs-10394.test.tsx

What the pins check:

  • Declaration rows, per key:
    • The html tier accepts a staticData-only node and a data-only node with zero diagnostics. That means no missing-required-prop on the calendar and no unknown-prop on map/gantt.
    • The declared arm equals the schema's arm, with the refused spelling as the control.
    • Each description names the position it is true about.
  • Controls:
    • A bogus key is still reported. This node is bound by objectName, so the row holds on both trees.
    • ObjectCalendarSchema refuses a block with no record source (RECORD_SOURCE_REQUIRED) and accepts the staticData-only block.
    • Both map keys publish identical lists.
  • Behaviour rows (map/gantt, through SchemaRenderer):
    • data wins over staticData and objectName.
    • staticData wins over objectName and issues no query.
    • An object provider queries its own object.
    • A bare array under data is not a record source.
    • Map: the api provider plots nothing. Gantt: the api provider fetches its URL.

All runs below are on the final head 9a2afd981, the last commit of this PR:

  • Red on the base. The three index.tsx files were checked out at the pinned base 557abc2f4, with the tests left at HEAD. Markers were counted on disk after the mutation:

    • calendar required: true = 1;
    • map name: 'staticData' = 0;
    • gantt name: 'staticData' = 0.

    Result: Tests 23 failed | 26 passed (49). This matches the direction predicted before running:

    • every declaration row went red;
    • every control, schema row, list-equality row and behaviour row stayed green.

    Failure reasons: expected [ 'missing-required-prop' ] to not include 'missing-required-prop' on the calendar, and has no prop "staticData" on the map and gantt.

  • Restore. The files were restored with git checkout HEAD -- path under a trap. Proof: each blob hash matches HEAD, and git diff HEAD is empty.

  • Green on the head. Tests 49 passed (49).

  • Affected suites and registry readers. Test Files 156 passed (156), Tests 1977 passed (1977). The run covered:

    • packages/plugin-calendar/, packages/plugin-map/ and packages/plugin-gantt/;
    • the eight apps/console tests that enumerate the whole registry;
    • calendar-flat-color-allday-8466, calendar-doc-key-set-8830 and component-input-retired-keys-7493 in packages/types;
    • two examples/schema-catalog record-source render tests.
  • Type-check. pnpm --filter @object-ui/PKG type-check (tsc --noEmit && tsc -p tsconfig.test.json) exits 0 for plugin-calendar, plugin-map and plugin-gantt, after building their 15-package dependency closure. --listFiles confirms that each new pin is in its package's test program. The first type-check run caught TS7006 on an untyped mock-call parameter in the two map/gantt pins, and that was corrected in the last commit.

Gates (local, targeted)

Exit 0:

  • changeset presence (7 source file(s) of 3 released package(s) changed … declares 1 changeset(s))
  • check-changeset-fixed / no-major / overwrite
  • check:changeset-claims — it named 6470-gantt-dependency-field-deprecated.md and 6939-objectql-record-source-refinement.md. I read both paragraphs and both are still true.
  • check:pending-changeset-literals
  • check:new-line-citations (VERDICT new-cross-file-line-citations: 0 new citation(s))
  • check:control-bytes
  • check:phantom-deps
  • check:unused-deps
  • check:lockfile-integrity (VERDICT clean)
  • check:lockfile-dedupe (VERDICT deduped)
  • check:pre-install-import-graph
  • check:self-import
  • check:element-data-source-declaration
  • check:registry-bare-names
  • check:test-path-roots
  • check:vi-mock-specifiers / inherit / override-shape
  • check:unreferenced-sources
  • check:designer-field-key-parity
  • check:doc-types
  • check:prompt-keys
  • check-doc-links
  • check-doc-fence-languages
  • check-governed-queue-guard --test (NOT GOVERNED)
  • check:component-surface-parity (report-only; see Acceptance notes)

ESLint (--no-inline-config --format json) over the 7 touched .ts/.tsx files gave 7 results, 0 errors, and warnings only, of kinds the files already carry (no-explicit-any, only-export-components). The config has no type-aware linting (no parserOptions.project), so this diff cannot change a verdict on an untouched file.

NOT MEASURED: check:readme-exports. Reason: it needs every package's dist/index.d.ts, and only the dependency closure was built, so it exits 1 with self-import(s) could not be judged. That is a prerequisite miss, not a verdict. The README edit changes no import or export line. Repo-wide pnpm lint and the rest of the CI farm are left to CI.

Surface beyond the claim, and why

  • packages/plugin-gantt/README.md: its sentence "It declares two inputs" became false with this change. It now names four inputs and says that data is a provider configuration.
  • packages/plugin-map/src/ObjectMap.tsx: this is a comment-only change. The getDataConfig docblock said the registration "declares no data input", which became false. It now says the registration declares data on the same object arm.
  • packages/plugin-map/package.json, packages/plugin-gantt/package.json, pnpm-lock.yaml: the new pins import validateTree from @object-ui/sdui-parser, which neither package declared, so check:phantom-deps was red. It is now a devDependency, as in plugin-calendar and plugin-kanban. The lockfile change is the two importer entries only.

Acceptance notes

  • check:component-surface-parity (report-only) gains three rows: plugin-map:object-map.staticData, view:map.staticData and plugin-gantt:object-gantt.staticData, each "outside (spec ∪ renderer reads)". The cause is that the static reader does not follow the shared ladder in @object-ui/core (resolveRecordSourceConfig), which is where staticData is read. The behaviour rows above show the read. The earlier object-map.map / view:map.map rows are unchanged.
    • An intermediate commit spread one shared map list into both registrations. That hid both registrations from this reader (its "cannot name" count went from 22 to 24), so the lists are spelled inline again and the count is 22, the same as on the base.
  • After this change, validateTree no longer reports a calendar that has no record source at all. Before, it did so only through the objectName requiredness. The zod refinement is the only enforcement now. This is the same accepted trade the objectui#7470 ruling made for map and gantt: no one-of vocabulary in inputs.
  • The calendar's objectName description says "the object-calendar schema refuses". That is true of ObjectCalendarSchema in @object-ui/types, which the pin measures. The spec face ComponentPropsMap['object-calendar'] (on @objectstack/spec 17.4.0) parses an empty object, so the refusal lives in this repo's mirror and not in the spec row.

Findings for the seat (not filed here)

  • class (b): ObjectMapSchema.data is ViewDataSchema, which accepts the api arm ({ provider: 'api', read, write }). ObjectMap does not implement it: the map logs API provider not yet implemented for ObjectMap, plots nothing, and still shadows staticData. This is pinned as a gap in index.recordSourceInputs-10394.test.tsx.
    • Seam: spec:ObjectMapSchema.data (ViewData api arm) → renderer:ObjectMap fetch effect.
    • The schema arm ({ provider: 'schema', … }) on either renderer is NOT MEASURED.
    • Dedupe words: ObjectMap api provider not implemented · object-map data provider api · map ViewData api arm.
  • class (a): packages/plugin-map/README.md says that "staticData, a bare array under data, and data: { provider: 'value', items } all reach the same in-memory adapter". A bare array under data reaches nothing. Through SchemaRenderer it is neither a record source nor spread as a prop. On the host-prop path it is drawn without the adapter's filter. The failing probes are the "a bare array under data is not a record source" row here and the retirement rows in ObjectMap.schemaDataShorthand.test.tsx.
    • Dedupe words: plugin-map README bare array data · map README inline providers filter · bare array under data map.
    • Possible carrier: objectui#10393, which is next in plugin-map and edits its registration section.

Generated by Claude Code

The shared `object-calendar` / `calendar` input list declared `objectName`
with `required: true`, while `ObjectCalendarSchema` carries
`requireRecordSource('object-calendar')`: the record source is one of `data`,
`staticData` and `objectName`. `validateTree` therefore raised a
`missing-required-prop` error on a `staticData`-only calendar the schema
accepts. Drop the flag and state the rule in the description, the same form
the map and gantt registrations took.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
… sources

`ObjectMapSchema` and `ObjectGanttSchema` declare `data` and `staticData`,
two of the three record sources `requireRecordSource` accepts, but the
`object-map`, `map` and `object-gantt` registrations listed neither, so
`validateTree` reported a block authored on either as `unknown-prop`.

Declare both on the schema's own arms: `data` is a `{ provider, ... }`
data-source configuration (`type: 'object'`, so a bare array there draws
`type-mismatch`, matching the schema and the ladder's `view-data` arm), and
`staticData` is an array of records. Each description names only what the
renderer was measured to do, including that the map does not implement the
`api` provider. The two map keys now share one input list. The gantt README
sentence listing the inputs and an `ObjectMap` comment that said the
registration declares no `data` input are corrected.

The changeset covers both commits of this PR.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
The control row reused the staticData-only node, so on the unfixed tree it
also carried the missing-required-prop error and flipped with the fix. Bound
by `objectName`, it holds on both trees and only proves that the manifest
resolves the tag and still reports a bogus key.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
…jectName

The control rows reused the staticData-only node, so on the unfixed tree
they also carried the staticData unknown-prop warning and flipped with the
fix. Bound by `objectName`, they hold on both trees and only prove that the
manifest resolves the tag and still reports a bogus key.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
The shared `OBJECT_MAP_INPUTS` constant was spread into both registrations,
and `check:component-surface-parity` cannot name the entries of a spread, so
both map registrations dropped out of that reader's population (its
"cannot name" count went from 22 to 24). Spell the list inline in each
registration, as before this PR, and keep the pin that asserts the two lists
are identical. The changeset no longer mentions a shared list.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
…he html-tier pins

The new record-source pins run `validateTree` from `@object-ui/sdui-parser`,
which neither package declared, so `check:phantom-deps` reported both test
imports as undeclared tooling. Declare it as a devDependency, the same way
plugin-calendar and plugin-kanban already do for the same kind of pin. The
lockfile change is the two importer entries only.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
`tsc -p tsconfig.test.json` refused the untyped `call` parameter in the two
new record-source pins (TS7006). Annotate it as `unknown[]`; nothing the
tests assert changes.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
@github-actions github-actions Bot added documentation Improvements or additions to documentation dependencies plugin tests labels Sep 25, 2026
@github-actions

Copy link
Copy Markdown
Contributor

changeset-claim-re-read

⚠️ 5 pending changeset(s) describe a file this change touches

Their bodies publish verbatim into the CHANGELOG at the next release, so this is a request to re-read them against your diff — addressed here because you are the one seat that can answer it without re-deriving anything.

⛔ Nothing here blocks, and nothing here is a verdict on your change. This gate exits 0, is not a required context, and judges name resolution, never meaning: it asked whether a pending body names a file you touched. "Is this sentence still true?" is the one question it will not answer, and the one you are being asked to answer.

.changeset/5793-spec-range-floors.md

  • names pnpm-lock.yaml → pnpm-lock.yaml — edited by this change

    Nothing a consumer installs today changes: normal resolution already picks the newest 17.x, and pnpm-lock.yaml still resolves 17.2.0 on this edge after the bump. The change is to the declared floor only, which is why it is scored patch rather than minor — the same reasoning objectui#5753 used for the other direction on this dependency.

.changeset/6361-spec-floor-17-2-0.md

  • names pnpm-lock.yaml → pnpm-lock.yaml — edited by this change

    Nothing a consumer installs today changes: normal resolution already picks the newest 17.x, and pnpm-lock.yaml still resolves 17.2.0 on both edges after the bump — only the recorded specifier: moves. No source and no behaviour changes, which is why this is scored patch, on the reasoning objectui#5793 used for the same remediation on @object-ui/plugin-detail.

.changeset/6470-gantt-dependency-field-deprecated.md

  • names packages/plugin-gantt/README.md → packages/plugin-gantt/README.md — edited by this change

    packages/plugin-gantt/README.md's ObjectGanttSchema example authored the singular; it was the only in-repo site that did, and it now authors the plural with the alias named as legacy. No runtime code, fixture, example app or catalog schema authored it.

.changeset/6939-objectql-record-source-refinement.md

  • names plugin-map/src/ObjectMap.tsx → packages/plugin-map/src/ObjectMap.tsx — edited by this change

    Both renderers resolve their records from one of three keys, in this order — getDataConfig in plugin-map/src/ObjectMap.tsx and plugin-gantt/src/ObjectGantt.tsx: data, then staticData, then objectName. Both mirrors required objectName alone, so a document authored on staticData drew correctly and was refused by safeValidateSchema — six catalog entries, three per component.

.changeset/7122-objectstack-family-17-3-0.md

  • names pnpm-lock.yaml → pnpm-lock.yaml — edited by this change

    @objectstack/client, core, formula and lint each pin @objectstack/spec EXACTLY, so resolving the spec alone to 17.3.0 left the console bundling TWO copies of it. Moving the family with it in pnpm-lock.yaml collapses the duplicate; every declared range already admitted 17.3.0, so no manifest moved.

Read the paragraph, not the line: both false halves of the objectui#8617 claim sat in one paragraph, and correcting either alone would have left it asserting the same wrong thing.

If a claim did go false, correct the body. That is precedented and prose-only, frontmatter untouched; check-changeset-overwrite.mjs will report the correction as its own case 2 ("correcting a declaration on purpose … legitimate"), which is the intended shape — one gate asks for the read, the other records the write.

Not covered, stated so nobody reads this as more: a born-false claim that spells no line address at all (objectui#9495 coordinated one by ORDINAL — "a grep finds that member first" — and deciding that means reading what the sentence means), a claim spelled as a symbol or a package rather than a backticked file name, and a file named ambiguously.

Compared the checked-out tree with 660d31185 (merge-base with origin/main): 11 file(s) changed outside .changeset/, read against 1416 pending declaration(s) that publish a body (1996 pending in total). · run

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3044.6 KB 3104.5 KB
Main entry chunk (gzip) 147.8 KB 350 KB
Entry file index-oTALx68M.js —
Status PASS —

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


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.68KB 6.20KB
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) 27.95KB 10.04KB
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.52KB 3.45KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.13KB 7.95KB
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) 544.62KB 130.17KB
core (index.js) 9.22KB 3.71KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 223.86KB 62.25KB
fields (index.js) 256.68KB 65.01KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.40KB 12.91KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 39.28KB 11.09KB
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) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
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) 16.01KB 3.93KB
plugin-calendar (index.js) 51.38KB 14.60KB
plugin-charts (index.js) 74.76KB 20.82KB
plugin-chatbot (index.js) 198.36KB 47.20KB
plugin-dashboard (index.js) 133.59KB 35.39KB
plugin-designer (index.js) 216.25KB 44.39KB
plugin-detail (index.js) 232.19KB 61.38KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 146.50KB 37.51KB
plugin-gantt (index.js) 169.18KB 41.79KB
plugin-grid (index.js) 215.45KB 58.90KB
plugin-kanban (index.js) 49.30KB 15.39KB
plugin-list (index.js) 114.48KB 28.29KB
plugin-map (index.js) 23.82KB 7.42KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.55KB 11.99KB
plugin-timeline (index.js) 30.64KB 8.94KB
plugin-tree (index.js) 10.52KB 3.69KB
plugin-view (index.js) 87.90KB 21.97KB
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) 114.58KB 37.60KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.03KB 1.86KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.78KB 2.09KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.78KB 2.56KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 18.27KB 6.20KB
types (ai.js) 4.11KB 2.06KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 17.15KB 6.32KB
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

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 9a2afd9817ff6f92b891d52dc40d64a7bd6171c7

Method: git rev-parse refs/review/pr-10508 = 9a2afd981… (branch has not moved; PR API head re-read twice, still 9a2afd9, 7 commits, 12 files, +736/−7). Merge-base with fetched main (00715f5ba) is 557abc2f4, equal to the dev's pinned base. Full diff saved under the scratch dir. Checkout untouched (no checkout/edit/stash/commit; git fetch only, as ordered).

① Derived judgments

#10392 (calendar). The one edit is in the shared OBJECT_CALENDAR_INPUTS (spread into object-calendar and calendar): { name: 'objectName', type: 'string', required: true } becomes { name: 'objectName', type: 'string', description: 'ObjectQL object name. The record source is one of data, staticDataandobjectName; the object-calendar schema refuses a block that declares none of them.' }. Wording is the #10390 form verbatim, with object-map/object-gantt swapped for object-calendar (git show refs/review/main:packages/plugin-map/src/index.tsx line 72 and gantt line 125 carry the template). Only required on objectName drops; the other 14 rows are untouched. Pins (recordSourceInput-10392.test.ts, 12 rows): staticData-only and data-only (array, the calendar's arm) nodes assert diagnostics toEqual([]) per tag via a live manifestFromConfigs manifest; the no-record-source control asserts ObjectCalendarSchema.safeParse fails with RECORD_SOURCE_REQUIRED (matches requireRecordSource in objectql.zod.ts, refine at the ObjectCalendarSchema tail). Both pin requirements met. Trade disclosed in the PR body and correct: validateTree no longer flags a calendar with no record source at all (same trade #7470 made; validate.ts has no one-of vocabulary).

#10394, declarations. object-map, map and object-gantt each gain { name: 'data', type: 'object' } and { name: 'staticData', type: 'array' }; both map lists are spelled inline and identical (diffed; the pin both keys publish identical lists asserts toEqual). data: object is right on every face: objectui ObjectMapSchema.data and ObjectGanttSchema.data are ViewDataSchema.optional() (a discriminatedUnion('provider', [strictObject…×4]) per objectstack/packages/spec/src/ui/view.zod.ts); the core ladder is called with 'view-data' at ObjectMap.tsx getDataConfig and ObjectGantt.tsx rawDataConfig; the spec's pending rows (objectstack/.changeset/18305-component-props-map-map-gantt-tree.md, unreleased relative to the @objectstack/spec@17.4.0 registry tarball objectui's lockfile pins) declare ObjectMapPropsSchema.data / ObjectGanttPropsSchema.data as ViewDataSchema with "the bare-array shortcut is refused", and staticData: z.array(z.unknown()). Grid precedent: plugin-grid declares data as type: 'object'. Bare array under data: validate.ts checkType arm 'object' is typeof value === 'object' && value !== null && !Array.isArray(value), so an array draws type-mismatch at severity warning (single non-enum arm); the schema refuses the same value (pins assert ObjectMapSchema.safeParse({data: DATA_ROWS}).success === false, likewise gantt). Not a false diagnostic; before this PR the same node drew unknown-prop, also a warning.

#10394, descriptions vs the real ladder. resolveRecordSourceConfig (packages/core/src/utils/record-source.ts): rung 1 returns schema.data when authoredDataIsOnTheDeclaredArm (for 'view-data': truthy and !Array.isArray), rung 2 wraps staticData as { provider: 'value', items }, rung 3 folds objectName. So: (1) data is read first and wins — true, and any object under data (including { provider: 'api' }) shadows staticData. (2) Map api provider: ObjectMap.tsx fetch effect ends else if (dataProvider === 'api') { console.warn('API provider not yet implemented for ObjectMap'); setData([]); } — plots nothing and, by rung 1, still shadows staticData; pinned through the real SchemaRenderer (lats toEqual([]), queried toEqual([]), warn message asserted). (3) Gantt api provider: resolveDataSource case 'api' builds an ApiDataSource whose find calls this.fetchFn(url, init) (fetchFn = config.fetch ?? globalThis.fetch); pinned by spying globalThis.fetch and asserting https://api.test/tasks was called and the returned row charted. The filter/sort clauses in the descriptions defer to ObjectMap.inlineQueryKeys-9061.test.tsx and ObjectGantt.inlineQueryKeys-8769.test.tsx (staticDataSpelling rows exist; map file also has offArmDataSpelling). The schema provider is not described and is disclosed as NOT MEASURED. All three claims hold.

Surface beyond the claims. plugin-gantt/README.md: "declares two inputs" was made false by this diff; the replacement ("four inputs … data is a { provider, … } data-source configuration, never a bare array; inline rows go under staticData") is true of the source list (same counting convention as before: the elementDataSourceBlock seam injects a fifth dataSource input at register time, already uncounted in the old sentence). Needed and correct. ObjectMap.tsx: comment-only, 2 lines; "declares no data input" became false and now reads "declares data on the same OBJECT arm (type: 'object', objectui#10394)" — true. package.json ×2: "@object-ui/sdui-parser": "workspace:*" added under devDependencies only (diff hunks sit inside the devDependencies block; none of the eight publish-contract fields move); needed because both new pins import validateTree/manifestFromConfigs; precedent plugin-calendar and plugin-kanban carry the same devDependency. sdui-parser has no runtime dependencies, so no production cycle. pnpm-lock.yaml: +6 lines, exactly two importer entries (link:../sdui-parser), nothing else; Lockfile Integrity Check and Lockfile Dedupe Check both success on the head.

Fold mechanics. Per-commit file lists: d0c656522 (calendar index + calendar pin) and f7b7ce204 (calendar pin) are #10392 only; 11decadcb, ec1ddd85f, db55d232e, a7abecf2a, 9a2afd981 touch only map/gantt files plus the shared changeset — #10394 only. Attribution "2 + 5, each commit one card" is honest; the shared changeset riding in 11decadcb is disclosed. "One commit per card" is not met (7 commits), disclosed with the force-push ban as the reason; intermediate 11decadcb spread a shared map list that db55d232e reverted, so two commit messages describe a state the head no longer has (history noise only). Both cards fully delivered: #10392 both tags via the shared list + pins; #10394 all three registrations + pins. Two Fixes lines are right.

Report-only check:component-surface-parity. Not re-run. From the script's own contract (scripts/check-component-surface-parity.mjs lines 89-107): READS reach schema.<key> accesses "through same-file declarations, one-level aliases, the HOC spelling, static relative imports inside the package, and the <Child schema> chain" plus FRAMEWORK reads from SchemaRenderer.tsx. staticData is read only inside @object-ui/core's ladder (bare-specifier import, not followed); neither ObjectMap.tsx nor ObjectGantt.tsx name-reads schema.staticData (grep over code lines: 0 hits), while ObjectCalendar.tsx does (staticData: schema.staticData), which is why the calendar has no such row. The installed spec 17.4.0 has no object-map/object-gantt ComponentPropsMap row (core docblock; the rows are in the unreleased changeset 18305). So the 3 rows are the static reader's blind spot, not a gap: the behaviour pins prove the read through the real renderer, and the pending spec rows declare staticData, which will retire the rows on the spec side once objectui bumps.

Nit (not blocking). packages/plugin-gantt/src/index.tsx new comment cites "Pinned in __tests__/recordSourceInputs-10394.test.ts"; the file is recordSourceInputs-10394.test.tsx (git ls-tree confirms). Calendar and map comments cite their pins correctly.

② Semver level

patch on @object-ui/plugin-calendar, @object-ui/plugin-map, @object-ui/plugin-gantt is right. AGENTS.md §9 版本号策略: fixed group (.changeset/config.json fixed lists all three), never major, breaking → minor; this is a registration-metadata bug fix aligning the lowest-authority surface to a landed schema rule, with no renderer, zod, export or runtime-dependency change. Changeset Declaration, Changeset Bump Policy, Changeset Fixed Group Check, Changeset Overwrite Report, Changeset Claim Re-read all success. Changeset prose checked sentence by sentence: ladder order (core), requireRecordSource on all three zod schemas (objectql.zod.ts refine tails), missing-required-prop is severity: 'error' and unknown-prop is warning (validate.ts), the bare-array type diagnostic (type-mismatch) matches the schema refusal, the map api limitation is stated in the description, renderers and zod unchanged (diff), gantt README updated — all true.

③ Boundary flags

  • Declared deviations (7): all disclosed and judged acceptable. The three "surface beyond the claims" edits are needed and correct (above), devDependency-only. Commit count and the reverted shared-list commit are history-only. Control-row rebinding by objectName is sound (holds on both trees). Trailers are Co-Authored-By: Claude <noreply@anthropic.com> + Claude-Session:; objectui AGENTS.md carries no trailer rule and the cited role file is outside this review's permitted inputs, so unverified, and immaterial to landing. Probe tests deleted before commit; the diff shows none.
  • Clause-②: no: consistent with triage 5825143164 ("the same repair applies without a new ruling") and 5825168539 ("declaring inputs the schema already declares needs no new ruling"); the contract accept set (zod/spec) does not move, only the html-tier diagnostics catch up, which is the fix itself. Separately, AGENTS.md §9's own clause ② (a dispatched PR with a Claim: on the card stays draft; the seat lands it after CI) applies and is honoured: PR is draft: true.
  • Out-of-scope findings, both accurate: (b) map api provider unimplemented — confirmed at the console.warn('API provider not yet implemented for ObjectMap') branch; pre-existing; pinned as a gap; correctly not fixed here. (a) plugin-map/README.md sentence "staticData, a bare array under data, and data: { provider: 'value', items } all reach the same in-memory adapter" is false against authoredDataIsOnTheDeclaredArm('view-data') and the 9061 offArmDataSpelling row; pre-existing since the 8348 arm ruling, not this PR's obligation; carrier finding(plugin-map): the bare map registration key has no AnyComponentSchema arm — a map node fails validation (invalid_union) while the same object-map node passes; the shape objectui#8008 retired for gantt #10393 is a sensible suggestion. Note for the seat: the spec's pending changeset 18305 declares object-map/object-gantt rows with data: ViewDataSchema and staticData, so the arms declared here will also satisfy registry-inputs-spec-parity.test.ts once objectui bumps the spec.
  • CI state (head, polled 05:47Z–05:57Z): 45 check runs; 41 success, 3 skipped (coverage ×2, dependabot), 1 in_progress: Lint (started 05:43:32Z). All 8 test shards, Type Check, Spec Main Shape Gate, Build & E2E, README Export Check (the gate the dev could not measure locally), lockfile and changeset gates are success. Local eslint over the 7 touched files reported 0 errors per the dev; the repo-wide verdict is still Lint's.
  • Should stop landing: nothing. Before flipping ready, the seat should wait for Lint and may add a one-line commit fixing the .test.ts → .test.tsx citation in the gantt index comment.

Implemented-by: claude/issue-10392-registration-record-source-inputs
Reviewed-by: session_014mXUNuFomfj24w7s1pZzhN

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review September 25, 2026 06:23
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Sep 25, 2026
Merged via the queue into main with commit 875ee61 Sep 25, 2026
47 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-10392-registration-record-source-inputs branch September 25, 2026 06:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment