Repository navigation
decision: the tenant Localization settings (date format, time format, number format, first day of week) are applied by no renderer — honour them, or stop offering them #11675
Description
Activity
- addeddomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seatarea:i18nThe customer's own language, across UI, metadata and notificationsThe customer's own language, across UI, metadata and notifications
on Oct 6, 2026 objectstack-fleet commented
on Oct 6, 2026 ContributorAuthorMore actionsRuling recorded — B: formats follow the locale, the four separate format settings retire, and this card keeps only the week start
Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-06T06:32Z.Provenance (who / verbatim / where): the maintainer, in the triage seat's live chat (
session_01AavokzJ5DndAwitDXvKy4U), answering decision batch 2 (director format, item 1, recommending B), verbatim: 「同意」.Ruled:
- Dates, times, numbers and the first day of the week follow the user's locale (language and region), the Salesforce Locale model.
date_format,time_format,number_formatandfirst_day_of_weekleave the Localization settings. ⛔ They are not implemented. The fallback (A, honour them) is not taken.timezone,localeandcurrencystay live settings.
Read before executing: nothing reads the four keys in objectstack (server), objectui, cloud or hotcrm. The only matches are SQL's own
date_format(), an export transform name and comments.Execution:
- settings(localization): retire
date_format,time_format,number_formatandfirst_day_of_weekfrom the Localization manifest — no renderer honours them; formats follow the locale (ruled on objectui#11675, B) objectstack#21958 (domain:services, p2) retires the four rows fromservice-settings' Localization manifest and its translations, and states how stored values are treated. - objectui#11693 (p3): the console's localization fetch drops the
timezonethe server sends. That is the follow-up the decision named. - This card's remaining scope: the calendar and the timeline take the first day of the week from the locale, not hard-coded. Today the calendar starts on Sunday (
plugin-calendar/src/CalendarView.tsx, about:438–:451) and the timeline on Monday (plugin-timeline/src/ObjectTimeline.tsx, about:745).- Pins: under
en-USboth start on Sunday, and underzh-CN(oren-GB) both start on Monday, from the locale's week info.
- Pins: under
State:
needs-user-decision→pm:queue, re-gradedbug·priority:p3(the remaining scope is two sites).
Generated by Claude Code
- addedbugSomething isn't workingSomething isn't workingand removed
on Oct 6, 2026 objectstack-fleet commented
on Oct 6, 2026 ContributorAuthorMore actionsClaim: PM loop round 1
Session:session_01FngvPpdrnhHMdHHq6vwwju
Account:os-justin
Branch:claude/issue-11675-week-start-from-locale
Worktree:objectui-issue-11675
Domain:domain:ui
Seat:domain:ui#2
File surface:packages/plugin-calendar/src/CalendarView.tsx(the week grid's start, about:438–:451),packages/plugin-timeline/src/ObjectTimeline.tsx(startOfWeek, about:745), one shared locale week-start helper in a package both plugins already import (if the dev measures that one is needed), the tests beside them, and.changeset/11675-*.md(stop on breach; explain in the report)
Container & model:M,mode:subagent,model: opus(dispatch-gates --tier --repo objectstack-ai/objectui: no path-derived mandate; default tier)
Clause-②: yes
Thread-read: 6010771237
Ruling-ref: 6010771237 (ruling B, the maintainer's 「同意」 recorded by the triage seat), retrieved this round.
Serial constraints cleared:noneblocking. No open PR (objectui#11703, #11706, #11707, #11708, #11069) touchesCalendarView.tsxorObjectTimeline.tsx. objectui#11676's remainder (retiringtimeline.bucket.overdue) is unclaimed and touchesuseTimelineTranslation.tsand the locale packs, notstartOfWeek. It is held behind this card for the same file. objectstack-ai/objectstack#21958 (the server half of ruling B) touches no objectui file. Read 2026-10-06T09:01Z.Why
Clause-②: yes: two plugins take one locale rule, so the likely shape is one shared helper exported from a package both import, which widens that package's surface. If the dev keeps the rule module-private, it reports the built-declaration reading and the seat amends this line tonobefore any review.
Generated by Claude Code
objectstack-fleet commented
on Oct 6, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 11675, "status": "done", "branch": "claude/issue-11675-week-start-from-locale", "pr": "https://github.com/objectstack-ai/objectui/pull/11710", "session": "session_01FngvPpdrnhHMdHHq6vwwju — subagent = parent's (container CLAUDE_CODE_REMOTE_SESSION_ID cse_01FngvPpdrnhHMdHHq6vwwju; the relay stamped the same session)", "premise_still_valid": true, "summary": "Ruling B's remaining scope is implemented in draft PR objectui#11710 (head e4f3430, base daa7caf), and its premise held on origin/main. @object-ui/i18n now exports firstDayOfWeek(locale) plus a WeekdayIndex type (0 = Sunday, the getDay and react-day-picker weekStartsOn numbering). It reads the engine's Intl.Locale week info (getWeekInfo(), else the weekInfo accessor; Node 22 has the accessor only, Chromium 141 has both, Firefox was not measured) and falls back to a CLDR 47 region table, with Monday, CLDR's 001 default, for regions the table does not list. A parity test checks the table against the runtime region by region. CalendarView reads it once from effectiveLocale and starts every week from it: the month grid and its heads, the week view's columns, the header's week range, a wrapped span's title day, and the date popover via weekStartsOn (date-fns's own week start differs for es-MX and reads enUS until the locale loads). ObjectTimeline's This week and Next week buckets start on firstDayOfWeek(useDisplayLocale()), and the bucket-bounds block now steps local midnights, which also corrects the DST misbucketing of Tomorrow and of next week's first day. Pins cover en-US (Sunday), en-GB and zh-CN (Monday) and ar-EG (Saturday). Clause-② holds: the built dist/utils/first-day-of-week.d.ts declares export declare function firstDayOfWeek(locale: string): WeekdayIndex, and dist/index.d.ts re-exports it. The PR assignee is NOT set: the auto-mode classifier refused the label-write (see deviations).", "tests": "All runs are at head e4f3430 unless marked, the heavy ones through os-verify-lock (slot issue-11675). (1) pnpm exec vitest run packages/i18n/ packages/plugin-calendar/ packages/plugin-timeline/ exited 0: 'Test Files 184 passed (184) / Tests 2281 passed | 145 skipped (2426)'. (2) pnpm exec vitest run scripts/__tests__/date-only-zone-pins-10183.test.ts exited 0: 'Tests 27 passed (27)'. The driver counts a skipped child case as a failure, so the new DST cases ran. (3) type-check for the three packages exited 0, and --listFiles shows every touched test file in its package's test program. (4) The new pins: firstDayOfWeek-11675 has 12 cases, CalendarView.weekStartFromLocale-11675 has 10, ObjectTimeline.weekBucketsFromLocale-11675 has 4, plus a DST block in ObjectTimeline.dateOnlyZone-10866 (rig, fixture validity, buckets). (5) Before the fixture re-judge (at 4f1fc12, the implementation alone): 'Tests 4 failed | 961 passed' across the plugins, every failure in CalendarView.gridcellLocale-10144 and CalendarView.displayLocale-10442, whose weekday-head helpers assumed a Sunday-first grid under de / de-CH / fr-FR. They now take the first day as an explicit literal, and their assertions are otherwise unchanged. (6) Eight ablations, each through objectstack scripts/ablation-replace.mjs from a committed tree, each printing 'ok mutation landed: anchor 1 to 0, blob X to Y' and 'ok restored: blob == HEAD and git diff HEAD is empty'. No rebuild was needed: vitest.config.mts aliases @object-ui/i18n to packages/i18n/src, and the plugin tests import the components relatively. A1a (timeline week start hard-coded Monday): 2 failed / 2 passed, en-US and ar-EG red, en-GB and zh-CN green, as predicted. A1b (endOfWeek back to 24-hour steps) and A1c (tomorrow = today + 86400000): the zone driver went red on its timeline-pin row, and the failing child case was the new DST case. A2 (calendar weekStart = 0): 11 failed / 8 passed, every non-Sunday case red, en-US and es-MX green. A2b (popover weekStartsOn removed): 1 failed, Expected domingo, Received lunes. A2c (title day back to getDay() === 0): 1 failed, the title-day case. A3 (CLDR table removed): 5 failed / 7 passed, the table-path and parity cases. A3b (engine path skipped): 2 failed / 10 passed, the -u-fw- and getWeekInfo cases. Every observed direction was the predicted one.", "gates": [ { "cmd": "pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-calendar^...' --filter '@object-ui/plugin-timeline^...' build", "exit": 0, "head": "4f1fc12 (i18n src unchanged since)" }, { "cmd": "pnpm exec turbo run build $(node scripts/check-doc-snippet-types.mjs --build-filter) --concurrency=2", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm exec vitest run --maxWorkers=2 packages/i18n/ packages/plugin-calendar/ packages/plugin-timeline/", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm exec vitest run scripts/__tests__/date-only-zone-pins-10183.test.ts", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm --filter @object-ui/i18n --filter @object-ui/plugin-calendar --filter @object-ui/plugin-timeline run type-check", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm --filter @object-ui/i18n --filter @object-ui/plugin-calendar --filter @object-ui/plugin-timeline run lint", "exit": 0, "head": "e4f3430", "note": "0 errors; per-rule warning counts identical at daa7caf and e4f3430 for CalendarView.tsx, ObjectTimeline.tsx and the i18n entry files; new files 0 warnings" }, { "cmd": "pnpm check:new-line-citations", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm check:control-bytes", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm check:changeset-claims", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm check:pending-changeset-literals", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm check:readme-exports", "exit": 0, "head": "e4f3430", "note": "after the scoped build; before it, exit 1 on its population-collapse floor (prerequisite: 23 packages unbuilt), and --list already judged firstDayOfWeek in the i18n README as real" }, { "cmd": "pnpm check:doc-snippets", "exit": 0, "head": "e4f3430", "note": "779 of 779 blocks judged, 0 failed; before the scoped build, exit 2 PRECONDITION NOT MET" }, { "cmd": "pnpm check:self-import", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm check:phantom-deps", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm check:unused-deps", "exit": 0, "head": "e4f3430" }, { "cmd": "node scripts/check-changeset-no-major.mjs", "exit": 0, "head": "e4f3430" }, { "cmd": "node scripts/check-changeset-presence.mjs", "exit": 0, "head": "e4f3430" }, { "cmd": "node scripts/check-changeset-overwrite.mjs", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm check:doc-fences", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm check:vi-mock-specifiers", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm check:vi-mock-inherit", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm check:vi-mock-override-shape", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm check:test-path-roots", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm check:unreferenced-sources", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm check:esm-specifiers", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm check:shell-escape-residue", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm check:dist-completeness", "exit": 0, "head": "e4f3430" }, { "cmd": "pnpm check:published-dist", "exit": 0, "head": "e4f3430" }, { "cmd": "node scripts/check-governed-queue-guard.mjs --test (17 changed paths)", "exit": 0, "head": "e4f3430", "note": "NOT GOVERNED" }, { "cmd": "pnpm check:node-esm-load", "exit": 1, "head": "e4f3430", "note": "NOT MEASURED: its provenance leg refused 8 entries turbo replayed from another worktree's shared cache (auth, core, data-objectstack, mobile, permissions, providers, react-runtime, types); none is in this diff and none of the three touched packages was refused or failed; a clean reading needs --force-build (CI's whole-tree run)" }, { "cmd": "CI", "exit": null, "head": "e4f3430", "note": "in_progress: not read; CI convergence is the PM's. Repo-wide pnpm lint and the full pnpm test are CI's" } ], "line_budget": "not applicable: the diff touches no skills/** and no governed surface (17 files, +863 / -41)", "files_changed": [ ".changeset/11675-week-start-from-locale.md", "content/docs/plugins/plugin-calendar.mdx", "content/docs/plugins/plugin-timeline.mdx", "packages/i18n/README.md", "packages/i18n/src/__tests__/firstDayOfWeek-11675.test.ts", "packages/i18n/src/index.ts", "packages/i18n/src/utils/first-day-of-week.ts", "packages/i18n/src/utils/index.ts", "packages/plugin-calendar/README.md", "packages/plugin-calendar/src/CalendarView.displayLocale-10442.test.tsx", "packages/plugin-calendar/src/CalendarView.gridcellLocale-10144.test.tsx", "packages/plugin-calendar/src/CalendarView.tsx", "packages/plugin-calendar/src/__tests__/CalendarView.weekStartFromLocale-11675.test.tsx", "packages/plugin-timeline/README.md", "packages/plugin-timeline/src/ObjectTimeline.tsx", "packages/plugin-timeline/src/__tests__/ObjectTimeline.dateOnlyZone-10866.test.tsx", "packages/plugin-timeline/src/__tests__/ObjectTimeline.weekBucketsFromLocale-11675.test.tsx" ], "deviations": [ "PR assignee NOT written: node scripts/pm/label-write.mjs --repo objectstack-ai/objectui --issue 11710 --assign os-justin was refused by the Claude Code auto-mode classifier ('[External System Writes]') before any request was sent. Not re-routed (no curl, no MCP, no hand write); the seat performs it.", "File surface: beyond the claim's list, the diff adds docs that AGENTS.md #2 requires (packages/i18n/README.md, packages/plugin-calendar/README.md, packages/plugin-timeline/README.md, content/docs/plugins/plugin-calendar.mdx, content/docs/plugins/plugin-timeline.mdx) and the helper's two export lines (packages/i18n/src/index.ts, src/utils/index.ts). All are additive; the seat may amend the claim's surface.", "Touched published defect corrected in place: the timeline's bucket-bounds block was rewritten as a unit, so tomorrow and the two week ends now step local midnights instead of 24-hour multiples, which misbucketed across a DST change. Pinned by the driven DST case; ablations A1b and A1c each show it red alone. Declared in the PR's Acceptance notes.", "Two existing pins re-judged, not weakened: the weekday-head helpers in CalendarView.gridcellLocale-10144 and CalendarView.displayLocale-10442 modelled a Sunday-first grid; they now take the first day as a stated literal.", "Attribution: commits end with AGENTS.md's model-free pair (Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named trailer, and the PR body ends with os-dev.md's session-URL footer, not the harness reminder's form. Both follow the rule that the repo or role file wins.", "check:node-esm-load recorded as NOT MEASURED (provenance refusal of foreign cache entries), and repo-wide lint and the full test are declared to CI; the claim's and order's named gate clues were all run." ], "mcp_calls": "0 — no MCP GitHub tool was called", "api_writes": "2 — (1) pr_create through the fleet-write relay: POST /repos/objectstack-ai/objectstack/dispatches, executed as POST /repos/objectstack-ai/objectui/pulls (draft), giving objectui#11710, body read back identical (12453 of 12453 bytes); (2) this os-dev-report comment via post-stamped: POST /repos/objectstack-ai/objectui/issues/11675/comments. Refused before any request: the PR-assignee label-write (classifier). Not REST: 4 git pushes to the branch.", "open_questions": [], "out_of_scope_findings": [ "carrier: 承接者: 无 · noted, not filed — date pickers outside the calendar, built on the @object-ui/components Calendar primitive with no weekStartsOn, take date-fns's week start for the tag. That is not CLDR's for tags date-fns has no locale of its own for (es-MX reads es, a Monday start, where CLDR starts on Sunday), and it is a Sunday start until the date-fns locale loads. The mechanism was measured on the primitive (ablation A2b: lunes where domingo is expected), not through a field's public door, so there is no reach reading. Dedupe words: weekStartsOn, date-fns week start, es-MX, date picker first day of week", "carrier: 承接者: 无 · noted, not filed — the gantt variant's week axis counts plan weeks (Week 1, Week 2) from the axis's first day, a choice its renderer docblock documents. It hard-codes no weekday, so ruling B does not reach it. Dedupe words: gantt week axis, Week N, calendar week snap", "carrier: 承接者: 无 · noted, not filed — firstDayOfWeek's table path reads the region only, so a -u-fw- or -u-rg- keyword is honoured only where the engine has week info. No producer writes those keywords today. Dedupe words: -u-fw-, -u-rg-, week info fallback" ] }
Generated by Claude Code
objectstack-fleet commented
on Oct 6, 2026 ContributorAuthorMore actionsACCEPT: PR objectui#11710 at
e4f3430(Fixes #11675). The at-tier contract review is owed before enqueuedomain:uiexecution seat 2 ·session_01FngvPpdrnhHMdHHq6vwwju(os-justin) · 2026-10-06T10:01Z. Dev report:os-dev-reporton this card.- Shape: draft, base
main, first lineFixes #11675, and the body has no other closing keyword.Clause-②: yesis at the start of a line. 17 files: the helper and its two export lines in@object-ui/i18n,CalendarView.tsx,ObjectTimeline.tsx, three new pin files, two re-judged calendar pins, the timeline's DST zone suite, three package READMEs, twocontent/docs/plugins/*.mdxpages and one changeset. No governed path, nocontent/docs/releases/edit. +863/−41. - Beyond the claim's listed surface: the READMEs, the docs pages and the export lines. The seat accepts them: the export lines are the claimed helper's, and the docs follow AGENTS.md Add automated testing infrastructure and CI/CD workflows #2 for the changed behaviour.
- Seat's own reading of the diff:
firstDayOfWeek(locale)readsIntl.Locale'sgetWeekInfo(), else itsweekInfoaccessor. Without either, it falls back to a CLDR first-day table by region (or the likely-subtags region), with Monday as CLDR's001default. A parity test checks the table against the runtime.- It is exported with
WeekdayIndexfrom@object-ui/i18n's entry. That is the one widening, which makes thisClause-②: yes. CalendarViewstarts every week surface from it.ObjectTimeline's "This week" / "Next week" bounds start from it.- The bucket-bounds block now steps local midnights. That is a touched published defect (DST misbucketing), fixed in place and pinned by the driven DST case.
- Ruling B (
6010771237): no setting is added, and the first day comes from the locale the dates are already formatted with. The four retired settings are not read. - Changeset prose (
i18n,plugin-calendar,plugin-timeline, allminor), checked sentence by sentence against the diff:- the en-US / en-GB / zh-CN / ar-EG sentence matches the pins;
- the helper bullet (engine week info, then the CLDR table, Monday default,
RangeErroron a malformed tag) matchesfirst-day-of-week.ts; - the calendar bullet (grid, heads, week view, header range, wrapped-span title day, popover
weekStartsOn) and the timeline bullet (week bounds and DST stepping) match the two components; - the host-behaviour sentence and the gantt-unchanged sentence state the boundary.
- Tests:
- 26 new pin cases plus the DST block; two calendar pins re-judged to take the first day as a literal, with no assertion weakened.
- Eight ablations, each red in the predicted direction and restored by blob.
i18n+plugin-calendar+plugin-timeline: 184 files passed. The zone driver: 27 passed.check:readme-exportsandcheck:doc-snippets(779 of 779) are green after the scoped build.
- Out-of-scope findings (3), Acceptance notes, none filed:
- date pickers on the
Calendarprimitive outside the calendar take date-fns's week start (mechanism measured on the primitive, no reach reading at a field door); - the gantt axis counts plan weeks (documented, not a weekday);
- the table path reads the region only, so
-u-fw-/-u-rg-are honoured only with engine week info (no producer).
- date pickers on the
- Deviation: the dev's PR-assignee write was refused by its session's permission classifier. It was not retried, and the seat does not redo a refused write under another identity. It has been raised to the maintainer.
- Owed before enqueue: the at-tier contract review.
needs:contract-reviewis hung on the PR in this stroke.
Generated by Claude Code
- Shape: draft, base
objectstack-fleet commented
on Oct 6, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 11675, "round": "patch 1", "status": "done", "branch": "claude/issue-11675-week-start-from-locale", "pr": "https://github.com/objectstack-ai/objectui/pull/11710", "head": "a393686", "session": "session_01FngvPpdrnhHMdHHq6vwwju — subagent = parent's (container CLAUDE_CODE_REMOTE_SESSION_ID cse_01FngvPpdrnhHMdHHq6vwwju)", "premise_still_valid": true, "summary": "CI went red at e4f3430 on this PR's own parity pin. Cause: the table transcribed CLDR 47, while CI's floating 22.x Node ships CLDR 48, where Iceland starts the week on Sunday, and the pin compared the table with whatever CLDR the runtime ships. Fixed at the root in a393686, after merging main (da35453) in the merge commit 98877dd (no rebase, no force-push). The table now declares the release it transcribes (WEEK_DATA_CLDR = '48') and carries IS on Sunday; all three rows equal the CLDR 48 measurement region for region. The parity pin reads the runtime's release from process.versions.cldr and requires the set of table/engine disagreements to EQUAL a measured ledger row for that release (RELEASE_DELTAS: 46 and 47 each record IS on Monday). That set must be empty on the table's own release and on any release the ledger does not list. A rig case and a ledger-honesty case sit beside it. Three official Node builds, checksum-verified, were measured: 22.13.0 (CLDR 46, the engines floor), 22.22.0 (CLDR 47, this container) and 22.23.3 (CLDR 48, CI's 22.x). IS is the only region that differs. The pin is green on all three, and ablations show it red on real drift on every runtime. Every other pin is unchanged in assertion. The PR body needs the seat-applied pr_body_patch below.", "tests": "At head a393686, heavy runs through os-verify-lock (slot issue-11675). (1) pnpm exec vitest run --maxWorkers=2 packages/i18n/ packages/plugin-calendar/ packages/plugin-timeline/ exited 0 on Node 22.22.0 (CLDR 47): 'Test Files 184 passed (184) / Tests 2283 passed | 145 skipped (2428)'. The same command through node_modules/vitest/vitest.mjs under Node 22.23.3 (CLDR 48, CI's release) exited 0 with the same counts. (2) firstDayOfWeek-11675.test.ts alone: 'Tests 14 passed (14)' on CLDR 46, 47 and 48. (3) The zone driver scripts/__tests__/date-only-zone-pins-10183.test.ts exited 0: 'Tests 27 passed (27)'. (4) type-check for the three packages exited 0. (5) Ablations through objectstack scripts/ablation-replace.mjs, each printing 'ok mutation landed' and 'ok restored: blob == HEAD and git diff HEAD is empty', each run on all three runtimes. A4 (IS removed from the table, i.e. the CLDR 47 content): red on all three; CLDR 48 reproduces CI's shape ('expected { IS: +0 } to deeply equal {}'), 46 and 47 give 'expected {} to deeply equal { IS: 1 }', and the ledger-honesty case is red everywhere. A6 (the ledger's 47 row removed): red on CLDR 47 only ('expected { IS: 1 } to deeply equal {}'), green on 46 and 48. A3 (CLDR table removed): 6 failed / 8 passed on each runtime (round one's 5 plus ledger honesty). A3b (engine path skipped): 2 failed / 12 passed on each runtime (the -u-fw- and getWeekInfo cases). Every observed direction was the predicted one.", "gates": [ { "cmd": "pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-calendar^...' --filter '@object-ui/plugin-timeline^...' build", "exit": 0, "head": "a393686" }, { "cmd": "pnpm exec vitest run --maxWorkers=2 packages/i18n/ packages/plugin-calendar/ packages/plugin-timeline/ (Node 22.22.0, CLDR 47)", "exit": 0, "head": "a393686" }, { "cmd": "node_modules/vitest/vitest.mjs run --maxWorkers=2 packages/i18n/ packages/plugin-calendar/ packages/plugin-timeline/ (Node 22.23.3, CLDR 48)", "exit": 0, "head": "a393686" }, { "cmd": "vitest run packages/i18n/src/__tests__/firstDayOfWeek-11675.test.ts on Node 22.13.0 (CLDR 46) / 22.22.0 (47) / 22.23.3 (48)", "exit": 0, "head": "a393686", "note": "14 of 14 on each" }, { "cmd": "pnpm exec vitest run scripts/__tests__/date-only-zone-pins-10183.test.ts", "exit": 0, "head": "a393686" }, { "cmd": "pnpm --filter @object-ui/i18n --filter @object-ui/plugin-calendar --filter @object-ui/plugin-timeline run type-check", "exit": 0, "head": "a393686" }, { "cmd": "pnpm --filter @object-ui/i18n --filter @object-ui/plugin-calendar --filter @object-ui/plugin-timeline run lint", "exit": 0, "head": "a393686", "note": "0 errors; package warning totals unchanged from round one (33 / 146 / 248); both edited files 0 warnings" }, { "cmd": "pnpm check:new-line-citations", "exit": 0, "head": "a393686" }, { "cmd": "pnpm check:control-bytes", "exit": 0, "head": "a393686" }, { "cmd": "pnpm check:changeset-claims", "exit": 0, "head": "a393686" }, { "cmd": "pnpm check:pending-changeset-literals", "exit": 0, "head": "a393686" }, { "cmd": "node scripts/check-changeset-no-major.mjs", "exit": 0, "head": "a393686" }, { "cmd": "node scripts/check-changeset-presence.mjs", "exit": 0, "head": "a393686" }, { "cmd": "node scripts/check-changeset-overwrite.mjs", "exit": 0, "head": "a393686" }, { "cmd": "pnpm check:unreferenced-sources", "exit": 0, "head": "a393686" }, { "cmd": "pnpm check:test-path-roots", "exit": 0, "head": "a393686" }, { "cmd": "pnpm check:readme-exports / pnpm check:doc-snippets", "exit": null, "head": "a393686", "note": "not re-run: no README, doc or changeset text changed this round (the order's condition); round one's readings at e4f3430 were exit 0" }, { "cmd": "CI", "exit": null, "head": "a393686", "note": "in_progress: not read; CI convergence is the PM's" } ], "line_budget": "not applicable: the diff touches no skills/** and no governed surface (17 files against da35453, +925 / -41; this round's own change is 2 files, +82 / -20)", "files_changed": [ "packages/i18n/src/utils/first-day-of-week.ts", "packages/i18n/src/__tests__/firstDayOfWeek-11675.test.ts" ], "files_changed_note": "This round's commits are 98877dd (a merge of main at da35453) and a393686 (the two files above). The PR's whole file set against da35453 is the same 17 paths as round one.", "deviations": [ "Measurement inputs: to make the pin deterministic on every supported runtime, I downloaded official Node 22.13.0 and 22.23.3 linux-x64 builds from nodejs.org into fresh directories under my scratchpad issue-11675/runtimes, verified them against nodejs.org's SHASUMS256.txt, and ran the repo's own vitest with them from the repo root. These are reads, not GitHub writes. The verified binaries are kept there for reproduction; the tarballs were deleted.", "Ledger rows are measured, not inferred: RELEASE_DELTAS lists only releases measured on a runtime that ships them (46, 47). A runtime shipping an unlisted release must agree with the table entirely, and its failure message names both remedies.", "Carried from round one, still the seat's: the PR assignee (os-justin) is unset, because the classifier refused the label-write; and the contract review 6014049550 covers e4f3430 only, so a new at-tier record is needed for a393686.", "The PR body says 'a snapshot of CLDR 47' and describes the old parity case, so it is now stale. pr_body_patch gives the exact edits for the seat to apply; I did not PATCH it." ], "mcp_calls": "0 — no MCP GitHub tool was called", "api_writes": "1 — this os-dev-report comment via post-stamped (fleet relay): POST /repos/objectstack-ai/objectui/issues/11675/comments. Not REST: 1 git push (98877dd + a393686). Reads only otherwise: GET of PR comment 6014128933, of pull 11710 (to check the patch anchors), and the nodejs.org downloads.", "open_questions": [], "out_of_scope_findings": [ "carrier: 承接者: 无 · noted, not filed — CI's node-version '22.x' floats, so any test that reads the runtime's ICU/CLDR data can turn red on main when the runner picks up a newer Node 22 minor, with no repository change. This PR's pin now records per-release differences, so it goes red only when a first day actually moves. Other Intl-reading pins were not surveyed. Dedupe words: node-version 22.x floating, process.versions.cldr, ICU update CI red" ], "pr_body_patch": [ { "op": "replace", "find": "- The table is a snapshot of CLDR 47, generated from Node's ICU. Engines carry their own CLDR release, and releases differ: Chromium 141 starts `AE` on Saturday, CLDR 47 on Monday. That is why the engine's answer wins wherever there is one. A parity case re-derives the table against the running engine, region by region.", "replace": "- The table transcribes one CLDR release, declared in the source as `WEEK_DATA_CLDR` (`48`, the release CI's floating `22.x` Node ships), and was generated from Node's ICU. Engines carry their own week data, and it differs: CLDR 48 moved Iceland to a Sunday start, and Chromium 141 starts `AE` on Saturday where Node's CLDR 46, 47 and 48 all start it on Monday. That is why the engine's answer wins wherever there is one. A parity case re-derives the table against the running engine, region by region (see Patch round 1)." }, { "op": "replace", "find": "- New `packages/i18n/src/__tests__/firstDayOfWeek-11675.test.ts` (12 cases):", "replace": "- New `packages/i18n/src/__tests__/firstDayOfWeek-11675.test.ts` (14 cases):" }, { "op": "replace", "find": " - a **parity** case: for every region the runtime names, the table answers what the engine answers;", "replace": " - a **parity** case: for every region the runtime names, the regions where the table and the engine disagree must equal exactly the ones a measured ledger (`RELEASE_DELTAS`) records for the runtime's CLDR release, which is none on the table's own release. A rig case and a ledger-honesty case sit beside it;" }, { "op": "insert_before", "anchor": "## Acceptance notes", "text": "## Patch round 1: CI red on the parity pin at `e4f3430`\n\n**Cause.** CI's `node-version: '22.x'` floats to the newest Node 22, which ships CLDR 48.0. In CLDR 48 Iceland's week starts on Sunday. The table transcribed CLDR 47, where `IS` reads the Monday default, and the pin compared it with whatever CLDR the runtime ships. So the pin was green in a CLDR 47 container and red on CI (`IS: engine 0, table 1`), and updating the table alone would only have moved the red to the CLDR 47 runtime.\n\n**Measured runtimes.** Three official Node builds were run, checksum-verified against nodejs.org's `SHASUMS256.txt`: 22.13.0 (CLDR 46.0, the `engines` floor), 22.22.0 (CLDR 47.0) and 22.23.3 (CLDR 48.0, what CI's `22.x` resolves to). Across the three, `IS` is the only region whose first day differs (Monday, Monday, Sunday).\n\n**Shape chosen: a declared release and an exact-equality ledger.**\n- `utils/first-day-of-week.ts` declares the release its table transcribes, `WEEK_DATA_CLDR = '48'`, and the table now carries `IS` on Sunday. All three rows equal the CLDR 48 measurement, region for region.\n- The pin reads the runtime's release from the major part of `process.versions.cldr`. The set of regions where the table and the engine disagree must EQUAL `RELEASE_DELTAS[release]`, a ledger in the test whose rows were measured on those runtimes (`46: { IS: Monday }`, `47: { IS: Monday }`). On the table's own release, and on a release the ledger does not list, that set is empty.\n- Why equality, not \"every disagreement is listed in the delta\": a subset check would stay green on a CLDR 46 or 47 runtime if Iceland were reverted in the table, because the disagreement simply disappears there. Equality goes red for that edit on every runtime, and also when a recorded row stops holding.\n- Why an empty set for an unlisted release: such a runtime is green when it agrees with the table, and red, naming each region and the remedy, when its CLDR moves a first day. That red is the real drift signal. A new release that moves nothing does not go red.\n- Not chosen: skipping the comparison when the release differs. That would turn the pin into a no-op on two of the three supported runtimes.\n- What remains: when CI's Node moves to a CLDR release that moves a first day, this pin goes red until the table or the ledger is updated. That is the drift the round asked to keep catching, and the failure message names both remedies.\n\n**Ablations on the new head**, each through `scripts/ablation-replace.mjs`, each with the mutation proven landed and the restore proven (`blob == HEAD`, `git diff HEAD` empty), and each run on all three runtimes:\n\n| Leg | Mutation | CLDR 46 | CLDR 47 | CLDR 48 |\n| --- | --- | --- | --- | --- |\n| A4 | Iceland removed from the table (back to CLDR 47 content) | red: parity and ledger honesty | red: parity and ledger honesty | red: parity (CI's shape, `{ IS: 0 }` found) and ledger honesty |\n| A6 | the ledger's `47` row removed | green | red: `{ IS: 1 }` found, `{}` expected | green |\n| A3 | the CLDR table removed | 6 red | 6 red | 6 red |\n| A3b | the engine path skipped | 2 red | 2 red | 2 red |\n\n**Re-run at `a393686`** (after merging `main` at `da35453` in `98877dd`, a merge commit; no rebase, no force-push):\n- `pnpm exec vitest run --maxWorkers=2 packages/i18n/ packages/plugin-calendar/ packages/plugin-timeline/` exited 0 on CLDR 47: 184 files, 2283 passed, 145 skipped. The same suites under Node 22.23.3 (CLDR 48, CI's release) exited 0 with the same counts.\n- `firstDayOfWeek-11675.test.ts` alone: 14 of 14 passed on CLDR 46, 47 and 48.\n- The zone driver `scripts/__tests__/date-only-zone-pins-10183.test.ts` exited 0, 27 passed.\n- `type-check` and `lint` for the three packages exited 0. The package warning totals are unchanged, and both edited files have 0 warnings.\n- `check:new-line-citations`, `check:control-bytes`, `check:changeset-claims`, `check:pending-changeset-literals`, `check-changeset-no-major`, `check-changeset-presence`, `check-changeset-overwrite`, `check:unreferenced-sources` and `check:test-path-roots` each exited 0.\n- No README, doc or changeset text changed this round, so `check:readme-exports` and `check:doc-snippets` were not re-run.\n\n" } ] }
Generated by Claude Code
objectstack-fleet commented
on Oct 6, 2026 ContributorAuthorMore actionsACCEPT (patch round 1): PR objectui#11710 at
a393686(Fixes #11675). A new at-tier contract review is owed before enqueuedomain:uiexecution seat 2 ·session_01FngvPpdrnhHMdHHq6vwwju(os-justin) · 2026-10-06T11:16Z. Dev report: the round-1os-dev-reporton this card. This supersedes the seat's ACCEPT6013900089(ate4f3430) for the new head. Contract review6014049550coverse4f3430only.- Shape: still draft, base
main, first lineFixes #11675,Clause-②: yesat the start of a line. 17 files againstda35453, +925/−41. NOT GOVERNED. This round's commits:98877ddmergesmainatda35453(a merge commit; no rebase, no force-push), anda393686touches two files (utils/first-day-of-week.ts,__tests__/firstDayOfWeek-11675.test.ts). - The round's fix, read by the seat:
- The table declares the release it transcribes,
WEEK_DATA_CLDR = '48', and addsISto the Sunday row. - The parity pin compares the set of table/engine disagreements, by exact equality, with
RELEASE_DELTAS[major(process.versions.cldr)]:46and47recordISon Monday, measured on Node 22.13.0 and 22.22.0, and the table's own release expects none. A rig case and a ledger-honesty case sit beside it. - The pin is not skipped or loosened. Equality stays red on every runtime when the table is edited away from its release, when an unrecorded region moves, and when a recorded row stops holding. The dev's A4 / A6 / A3 / A3b ablations, each on CLDR 46, 47 and 48 and each restored by blob, show it.
- The table declares the release it transcribes,
- Surface: the entry is unchanged from round one (
firstDayOfWeek,WeekdayIndex).WEEK_DATA_CLDRis a module export that the test imports. It is not re-exported fromsrc/index.ts, and the entry's type graph does not reach it. Published behaviour moves by one region: the table path, used where the engine has no week info, startsis-ISon Sunday, which is CLDR 48. The changeset prose names no CLDR release, so it still holds sentence by sentence. The PR body's CLDR 47 sentence and parity description are corrected in this stroke from the dev'spr_body_patch, with a "Patch round 1" section added. - CI on
a393686: 43 check-runs, 40 success and 3 skipped, 0 failed.Test (shard 4/8), red ate4f3430, is green. - Out-of-scope finding, Acceptance note, not filed: CI's floating
node-version: '22.x'can turn anyIntl-data pin red with no repository change. This pin now records per-release differences; otherIntl-reading pins were not surveyed. - Still the maintainer's: the PR assignee is unset, because the dev's label-write was refused by its session's classifier. It is not redone under another identity.
- Owed before enqueue: an at-tier contract review on
a393686.needs:contract-reviewis hung on the PR in this stroke.
Generated by Claude Code
- Shape: still draft, base
objectstack-fleet commented
on Oct 6, 2026 ContributorAuthorMore actionsLanded: PR objectui#11710 →
main9ca3cac, verified by content.Fixesclosed this carddomain:uiexecution seat 2 ·session_01FngvPpdrnhHMdHHq6vwwju(os-justin) · 2026-10-06T11:48Z.-
The merge. Squash
9ca3cacwent through the merge queue, with one parent,abd374b, and is an ancestor oforigin/main. 17 files, +925/−41. Its diff against the parent is byte-identical to the PR's net diff ata393686(md52c501b13…on both, same 17 paths). Contract review6015247684PASS, on the landed heada393686. -
Content check against the first parent:
reading abd374b9ca3cacfirstDayOfWeekinpackages/i18n/src/index.ts0 1 WEEK_DATA_CLDR = '48'inutils/first-day-of-week.tsabsent 1 firstDayOfWeekinplugin-calendar'sCalendarView.tsx0 2 firstDayOfWeekinplugin-timeline'sObjectTimeline.tsx0 3 -
Closures.
Fixes #11675closed this card as completed at the merge. No other issue closed in the landing window.pm:dispatchedcomes off in this stroke. -
Unblocked: objectui#11676's remainder (retiring
timeline.bucket.overdue) was serialised behind this PR'sObjectTimeline.tsx. It can now be dispatched. -
Recorded, not filed:
- CI's floating
node-version: '22.x'can turn anIntl-data pin red with no repository change. This pin now records per-release differences. - The date pickers on the
Calendarprimitive outside the calendar keep date-fns's week start, with no reach reading at a field door.
- CI's floating
Generated by Claude Code
-
Path: ② the capabilities an end user meets in the app — localization | 缺项 | P2
Split by the triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4Ufrom objectui#11672 (the 2026-10-06 console dogfood sweep, showcase, frameworkce577ec4), item 2. Re-read on objectuimain(848ba0e12f) before filing: still live, with no open duplicate. ⛔ Not a claim, ⛔ not a dispatch.Triage: the choice lands in objectstack (the settings manifest the Settings form is drawn from) or in objectui (the formatters) ⇒
domain:ui, with the objectstack half declared on the card; rationale: a setting that no renderer reads is a surface that lies, and the two ways to fix it differ in cost by an order of magnitude. So this is the maintainer's call, not triage's.What happens
GET /api/settings/localizationreportsdate_format: "YYYY-MM-DD",time_format: "24h",number_format: "1,234.56"andfirst_day_of_week: "monday"(allsource: default), and Setup → Settings → Localization shows them. Nothing honours them:CalendarView.tsxabout:438–:451) while the timeline's start on Monday (ObjectTimeline.tsxabout:745).Outside
packages/types/src/data.ts, no objectui source reads those four keys.core/src/utils/date-display.ts(about:517) hard-codeshour12: true.Options
/api/v1/auth/me/localizationmust serve the four values (today it confirms only currency, locale and timezone; the console's fetch atapps/console/src/LocalizationFetchProvider.tsxabout:108already drops the timezone it gets).LocalizationValuegrows. About 5 central formatters change, about 194 directtoLocale*/Intl.*calls in about 72 files across 21 packages are migrated, and 2 week-start sites are fixed.number_formatneeds a meaning ruled, because a fixed pattern conflicts with locale-drivenIntlgrouping.Triage's recommendation: B now, and A as its own measured feature card if a customer pulls for it. It is the smallest change that stops the surface lying, and A's 194-site migration has no measured pull today. The fallback is A, scoped to the 5 central formatters plus the week start, with
number_formatruled out.Reply with one letter.
Generated by Claude Code