Repository navigation
[fields] the readonly datetime WIDGET faces are the same omission one type over — a bare toLocaleDateString + toLocaleTimeString pair, not formatDateTime #8209
Description
Found while implementing objectui#8194 (converging the four readonly date widget faces onto formatDate). Render-measured on origin/main 158d75bb3. Filing unassigned — recording, not claiming.
⛔ Deliberately NOT folded into #8194: that card's landing point is formatDate's year-dropping decision, and the maintainer ruling it follows (objectui#7620, option A) is about formatDate and nothing else. These two sites are datetime faces whose one home is formatDateTime, and picking one of ITS named faces is a second display-convention decision.
The claim
#8194's population is defined by OMISSION — a date rendered with no options bag — so it was re-enumerated by mechanism rather than by spelling. Across the 78 non-test source files of @object-ui/fields the complete set of "a Date becomes user-visible text" mechanisms is toLocaleDateString (7 occurrences), toLocaleTimeString (2), and the shared formatDate / formatDateTime family. There is no Intl.DateTimeFormat, no toDateString / toUTCString, and no date-fns / dayjs / luxon / moment anywhere in the package. (toLocaleString, 4 occurrences, is number formatting.)
That enumeration returns six bare no-bag sites, not the four #8194 names. The two extra ones are these:
| site | spelling |
|---|---|
packages/fields/src/widgets/DateTimeField.tsx (readonly branch) |
date.toLocaleDateString(locale) and date.toLocaleTimeString(locale), joined by a space |
packages/fields/src/widgets/GridField.tsx (temporalText, the datetime branch) |
the same pair, same join |
Neither ever calls formatDateTime, which since objectui#7443 is the declared ONE home for the datetime display convention.
Measured, five locales, origin/main, TZ=UTC
Value 2026-07-04T07:00:00.000Z, rendered in the readonly DateTimeField and in the sub-grid datetime cell (both sites produce the identical string):
| locale | these two sites render | formatDateTime 'compact' (what the datetime CELL renders) |
|---|---|---|
| en | 7/4/2026 7:00:00 AM |
7/4/2026 7:00 am |
| de | 4.7.2026 07:00:00 |
4.7.2026 7:00 am |
| zh | 2026/7/4 07:00:00 |
2026/7/4 上午7:00 |
| ja | 2026/7/4 7:00:00 |
2026/7/4 午前7:00 |
| ar | 4/7/2026 7:00:00 ص |
4/7/2026 7:00 ص |
(The ar forms carry U+200F marks around the date separators; they are omitted here so the table stays readable.)
The date half agrees with the compact face by coincidence — formatDateTimeCompactParts asks for { month: 'numeric', day: 'numeric', year: 'numeric' }, which is what Intl's no-options default happens to produce for these locales. The time half does not: these sites carry seconds and, where the locale writes one, a differently-cased meridiem.
⭐ One thing a triager should notice in that right-hand column rather than take from me: the compact face declares hour12: true, so the German session renders 7:00 am. date-display.ts records that as design ("the 12-hour face is its design, not a locale artefact"), which is exactly why "obviously converge on compact" is not a free move for a readonly FORM field.
Why it is worth a card
Same mechanism as objectui#7443, objectui#7620, objectui#8194 and objectui#4576 — more than one option bag for one concept (here: one bag and one absence of a bag), kept in step by nothing. #7443 gave datetime one home and converged the CELL onto it under a constraint that no pixel move elsewhere; these two widget faces are what that constraint left behind, and nothing says out loud that they opted out.
What the answer is NOT, yet
Converging them requires choosing WHICH formatDateTime face, and that is the decision:
'compact'— what everydatetimeCELL renders. Matches the cell beside it; drops the seconds these sites currently show, and imports the forced 12-hour face above.- the verbose default (
Jul 4, 2026, 07:00 AMinen) — what a non-cell caller (dataset measure, gantt tooltip, data-table) gets. Arguably the right register for a readonly FORM field, and it also carries the year-dropping questiondatehas the same two-convention splitdatetimejust had:data-table's date-only cell keeps a year thatformatDatedrops #7620 answered fordatebut nobody has asked fordatetime.
Either way pixels move on the readonly form / detail surfaces and in the sub-grid, so it wants the treatment #7620 and #8194 got — a ruling, then a pin against a verbatim copy of the former face — not a drive-by edit. ⛔ In particular the answer is NOT "obviously compact, to match the cell": DateTimeCellRenderer reads field.format and defaults to 'compact', while these widgets read no style at all, so "match the cell" is itself a proposal to give the widgets a style vocabulary.
Grading
Observation-class. Every face is locale-correct, no data is lost or misread. objectui#8194's PR leaves both sites untouched on purpose and pins that boundary in packages/fields/src/__tests__/fields-date-widget-convention-8194.test.tsx (SCOPE FENCE block), so this card has a measured starting point rather than a prose one.
Related: objectui#8194, objectui#7443, objectui#7620, objectui#4576.
Activity
os-justin commentedon Sep 16, 2026
转入决策箱 —— 卡片自己写了「答案还不是什么」,余下的是一次显示约定裁决
domain:ui执行席session_017bzjQQsBrHdwBy17iHVVe9,2026-09-16T10:0xZ。本卡带pm:queue坐在可派发队列里,但它的## What the answer is NOT, yet一节明写:收敛这两个面需要先选定formatDateTime的哪一张脸,而那是一次显示约定决策 ⇒ 状态修为needs-user-decision。⛔ 无代码改动,⛔ 无重新测量——卡片的五语种渲染表是 render-measured 的,且 objectui#8194 的 PR 已经用SCOPE FENCE把这两个站点的当前面逐字钉住,所以本卡有一个测量过的起点。Governing text:四棱决策框架第三轴与第四轴(创业阶段聚焦,维护者 2026-08-04)· 本项目基本裁决原则(维护者 2026-09-10:spec 声明 > 实现 > 文档面)· objectui#7443 已裁「datetime只有一个家 =formatDateTime」。维护者速读
事情: 只读的日期时间字段,在表单/详情页上和在表格单元格里,显示得不一样 —— 而它们本该是同一个约定。
两个站点(只读的
DateTimeField、子表格的datetime格子)自己拼toLocaleDateString+toLocaleTimeString,从不走项目声明的唯一入口formatDateTime。后果是它们带秒,而单元格不带;并且在写「上午/下午」的语种里大小写也不一致。7/4/2026 7:00:00 AM7/4/2026 7:00 am4.7.2026 07:00:004.7.2026 7:00 am2026/7/4 07:00:002026/7/4 上午7:00两个选项 —— 收敛到
formatDateTime的哪张脸:'compact'(单元格用的那张)。 和旁边的格子长得一样。代价:丢掉现在显示的秒,并且把强制 12 小时制带进来 —— 德语会话会渲染成7:00 am。卡片查到date-display.ts把这条记为有意设计,不是语种瑕疵。en下是Jul 4, 2026, 07:00 AM。这是所有非单元格调用方(数据集度量、甘特悬浮、数据表)今天已经拿到的那张脸。field.format之后默认到 compact 的,而这两个 widget 根本不读任何 style。所以「跟单元格一致」本身就是一个提案:给 widget 新增一套 style 词汇。四棱分析:
⇒ 席位推荐 B(冗长默认面),三、四两轴同向,第二轴中立。⚠️ 两条路都会动像素(只读表单/详情面与子表格),所以无论选哪条,都应照 objectui#7620 / objectui#8194 的待遇:先裁决,再对旧面留一份逐字拷贝的 pin。⚠️ 另有一个 B 会顺带撞上的问题:
date的省略年份规则(objectui#7620 已答)没有人替datetime问过。选 B 请顺便说一句datetime要不要省略年份。你要做的: 回 A(compact,跟单元格一致)或 B(冗长默认面,推荐);选 B 请附一句
datetime是否省略年份。domain:uiexecution seat ·session_017bzjQQsBrHdwBy17iHVVe9· 2026-09-16T10:0xZGenerated by Claude Code
hotlong commentedon Sep 16, 2026
Ruling: batch #142 item 2 · letter = per register (readonly form → B default face; sub-grid cell → A compact) · maintainer 「同意」 2026-09-16T11:41Z
Director seat, summon #24,
session_01Wj1HUjzyeiBQ8atRf1ZhaL. Presented as batch #142 item 2 with the recommendation each site takes the face of its register, both through the one homeformatDateTime; the maintainer's reply, verbatim: 「同意」.Ruling
packages/fields/src/widgets/DateTimeField.tsx(readonly branch)Jul 4, 2026, 07:00 AMinen, what every non-cell caller already getsformatDateTime(value, { locale })packages/fields/src/widgets/GridField.tsx(temporalText,datetimebranch)'compact'— the face the siblingdatetimecell renders (DateTimeCellRendererreadsfield.format, default'compact')formatDateTime(value, { style: field.format ?? 'compact', locale })toLocaleDateString+toLocaleTimeStringbags; objectui#7443's 「datetimehas one home」 is now true for all six bare sites the card enumerated.field.formatthe wayDateTimeCellRendererdoes — reuse, not a new declaration.datetimedoes not drop the current year. The year-drop isformatDate's (date-only) cell rule per objectui#7620; the verbose default face carries the year, and nothing here extends the drop todatetime.'compact'insideoptions), objectui#7620 ruling A (one face per register within the grid family),date-display.ts:264(hour12is the compact cell's design).Execution (domain:ui seat)
needs-user-decision→pm:queue.dateWIDGET faces are a third convention — a baretoLocaleDateString(locale), notformatDate#8194 treatment: first a verbatim pin of the former face (objectui#8194'sSCOPE FENCEblock already pins today's strings — convert it to a flip pin), then the change, then the five-locale render table re-taken.field, so this is not expected).Four-facet reading: as presented in batch #142.
Generated by Claude Code
os-justin commentedon Sep 16, 2026
Claim: PM loop round 1⚠️ Adjacency ages inside a round — re-derive before opening the PR, ⛔ do not cite this line as fact.
Session:
session_012EpHzwH4wTy5sd7ibkD2yqBranch:
claude/issue-8209-datetime-widget-faces-formatdatetimeWorktree:
objectui-issue-8209Domain:
domain:uiSeat:
domain:ui#1File surface:
packages/fields/src/widgets/DateTimeField.tsx·packages/fields/src/widgets/GridField.tsx· their pin siblings underpackages/fields/(stop on breach; explain in the report)Container & model:
M,mode:subagent,model: default judgement tier— ⛔ no path-derived mandate:node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectui --tier packages/fields/src/widgets/DateTimeField.tsx packages/fields/src/widgets/GridField.tsxanswers verbatim 「dispatch-gates: REFUSING — asked for 'objectstack-ai/objectui', but this checkout is 'objectstack-ai/objectstack'. … a sister repo's list is hand-derived from its own package manifest and its own workflow files.」 ⇒ per-card seat judgement, recorded as such.Clause-②: no
Thread-read: 5696850133
Serial constraints cleared:
none— no open PR and no in-flight claim touchespackages/fields/**. Enumerated against all 12 open objectui PRs read this fire (returned == 12); the two in-flightdomain:uicards (objectui#7945 → PR #9592, objectui#9370 → PR #9378) are governed-surfaceskills/**+AGENTS.md, disjoint.Why
Clause-②: noBoth sites stop composing a
toLocaleDateString+toLocaleTimeStringbag and route throughformatDateTime, which objectui#7443 already declares the single home for thedatetimeconvention. The ruling is explicit that no declaration grows: 「⛔ No new widget style vocabulary: the sub-grid cell readsfield.formatthe wayDateTimeCellRendererdoes — reuse, not a new declaration.」 The accepted authoring set is unchanged; what moves is rendered text on two faces, pulling them onto a contract that already exists. That is the 拉回已声明契约 direction, which the charter says does not trip clause ②.datetimedoes NOT drop the current year. The year-drop belongs toformatDate(date-only) under objectui#7620. The verbose default face carries the year. ⛔ Do not extend the drop.'compact'insideoptions), ⛔ not a new parameter.domain:uiexecution seat ·session_012EpHzwH4wTy5sd7ibkD2yq· R1 claimGenerated by Claude Code
os-justin commentedon Sep 16, 2026
os-dev-report
{
"issue": 8209,
"status": "done",
"branch": "claude/issue-8209-datetime-widget-faces-formatdatetime",
"pr": "#9638",
"session": "session_012EpHzwH4wTy5sd7ibkD2yq",
"premise_still_valid": true,
"premise_detail": {
"card_premise": "HOLDS. Re-derived on today's main ff29450, not copied: the two named sites were the only live toLocale* date mechanisms left in @object-ui/fields (the other 5 toLocaleDateString hits are objectui#8194's own comments); Intl.DateTimeFormat / toDateString / toUTCString / date-fns / dayjs / luxon all zero, with toLocaleDateString as the lit control in the same query shape; every moment hit is the English word in prose. The card's five-locale BEFORE table reproduces byte for byte on today's main.",
"card_premise_drift": "Two measured drifts, neither load-bearing: non-test source files 81 (card said 78); toLocaleString (number formatting) 3 occurrences (card said 4).",
"pm_assumption_a": "VERIFIED then re-taken. Table re-measured by rendering both components, TZ=UTC, on this branch. Not copied from the card.",
"pm_assumption_b": "VERIFIED, with the two drifts above.",
"pm_assumption_c": "FALSIFIED. temporalText is handed (type, value, locale) and has no field. Its caller holds a GridColumn, and neither GridColumn nor the published GridColumnDefinition it mirrors declares a format key. There is nothing at this surface to reuse the way DateTimeCellRenderer reuses DateTimeFieldMetadata.format.",
"pm_assumption_d": "VERIFIED. objectui#8194's SCOPE FENCE block existed exactly as described and was converted in place."
},
"summary": "Both readonly datetime faces in @object-ui/fields stop composing a bare toLocaleDateString + toLocaleTimeString pair and call formatDateTime, each on the face its register was ruled: the readonly DateTimeField (form/detail) takes the verbose default, the GridField sub-grid datetime cell takes compact. The year is not dropped at either site. objectui#8194's SCOPE FENCE block is converted to the negative half of a flip pin (removed spelling kept verbatim, both sites asserted to have left it); a new datetime-widget-faces-8209.test.tsx pins which face each site arrived at, five locales plus the en literals the ruling quotes.",
"deviations": [
{
"what": "The sub-grid selects the compact style as a LITERAL, not as field.format ?? compact the way the ruling's call-shape column wrote it.",
"why": "PM assumption (c) is false: temporalText has no field, and the GridColumn / published GridColumnDefinition shape declares no format key. Spelling the authored read would require DECLARING that key, which the same ruling forbids in its next bullet (no new widget style vocabulary, reuse not a new declaration) and which is exactly the Clause-2 fork the dispatch says to stop on.",
"effect": "The ruled FACE is delivered exactly at both registers. Only the read that would have selected it is absent, because the vocabulary it would read does not exist on this surface. No authorable key declared, no published type widened, so Clause-2: no stands as declared.",
"fallback_not_taken": "The ruling's recorded fallback (both sites on the default face) was NOT taken. It is reserved for the per-register split proving unimplementable at the sub-grid; the split is implementable, it is the field.format READ that is not. Taking the fallback would have discarded the ruled grid-cell face over a spelling detail."
},
{
"what": "Four sibling pins that asserted the former faces were updated rather than left red.",
"why": "They pin the exact strings the ruling moved; objectui#8194 updated the DateField case in the same file the same way.",
"effect": "datetime-widgets.test.tsx (1 case), tests/date-locale-channel.test.tsx (1 case, via a new defaultDateTimeFace helper), widgets/GridField.test.tsx (2 cases, both expectations now asked of the shared formatters)."
}
],
"render_table_five_locales": {
"method": "rendered through I18nProvider + LocalizationProvider, TZ=UTC, value 2026-07-04T07:00:00.000Z, on this branch; the ar rows carry U+200F marks around the date separators, omitted here",
"rows": [
{
"locale": "en",
"before_both_sites": "7/4/2026 7:00:00 AM",
"after_readonly_widget": "Jul 4, 2026, 07:00 AM",
"after_subgrid_cell": "7/4/2026 7:00 am"
},
{
"locale": "de",
"before_both_sites": "4.7.2026 07:00:00",
"after_readonly_widget": "4. Juli 2026, 07:00",
"after_subgrid_cell": "4.7.2026 7:00 am"
},
{
"locale": "zh",
"before_both_sites": "2026/7/4 07:00:00",
"after_readonly_widget": "2026年7月4日 07:00",
"after_subgrid_cell": "2026/7/4 上午7:00"
},
{
"locale": "ja",
"before_both_sites": "2026/7/4 7:00:00",
"after_readonly_widget": "2026年7月4日 07:00",
"after_subgrid_cell": "2026/7/4 午前7:00"
},
{
"locale": "ar",
"before_both_sites": "4/7/2026 7:00:00 ص",
"after_readonly_widget": "4 يوليو 2026، 07:00 ص",
"after_subgrid_cell": "4/7/2026 7:00 ص"
}
],
"year_not_dropped": "every after cell carries 2026, both registers, all five locales",
"unparseable_value": {
"readonly_widget": "was the literal Invalid Date twice, now the shared em dash from formatDateTime",
"subgrid_cell": "unchanged, still shows the raw stored string (objectui#3569)"
}
},
"gates": {
"pnpm exec vitest run packages/fields/ (full package suite, 164 files / 2845 tests)": 0,
"pnpm exec turbo run lint --filter=@object-ui/fields --concurrency=2 (2 tasks)": 0,
"pnpm exec turbo run type-check --filter=@object-ui/fields --concurrency=2 (11 tasks, includes tsconfig.test.json)": 0,
"pnpm exec eslint on the 7 changed files (0 errors, 62 pre-existing warnings)": 0,
"node scripts/check-changeset-presence.mjs": 0,
"node scripts/check-changeset-no-major.mjs": 0,
"node scripts/check-changeset-claims.mjs (report-only; its one finding read and answered)": 0,
"node scripts/check-control-bytes.mjs": 0,
"node scripts/check-new-cross-file-line-citations.mjs (0 new)": 0,
"node scripts/check-test-path-roots.mjs": 0,
"node scripts/check-unreferenced-sources.mjs": 0,
"node scripts/check-comment-mask-corpus.mjs (report-only, within the held-open residue)": 0,
"node scripts/check-governed-queue-guard.mjs --test PATHS (NOT GOVERNED)": 0
},
"gates_not_run": "The repo-wide pnpm test / pnpm lint farm belongs to CI. Dependent packages' suites were not run locally; the narrowing is declared below. Remote CI on PR 9638 had not converged when this report was written.",
"narrowing_declared": "No file outside packages/fields/ names DateTimeField, GridField, LineItemsField or line-items-readonly; toLocaleTimeString occurs nowhere outside that package; a search of every dependent package's tests for a seconds-bearing clock literal returns only a debug drawer's own fixture strings and two timestamps inside a prose comment, with a positive control in the same query shape firing inside packages/fields.",
"tests": "Ablation (reverse verification), run from the committed fix: both widget files reverted to BASE ff29450 via git checkout BASE -- PATHS; mutation proven on disk (formatDateTime occurrences 4 and 6 -> 0 and 0; DateTimeField blob hash 0adfdaf9 -> 4d78ed98, differing from the HEAD blob) rather than by the editor's exit code; pins re-run -> 25 failed / 142 passed across both files (15 in datetime-widget-faces-8209, 10 in the FENCE LIFTED block = 5 locales x 2 sites). Restored with git checkout HEAD -- PATHS under a trap on EXIT/INT/TERM using absolute paths; restore proven by git diff HEAD being empty and git status --porcelain empty, not by an exit code. With the fix in place the same two files are 167 passed / 0 failed. Heavy runs serialized through ../objectstack/scripts/pm/os-verify-lock.sh, slot objectui-8209-dev; verdicts read from the VERDICT command-exit line, package exits echoed explicitly (LINT_TASK_EXIT=0, FIELDS_SUITE_EXIT=0) rather than read after a pipe.",
"line_budget": "n/a - no skills/** file touched, so the published-skill line ratchet does not apply. Diff size: 8 files, 469 insertions / 36 deletions.",
"files_changed": [
"packages/fields/src/widgets/DateTimeField.tsx",
"packages/fields/src/widgets/GridField.tsx",
"packages/fields/src/tests/datetime-widget-faces-8209.test.tsx (new)",
"packages/fields/src/tests/fields-date-widget-convention-8194.test.tsx (SCOPE FENCE -> FENCE LIFTED flip)",
"packages/fields/src/tests/date-locale-channel.test.tsx",
"packages/fields/src/datetime-widgets.test.tsx",
"packages/fields/src/widgets/GridField.test.tsx",
".changeset/8209-datetime-widget-faces.md (new, @object-ui/fields: minor, following the objectui#8194 precedent)"
],
"mcp_calls": "0 - no MCP GitHub tool called, read or write. All GitHub traffic went through the REST proxy with curl.",
"api_writes": "2 - POST /repos/objectstack-ai/objectui/pulls (draft), POST /repos//issues/8209/comments (this report). No label writes: objectui declares skip-changeset through empty-frontmatter changesets, and the dispatch budget named these two endpoints only. Reads, not writes: GET issues/8209, GET issues/8209/comments, GET pulls/9638 for the body read-back.",
"open_questions": [],
"out_of_scope_findings": [
"noted, not filed: the em dash a readonly datetime widget now shows for an unparseable value is formatDateTime's own hand-rolled one, so it carries no empty-value slot and no accessible name, unlike the absent-value branch beside it. The same gap exists at every site objectui#8194 converged, so it predates this card and is the objectui#8490 / objectui#8581 class. Asserted in the new pin so the difference is visible rather than assumed away. Carrier: whatever revisits the shared empty affordance across the date family.",
"noted, not filed (repaired in place, inside the very block this change had to edit): expectedDay in GridField.test.tsx was Intl's bare numeric default 6/17/2026, a string the datetime cell beside it CONTAINS, so since objectui#8194 moved the date column to Jun 17 that toContain assertion had been satisfied by the wrong column and would have stayed green with the date column rendering anything at all. Both faces are now named and a FIXTURE VALIDITY case pins that the three temporal faces are three distinct strings.",
"noted, not filed: check:changeset-claims reports, report-only, that pending .changeset/6625-retire-fieldmeta-decimals.md names GridField.tsx. Read and answered: its paragraph is about .decimals / .scale member reads, this diff adds and removes none, and the scale occurrence count in GridField.tsx is unchanged at 3. The claim stands. Carrier: none needed."
]
}
Generated by Claude Code
os-justin commentedon Sep 16, 2026
✅ ACCEPT — objectui#9638 · the ruled FACE delivered at both registers · ⛔ landing deferred, CI not converged
Reviewed by the dispatching
domain:uiseat,session_012EpHzwH4wTy5sd7ibkD2yq, R1. Verified against GitHub and against the tree, ⛔ not against the report's narrative.Checklist
main, body first lineFixes #8209. ✓+469/−36, matching the reportneeds:contract-review— correct,Clause-②: no, and it still holds (below)87533098eabereturned == total_count(36): 29 success, 3 skipped, 4in_progress, 0 red. ⇒ no red, not convergedmergeable_statebehind— base merge owed before landingmcp_calls⭐⭐ The deviation is CORRECT, and it is the ruling that was wrong
The ruling's call-shape column reads
formatDateTime(value, { style: field.format ?? 'compact', locale }), resting on the stated basis 「it has thefield, so this is not expected」. That basis is false, and the dev found it. Re-derived by this seat at source, ⛔ not taken from the report:packages/fields/src/widgets/GridField.tsx:356—function temporalText(type: string | undefined, value: any, locale: string): string. Nofieldparameter.:387— the sole call site passes three arguments:temporalText(c.type, value, locale).GridColumn, and the publishedGridColumnDefinition(exported atpackages/types/src/index.ts:524, declared atpackages/types/src/field-types.ts:933) declares noformatkey — probed and empty.⇒ spelling the authored read would mean declaring a new key on a published type. That is forbidden twice over: by the ruling's own very next bullet (「⛔ No new widget style vocabulary … reuse, not a new declaration」), and by the
Clause-②: nodeclared on this card — it is precisely the fork the dispatch says to stop on.⭐ The dev took the literal
'compact'and said so. The ruled face is delivered exactly at both registers; only the read that would have selected it is absent, because the vocabulary it would read does not exist on that surface. No authorable key declared, no published type widened ⇒Clause-②: nostands as declared, verified here rather than assumed.⭐ And the recorded fallback was correctly NOT taken. The ruling reserves 「both sites on the default face」 for the per-register split proving unimplementable at the sub-grid. The split is implementable — it is the
field.formatread that is not. Taking the fallback would have discarded the ruled grid-cell face over a spelling detail. That is exactly the right distinction to draw, and drawing it rather than reaching for the escape hatch is the judgement this card was dispatched at default tier to get.The five-locale table, re-taken
Re-measured on the branch by rendering both components (TZ=UTC,
2026-07-04T07:00:00.000Z), ⛔ not copied from the card. The year is carried in every after-cell, at both registers, in all five locales — the objectui#7620 year-drop isformatDate's and is correctly not extended todatetime.enlands onJul 4, 2026, 07:00 AM(readonly) and7/4/2026 7:00 am(sub-grid cell), which is the ruling's own quoted pair.⭐ Premise falsifications credited — assumption (c) was mine and it was load-bearing
toLocaleString3 (card said 4). ⭐ Reporting drift that changes nothing is how a census stays trustworthy.toLocaleDateStringas the lit control in the same query shape.⭐ A real defect repaired in place, inside the block this change had to touch
expectedDayinGridField.test.tsxwas Intl's bare numeric default6/17/2026— a string the datetime cell beside it contains. Since objectui#8194 moved the date column toJun 17, thattoContainassertion had been satisfied by the wrong column, and would have stayed green with the date column rendering anything at all. Both faces are now named, and a FIXTURE VALIDITY case pins that the three temporal faces are three distinct strings. ⭐ This is 「AN ASSERTION THAT PASSES IS NOT ONE THAT WITNESSES」 caught in the wild.Deviations — two declared, both accepted
'compact'in place of the ruled call shape — accepted, reasoned above; the ruling's premise is the thing at fault.git diff HEAD, ⛔ not by an exit code.Out-of-scope findings — re-judged, none owed a card
Three, all 「noted, not filed」, and I agree with each: the em-dash empty affordance predates this card and is the objectui#8490 / #8581 class (and is now asserted in the pin rather than assumed away); the
GridField.test.tsxfixture defect was repaired in place inside the block being edited, which is the correct call; and thecheck:changeset-claimsreport-only finding was read and answered on its merits (.decimals/.scalemember reads, unchanged at 3).⛔ Landing deferred
Work ACCEPTED. Not landing yet: 4 checks still
in_progress(no red, but not converged) andmergeable_state: behind. A base merge is owed, and this seat re-takescheck-harness-currentimmediately before any ready-flip or enqueue — a currency reading ages inside a round.domain:uiexecution seat ·session_012EpHzwH4wTy5sd7ibkD2yq· R1 ACCEPT · readings taken 2026-09-16T16:45Z on head87533098eabeGenerated by Claude Code
fix(fields): the two readonly datetime widget faces converge on forma…