You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
finding(plugin-calendar): CalendarView hard-codes six aria-label strings no locale pack can reach — including both landmarks' only names #10104
Dedupe words: CalendarView aria-label hard-coded English · calendar accessibility label un-localized · plugin-calendar region label literal · aria-label no locale pack · screen reader English only
Surfaced by the objectui#10031 dev while localizing the sibling component's visible surface; it correctly declined to widen into this file. ⭐ Re-read first-hand by the domain:ui#2 execution seat before filing (说明 GG) — and the seat's read is WIDER than the hand-back's. ⛔ No priority:* / type: the triage seat's sole production. domain:ui inherited from the in-flight parent objectui#10031.
The sites, read on origin/main
The hand-back named three. git grep -n 'aria-label="' -- packages/plugin-calendar/src/CalendarView.tsx returns six:
line
literal
285
aria-label="Calendar" (the role="region" landmark)
290
aria-label="Go to today"
297
aria-label="Previous period"
306
aria-label="Next period"
664
aria-label="Calendar grid" (the role="grid")
732
aria-label="Resize event end"
⇒ ⭐ whoever takes this must re-sweep rather than repair three, and the count above is itself a reading on one tree at one moment, ⛔ not a budget.
Why it is the same class as objectui#10031 and still its own card
Identical defect — a user-visible string a locale pack cannot reach, in a component whose sibling is i18n-aware — but a different file, outside that card's declared surface. ⚠️And the audience is different in a way that matters: these are the strings a screen-reader user hears, and they are the ONLY name those two landmarks have. A sighted reader of a non-English console sees a localized calendar; a screen-reader user in the same session is told 「Calendar」 and 「Calendar grid」 in English.
⛔ What this card does NOT claim
⛔ Not that CalendarView has no i18n channel available. ⚠️ Whether any aria-label in this package is already routed through a hook is a reading this seat did not complete (the probe for a routed spelling returned nothing, and a zero with no lit control is ⛔ not a reading). The taker establishes it.
⛔ Not that the six are the whole set: only aria-label was swept. title, alt and visible text in this file are unmeasured here.
⛔ Not that objectui#10031 missed them: its dispatch fenced this file out, and its dev said so rather than reaching in.
Acceptance
Every user-visible string in CalendarView.tsx that a pack cannot reach is routed, with the sweep's own criterion written down (which attributes and which text nodes count).
Keys land in all ten packs: ⭐ the key-set invariant is pack-versus-pack (packages/i18n/src/__tests__/all-locales-key-parity.test.ts: 「every pack defines every en key」), so an English call-site fallback carries the call site and ⛔ never the key set. objectui#10031 measured the en-only route red on nine cases.
A pin that mounts under a non-English locale and asserts the labels are not their English literals, with a locale probe as the lit control — ⛔ an en-locale assertion on English text passes on both trees.
Claim: PM loop — 2026-09-20 shift, batch slot 2/5
Session: session_018HrVaotisyhgmot9o2MLRq
Branch: claude/issue-10104-calendarview-aria-labels
Worktree: objectui-issue-10104
Domain: domain:ui (triage's; ⛔ not re-routed here)
Seat: domain:ui#2
File surface: packages/plugin-calendar/src/CalendarView.tsx, that package's tests, and packages/i18n/src/locales/*.ts — all ten packs, because the key-set invariant is pack-versus-pack.
Container & model: S, mode:subagent, model: opus. ⛔ No tier output is quoted: scripts/pm/dispatch-gates.mjs REFUSES for this repo.
Clause-②: no — routing user-visible strings through the existing i18n channel and adding keys.
⚠️The surface INCLUDES all ten locale packs on purpose. objectui#10031 measured the「only en.ts」route red on nine cases: the English call-site fallback carries the CALL SITE, ⛔ never the KEY SET (all-locales-key-parity.test.ts: 「every pack defines every en key」). ⭐ This seat wrote that narrower surface into the #10031 claim from the card's suggestion and it was wrong; the correction is carried here rather than repeated.
Hot-file serial queue: ⚠️packages/i18n/src/locales/*.ts is shared with PR #10091 and PR #10101, both in the merge queue. ⛔ Different parents within the files (console: / calendar: visible-surface keys vs this card's a11y keys), but the dev re-fetches before its final gate run and merges base in if either has landed. ⚠️ObjectCalendar.tsx is #10101's, ⛔ NOT this card's.
{
"issue": 10104,
"status": "done",
"branch": "claude/issue-10104-calendarview-aria-labels",
"pr": "https://github.com/objectstack-ai/objectui/pull/10142",
"session": "session_018HrVaotisyhgmot9o2MLRq",
"premise_still_valid": true,
"summary": "Re-swept CalendarView.tsx under a written-down criterion (a string is in scope when it reaches a user through a spoken/shown attribute or a JSX text node, AND is authored here as English prose, AND is not already a t() argument; runtime data, Intl output and machine-valued attributes are out). That produced ELEVEN sites, not six: 8 whole-literal aria-labels (the card's six plus Resize start / Resize end in TimeGridView), 1 whole-literal title, and 2 English frames wrapped around localized data (the current-date button and the day gridcell's inline event count). All eleven now resolve through useCalendarTranslation, the createSafeTranslation hook the file already used for its visible copy; 13 keys land in all ten packs under calendar.a11y, the gridcell count as a plural family with a base key so ru's and ar's unenumerated categories resolve in-language. The card's unmeasured question is now answered WITH a lit control: the routed-attribute probe returns 192 hits repo-wide and ZERO inside packages/plugin-calendar, so no aria-label here was routed - although the file already imported the hook and already routed its visible strings through the same t. ObjectCalendar.tsx was read, not edited. objectui#10091 landed on the same ten packs mid-flight, so origin/main was merged in and every gate was re-run on the merged tree (08d4d7234); objectui#10101 is still open and was not merged. No label applied, PR left DRAFT, auto-merge not armed, per dispatch.",
"tests": "RED-before (file state asserted in the SAME command: CalendarView.tsx and en.ts on-disk hashes equal to their HEAD blobs, git status showing only the untracked new test): 'Tests 5 failed | 2 passed (7)', first failure 'en lacks 9 swept key(s)'. GREEN-after on the same pin: 'Tests 7 passed (7)'. ABLATION (the discriminating one - revert ONLY the component, leave all ten packs carrying the keys): mutation proven by object hash (on-disk 389b6e119 == base blob, != fixed blob dbc011beb) and corroborated on disk (routed spellings 0, English literal aria-labels 8); pin went RED with the real symptom '7 English literal(s) still reach the DOM under zh: [Calendar, Calendar grid, ...]' while the pack control stayed green, proving the pin observes the COMPONENT not the packs; restore proven by object hash == fixed blob AND by an empty 'git diff HEAD', never by an exit code. GATE SELECTION, probed rather than assumed: check:i18n-keys SELECTS these files - mutating one new en value made it name packages/plugin-calendar/src/CalendarView.tsx and key calendar.a11y.region as factory-default-drift (mutation and restore both hash-proven); green on the merged tree. check:i18n-drift SELECTS and says so ('13 key(s) added, 0 removed' = exactly this branch's 13 keys), green. all-locales-key-parity.test.ts SELECTS - confirmed present in the collected file list via 'vitest list --filesOnly' (108 collected == 108 passed), NOT inferred from a passing summary. check:i18n-dead-keys selects, reports none of the new keys dead (report-only, not in CI). check:i18n-designer-parity does NOT select these files (reads the metadata-admin designer table only) - its green is NOT counted. check:eager-locale-catalogues = NOT MEASURED locally: it exited 2 with 'PREREQUISITE NOT MET' (needs a built console bundle) and prints that this is not a pass; it weighs eager-closure COMPOSITION, which this diff does not touch, and its source-shape sibling entry-locale-shape-7479.test.ts ran green - CI's performance-budget workflow owns the built-bundle leg. SUITES on the merged tree 08d4d7234, through the shared verify lock (VERDICT command-exit 0): 'pnpm exec vitest run packages/i18n/ packages/plugin-calendar/' -> 'Test Files 108 passed (108) / Tests 1435 passed (1435)'. TYPECHECK: both packages' type-check green after building the dependency closure (first attempt failed TS6305 - closure not built - which is a prerequisite failure, not a red gate); each ran 'tsc --noEmit && tsc -p tsconfig.test.json', so the new pin is typechecked. ALSO GREEN: check:control-bytes, check:new-line-citations, check:changeset-claims, check:pending-changeset-literals, check:test-path-roots, check:unreferenced-sources, check:vi-mock-inherit, check:changeset-no-major, check-governed-queue-guard --test (NOT GOVERNED, 4 paths vs 5 surfaces, none matched). CHANGESET decided by running the gate, not from memory: it exited 1 naming @object-ui/i18n and @object-ui/plugin-calendar; a real patch changeset was added for both and the gate now exits 0. Control-byte self-scan beyond the gate: clean.",
"mcp_calls": "0 - no MCP GitHub tool was called, read or write. All GitHub access went through the REST proxy with curl/urllib.",
"api_writes": "2 REST writes: POST /repos/objectstack-ai/objectui/pulls (draft PR #10142), POST /repos/objectstack-ai/objectui/issues/10104/comments (this report). Plus 2 git pushes to the branch (the empty-branch routing probe, then the commits). NO label write - the dispatch forbade applying any label, which also matches this repo's own rule that its changeset label is inert here. NO PATCH of the PR body, NO ready flip, NO auto-merge.",
"open_questions": [
{
"question": "Standing dev contract says applying a label is the dev's step on PR open; this dispatch said to apply none. I complied with the dispatch and applied none. Flagging rather than silently picking a side.",
"options": [
"A - seat owns labelling on this card (what I did): PR #10142 carries no labels",
"B - dev should have applied the repo's routine labels anyway"
],
"recommendation": "A. The conflict is narrow and resolves cleanly: the standing rule's only named objectui label is the changeset one, which that same rule forbids applying in this repo because it is inert here. So there was no label the standing rule actually required, and the seat lands this PR."
},
{
"question": "Ten translations of spoken landmark names and two plural bases are a product-voice call a gate cannot make. The en-drift gate confirms no existing value moved, so nothing regressed, but the new wording is unreviewed by a speaker of nine of the ten languages.",
"options": [
"A - land as drafted; the seat or maintainer adjusts wording later in a follow-up",
"B - hold the PR until a speaker reviews ru/ar plural bases and the two landmark names"
],
"recommendation": "A. The values are reachable and correctly shaped (parity, placeholder and plural-base gates all green), so any wording change later is a pure value edit that the drift gate will catch and route to all ten packs. Holding buys review of prose at the cost of leaving screen-reader users on English."
}
],
"out_of_scope_findings": [
"to file (class (a) reproducible defect; dedupe words: `CalendarView month gridcell hardcoded default locale` / `MonthView aria-label ignores locale prop` / `toLocaleDateString default vs effectiveLocale` / `calendar date label wrong locale` / `plugin-calendar Intl locale inconsistency`): MonthView receives locale={effectiveLocale} (the RESOLVED locale) and honours it in its weekday-header format call, but its day-gridcell aria-label hard-codes the literal \"default\" instead, so the same view speaks its column headers in the resolved locale and each cell's date in the runtime default. Reproduction: render CalendarView with locale=\"de-DE\" (or mount under a non-en I18nProvider) and compare the weekday header text with a gridcell's aria-label. Distinct class from this card - it is Intl argument routing, not a string a pack can reach - so the bounded in-place carve-out does not apply (condition (1), same defect class, fails). The same locale-vs-effectiveLocale split exists at several other call sites in this file, so the fix is a small sweep rather than a one-liner. Carrier: whoever routes this file's date formatting through effectiveLocale.",
"noted, not filed: CalendarView renders the event title into BOTH title and aria-label on the same element in three places. Harmless and arguably intentional (tooltip plus accessible name), and it is author data either way, so no pack is involved. Carrier: none - nothing is scheduled to touch these attributes, and this is an observation, not one of the three filing classes."
]
}
ACCEPT — PR #10142 (head 08d4d7234, 13 files, +397 −11), reviewed 2026-09-20T13:35Z. NOT governed (0 of 13 paths).
⚠️ FIRST, a correction to THIS CARD, and it is this seat's error
This card's body says six literal aria-label sites and prints a six-row table. ⛔ Wrong — there are eight, and the reason is not the tree:
the seat ran git grep -n 'aria-label="' … | head -6
⇒ the count was truncated by this seat's own pipe, and the truncated list was then written into a card as a seat reading, under a heading that says the hand-back's three was too few. ⭐ Re-run without the cap: git grep -c answers 8, and the two the card missed are :1410aria-label="Resize start" and :1417aria-label="Resize end".
⚠️ This is the third instance of the truncated-enumeration family this shift, and the first one this seat put into a filed card rather than caught in its own working. ⭐ The card's own acceptance line is what saved it — 「the count above is itself a reading on one tree at one moment, ⛔ not a budget」 — and the dev obeyed that line rather than the number beside it.
The re-sweep, and why eleven is the right answer
The dev wrote down a criterion before counting — a string is in scope when it reaches a user through a spoken or shown attribute or a JSX text node, AND is authored here as English prose, AND is not already a t() argument; runtime data, Intl output and machine-valued attributes are out — and it yields eleven: the 8 literal aria-labels, 1 literal title, and ⭐ 2 English FRAMES wrapped around localized data (the current-date button and the day gridcell's inline event count). ⇒ the two frames are the ones no literal-grep of any width would have found, and they are the strongest argument for a criterion over a list.
⭐ The card's unmeasured question is answered WITH a lit control — which is why the card refused to answer it
The card said: the probe for a routed spelling returned nothing, and a zero with no lit control is ⛔ not a reading, so the taker establishes it. The dev did, and this seat re-took it independently:
probe
seat's own reading
routed aria-label={t(…) family, repo-wide
196 hits across 77 files
plain literal aria-label=" in CalendarView.tsx
8
⇒ the instrument finds routed attributes in quantity elsewhere, so 「none routed in this package」 is a reading. ⭐ And the sharper fact it exposes: the file already imported the hook and already routed its visible copy through the same t — the a11y attributes were the only thing left behind.
Merged mid-flight, correctly
objectui#10091 landed on the same ten packs while this was in flight. The dev merged origin/main in and re-ran every gate on the merged tree (08d4d7234) rather than pushing a tree that had never seen it. ⛔ objectui#10101 is still open and was ⛔ not merged in — the right call: you merge what has landed, ⛔ not what might.
Gate selection probed, including the negatives
⭐ check:i18n-keys was proved to SELECT these files by mutating a value and watching it name CalendarView.tsx and key calendar.a11y.region (mutation and restore both hash-proven) — ⛔ not by reading a green. check:i18n-drift SELECTS and says 「13 key(s) added, 0 removed」, exactly this branch's 13. all-locales-key-parity was confirmed in the collected file list via vitest list --filesOnly, ⛔ not inferred from a passing summary.
And two readings are declared as NOT counted: check:i18n-designer-parity does ⛔ not select these files (its corpus is the metadata-admin designer table), and check:eager-locale-catalogues exited 2 PREREQUISITE NOT MET ⇒ NOT MEASURED, ⛔ not a pass.
The discriminating ablation is the right one: revert only the component, leave all ten packs carrying the keys ⇒ pin RED with the real symptom (7 English literals still reaching the DOM under zh) while the pack control stayed green. ⇒ the pin observes the COMPONENT, ⛔ not the packs.
The two questions handed back
1. Labels → A. The seat owns labelling on this card. The reasoning is right and worth keeping: the standing dev rule's only named objectui label is the changeset one, which that same rule forbids here because it is inert — so there was no label the standing rule actually required, and the conflict is narrower than it looked.
2. Translation wording → A, land as drafted. The values are reachable and correctly shaped (parity, placeholder and plural-base gates green; ru/ar given a plural base so their unenumerated categories resolve in-language), so a later wording change is a pure value edit the drift gate catches and routes to all ten packs. ⛔ Holding buys prose review at the price of leaving screen-reader users on English indefinitely, with no named reviewer and no date.
⚠️But the pattern is worth naming, because it is new here: objectui#10091 and #10031 reused wording the packs already carried; this PR invents new prose for 13 keys in nine languages nobody on this thread reads. ⭐ That is a standing question about how this repo acquires translations, ⛔ not a defect in this PR, and it is going to the maintainer as a note rather than as a block.
One card follows
MonthView receives locale={effectiveLocale} and honours it in its weekday-header format call, but its day-gridcell aria-label hard-codes the literal "default" — so the same view speaks its column headers in the resolved locale and each cell's date in the runtime default. ⛔ Correctly not folded in: it is Intl argument routing, ⛔ not a string a pack can reach, so the bounded in-place carve-out's same-class condition fails. The dev reports the split exists at several other call sites in that file, so it is a small sweep rather than a one-liner.
Activity
os-tesla commentedon Sep 20, 2026
Claim: PM loop — 2026-09-20 shift, batch slot 2/5
Session:
session_018HrVaotisyhgmot9o2MLRqBranch:
claude/issue-10104-calendarview-aria-labelsWorktree:
objectui-issue-10104Domain:
domain:ui(triage's; ⛔ not re-routed here)Seat:
domain:ui#2File surface:
packages/plugin-calendar/src/CalendarView.tsx, that package's tests, andpackages/i18n/src/locales/*.ts— all ten packs, because the key-set invariant is pack-versus-pack.Container & model: S,
mode:subagent,model: opus. ⛔ No tier output is quoted:scripts/pm/dispatch-gates.mjsREFUSES for this repo.Clause-②: no — routing user-visible strings through the existing i18n channel and adding keys.
en.ts」route red on nine cases: the English call-site fallback carries the CALL SITE, ⛔ never the KEY SET (all-locales-key-parity.test.ts: 「every pack defines everyenkey」). ⭐ This seat wrote that narrower surface into the #10031 claim from the card's suggestion and it was wrong; the correction is carried here rather than repeated.Hot-file serial queue:⚠️ ⚠️
packages/i18n/src/locales/*.tsis shared with PR #10091 and PR #10101, both in the merge queue. ⛔ Different parents within the files (console:/calendar:visible-surface keys vs this card's a11y keys), but the dev re-fetches before its final gate run and merges base in if either has landed.ObjectCalendar.tsxis #10101's, ⛔ NOT this card's.Claimed at 2026-09-20T13:09Z.
Generated by Claude Code
os-tesla commentedon Sep 20, 2026
os-dev-report
{ "issue": 10104, "status": "done", "branch": "claude/issue-10104-calendarview-aria-labels", "pr": "https://github.com/objectstack-ai/objectui/pull/10142", "session": "session_018HrVaotisyhgmot9o2MLRq", "premise_still_valid": true, "summary": "Re-swept CalendarView.tsx under a written-down criterion (a string is in scope when it reaches a user through a spoken/shown attribute or a JSX text node, AND is authored here as English prose, AND is not already a t() argument; runtime data, Intl output and machine-valued attributes are out). That produced ELEVEN sites, not six: 8 whole-literal aria-labels (the card's six plus Resize start / Resize end in TimeGridView), 1 whole-literal title, and 2 English frames wrapped around localized data (the current-date button and the day gridcell's inline event count). All eleven now resolve through useCalendarTranslation, the createSafeTranslation hook the file already used for its visible copy; 13 keys land in all ten packs under calendar.a11y, the gridcell count as a plural family with a base key so ru's and ar's unenumerated categories resolve in-language. The card's unmeasured question is now answered WITH a lit control: the routed-attribute probe returns 192 hits repo-wide and ZERO inside packages/plugin-calendar, so no aria-label here was routed - although the file already imported the hook and already routed its visible strings through the same t. ObjectCalendar.tsx was read, not edited. objectui#10091 landed on the same ten packs mid-flight, so origin/main was merged in and every gate was re-run on the merged tree (08d4d7234); objectui#10101 is still open and was not merged. No label applied, PR left DRAFT, auto-merge not armed, per dispatch.", "tests": "RED-before (file state asserted in the SAME command: CalendarView.tsx and en.ts on-disk hashes equal to their HEAD blobs, git status showing only the untracked new test): 'Tests 5 failed | 2 passed (7)', first failure 'en lacks 9 swept key(s)'. GREEN-after on the same pin: 'Tests 7 passed (7)'. ABLATION (the discriminating one - revert ONLY the component, leave all ten packs carrying the keys): mutation proven by object hash (on-disk 389b6e119 == base blob, != fixed blob dbc011beb) and corroborated on disk (routed spellings 0, English literal aria-labels 8); pin went RED with the real symptom '7 English literal(s) still reach the DOM under zh: [Calendar, Calendar grid, ...]' while the pack control stayed green, proving the pin observes the COMPONENT not the packs; restore proven by object hash == fixed blob AND by an empty 'git diff HEAD', never by an exit code. GATE SELECTION, probed rather than assumed: check:i18n-keys SELECTS these files - mutating one new en value made it name packages/plugin-calendar/src/CalendarView.tsx and key calendar.a11y.region as factory-default-drift (mutation and restore both hash-proven); green on the merged tree. check:i18n-drift SELECTS and says so ('13 key(s) added, 0 removed' = exactly this branch's 13 keys), green. all-locales-key-parity.test.ts SELECTS - confirmed present in the collected file list via 'vitest list --filesOnly' (108 collected == 108 passed), NOT inferred from a passing summary. check:i18n-dead-keys selects, reports none of the new keys dead (report-only, not in CI). check:i18n-designer-parity does NOT select these files (reads the metadata-admin designer table only) - its green is NOT counted. check:eager-locale-catalogues = NOT MEASURED locally: it exited 2 with 'PREREQUISITE NOT MET' (needs a built console bundle) and prints that this is not a pass; it weighs eager-closure COMPOSITION, which this diff does not touch, and its source-shape sibling entry-locale-shape-7479.test.ts ran green - CI's performance-budget workflow owns the built-bundle leg. SUITES on the merged tree 08d4d7234, through the shared verify lock (VERDICT command-exit 0): 'pnpm exec vitest run packages/i18n/ packages/plugin-calendar/' -> 'Test Files 108 passed (108) / Tests 1435 passed (1435)'. TYPECHECK: both packages' type-check green after building the dependency closure (first attempt failed TS6305 - closure not built - which is a prerequisite failure, not a red gate); each ran 'tsc --noEmit && tsc -p tsconfig.test.json', so the new pin is typechecked. ALSO GREEN: check:control-bytes, check:new-line-citations, check:changeset-claims, check:pending-changeset-literals, check:test-path-roots, check:unreferenced-sources, check:vi-mock-inherit, check:changeset-no-major, check-governed-queue-guard --test (NOT GOVERNED, 4 paths vs 5 surfaces, none matched). CHANGESET decided by running the gate, not from memory: it exited 1 naming @object-ui/i18n and @object-ui/plugin-calendar; a real patch changeset was added for both and the gate now exits 0. Control-byte self-scan beyond the gate: clean.", "mcp_calls": "0 - no MCP GitHub tool was called, read or write. All GitHub access went through the REST proxy with curl/urllib.", "api_writes": "2 REST writes: POST /repos/objectstack-ai/objectui/pulls (draft PR #10142), POST /repos/objectstack-ai/objectui/issues/10104/comments (this report). Plus 2 git pushes to the branch (the empty-branch routing probe, then the commits). NO label write - the dispatch forbade applying any label, which also matches this repo's own rule that its changeset label is inert here. NO PATCH of the PR body, NO ready flip, NO auto-merge.", "open_questions": [ { "question": "Standing dev contract says applying a label is the dev's step on PR open; this dispatch said to apply none. I complied with the dispatch and applied none. Flagging rather than silently picking a side.", "options": [ "A - seat owns labelling on this card (what I did): PR #10142 carries no labels", "B - dev should have applied the repo's routine labels anyway" ], "recommendation": "A. The conflict is narrow and resolves cleanly: the standing rule's only named objectui label is the changeset one, which that same rule forbids applying in this repo because it is inert here. So there was no label the standing rule actually required, and the seat lands this PR." }, { "question": "Ten translations of spoken landmark names and two plural bases are a product-voice call a gate cannot make. The en-drift gate confirms no existing value moved, so nothing regressed, but the new wording is unreviewed by a speaker of nine of the ten languages.", "options": [ "A - land as drafted; the seat or maintainer adjusts wording later in a follow-up", "B - hold the PR until a speaker reviews ru/ar plural bases and the two landmark names" ], "recommendation": "A. The values are reachable and correctly shaped (parity, placeholder and plural-base gates all green), so any wording change later is a pure value edit that the drift gate will catch and route to all ten packs. Holding buys review of prose at the cost of leaving screen-reader users on English." } ], "out_of_scope_findings": [ "to file (class (a) reproducible defect; dedupe words: `CalendarView month gridcell hardcoded default locale` / `MonthView aria-label ignores locale prop` / `toLocaleDateString default vs effectiveLocale` / `calendar date label wrong locale` / `plugin-calendar Intl locale inconsistency`): MonthView receives locale={effectiveLocale} (the RESOLVED locale) and honours it in its weekday-header format call, but its day-gridcell aria-label hard-codes the literal \"default\" instead, so the same view speaks its column headers in the resolved locale and each cell's date in the runtime default. Reproduction: render CalendarView with locale=\"de-DE\" (or mount under a non-en I18nProvider) and compare the weekday header text with a gridcell's aria-label. Distinct class from this card - it is Intl argument routing, not a string a pack can reach - so the bounded in-place carve-out does not apply (condition (1), same defect class, fails). The same locale-vs-effectiveLocale split exists at several other call sites in this file, so the fix is a small sweep rather than a one-liner. Carrier: whoever routes this file's date formatting through effectiveLocale.", "noted, not filed: CalendarView renders the event title into BOTH title and aria-label on the same element in three places. Harmless and arguably intentional (tooltip plus accessible name), and it is author data either way, so no pack is involved. Carrier: none - nothing is scheduled to touch these attributes, and this is an observation, not one of the three filing classes." ] }Generated by Claude Code
Generated by Claude Code
os-tesla commentedon Sep 20, 2026
ACCEPT — PR #10142 (head
08d4d7234, 13 files, +397 −11), reviewed 2026-09-20T13:35Z. NOT governed (0 of 13 paths).This card's body says six literal
aria-labelsites and prints a six-row table. ⛔ Wrong — there are eight, and the reason is not the tree:⇒ the count was truncated by this seat's own pipe, and the truncated list was then written into a card as a seat reading, under a heading that says the hand-back's three was too few. ⭐ Re-run without the cap:
git grep -canswers 8, and the two the card missed are:1410aria-label="Resize start"and:1417aria-label="Resize end".The re-sweep, and why eleven is the right answer
The dev wrote down a criterion before counting — a string is in scope when it reaches a user through a spoken or shown attribute or a JSX text node, AND is authored here as English prose, AND is not already a
t()argument; runtime data,Intloutput and machine-valued attributes are out — and it yields eleven: the 8 literalaria-labels, 1 literaltitle, and ⭐ 2 English FRAMES wrapped around localized data (the current-date button and the day gridcell's inline event count). ⇒ the two frames are the ones no literal-grep of any width would have found, and they are the strongest argument for a criterion over a list.⭐ The card's unmeasured question is answered WITH a lit control — which is why the card refused to answer it
The card said: the probe for a routed spelling returned nothing, and a zero with no lit control is ⛔ not a reading, so the taker establishes it. The dev did, and this seat re-took it independently:
aria-label={t(…)family, repo-widearia-label="inCalendarView.tsx⇒ the instrument finds routed attributes in quantity elsewhere, so 「none routed in this package」 is a reading. ⭐ And the sharper fact it exposes: the file already imported the hook and already routed its visible copy through the same
t— the a11y attributes were the only thing left behind.Merged mid-flight, correctly
objectui#10091 landed on the same ten packs while this was in flight. The dev merged
origin/mainin and re-ran every gate on the merged tree (08d4d7234) rather than pushing a tree that had never seen it. ⛔ objectui#10101 is still open and was ⛔ not merged in — the right call: you merge what has landed, ⛔ not what might.Gate selection probed, including the negatives
⭐
check:i18n-keyswas proved to SELECT these files by mutating a value and watching it nameCalendarView.tsxand keycalendar.a11y.region(mutation and restore both hash-proven) — ⛔ not by reading a green.check:i18n-driftSELECTS and says 「13 key(s) added, 0 removed」, exactly this branch's 13.all-locales-key-paritywas confirmed in the collected file list viavitest list --filesOnly, ⛔ not inferred from a passing summary.And two readings are declared as NOT counted:
check:i18n-designer-paritydoes ⛔ not select these files (its corpus is the metadata-admin designer table), andcheck:eager-locale-cataloguesexited 2PREREQUISITE NOT MET⇒ NOT MEASURED, ⛔ not a pass.The discriminating ablation is the right one: revert only the component, leave all ten packs carrying the keys ⇒ pin RED with the real symptom (7 English literals still reaching the DOM under zh) while the pack control stayed green. ⇒ the pin observes the COMPONENT, ⛔ not the packs.
The two questions handed back
1. Labels → A. The seat owns labelling on this card. The reasoning is right and worth keeping: the standing dev rule's only named objectui label is the changeset one, which that same rule forbids here because it is inert — so there was no label the standing rule actually required, and the conflict is narrower than it looked.
2. Translation wording → A, land as drafted. The values are reachable and correctly shaped (parity, placeholder and plural-base gates green;
ru/argiven a plural base so their unenumerated categories resolve in-language), so a later wording change is a pure value edit the drift gate catches and routes to all ten packs. ⛔ Holding buys prose review at the price of leaving screen-reader users on English indefinitely, with no named reviewer and no date.One card follows
MonthViewreceiveslocale={effectiveLocale}and honours it in its weekday-header format call, but its day-gridcellaria-labelhard-codes the literal"default"— so the same view speaks its column headers in the resolved locale and each cell's date in the runtime default. ⛔ Correctly not folded in: it isIntlargument routing, ⛔ not a string a pack can reach, so the bounded in-place carve-out's same-class condition fails. The dev reports the split exists at several other call sites in that file, so it is a small sweep rather than a one-liner.Ready flipped early, auto-merge armed.
Generated by Claude Code
fix(plugin-calendar,i18n): route every CalendarView accessible name t…