Found while delivering objectui#8348 (PR objectui#9234). ⛔ Not fixed there and not claimed here: it is a change to a published contract declaration, not to a renderer read, so it wants its own review.
The two faces disagree, on one key, in opposite directions
ComponentPropsMap['object-calendar'].data on @objectstack/spec 17.4.0 — the version pnpm-lock.yaml resolves for this repo — is the array arm:
z.array(z.unknown()).optional()
.describe('Pre-fetched records — skips the internal fetch')
safeParse({ objectName: 'visit', data: { provider: 'value', items: [] } })
-> success=false [{ code: 'invalid_type', path: ['data'], expected: 'array' }]
Both published faces of this repo's own mirror declare the object arm instead:
packages/types/src/zod/objectql.zod.ts — ObjectCalendarSchema.data: ViewDataSchema.optional().describe('Data source configuration — read FIRST by getDataConfig; undeclared on either face until objectui#7313')
packages/types/src/objectql.ts — data?: ViewData
So one key has two published shapes that refuse each other by kind. AGENTS.md Commandment #0 is explicit about which way that resolves:
#0 — Strict adherence to @objectstack/spec. All schemas/JSON structures/types MUST follow @objectstack/spec.
Why it matters now rather than as a curiosity
objectui#8348's ruling (decision batch #83, 2026-09-08, maintainer verbatim 「8348 以协议为准」) put the RENDERER on the spec's side: ObjectCalendar no longer honours a { provider, items } object under data. The mirror is now the only published face still declaring that spelling as authorable — so an author who validates against @object-ui/types gets a green verdict for metadata the renderer ignores, os validate refuses and the save gate rejects. That is declared !== enforced with the declaration on the wrong side, which is the shape AGENTS.md #0.1 exists to prevent.
The divergence pre-dates objectui#8348 — that card did not create it, and its PR is coherent without this — but that card is what makes the mirror the lone outlier.
What a fix touches, measured
This is not a one-line edit, which is the other reason it is filed rather than folded in:
- both mirror faces, kept at equal requiredness for the
zod-mirror-parity ratchet;
packages/types/src/__tests__/object-calendar-record-source-7313.test.ts, which pins the declaration at the TYPE level twice — Equal of TsObjectCalendarSchema.data and ViewData-or-undefined, and an equality with TsObjectGanttSchema.data (object-gantt keeps the object arm, so that pair must be split);
- the same file's document fixtures, whose
dataOnly calendar document is { data: { provider: 'value', items: [...] } };
requireRecordSource('object-calendar'), whose wording should follow (data becomes pre-fetched records, not a source to fetch from);
content/docs/plugins/plugin-calendar.mdx, already corrected on the renderer side by PR objectui#9234 and registered in scripts/markdown-test-inputs.mjs.
Related
objectui#8348 (the ruling and the renderer half) · objectui#7313 (which declared this key, in the object arm) · objectui#4631 (the general "three declared surfaces that disagree" class) · objectui#8201 · AGENTS.md #0 / #0.1
Reported by an ObjectUI development agent running Claude Code, in session session_01UzHd6hDYatoDn17BuwKxnZ, while delivering objectui#8348. Written as prose because issue creation strips an attribution footer block.
Generated by Claude Code
Found while delivering objectui#8348 (PR objectui#9234). ⛔ Not fixed there and not claimed here: it is a change to a published contract declaration, not to a renderer read, so it wants its own review.
The two faces disagree, on one key, in opposite directions
ComponentPropsMap['object-calendar'].dataon@objectstack/spec17.4.0 — the versionpnpm-lock.yamlresolves for this repo — is the array arm:Both published faces of this repo's own mirror declare the object arm instead:
packages/types/src/zod/objectql.zod.ts—ObjectCalendarSchema.data: ViewDataSchema.optional().describe('Data source configuration — read FIRST by getDataConfig; undeclared on either face until objectui#7313')packages/types/src/objectql.ts—data?: ViewDataSo one key has two published shapes that refuse each other by kind. AGENTS.md Commandment #0 is explicit about which way that resolves:
Why it matters now rather than as a curiosity
objectui#8348's ruling (decision batch #83, 2026-09-08, maintainer verbatim 「8348 以协议为准」) put the RENDERER on the spec's side:
ObjectCalendarno longer honours a{ provider, items }object underdata. The mirror is now the only published face still declaring that spelling as authorable — so an author who validates against@object-ui/typesgets a green verdict for metadata the renderer ignores,os validaterefuses and the save gate rejects. That isdeclared !== enforcedwith the declaration on the wrong side, which is the shape AGENTS.md #0.1 exists to prevent.The divergence pre-dates objectui#8348 — that card did not create it, and its PR is coherent without this — but that card is what makes the mirror the lone outlier.
What a fix touches, measured
This is not a one-line edit, which is the other reason it is filed rather than folded in:
zod-mirror-parityratchet;packages/types/src/__tests__/object-calendar-record-source-7313.test.ts, which pins the declaration at the TYPE level twice —Equal of TsObjectCalendarSchema.data and ViewData-or-undefined, and an equality withTsObjectGanttSchema.data(object-ganttkeeps the object arm, so that pair must be split);dataOnlycalendar document is{ data: { provider: 'value', items: [...] } };requireRecordSource('object-calendar'), whose wording should follow (databecomes pre-fetched records, not a source to fetch from);content/docs/plugins/plugin-calendar.mdx, already corrected on the renderer side by PR objectui#9234 and registered inscripts/markdown-test-inputs.mjs.Related
objectui#8348 (the ruling and the renderer half) · objectui#7313 (which declared this key, in the object arm) · objectui#4631 (the general "three declared surfaces that disagree" class) · objectui#8201 · AGENTS.md #0 / #0.1
Reported by an ObjectUI development agent running Claude Code, in session
session_01UzHd6hDYatoDn17BuwKxnZ, while delivering objectui#8348. Written as prose because issue creation strips an attribution footer block.Generated by Claude Code