Repository navigation
finding(types): objectui#7759 group F residue — DashboardComponentSchema.dateRange mirror is wider than its declaration (spec exports DATE_RANGE_DEFAULT_RANGES) #10334
Description
Activity
- addeddomain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec laneobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lane
on Sep 24, 2026 objectstack-fleet commented
on Sep 24, 2026 ContributorAuthorMore actionsClaim: PM loop round 10 — objectui#10334 (#7759 group F residue): settle
DashboardComponentSchema.dateRange
Session:session_01877XiBYSaRCk2CU7cMSg3S
Branch:claude/issue-10334-dashboard-daterange
Worktree:objectui-issue-10334
Domain:domain:spec
Seat:domain:spec#1
File surface:packages/types/src/complex.tsandzod/complex.zod.ts,DashboardComponentSchema.dateRangeonly;- the matching rows in the parity ledger;
- a pin;
- one
.changeset/10334-…md.
Container & model:S,mode:subagent,model: opus(TIER_DEFAULT)
Clause-②: yes
Thread-read: none
Serial constraints cleared: re-measured at 2026-09-24T18:14Z. PR objectui#10273 (the Dashboard twin region) is onmainas1bbaa16. The parity ledger is shared with the still-queued PRs objectui#10294 / fix(types): settle FilterField.operators, Container.maxWidth and HeaderBar.variant between mirror and declaration (objectui#10286) #10300 / fix(types,components): calendar date-value keys cross the JSON/TS boundary once (objectui#10293) #10302 / feat(types)!: DetailViewFieldSchema.options reads the spec's authoring SelectOptionSchema (#7759 group F) #10307, and whichever lands later mergesmain.
Dispatch authority: objectstack-ai/objectstack#19980 and 「任务很多,并发保持3」 (the maintainer).
objectstack-fleet commented
on Sep 24, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 10334, "status": "done", "branch": "claude/issue-10334-dashboard-daterange", "pr": "https://github.com/objectstack-ai/objectui/pull/10338", "session": "session_01877XiBYSaRCk2CU7cMSg3S — the parent PM seat's id (mode:subagent)", "premise_still_valid": true, "summary": "Rule 1 / F1 governs. The spec declares DashboardSchema.dateRange in both installed 17.4.0 and objectstack main b81da66d with the same shape: a strict object with field? string, defaultRange a ZodDefault enum over DATE_RANGE_DEFAULT_RANGES (14 names: the presets plus custom), and allowCustomRange a ZodDefault boolean. Step 1 was a key-by-key tsc probe of the old mirror input against the old TS member. It showed that ONLY defaultRange was wider (a bare string against the 14-literal DateRangeDefaultRange); field and allowCustomRange agreed. The mirror also stripped unknown keys, which tsc cannot see. CHANGE: dateRange left DASHBOARD_SPEC_EXCLUDED, the one as-const list that both faces read. The Zod mirror now takes it through specFieldsExcept(stripImportedDefaults(SpecDashboardSchema).shape), and the TS twin takes it through the Omit over the spec Dashboard input type. The hand-written mirror element and TS member were deleted, as was the now-unused DateRangeDefaultRange import. The WiderThanDeclared key and the WIDER_ARMS row were removed, and the WIDER header figures were re-derived to 17/25/29 and 5/20/0/4 with a history sentence. The Dashboard 'omitted' list in page-app-dashboard-spec-parity lost dateRange. The docs guide dashboard-filters.md now states the spec shape and the refusals. There was no renderer change: resolveDashboardFilterDefs in @object-ui/core already implements every arm (each preset, the custom sentinel, field with its created_at fallback, and allowCustomRange read as !== false). Changeset .changeset/10334-dashboard-daterange-spec-authoring.md is a minor bump on @object-ui/types and states the breaking change to the validator only. The PR body carries Closes #10334, Part of #7759 and Clause-② yes. I made zero label writes and left the assignee untouched, as the PM directed.", "tests": "HEAD a72f5f9b8 (the final commit is a merge of origin/main 7616d8935, which moved nothing under packages/types). (1) Under the verify lock, at a72f5f9b8: pnpm --filter @object-ui/types type-check (tsc, examples and the test config) exited 0, then pnpm exec vitest run packages/types/ gave 'Test Files 217 passed (217)' and 'Tests 4965 passed (4965)'; VERDICT command-exit 0. (2) New pin packages/types/src/__tests__/dashboard-daterange-spec-10334.test.ts, 7 tests, run alone 'Tests 7 passed (7)'. It covers: Equal of both the TS twin and the mirror input with Dashboard['dateRange'], plus a negative control; code invalid_value at path dateRange.defaultRange for last_7_dayz; unrecognized_keys at dateRange for an unknown key; all 14 names accepted; no default injected; and verdict parity with the spec schema over 8 samples. (3) Reverse verification: the fix was committed first, and the trap restore used absolute paths. I wrote the base-commit complex.zod.ts and complex.ts into place, and the on-disk markers read bare-string defaultRange 1, 'dateRange' in the exclusion list 1, old TS member 1. The pin then gave 'Tests 4 failed | 3 passed (7)', and tsc -p tsconfig.test.json exited 2 with 3 errors: the pin's mirror Equal, plus WiderLedgerMismatch on complex.zod.ts#DashboardComponentSchema and on 'dateRange'. The restore used git checkout HEAD -- FILE; afterwards git diff HEAD was 0 bytes, and the blob hashes of HEAD and disk matched for both files (b304dfab, b9723447). (4) Forward compatibility: I built @objectstack/spec from objectstack main b81da66d in a detached worktree under the lock, ran npm pack, and ran node scripts/spec-main-shape-gate.mjs inject, which exited 0 and re-pointed zod to 4.6.1. The control was that the resolved spec's package.json declares zod ^4.6.1 and its build-input-hash equals the main build. Against it, types type-check gave TYPECHECK_EXIT=0, and the pin, zod-mirror-parity, page-app-dashboard-spec-parity and twins-9736 gave 'Tests 72 passed (72)'. The pinned install was then restored with pnpm install --force; the resolved spec is back to 17.4.0 with zod ^4.4.3. (5) Downstream, against pinned 17.4.0: turbo build of the @object-ui/plugin-dashboard^... closure ('Tasks: 12 successful, 12 total'), then pnpm --filter @object-ui/core type-check and pnpm --filter @object-ui/plugin-dashboard type-check, all exit 0. The dateRange consumer suites DashboardRenderer.filters, dashboardAuthoredInputs and core dashboard-filters gave 'Tests 80 passed (80)'. Downstream type-check against the main spec was NOT MEASURED, reason: only the types package was compiled against main locally, and the full consumer compile is the CI gate's job. (6) eslint --no-inline-config --format json over the 5 changed TS files: 5 files, 0 errors, and 13 no-explicit-any warnings, all on untouched pre-existing lines. The population is exactly those 5 files. Type-aware linting is not configured (eslint.config.js has no parserOptions.project), so the diff cannot move any untouched file's verdict. (7) Gates at exit 0: check-changeset-presence, check:spec-symbols, check:new-line-citations ('0 new citation(s)'), check-changeset-no-major, check:control-bytes, check:changeset-claims, check:pending-changeset-literals, check:installed-pin-claims, check:doc-fences and check-doc-links. NOT MEASURED: check:doc-snippets, reason: exit 2 PREREQUISITE (it needs a scoped workspace build); the doc edit adds no code block. dispatch-gates.mjs is objectstack-only, so I derived objectui's gate list by hand from the dispatch.", "mcp_calls": "0", "api_writes": "2 — both through the fleet-write relay (a repository_dispatch to objectstack-ai/objectstack, executed as objectstack-fleet[bot]): pr_create POST /repos/objectstack-ai/objectui/pulls (draft, PR #10338, run 36042703128; body read back and diff-identical, 0 angle brackets); comment POST /repos/objectstack-ai/objectui/issues/10334/comments (this report). Plus git push of the branch, which is not a REST write. Zero label writes, per the PM's instruction.", "open_questions": [], "out_of_scope_findings": [ "class: b · The spec declares DashboardSchema.dateRange.defaultRange with .default('this_month') (objectstack main dashboard.zod.ts, the dateRange strictObject: 'defaultRange: z.enum(DATE_RANGE_DEFAULT_RANGES).default('this_month')'). But an authored dateRange that omits defaultRange starts with NO window at the read site: resolveDashboardFilterDefs sets defaultValue to undefined when preset is absent, and the mirror deliberately authors no default (stripImportedDefaults, batch #90). So dateRange: { field: 'created_at' } renders unfiltered, where the spec's parsed document says this_month. allowCustomRange is consistent (default true, read as !== false). Seam: spec:DashboardSchema.dateRange.defaultRange (default this_month) → runtime:resolveDashboardFilterDefs (@object-ui/core utils/dashboard-filters) | renderer:DashboardFilterBar. Not filed, not fixed (it is a renderer behaviour change). Dedupe words: dateRange defaultRange default this_month resolveDashboardFilterDefs omitted", "carrier: the queued PRs objectui#10294 / #10300 / #10302 / #10307 · noted, not filed. They edit the same WIDER header figure line in zod-mirror-parity.test.ts. Whichever lands after PR #10338 must re-derive the six figures from WIDER_ARMS, and the header pin prints the right values." ] }
Generated by Claude Code
objectstack-fleet commented
on Sep 24, 2026 ContributorAuthorMore actionsACCEPT: objectui#10334 (#7759 group F residue), delivered by PR objectui#10338 at head
a72f5f9. Sessionsession_01877XiBYSaRCk2CU7cMSg3S,domain:spec@ objectui seat.Change
- Rule 1 / F1 governs: the spec declares
DashboardSchema.dateRange, identically on 17.4.0 and onmain. dateRangeleavesDASHBOARD_SPEC_EXCLUDED, so both faces take the spec's authoring element:- the mirror through
specFieldsExcept(stripImportedDefaults(...)); - the TS twin through the
OmitoverDashboard.
- the mirror through
- The hand-written element and member are deleted.
- Only
defaultRange(a bare string, versus the 14 literals) and the key set narrow, and only on the validator. - No default is injected.
- The ledger loses the row.
- No renderer change is needed, because
resolveDashboardFilterDefsalready implements every arm.
Review: Clause-② yes. The isolated contract review record at this head, on the PR, is PASS. It confirms:
- the shape is identical on both spec versions;
- the probed refusals;
- no default is injected;
- no stored document is refused;
- nothing published is removed.
Tests
- 4965 in types.
- The pin passes 7 of 7.
- A reverse verification was run.
- The type-check was also run against spec built from objectstack
main: 72 tests green. - The downstream core and plugin-dashboard type-checks pass.
Out of scope, filed and dispatched as objectui#10339 (class b): the spec's
defaultRangedefaultthis_monthis not applied at the read site, sodateRange: { field }renders unfiltered.Landing: the PR is serial behind the shared parity-ledger chain (#10294 → #10302 → #10307 → #10300). After the one ahead lands, merge
main, re-derive the WIDER header, flip ready and enqueue.
Generated by Claude Code
- Rule 1 / F1 governs: the spec declares
- added a commit that references this issue
on Sep 28, 2026
This card is the residue of #7759 group F. The objectui#10296 dev (PR objectui#10307) correctly STOPPED on this row, because it sat in PR objectui#10273's Dashboard-twin region. objectui#10273 landed on
mainas1bbaa16, so the row is now free to settle.It was filed by the
domain:spec@ objectui execution seat, sessionsession_01877XiBYSaRCk2CU7cMSg3S. Priority and domain are inherited from the parent (priority:p2,domain:spec).The row, on
mainf3f4e4czod-mirror-parity.test.ts:WiderThanDeclared['complex.zod.ts#DashboardComponentSchema']includes'dateRange', andWIDER_ARMShascomplex.zod.ts#DashboardComponentSchema::dateRange: ['CONCRETE'].complex.zod.ts, about:1196:dateRange: z.object({ … }).dateRangeis onDASHBOARD_SPEC_EXCLUDED, so objectui's own element schema is used.ChatbotSchema.body— the remaining CONCRETE mirror-wider-than-declaration rows, settled per ruling F1 and rules 1/2 #10296 dev:@objectstack/spec17.4.0 exportsDATE_RANGE_DEFAULT_RANGES/DateRangeDefaultRangefrom@objectstack/spec/ui, so rule 1 likely governs. The mirror'sdefaultRangevocabulary should take the spec's, and the declaration should follow.Rules (#7759 ruling 5617465269 + ordering note 5617614225)
DashboardRenderer);Done when
The row leaves
WiderThanDeclared/WIDER_ARMS, or is recorded as an expected divergence with its reason. A pin reddens on revert. One@object-ui/typeschangeset is added (minor, Clause-② yes).