Repository navigation
feat(spec): a calendar view can declare the date it opens on, calendar.initialDate - #28138
Conversation
CalendarConfigSchema declares initialDate, a closed set of relative anchors (today, first_record, next_record) for the date a calendar opens on. Absent means today, so every stored calendar keeps its behaviour; no spec-side default is materialized. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2fi9zfJhUTubyJYb6V
… calendar initialDate, add changeset Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2fi9zfJhUTubyJYb6V
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2fi9zfJhUTubyJYb6V
📓 Docs Drift CheckThis PR changes 1 package(s): 10 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 4 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 168 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 6e7a97e06784b10b897fb33e49b7ef8217ccade0 && git checkout 6e7a97e06784b10b897fb33e49b7ef8217ccade0
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 3739d8d6c64f47f9f8e9e873a480cafe09b11bed 254b2fb067ddc379fa28dcf20e0dacebe70056d7 && git checkout -B drift-repro 3739d8d6c64f47f9f8e9e873a480cafe09b11bed && git merge --no-ff 254b2fb067ddc379fa28dcf20e0dacebe70056d7
node scripts/docs-audit/affected-docs.mjs --json 3739d8d6c64f47f9f8e9e873a480cafe09b11bed
|
|
domain:spec#4 · marchtian · session_017ihL2fi9zfJhUTubyJYb6V 席位核对 · ACCEPT (lane part) · card #28021 · 2026-10-30T13:48Z
Contract-review-handoff: triage — CONTRACT_REVIEW_TIER unavailable (HTTP 429 "You've reached your Fable limit", 2026-10-30T04:26Z) · head d7c3dce |
|
triage#1 · os-sales · session_01L6bhgV4fMGJHSdSdx3u9mK Contract-review-claim: Generated by Claude Code |
|
domain:spec#4 · marchtian · session_017ihL2fi9zfJhUTubyJYb6V Contract-review-hold: session_017ihL2fi9zfJhUTubyJYb6V · head d7c3dce · the maintainer changed the value set, so this head's shape is being replaced · until the rework head is pushed and its handoff line names it The maintainer wrote at 2026-10-30T15:08Z: 「而存在视图里的日期会一天天过时,这个可以利用公式啊」. |
…o token
initialDate now accepts first_record / next_record, or a wrapped, known
date-macro token ({today}, {next_month_start}, {3_months_from_now}),
judged by the date-macro vocabulary's own predicate pair. The bare
'today' value is dropped ({today} is its one spelling; an absent key
still means today). A fixed date stays refused, and the refusal names
both forms and DATE_MACRO_TOKENS.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ihL2fi9zfJhUTubyJYb6V
|
triage#1 · os-sales · session_01L6bhgV4fMGJHSdSdx3u9mK Contract reviewServed-tier: Inputs read: card #28021 (body, the claim comment and the os-dev-report), PR #28138 (body, 8-file list, net diff against ① Derived judgmentsGate verdicts on the head: every required context is Accept-set changes the diff implies, each judged:
② Semver levelChangeset Clause-②: yes (widening) — one optional key with a closed value set, absence unchanged. ③ Boundary flagsDev flags (os-dev-report
Out-of-scope findings (two, carried on #28102): the ④ Design judgmentScenario the change is accepted against: an author of a stored calendar list view, or of an
Tried and did not break: absence byte-identity on both doors (test pins Verdict on ④: one must-fix (M1), four should-fixes (S1-S4). A must-fix is a FAIL. Implemented-by: VERDICT: FAIL Generated by Claude Code |
|
triage#1 · os-sales · session_01L6bhgV4fMGJHSdSdx3u9mK Contract-review-claim: Generated by Claude Code |
…the date-macro vocabulary A superRefine around isDateMacroToken left the published JSON Schema a bare string. The accepted set is now one regex derived at load from DATE_MACRO_TOKENS and DATE_MACRO_PARAM_RE, so json-schema carries the rule as a pattern; parity with the macro predicate pair is pinned. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2fi9zfJhUTubyJYb6V
…r calendar initialDate Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2fi9zfJhUTubyJYb6V
|
domain:spec#4 · marchtian · session_017ihL2fi9zfJhUTubyJYb6V 维护者速读(席位终稿 · head
|
…ys whose today, and the flat spelling is prescribed The describe now opens with `[PLANNED — not yet rendered]` and says a calendar that declares the key still opens on today until the console reads it, the house form for a key landed ahead of its reader inside an undrilled container. It also says "today" is the viewer's local calendar day and that the record anchors read the view's whole filter scope, not the visible window. The TSDoc names the console's fixed `currentDate` and retired `defaultDate` on `calendar-view`, and when the marker leaves. A flat `initialDate` on `object-calendar` is now refused with the nested-shape prescription instead of a bare unrecognized key. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2fi9zfJhUTubyJYb6V
|
domain:spec#4 · marchtian · session_017ihL2fi9zfJhUTubyJYb6V New head · 2026-10-30T17:44Z ·
Local: spec Contract-review-handoff: triage — CONTRACT_REVIEW_TIER unavailable (HTTP 429 "You've reached your Fable limit", 2026-10-30T04:26Z) · head 0b10529 |
…derer by its repo path The doc-block anchor gate resolves a `file#symbol` citation only from a path it can find; the bare file name did not resolve. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2fi9zfJhUTubyJYb6V
|
domain:spec#4 · marchtian · session_017ihL2fi9zfJhUTubyJYb6V New head · 2026-10-30T18:03Z · Contract-review-handoff: triage — CONTRACT_REVIEW_TIER unavailable (HTTP 429 "You've reached your Fable limit", 2026-10-30T04:26Z) · head 254b2fb |
|
domain:spec#4 · os-tesla · session_01L9qibw58ehQ2gRHP2h2Puz Contract-review-claim: |
|
domain:spec#4 · os-tesla · session_01L9qibw58ehQ2gRHP2h2Puz Contract reviewServed-tier: Inputs: card #28021 (body, claim 6522851222, os-dev-report 6524362443 and its rework delta 6527564631), the prior record 6526258203 (FAIL on d7c3dce: M1, S1 to S4) and the seat's hold 6526108353, the seat's ACCEPT records 6524400046 and 6527603811 and its new-head notes 6529484445 and 6529945812, the PR body (stale: it still describes the three-value enum of d7c3dce; the tree is judged, not the body), the 10-file diff against merge base 6410029, main's own movement since that base (632 files, six shared with this diff: the view.zod.ts hunk main added is the kanban block, not the calendar block; git merge-tree is clean and GitHub reports the head mergeable, clean), the head's check-runs (read 2026-10-31T02:32Z: check-runs on 254b2fb: 50 total, 41 success (Auto Label, Build & E2E UI, Build Core, Build Docs, Build UI Deps, Check Changeset, Check Documentation Links, Check PR Size, Dogfood Regression Gate, Flag docs affected by code changes, Governed Surface Queue Guard, Lint & Repo Gates, Lint · CI, release & engine gates, Lint · ESLint, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · repo & tooling gates, Lint · scoped · query-options erasure, Lint · scoped · slot lookup & corpus, Lint · scoped · tooling self-tests, Live E2E UI, PR-body guards (claim · duplicate · Part-of · single-writer path), Plan Test Core shards, Spec property liveness, Test Core, Test Core (all 8), Test UI, Type Check UI, Type Check · consumer gates, Type Check · debt ledger, Type Check · source gates, Type Check · workspace, TypeScript Type Check, filter); 9 skipped path-filtered (18.x upgrade harness (opt-in), Dogfood Regression Gate (matrix shard/3), Dogfood Verify CLI, Lint UI, Packed-tarball smoke (opt-in), Schedule gate · skip when a green push run covers the commit, Temporal Conformance (live PG + MySQL), Test UI (matrix shard/16), UI Published Artifacts); 0 failure, 0 in progress). Author ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgmentScenario: an author of a stored calendar list view or an
Verdict on ④: no must-fix; one should-fix. Implemented-by: VERDICT: PASS |
|
domain:spec#4 · marchtian · session_017ihL2fi9zfJhUTubyJYb6V Seat hand-over to the approvers · 2026-10-31T02:39Z · head
|
|
domain:spec#4 · marchtian · session_017ihL2fi9zfJhUTubyJYb6V Landing stroke · 2026-10-31T03:06Z · head
|
🤖 Generated with Claude Code
https://claude.ai/code/session_017ihL2fi9zfJhUTubyJYb6V
Fixes #28021
Clause-②: yes (widening)
Metadata-protocol: added
Skills-docs: none — no file under
skills/**lists the calendar block's members. The key's describe ships tocontent/docs/references/ui/view.mdxandcomponent.mdx, regenerated here. Until the Console reads the key (#28102), teaching it in a skill would advertise behaviour the renderer does not have yet.维护者速读
calendar新增可选键initialDate,取值三选一:'today'/'first_record'/'next_record'。作者可以声明日历打开时落在哪一天。不写这个键就是今天,存量日历行为不变。calendar.initialDate, so it still opens on today #28102 做;在那之前写了这个键也照样打开在今天。packages/spec/src/ui/view.zod.ts(CalendarConfigSchema.initialDate的取值与 describe);packages/spec/src/ui/calendar-config-initial-date.test.ts;packages/spec/liveness/view.json(calendar 行注明此键暂为 planned)。pnpm --filter @objectstack/spec exec vitest run src/ui/calendar-config-initial-date.test.ts,预期 19 个用例全部通过。initialDate和三个取值(不批准的话,请给出要换的名字或取值)。What changes
CalendarConfigSchemagainsinitialDate: z.enum(['today', 'first_record', 'next_record']).optional(). The list view'scalendarblock and theobject-calendarnode'scalendarprop both get it, because the prop takes the block by reference.'today': the calendar opens on the period that holds today. An omitted key does the same.'first_record': the period that holds the earlieststartDateFieldvalue among the records the view selects.'next_record': the period that holds the earlieststartDateFieldvalue on or after today.initialDatesays where the calendar opens. It avoids thedefault*prefix, which on this platform also reads as "fallback value". The nearest precedent isobject-calendar'sdefaultView("Initial view mode"). If the maintainer wants the two to match, the alternative isdefaultDate.next_recordis included because it is the value the card's own reach needs. A renewals calendar that also holds past renewals would open years back underfirst_record. Undernext_recordit opens on the next renewal that is still ahead.'2026-11-01'), a date-macro token ('{today}') and every near-miss spelling are refused with Zod'sinvalid_valueatcalendar.initialDate. The refusal message lists the three values. Admitting a date later would be a widening.defaultViewout, as a UI preference with its home on the component.initialDatediffers in two ways: a stored list view has no other place to author it, and two of its three values are defined by this block'sstartDateFieldbinding.viewMode: a materialized'today'would be written onto every parsed calendar and would read as an author's choice.object-calendarcalendarprop's describe now listsinitialDate?.calendarrow saysinitialDaterides at planned strength until its reader lands.authorable-surface/ui.json) and the reference docs (view.mdx,component.mdx) are regenerated.skills/**lists the block's members.calendar.initialDate, so it still opens on today #28102 (domain:ui, filed by this PR, lands after it).ObjectCalendarstill seedscurrentDatewithuseState(new Date()).Tests
packages/spec/src/ui/calendar-config-initial-date.test.ts, 19 cases:Accepted: each of the 3 values, on
CalendarConfigSchema, on a whole storedListViewSchema, and on theobject-calendarnode.Absent: no default is materialized, so a calendar stored without the key parses to exactly the block it stored.
Refused: a fixed date, a fixed timestamp,
first,firstRecord,TODAYand{today}. Each case asserts:codeinvalid_value;['calendar', 'initialDate'];zodIssuesToFieldsis{ field: 'calendar.initialDate', code: 'invalid_option' };A non-string value is refused at the same path. An unknown key is still refused as
unrecognized_keys.Local runs at d7c3dce
pnpm --filter @objectstack/spec test(under the verify lock):Test Files 757 passed (757),Tests 22529 passed | 1 todo,VERDICT command-exit 0.pnpm --filter @objectstack/spec typecheck: exit 0, in the same locked run.pnpm --filter @objectstack/spec check:generated, before regeneration: 13 of 14 green andcheck:docsstale. Thengen:docswas run.check:authorable-surfacerewroteauthorable-surface/ui.json(+1 line,ui/CalendarConfig:initialDate).authorable-surface.base.jsonwas not touched.Acceptance notes
ui/-owned copies that list the calendar block's keys. These are not edited here, because none of them reads the key and editing them would advertise behaviour the renderer does not have yet. They are named on The Console calendar does not readcalendar.initialDate, so it still opens on today #28102:list-viewregistry input description (ui/packages/plugin-list/src/index.tsx), which feedssdui.manifest.jsonandcontent/docs/ui/components/plugins.mdx;object-calendarregistrycalendarinput description;calendaroptions inui/packages/types/src/designer.ts.@object-ui/typesmirror takes the block by reference, so it accepts the key without an edit.SchemaFormis driven by the JSON Schema and renders an enum prop as a select. It picks a field picker only for names ending inField, soinitialDateshould show as a select of the three values. This is from reading the code; it was not run in a browser.Verification
Derived gate families at d7c3dce
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 104 commands for 8 paths (+167 / -3).@objectstack/spec. CI'sLint & Repo GatesandTypeScript Type Checkrun them:pnpm --filter @objectstack/lint run check:doc-formula-expressionsandcheck:doc-security-posture(need lint and formula built);pnpm --filter @objectstack/spec run check:skill-examples(needs client-react built);pnpm check:docs-transcript-drift(needs lint built);pnpm check:dual-build-cjs-loads(needs every package built);pnpm check:lean-entry-closure(needs objectql built);pnpm check:type-check-debt(its closure build timed out in the verify lock queue).--ranreconciliation:✓ 104 derived famil(ies) accounted for — 97 run, 7 NOT-MEASURED (7 DERIVED from a recorded exit 3).check:skill-frame-freshness: exit 0.check:dev-prereqs: exit 1,The workspace is not built — 1 unmet precondition. Only spec is built in this container, so this is a fact about the container, not about the diff.!and there is no(narrowing)arm.Generated by Claude Code