Skip to content

docs(types,plugin-calendar): teach object-calendar's field-name keys inside the calendar block; the flat spelling is the runtime handoff (objectui#8831) - #11308

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-8831-calendar-flat-teaching-face
Oct 1, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-8831-calendar-flat-teaching-face

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #8831

Clause-②: no

What changes

@objectstack/spec refuses startDateField / endDateField / titleField / colorField / allDayField written flat on an object-calendar node. Its diagnostic prescribes calendar: { startDateField, endDateField, titleField, colorField, allDayField }. Since 17.5.0 the spec's CalendarConfigSchema declares all five, allDayField included. This PR is ruled direction (a): objectui stops teaching the flat spelling at the object-calendar position and teaches the container.

  • packages/plugin-calendar/README.md

    • Both object-calendar snippets ("With ObjectQL Integration" and "ObjectQL Integration") now write the five keys inside calendar, with allDayField in the block. Both are compiled by check:doc-snippets.
    • One paragraph names the flat spelling for what it is: the runtime handoff ObjectView / ListView emit, which getCalendarConfig reads only when the node has no calendar block. It is declared because the renderer reads it, and it is not a second authorable spelling (Prime Directive [WIP] Enhance UI components for forms and layouts #12).
    • The snippet comment no longer says the block "proves" the flat keys are declared. It now says what the annotation checks on the block (values, not key names).
    • The "gates the whole configuration" paragraph is rewritten for the block, because it described the flat path. Its behavioural claims were measured, see below.
  • packages/types, both faces of ObjectCalendarSchema

    • The five flat members' .describe() text (one shared helper, objectCalendarFlatField) and TS docblocks call them the FLAT spelling, read but not authored, and point at calendar.KEY.
    • The calendar member's text calls the block the authored spelling.
    • The allDayField docblock no longer says the key is objectui-local. It records that 17.5.0 declares it.
  • ObjectCalendarBlockConfigSchema's .extend({ allDayField }). Only its description and comment changed: it no longer says the spec refuses the key. See H2.

  • Pin. The calendar-flat-color-allday-8466 row "the README still teaches all five together, which is what makes them authorable" is inverted. It now reads the README's authored object-calendar nodes by brace matching and asserts:

    • none writes a field-name key flat;
    • one calendar block carries all five;
    • control, same instrument, opposite verdict: a calendar-view node is seen writing titleField flat.

    The file's header gets a dated note.

  • Changesets. New .changeset/8831-calendar-flat-teaching-face.md (@object-ui/types patch, @object-ui/plugin-calendar patch). The pending .changeset/8466-calendar-color-allday-fields.md says the README "already teaches" the flat keys, which this release makes false. It gets a dated, append-only note, and its frontmatter is byte-identical (md5 of the first three lines unchanged).

What is NOT changed

  • No accept set moves. The flat members stay declared on both faces with the same types, because ObjectCalendar reads them and ObjectView / ListView emit them.
  • Excluded regions are untouched: ObjectCalendarSchema.objectName and requireRecordSource (held by objectui#11117), the CalendarViewSchema declarations, navigation, and registry-inputs-spec-parity.test.ts (held by objectui#11168).

Premises, re-measured in this worktree (base 1ccb5ba7d, installed @objectstack/spec 17.5.0, single store copy)

  • Unlock predicate. The card's probe exits 0. Two lit controls run beside it: { startDateField } parses (true), and { startDateField, bogusKeyZz } is refused (false, unrecognized_keys naming bogusKeyZz). Shape keys: allDayField, colorField, endDateField, startDateField, titleField.
  • The trap is real at the public row.
    • ComponentPropsMap['object-calendar'] refuses the README's old first snippet: unrecognized_keys on all five, and the message starts "Write this as a key of the calendar config object instead".
    • It also refuses the second snippet (three keys).
    • It accepts the rewritten container form.
    • Control: a bogus key is refused.
  • H1, the calendar-view site. ComponentPropsMap has no calendar-view row (55 rows; the object-calendar control is present), and CalendarViewSchema has no calendar container. So the flat keys are that element's only spelling, and the container cannot be taught there.
    • Decision: keep the five-key sentence, scope it explicitly to calendar-view ("on a calendar-view node ... here the flat keys are the only spelling"), and point to the object-calendar block in the next section.
    • The compiler-pinned CalendarViewNode listing and the "Calendar Event Structure" fence are calendar-view's and stay.
  • H2, the .extend({ allDayField }). It is now an identity. The spec's CalendarConfigSchema.partial() member and the local z.string().optional() agree on 8 of 8 values: two strings, undefined, 42, true, null, {}, an array. On the TS side, ObjectCalendarSchema['allDayField'] equals CalendarConfig['allDayField']; a tsc probe checked this, and its control fired.
    • Only the description and comment changed. The member is kept: removing it is an accept-set no-op, but the zod-mirror-parity ledger comment names this extension, and that file is outside this claim.
  • H3, docs pages. Falsified. Every object-calendar snippet on content/docs/plugins/plugin-calendar.mdx already writes calendar: { ... }, and its Schema API fence lists no flat key. git grep found no other content/docs/**, examples/** or skills/** site that authors object-calendar with a flat key. The flat keys in content/docs/api/schema-reference.md and the schema-catalog JSON are calendar-view's. ⇒ no docs page changed.
  • H4, the 8830 header. Left as it is. It is framed "Measured on the dispatch base, with @objectstack/spec 17.4.0 installed then", and the test body's 17.5.0 row explains the move. A reader does not take it as current.
  • README behavioural claims, measured. A one-off render probe went through the real SchemaRenderer and registry, and was deleted afterwards (tree clean):
    • control: a correct block draws both rows, with no unscheduled area;
    • a misspelt start key inside the block draws nothing, shows Unscheduled (2), and no refusal screen;
    • a node with no calendar block renders "Calendar configuration required".

Verification, all at HEAD bac7f8789

Run from the worktree; heavy runs went through the shared verify lock. The verdict lines are quoted.

gate result
turbo run build over check:doc-snippets --build-filter (36 packages, --concurrency=2) Tasks: 35 successful, 35 total, VERDICT command-exit 0
pnpm check:doc-snippets exit 0, Semantic phase: 698 of 698 block(s) judged, 0 failed.
pnpm check:readme-exports exit 0, check-readme-exports: OK (... 554 real, 0 wrong-path, 0 fabricated ...)
pnpm --filter @object-ui/types type-check (the script echoed: tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json) exit 0. tsc -p tsconfig.test.json --listFiles counts the 8466 file once, so the test face is in it
pnpm exec vitest run --maxWorkers=2 packages/types/ packages/plugin-calendar/src/readme-calendar-view-schema.test.ts Test Files 302 passed (302), Tests 7605 passed (7605), VERDICT command-exit 0
eslint on the three changed TS files (--no-inline-config) 0 errors. The 8466 file keeps exactly its 2 documented no-explicit-any warnings
check:doc-types, check:doc-fences, check:doc-example-ids, check:installed-pin-claims, check:new-line-citations, check:control-bytes, check:test-path-roots, check:pending-changeset-literals, check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape, check:spec-symbols, check:component-surface-parity, check:designer-field-key-parity, check:element-data-source-declaration all exit 0
check-changeset-presence / -no-major / -fixed exit 0, 3 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)
markdown-test-inputs --audit exit 0, 107 candidate test files, all adjudicated; 78 declared entries, all present.
check:comment-mask-corpus exit 0, within the residue objectui#7882 holds (1 file, 0 fabricated)
check:changeset-claims, check-changeset-overwrite (report-only) Read. 30 pending changesets name the touched files. The three that mention calendar keys (7632, 7804, 9606) describe other regions and are not made false. The overwrite report is case 2 (deliberate append, declaration unchanged)
check-governed-queue-guard --test over the six paths NOT GOVERNED

The repo-wide pnpm lint and the full CI matrix are left to CI. dispatch-gates.mjs --repo objectstack-ai/objectui refuses (exit 2), as it does for any objectui card, so this list is hand-derived from the diff.

Reverse verification (one-shot; each mutation landed through ablation-replace.mjs, which checks the anchor count and the blob hash, and was restored to the HEAD blob with git diff HEAD empty)

  • The new pin can fail. A flat titleField was put back on the README's second object-calendar node.
    • Result: × the README authors the five INSIDE the calendar block ..., AssertionError: a README object-calendar node writes titleField flat, Tests 1 failed | 18 passed. Direction as expected: red.
    • The first attempt was a no-op and is declared here: its replacement contained the anchor, the tool refused it before running anything, and no reading was taken.
  • check:doc-snippets judges the README block's values.
    • allDayField: 'isAllDay' was changed to allDayField: 42 inside the block.
    • Result: [semantic] packages/plugin-calendar/README.md ... TS2322: Type 'number' is not assignable to type 'string'., 698 of 698 block(s) judged, 1 failed. Red, as expected.

Round 2 (a86a6afdb)

Two findings from round 1, folded in on the seat's order. They are this card's own subject (what the published faces teach about the calendar container and allDayField), and neither could ride anywhere else.

  • content/docs/plugins/plugin-calendar.mdx, section "CalendarConfig": the paragraph that said neither published face of ObjectCalendarSchema declares the calendar container (false since objectui#8651) now says what holds on the installed 17.5.0:
    • Both faces declare the container, with the five keys as members.
    • Values are checked: calendar: { startDateField: 42 } is refused, and dateField / endField are refused by name (objectui#8355).
    • The block is .passthrough(), so any other key parses.
    • On object-calendar, the spec declares the calendar key but not its shape.
    • On the list-view path, objectui's mirror is open while the spec's own block is strict.
  • Dated, append-only corrections, each with its frontmatter and existing bytes identical (prefix md5 equal, 0 deleted lines):
    • .changeset/8026-objectcalendar-alldayfield-honoured.md: its "Not spec surface" paragraph. Made false by objectui#11073.
    • .changeset/8830-calendar-doc-key-set.md: "objectui's own allDayField". Made false by objectui#11073.
    • .changeset/olive-buckets-scream.md: "the four CalendarConfigSchema names plus objectui's allDayField", made false by objectui#11073; and the kept dateField / endField rungs and the parsing calendar.dateField, made false by objectui#8355.
  • Left as dated history: .changeset/7928-listviews-by-reference-fold.md, whose list of refused named-view keys is labelled "Measured on 17.4.0".
  • Gates at a86a6afdb, all exit 0:
    • check:doc-snippets (698/698 judged, 0 failed), check:doc-types, check:doc-fences, check:doc-example-ids;
    • check-changeset-presence / -no-major / -fixed / -overwrite, check:changeset-claims, check:pending-changeset-literals;
    • check:new-line-citations, check:control-bytes, check:installed-pin-claims, check-doc-links.
  • The 19 tests that read the four changed markdown files: 773 passed.

Acceptance notes

None of these was changed here. Each one is drift, outside this claim, or both:

  • packages/plugin-calendar/src/ObjectCalendar.tsx, the ObjectCalendarConfig docblock, still says allDayField is not a spec key. That sentence is already a stale entry in check-installed-spec-pin-claims.mjs's ledger. Carrier: none.
  • apps/console/src/__tests__/registry-inputs-spec-parity.test.ts pin text calls allDayField "an objectui-local extra key" and the spec side "exactly the four documented keys". Carrier: objectui#11168, which holds that file this round.
  • packages/types/src/__tests__/zod-mirror-parity.test.ts, the ledger comment beside objectql.zod.ts#ObjectCalendarSchema, still speaks of the "four-key calendar config vocabulary" and objectui's "single local knob". Removing the now-identity allDayField extension would make it fully false, which is why that removal is not in this PR. Carrier: none; objectui#6152 (another seat) holds that file.
  • packages/types/src/zod/objectql.zod.ts, the list-view mirror note (".passthrough() is kept ... because the renderers grow config knobs ahead of the protocol (calendar's allDayField, for one)") cites an example that has been out of date since 17.5.0. The list-view CalendarConfig mirror now takes allDayField from the spec. The note sits outside this card's region (PR feat(types)!: showFilters is retired on object-grid, refused by name with the list view's userActions.filter named (objectui#11068) #11306 and objectui#11117 hold neighbouring regions). Carrier: none.
  • Round 1's two items on plugin-calendar.mdx and the three pending changesets were folded into round 2 above.

Generated by Claude Code

…s inside the calendar block, and name the flat spelling as the runtime handoff (objectui#8831)

The spec refuses startDateField / endDateField / titleField / colorField /
allDayField written flat on an object-calendar node and prescribes the
calendar block; 17.5.0 declares all five there. The README's two
object-calendar examples now write the block, the calendar-view sentence is
scoped to calendar-view (it has no calendar block), and the types' flat
member descriptions call the flat spelling the read-only handoff. No accept
set moves: the flat members stay declared because the renderer reads them.

The 8466 README pin is inverted to the new teaching, and the 8466 changeset
gets a dated note.

Claude-Session: https://claude.ai/code/session_01VhxTqosz7wn54ahqyxgERT
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation package: types plugin tests labels Oct 1, 2026
@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

changeset-claim-re-read

⚠️ 31 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/10872-container-children-channel.md

  • names objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    Also in this change, with no behaviour change: objectql.zod.ts's two public-block arms (object-metric, object-master-detail-form) build their properties member with the same propsBag helper as the other public-block arms, instead of a byte copy of it. The member's description text is unchanged.

.changeset/5903-objectgantt-declared-keys.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    Both halves move together. The TS declaration (packages/types/src/objectql.ts) and its zod mirror (src/zod/objectql.zod.ts) gain the same ten keys at the same requiredness — all optional — and no KnownDrift entry is added. navigation is taken from @objectstack/spec's NavigationConfigSchema by reference rather than restated, matching ObjectGridSchema.navigation.

  • names src/zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    Both halves move together. The TS declaration (packages/types/src/objectql.ts) and its zod mirror (src/zod/objectql.zod.ts) gain the same ten keys at the same requiredness — all optional — and no KnownDrift entry is added. navigation is taken from @objectstack/spec's NavigationConfigSchema by reference rather than restated, matching ObjectGridSchema.navigation.

.changeset/6152-object-form-unmirrored-members.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    ObjectFormSchema in @object-ui/types (objectql.ts) declared a set of members that its zod mirror in @object-ui/types/zod had never heard of. Every one of them is read by the object-form renderer (ObjectForm in @object-ui/plugin-form). The two published faces answered differently:

.changeset/6940-rowactions-boolean-mirror.md

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    The list view's same-named rowActions in zod/objectql.zod.ts — z.array(z.string()), the legacy bare-name action list on ObjectGridSchema — is a different key that is correct as it stands, is in parity with its own TS twin (rowActions?: string[]), and is not touched.

.changeset/7113-chart-data-model.md

  • names objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    .extend() with a NEW key still works and preserves the fold and the refinement; .optional(), z.discriminatedUnion, z.toJSONSchema and safeValidateSchema are all unaffected. Nothing in this repository calls the throwing combinators on either const, and the published surface already ships refined mirrors (objectql.zod.ts, complex.zod.ts, form.zod.ts, app.zod.ts), so the class is not new — but it is a real behaviour change on a published export and it belongs in the release note rather than in a reviewer's file.

.changeset/7200-object-form-section-style-keys-undeclared.md

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    The authored-metadata type now agrees with @objectstack/spec, whose FormSectionSchema is a strict object declaring neither key, and with the ruling's rationale (maintainer 2026-09-01, verbatim): "retire the reads … Declaring the keys was weighed and not adopted: it would formally invite free Tailwind strings into authored metadata, the exact class the boundary exists to keep out." A ?: never tombstone was not used: ObjectFormSection has no zod mirror (ObjectFormSchema in zod/objectql.zod.ts does not declare sections), so there is no parse door to refuse at, and a tombstone is still a declaration in completion and in the published .d.ts.

.changeset/7265-types-user-filter-field-derives.md

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    zod/objectql.zod.ts declared two schemas under names @objectstack/spec/ui already exports. They were triaged separately, by reading their sites, and went different ways.

.changeset/7313-object-calendar-record-source.md

  • names content/docs/plugins/plugin-calendar.mdx → content/docs/plugins/plugin-calendar.mdx — edited by this change

    A widening. A node authoring staticData or data without objectName now validates (it always rendered — the read is resolveRecordSourceConfig(schema), keyed on the three). Every document that validated before still validates: objectName alone still parses, an empty one included, because presence is !== undefined. The one shape the refinement refuses (none of the three) was refused before too, at objectName. The two static-data examples in content/docs/plugins/plugin-calendar.mdx are now annotated ObjectCalendarSchema and compile under the doc-snippet gate.

.changeset/7322-object-kanban-group-by-limit.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    Breaking for authored metadata: ObjectKanbanSchema.groupField is RETIRED (objectui#7322, ADR-0049 enforce-or-remove), and the two keys the object-kanban renderer actually reads — groupBy and limit — are now DECLARED and validated on both published faces: the TypeScript interface in objectql.ts and the Zod mirror in zod/objectql.zod.ts.

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    Breaking for authored metadata: ObjectKanbanSchema.groupField is RETIRED (objectui#7322, ADR-0049 enforce-or-remove), and the two keys the object-kanban renderer actually reads — groupBy and limit — are now DECLARED and validated on both published faces: the TypeScript interface in objectql.ts and the Zod mirror in zod/objectql.zod.ts.

.changeset/7352-drill-down-config-mirror.md

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    DrillDownConfigSchema is the zod mirror of DrillDownConfig, and both declarations that carry drillDown reference it — ChartSchema (zod/data-display.zod.ts) and ObjectDataTableSchema (zod/objectql.zod.ts) — so the published validator under @object-ui/types/zod reads the key for the first time (objectui#7352).

.changeset/7363-objectql-union-arms.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    ObjectGallerySchema and ObjectDataTableSchema are members of ObjectQLComponentSchema on both faces — the TS union in objectql.ts and the zod union in zod/objectql.zod.ts — so AnyComponentSchema, and with it validateSchema / safeValidateSchema / objectui validate, has an arm for object-gallery and object-data-table nodes (objectui#7363).

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    ObjectGallerySchema and ObjectDataTableSchema are members of ObjectQLComponentSchema on both faces — the TS union in objectql.ts and the zod union in zod/objectql.zod.ts — so AnyComponentSchema, and with it validateSchema / safeValidateSchema / objectui validate, has an arm for object-gallery and object-data-table nodes (objectui#7363).

.changeset/7632-shared-record-source-config.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    That ladder is published contract on both faces — packages/types/src/objectql.ts and its zod mirror both ship .describe() strings naming getDataConfig's order (77cb489b4, maintainer ruling 2026-09-02), pinned by objectql-record-source-refinement-6939.test.ts — and it was hand-copied into five plugin components with no gate holding them together. A change to the ruled order had five edit sites and nothing that noticed a missed one; that is the AGENTS.md #0.1 drift class.

.changeset/7804-objectql-handler-key-arms.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    The four plain objectql.ts node faces declare the nine handler keys their registered renderers read (the objectql.ts slice): ObjectFormSchema.onCancel / .onError / .onOpenChange / .onStepChange / .onSuccess, ObjectGallerySchema.onCardClick / .onRowClick, ObjectGridSchema.onNavigate and ObjectViewSchema.onNavigate.

.changeset/7804-tree-view-handler-slot.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    'runtime-slot' and not 'retired', measured at this key's own channel. 'retired' publishes "no renderer reads this key, so nothing could ever run it" — true of the two siblings already tombstoned on this arm (onSelectChange, onExpandChange) and flatly false here, since the read is live and INVOKED. ⚠️ No in-repo host builds a tree-view node carrying the key: the channel is wired end to end and only the supplier is absent, which is the same shape as ObjectFormSchema.onStepChange in this card's objectql.ts slice and is not evidence of a dead read. The TypeScript declaration is unchanged and still callable, so a programmatic host supplies it exactly as before.

.changeset/7917-export-breadcrumb-object-tree-zod-schemas.md

  • names objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    AnyComponentSchema declares 107 node component types. 105 of them could be named on the ./zod barrel — ButtonSchema.safeParse(node), which is what a designer, a form builder or a targeted test needs. The arms declaring type: 'breadcrumb' (navigation.zod.ts) and type: 'object-tree' (objectql.zod.ts) could not: both were already export const in their own module, but index.zod.ts — the package's only zod entry point — did not re-export them, so the schemas existed, were maintained, and were applied by the union while no consumer could name them.

.changeset/7963-alert-dialog-footer-keys-retired.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    Nothing else moves. These spellings are overloaded across the tree and every other owner is a live key on a different declaration — FormSchema.cancelLabel, objectql.ts's confirmLabel, plugin-designer's ConfirmDialog React props, plugin-grid's def.confirmLabel, and plugin-form's ModalForm / DrawerForm, which build a local cancelLabel from schema.cancelText. None is an AlertDialogSchema; none is touched, and a pin asserts it. No fixture, catalog schema, example app or doc fence authored any of the three on an alert-dialog node, so no shipped document is stranded.

.changeset/8478-describe-line-addresses.md

.changeset/8735-objectql-mirror-docblocks-not-defaulted.md

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    Correct four zod/objectql.zod.ts docblocks that described the behaviour objectui#8317 removed. Since that change the zod mirrors strip imported @objectstack/spec defaults at this package's import boundary, but the docblocks on HttpRequestSchema, ListColumnSchema, SelectionConfigSchema and PaginationConfigSchema still said, in the present tense, that method, prefix.type, type and pageSize are defaulted on parse — the opposite of what each export does. Each now says the key is declared and accepted but NOT defaulted on parse.

.changeset/8767-object-grid-refuses-string-sort.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    Migration. Write the array: sort: [{ field: 'name', order: 'desc' }]. Both keys are required. SortConfig.order carries no ? in @object-ui/types (packages/types/src/objectql.ts) and no .optional() in its zod mirror, and the protocol's own reusable SortItemSchema requires order as well — measured: that schema refuses [{ field: 'name' }] with invalid_value at 0.order. Do not omit it: this block's array arm interpolates whatever is present, so an omitted order lowers to $orderby: 'name undefined' today. That is pre-existing behaviour on the arm this change does not touch, and it is filed as a successor card rather than widened into here.

.changeset/8801-object-kanban-allow-collapse-retired.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    • the declarations retired here — packages/types/src/objectql.ts and its mirror packages/types/src/zod/objectql.zod.ts; - the pins that assert the retirement — object-kanban-allow-collapse-retired-8801.test.ts and bare-kanban-node-key-retired-8802.test.ts; - a comment in packages/types/src/zod/complex.zod.ts, recording that the deleted retiredZeroReadKanbanKey helper once carried this spelling on the SIBLING arm; - one row of content/docs/api/schema-reference.md; - the .changeset/ release notes that discuss it — this one, the two historical entries covering the sibling arm's own spelling, and objectui#9629's note recording the correction to this paragraph.
  • names packages/types/src/zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    • the declarations retired here — packages/types/src/objectql.ts and its mirror packages/types/src/zod/objectql.zod.ts; - the pins that assert the retirement — object-kanban-allow-collapse-retired-8801.test.ts and bare-kanban-node-key-retired-8802.test.ts; - a comment in packages/types/src/zod/complex.zod.ts, recording that the deleted retiredZeroReadKanbanKey helper once carried this spelling on the SIBLING arm; - one row of content/docs/api/schema-reference.md; - the .changeset/ release notes that discuss it — this one, the two historical entries covering the sibling arm's own spelling, and objectui#9629's note recording the correction to this paragraph.

.changeset/8885-object-chart-drilldown-title-compareto.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    ObjectChart.tsx reads all three off schema, and until now neither published copy declared any of them: not the TS interface (packages/types/src/objectql.ts) and not the zod mirror (packages/types/src/zod/objectql.zod.ts). They rode BaseSchema's index signature / .passthrough() and arrived unvalidated. drillDown was the sharpest case — this component's registry inputs advertise it to the designer palette, and @objectstack/spec publishes ChartDrillDownSchema for exactly this carrier, so an author was offered a key that neither published shape mentioned.

  • names packages/types/src/zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    ObjectChart.tsx reads all three off schema, and until now neither published copy declared any of them: not the TS interface (packages/types/src/objectql.ts) and not the zod mirror (packages/types/src/zod/objectql.zod.ts). They rode BaseSchema's index signature / .passthrough() and arrived unvalidated. drillDown was the sharpest case — this component's registry inputs advertise it to the designer palette, and @objectstack/spec publishes ChartDrillDownSchema for exactly this carrier, so an author was offered a key that neither published shape mentioned.

.changeset/8913-object-kanban-columns-declared.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    What moved. ObjectKanbanSchema gains columns on both halves that move together — the TypeScript interface (objectql.ts) and its Zod mirror (zod/objectql.zod.ts). Retiring the bare kanban node type key (objectui#8802) removed the only face that judged a lane, and object-kanban had never declared the key, so it rode BaseSchema's [key: string]: any / .passthrough(): read by the renderer at three sites, named by no published face.

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    What moved. ObjectKanbanSchema gains columns on both halves that move together — the TypeScript interface (objectql.ts) and its Zod mirror (zod/objectql.zod.ts). Retiring the bare kanban node type key (objectui#8802) removed the only face that judged a lane, and object-kanban had never declared the key, so it rode BaseSchema's [key: string]: any / .passthrough(): read by the renderer at three sites, named by no published face.

.changeset/8990-object-kanban-groupby-optional.md

  • names packages/types/src/objectql.ts → packages/types/src/objectql.ts — edited by this change

    @objectstack/spec declares the key optional — groupBy: z.string().optional() on ObjectKanbanPropsSchema — while this package required it on the TypeScript declaration (packages/types/src/objectql.ts) and on the Zod mirror (packages/types/src/zod/objectql.zod.ts). objectui was therefore narrower than the protocol on a published key: ObjectKanbanSchema.safeParse and safeValidateSchema refused an object-kanban node the protocol accepts, and such a node could not be annotated with its own type.

  • names packages/types/src/zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    @objectstack/spec declares the key optional — groupBy: z.string().optional() on ObjectKanbanPropsSchema — while this package required it on the TypeScript declaration (packages/types/src/objectql.ts) and on the Zod mirror (packages/types/src/zod/objectql.zod.ts). objectui was therefore narrower than the protocol on a published key: ObjectKanbanSchema.safeParse and safeValidateSchema refused an object-kanban node the protocol accepts, and such a node could not be annotated with its own type.

.changeset/8992-user-actions-collapse-and-docblock.md

  • names objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    objectql.zod.ts's UserActionsSchema read stripImportedDefaults(Spec).extend({ group, hideFields, rowColor }), an extension that existed only because @objectstack/spec did not declare those three keys while normalizeListViewSchema folded objectui's legacy showGroup / showHideFields / showColor onto them. The protocol adopted all three in 17.3.0 (objectui#5435's ruling), so the extension is now a second local copy of a protocol declaration — the shape two faces start drifting from — and it collapses into the plain by-reference re-export its own note always said it would become.

.changeset/9092-inline-locale-declared-face.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    • AppComponentSchema.label (app.ts) - ObjectGridSchema.label and .description (objectql.ts) - PageNodeSchema.aria.ariaLabel (layout.ts)

.changeset/9309-object-gallery-filter-destination-typed.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    ObjectGallerySchema.filter is typed as the destination its own docblock names — QueryParams['$filter'] — on both faces, the TS interface in objectql.ts and the zod mirror in zod/objectql.zod.ts (objectui#9309).

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    ObjectGallerySchema.filter is typed as the destination its own docblock names — QueryParams['$filter'] — on both faces, the TS interface in objectql.ts and the zod mirror in zod/objectql.zod.ts (objectui#9309).

.changeset/9511-record-id-is-a-string.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    The three authorable keys, each on BOTH faces. ObjectFormSchema.recordId (objectql.ts + zod/objectql.zod.ts), DetailViewSchema.resourceId (views.ts + zod/views.zod.ts) and DetailSchema.resourceId (crud.ts + zod/crud.zod.ts). ⚠️ The crud pair is DetailSchema, not DetailViewSchema, and it reaches the same renderer — not by symbol but by data flow: plugin-detail registers the 'detail' node type onto DetailView. A read that follows TypeScript symbols alone finds two keys and is incomplete.

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    The three authorable keys, each on BOTH faces. ObjectFormSchema.recordId (objectql.ts + zod/objectql.zod.ts), DetailViewSchema.resourceId (views.ts + zod/views.zod.ts) and DetailSchema.resourceId (crud.ts + zod/crud.zod.ts). ⚠️ The crud pair is DetailSchema, not DetailViewSchema, and it reaches the same renderer — not by symbol but by data flow: plugin-detail registers the 'detail' node type onto DetailView. A read that follows TypeScript symbols alone finds two keys and is incomplete.

.changeset/9549-tree-filter-declared.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    ObjectTreeSchema.filter is declared on both faces, in the shape objectui#9309 settled for ObjectGallerySchema.filter: QueryParams['$filter'] by indexed access on the TS interface in objectql.ts, and the same two-arm union (array first) on the zod mirror in zod/objectql.zod.ts (objectui#9549).

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    ObjectTreeSchema.filter is declared on both faces, in the shape objectui#9309 settled for ObjectGallerySchema.filter: QueryParams['$filter'] by indexed access on the TS interface in objectql.ts, and the same two-arm union (array first) on the zod mirror in zod/objectql.zod.ts (objectui#9549).

.changeset/9550-object-tree-root-barrel.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    ObjectQLComponentSchema declares the node types an ObjectQL block may be. Every one of its arms was a named export of this package's root barrel except ObjectTreeSchema, which was declared in objectql.ts, applied by the union, and re-exported by the ./zod barrel (objectui#7917) — while no TypeScript consumer could name it. There is no ./objectql subpath to reach around the barrel: the package's exports map is pinned by packages/types/src/__tests__/package-exports-manifest.test.ts, and the root barrel was the only route to this type.

.changeset/9606-object-kanban-card-title.md

  • names zod/objectql.zod.ts → packages/types/src/zod/objectql.zod.ts — edited by this change

    Both published faces of the object-kanban arm now name the key: the zod mirror ObjectKanbanSchema in zod/objectql.zod.ts and its TypeScript twin, the ObjectKanbanSchema interface in objectql.ts. Both declare it OPTIONAL, at the same requiredness the other face uses, so the two faces accept and refuse the same documents. (Located and cited by SYMBOL: line addresses in zod/objectql.zod.ts have drifted before, and this change is itself about a drifted mirror.)

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    Both published faces of the object-kanban arm now name the key: the zod mirror ObjectKanbanSchema in zod/objectql.zod.ts and its TypeScript twin, the ObjectKanbanSchema interface in objectql.ts. Both declare it OPTIONAL, at the same requiredness the other face uses, so the two faces accept and refuse the same documents. (Located and cited by SYMBOL: line addresses in zod/objectql.zod.ts have drifted before, and this change is itself about a drifted mirror.)

.changeset/9628-kanban-column-collapsed-honoured.md

  • names objectql.ts → packages/types/src/objectql.ts — edited by this change

    The key was declared on both published faces of the object-kanban arm — the lane element of ObjectKanbanSchema (objectql.ts and its Zod mirror) and the runtime lane KanbanColumn (complex.ts and its mirror) — and read by KanbanEnhanced alone, a module no production source imports. An authored { "id": "todo", "title": "To Do", "collapsed": true } therefore parsed green on both faces and reached a board that did nothing with it: KanbanImpl's only collapse is the SWIMLANE row's, held in viewer state under objectui:kanban-collapsed:ANGLE-BRACKETS(swimlaneField) and never keyed to a lane's declared value. That is the ADR-0049 declared-but-unhonoured shape.

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.

Angle-bracketed names in the quoted prose above are rewritten as ANGLE-BRACKETS(name): GitHub deletes tag-shaped fragments from a stored body, and a quote that silently loses the identifier it is about is worse than a visible repair.

Compared the checked-out tree with 582edef1c (merge-base with origin/main): 5 file(s) changed outside .changeset/, read against 1871 pending declaration(s) that publish a body (2483 pending in total). · run

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 330 chunks) 3584.9 KB 3607.4 KB
Main entry chunk (gzip) 150.1 KB 350 KB
Entry file index-DnEr2snK.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.88KB 6.25KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
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.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.17KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
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) 570.17KB 136.43KB
core (index.js) 10.00KB 3.96KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 229.96KB 63.80KB
fields (index.js) 261.11KB 66.26KB
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 (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.49KB 9.23KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 40.95KB 11.48KB
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.86KB 5.00KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.52KB 2.26KB
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) 52.90KB 15.35KB
plugin-charts (index.js) 84.09KB 22.93KB
plugin-chatbot (index.js) 198.22KB 46.97KB
plugin-dashboard (index.js) 139.27KB 37.26KB
plugin-designer (index.js) 216.45KB 44.60KB
plugin-detail (index.js) 244.79KB 64.47KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 173.75KB 44.64KB
plugin-gantt (index.js) 173.03KB 43.07KB
plugin-grid (index.js) 231.61KB 63.61KB
plugin-kanban (index.js) 49.32KB 15.48KB
plugin-list (index.js) 116.63KB 28.97KB
plugin-map (index.js) 23.50KB 7.82KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.04KB 12.21KB
plugin-timeline (index.js) 33.05KB 9.67KB
plugin-tree (index.js) 11.20KB 3.89KB
plugin-view (index.js) 90.32KB 22.76KB
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.81KB 3.58KB
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) 119.55KB 39.23KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.50KB 2.06KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.50KB 1.99KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 6.06KB 2.68KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 21.42KB 7.05KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 3.19KB 1.62KB
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.26KB
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) 2.52KB 1.31KB
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) 4.99KB 1.96KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 21.59KB 7.71KB
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

…es, and allDayField is a spec key since 17.5.0 (objectui#8831)

The plugin-calendar docs page said neither published face of
ObjectCalendarSchema declares the calendar container; both have since
objectui#8651. The paragraph now states what the two faces and the spec
check inside the block, measured on the installed 17.5.0.

Three pending changesets (8026, 8830, olive-buckets-scream) still described
allDayField as objectui-local or refused by the spec, which objectui#11073's
bump made false; olive-buckets-scream also said the dateField / endField
rungs are kept, which objectui#8355 made false. Each gets a dated,
append-only correction with its frontmatter unchanged.

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

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 330 chunks) 3585.1 KB 3607.4 KB
Main entry chunk (gzip) 150.4 KB 350 KB
Entry file index-CxR2G_gj.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.88KB 6.25KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
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.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.17KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
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) 570.17KB 136.43KB
core (index.js) 10.00KB 3.96KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 229.96KB 63.80KB
fields (index.js) 261.11KB 66.26KB
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 (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.49KB 9.23KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 40.95KB 11.48KB
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.86KB 5.00KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.52KB 2.26KB
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) 52.90KB 15.35KB
plugin-charts (index.js) 84.09KB 22.93KB
plugin-chatbot (index.js) 198.22KB 46.97KB
plugin-dashboard (index.js) 139.36KB 37.31KB
plugin-designer (index.js) 216.45KB 44.60KB
plugin-detail (index.js) 244.79KB 64.47KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 173.75KB 44.64KB
plugin-gantt (index.js) 173.03KB 43.07KB
plugin-grid (index.js) 231.61KB 63.61KB
plugin-kanban (index.js) 49.32KB 15.48KB
plugin-list (index.js) 116.63KB 28.97KB
plugin-map (index.js) 23.50KB 7.82KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.04KB 12.21KB
plugin-timeline (index.js) 33.05KB 9.67KB
plugin-tree (index.js) 11.20KB 3.89KB
plugin-view (index.js) 90.32KB 22.76KB
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.81KB 3.58KB
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) 119.55KB 39.23KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.50KB 2.06KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.50KB 1.99KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 6.06KB 2.68KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 21.42KB 7.05KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 3.19KB 1.62KB
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.26KB
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) 2.52KB 1.31KB
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) 4.99KB 1.96KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 21.59KB 7.71KB
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: a86a6afdbdee780ec7c8c4b6be8e46ec8ee710fa
Local-runs: none

Reviewed at 2026-10-01T02:19Z. Inputs: card #8831 (body and all 15 comments), PR #11308 (body, 10-file list, net diff against main at the head), the check-runs on the head, objectui AGENTS.md at origin/main, and the installed spec 17.5.0 source at objectstack 0f6dcac5e9 (component.zod.ts, view.zod.ts). Files on main and on the head were read with git show, never checked out. Head and base agree with the PR: two commits on top of 1ccb5ba7d, 10 files, +324/-110.

① Derived judgments

Each published-face change the diff implies, judged against 17.5.0 and the tree on main:

  • zod face, ObjectCalendarSchema flat members (startDateField, endDateField, titleField, colorField, allDayField): only the .describe() string moves, through the new helper objectCalendarFlatField. Each stays z.string().optional(). Accept set unchanged. The new text is true: getCalendarConfig on main returns schema.calendar whole when present and reads the flat keys only in its if (schema.startDateField) fallback; ListView's and ObjectView's object-calendar branches emit the flat keys on the node they build (startDateField, endDateField, titleField explicitly, the rest through ...restCalendar); and 17.5.0's OBJECT_CALENDAR_FLAT_FIELD_GUIDANCE refuses all five flat on object-calendar with the prescription "Write this as a key of the calendar config object instead". Right.
  • zod face, ObjectCalendarSchema.calendar: description only ("the AUTHORED spelling of the five field-name keys ... Read FIRST by getCalendarConfig"). Schema unchanged (ObjectCalendarBlockConfigSchema.optional()). Matches the renderer's read order. Right.
  • zod face, ObjectCalendarBlockConfigSchema.allDayField: description and comment only; the member stays z.string().optional(). The claim "Declared by the spec's CalendarConfigSchema since 17.5.0, with the same accept set as this member" is true at the source: 17.5.0's CalendarConfigSchema declares allDayField: z.string().optional(). The extension is an identity, as the PR says. Right.
  • TS face, ObjectCalendarSchema docblocks (calendar and the five flat members; publishes into the .d.ts): no member type or optionality moves. Claims checked: ComponentPropsMap['object-calendar'].calendar is z.unknown().optional() on 17.5.0 (true, read at the source); "since 17.5.0 CalendarConfigSchema declares all five" (true); "this flat member is still typed string ... the two types are equal" (true: string | undefined both sides; CalendarConfig resolves, it is re-exported from @objectstack/spec/ui in that file). Right.
  • README, packages/plugin-calendar/README.md: both object-calendar snippets now write the field-name keys inside calendar: { ... } (first: all five; second: three). Doc Snippet Type Check on the head is green, so the snippets compile against the TS face. The behavioural prose is true against ObjectCalendar.tsx on main: a block is returned whole, so a misspelt start key leaves record[startDateField] empty and the events pass pushes every record to unscheduled (no refusal screen); a node with no block and no flat start key returns null and renders "Calendar configuration required", whose hint text names "the view's calendar block". The calendar-view sentence is kept flat and scoped in words; that is correct, since 17.5.0's ComponentPropsMap has no calendar-view row and CalendarViewSchema on main declares the five flat keys and no calendar member. Right.
  • Docs page, content/docs/plugins/plugin-calendar.mdx, CalendarConfig paragraph: each sentence holds. Both faces declare the container (ObjectCalendarBlockConfigSchema, derived ObjectCalendarBlockConfig); values are checked (derived from the spec's z.string() members); dateField / endField are refused by name there (CalendarContainerDateAliasRefusals); the block ends .passthrough(); the spec declares the calendar key on object-calendar as z.unknown(); the list-view mirror CalendarConfig is stripImportedDefaults(SpecCalendarConfigSchema).partial().extend({...}).passthrough() while the spec's own CalendarConfigSchema is a strictObject. Right.
  • Changesets, five bodies that publish verbatim:
    • new 8831-calendar-flat-teaching-face.md: true against 17.5.0 (the refusal, the prescription, the five-key CalendarConfigSchema). One imprecision, not a falsehood: "both object-calendar examples in the README write the five keys inside calendar" — the second example writes three of the five, all inside calendar. Right, with that note.
    • 8026 note: "declares five keys, allDayField among them ... still refuses defaultView" (true: strict object of five, no defaultView); "that mirror derives from the spec schema, so allDayField is now a declared member of it" (true: CalendarConfig is derived, with no local allDayField extension); attribution to objectui#11073, whose changeset is pending on main, so "this same release" holds. Right.
    • 8466 note: the entry's first two paragraphs do say the README teaches the five flat keys; the README now does not, on object-calendar; the calendar-view sentence stays; the declarations are unchanged; the spec twin claim is true on 17.5.0. Right.
    • 8830 note: "the four plus objectui's own allDayField" is false on 17.5.0, as the note says; the rest of the entry re-measures true (both objectui faces still .passthrough(); calendar-doc-key-set-8830.test.ts is on main). Right.
    • olive-buckets-scream note: the dateField / endField rungs are gone from getCalendarConfig on main and the container refuses both by name; objectui#8355's changeset is pending on main, so "in this same release" holds; calendar.defaultView and unexamined keys still parse (.passthrough(), no defaultView refusal in the block). Right.
    • Append-only discipline: all four hunks are pure appends at end of file, 0 deletions, frontmatter untouched. Changeset Overwrite Report and Changeset Claim Re-read are green on the head.
  • Test, calendar-flat-color-allday-8466.test.ts: the README row is inverted to the new teaching with brace-matched extraction and a calendar-view control (the README has a flat titleField on a calendar-view node, so the control can fire). The maskComments import with its @ts-expect-error is the same construction calendar-doc-key-set-8830.test.ts in the same directory already uses. Not a published face; the dev's reverse verification reddened it on a planted flat key.
  • Region held: the diff touches neither ObjectCalendarSchema.objectName nor requireRecordSource (objectui#11117); objectName appears only in unchanged README snippet lines and one README prose line.
  • AGENTS.md [WIP] Update documentation for project #11: no path:line citation in any added line; Line Citation Gate green.

② Semver level

Clause-②: no is verified from the zod and TS diffs: no member added or removed, no type or requiredness moved, no refusal added; only .describe() strings, comments, docblocks, README, docs page and a test. The changeset declares @object-ui/types: patch and @object-ui/plugin-calendar: patch. That matches what publishes: changed .describe() bytes on the zod face, changed docblocks in the .d.ts, and a rewritten package README. An empty frontmatter would under-declare published-byte changes; minor would over-declare, since nothing an author can write changes verdict. No major (Changeset Bump Policy and Fixed Group Check green). Right.

③ Boundary flags

  • H1 (calendar-view site): kept flat, scoped in words. Verified true (no calendar-view row in the 17.5.0 map; no container on CalendarViewSchema). Answered.
  • H2 (.extend({ allDayField }) now an identity): description-only edit; the member is kept so the zod-mirror-parity.test.ts ledger comment is not made false. Answered for this PR. The removal and that ledger comment have no carrier (objectui#6152 holds the file, it does not carry this). Escalated: the seat should open or name a carrier.
  • H3 (docs pages teaching the flat object-calendar spelling): falsified; the one stale plugin-calendar.mdx paragraph was fixed in round 2 instead. Answered.
  • H4 (8830 test header): left as a dated measurement, framed "with @objectstack/spec 17.4.0 installed then"; its AUTHORING FACE row about the undeclared container is likewise history. Acceptable as dated history in a test comment, not a published face. Answered.
  • Round 1 open_questions: none.
  • Out-of-scope findings and Acceptance notes: the mdx drift and the three pending changesets were folded into round 2 (done). The ObjectCalendar.tsx ObjectCalendarConfig docblock is a stale entry in check-installed-spec-pin-claims.mjs (carrier: that ledger). The registry-inputs-spec-parity.test.ts pin text: objectui#11168 holds the file and the seat booked it there. The list-view mirror note in objectql.zod.ts that cites "calendar's allDayField" as a knob ahead of the protocol has no carrier (outside this region; neighbouring regions held by PR feat(types)!: showFilters is retired on object-grid, refused by name with the list view's userActions.filter named (objectui#11068) #11306 and objectui#11117). Escalated with H2: one follow-up card for the three 17.5.0 drifts without a carrier (identity extension removal, zod-mirror-parity ledger comment, list-view mirror note).
  • Deviations declared by the dev: git fetch --deepen=1000 on the shared clone (additive); a scratch test created and deleted; one no-op ablation attempt re-run. None touches the contract.
  • Check-runs on the head, read at 2026-10-01T02:17Z: 42 runs, 30 success, 3 skipped, 9 in_progress. In progress, recorded as such and not as verdicts: Type Check, Spec Main Shape Gate, Test shards 1, 2, 3, 4, 6, 7, 8. Green and load-bearing for the faces above: Doc Snippet Type Check, README Export Check, Lint, Line Citation Gate, the five Changeset gates, Doc Component Type Check, Doc Fence Language Check, Test (dist pins), Test shard 5.

Implemented-by: claude/issue-8831-calendar-flat-teaching-face
Reviewed-by: session_01VhxTqosz7wn54ahqyxgERT

VERDICT: PASS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation package: types plugin tests

Projects

None yet

2 participants