You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(spec): calendar in allowedVisualizations requires calendar.startDateField (#13817) (#14075)
Cross-field refinement on the list-view schema, attached at all three doors
(ListViewSchema, ObjectListViewSchema, the flattened runtime overlay arm):
'calendar' in appearance.allowedVisualizations with no calendar: block now
refuses loudly at parse, naming calendar.startDateField and both remedies.
titleField on CalendarConfigSchema moves required -> optional per the ruled
'only startDateField is load-bearing' measurement (ADR-0079 title fallback,
measured in objectui ObjectCalendar.tsx). Regenerated reference docs.
Ruled on #13748 (2026-08-31, director batch #19, option A); spec half of the
two-half fix, objectui#7029 is the runtime half.
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
Co-authored-by: Claude <noreply@anthropic.com>
feat(spec): calendar in `appearance.allowedVisualizations` now requires `calendar.startDateField` on list views (#13817)
6
+
7
+
**BREAKING** accept-set narrowing on `ListViewSchema` (and its two derived
8
+
doors, `ObjectListViewSchema` and the flattened `ViewMetadataSchema` list
9
+
overlay), shipped as `minor` under the repo's launch-window convention for
10
+
breaking changes. Ruled on #13748 (2026-08-31, option A — fix both halves);
11
+
this is the spec half, objectui#7029 is the runtime half.
12
+
13
+
A view declaring `appearance.allowedVisualizations: [... 'calendar']` with no
14
+
`calendar:` block used to parse clean. Downstream (measured on #13748): the
15
+
calendar toggle rendered and was clickable, objectui invented
16
+
`startDateField: 'due_date'`, and the renderer landed every record without
17
+
that field on "today" — a plausible-looking, fully wrong screen, with the
18
+
renderer's own refusal screen unreachable because the synthesized config
19
+
always looked complete. The parse now **rejects loudly**, naming
20
+
`calendar.startDateField`, why the date has no truthful fallback, and both
21
+
remedies (declare the block, or drop `'calendar'` from the whitelist).
22
+
23
+
In the same stroke `CalendarConfigSchema.titleField` moves required →
24
+
**optional**: only `startDateField` is load-bearing — the renderer resolves a
25
+
missing title through the ADR-0079 record display-name chain (measured in
26
+
objectui `ObjectCalendar.tsx`: an explicit `titleField` wins only "when
27
+
present"). Keeping it required would have made the new cross-field gate
28
+
demand more than the renderer reads, which the ruling forbids. Every
29
+
previously-valid calendar block stays valid.
30
+
31
+
Scope: `calendar` only — the measured defect. Whether `timeline` or another
32
+
visualization has the same shape is a separate finding to measure first (the
33
+
ruling says so in those words); a scope pin test asserts the requirement does
34
+
not leak to `timeline`.
35
+
36
+
<!-- adr-0087: not-required (no-migration-prescription) A validity narrowing over existing keys plus an optionality widening: no key is removed, renamed or re-shaped, so there is no tombstone and nothing mechanical for `objectstack migrate meta` to rewrite. The refusal is the channel that reaches an affected author, at the parse site, naming the one missing key and both remedies; whether a calendar switcher entry meant "bind a date field" or "drop the visualization" is authoring intent no migration entry can decide. The measured in-repo population of affected sources is zero (examples, lint fixtures, spec fixtures, skills, docs snippets all either bind `calendar.startDateField` already or do not whitelist calendar). -->
0 commit comments