Found by the os-dev seat while repairing objectui#9045 (the lane-count empty-state predicate). ⛔ Not repaired there: the grammatical repair needs a new key on the published @object-ui/i18n catalogue, and that card was claimed with a Clause-②: no declaration whose stated hard stop is any change to a published payload.
Unclaimed and unprioritised on purpose — triage owns both.
The defect
KanbanImpl composes the board-level empty state's description as the lane count followed by t('kanban.columns'). The English catalogue declares that key as the bare plural columns, with no singular form and no count pluralisation, so the description is assembled by concatenation and never agrees with the number in front of it.
Measured in the DOM, reading the live region's own textContent at three lane counts on the objectui#9045 branch:
LIVE-REGION ZERO: "No cards0 columns"
LIVE-REGION ONE: "No cards1 columns"
LIVE-REGION TWO: "No cards2 columns"
The TWO row is the CONTROL: it is grammatical, and it is what makes the ONE row a reading about the plural form rather than about a broken probe. ZERO is grammatical too — English takes the plural for zero. Only the one-lane form is wrong.
DataEmptyState there is role="status" aria-live="polite", so this is read aloud, not merely printed.
Why it is being filed NOW rather than earlier
⭐ The string is not new; its REACHABILITY at one lane is. The predicate used to require more than one lane, so the region never painted below two and the count in front of columns was always at least 2 — the bare plural was correct for every board that could reach it. objectui#9045 makes the region paint at zero and one lane, which is the first time the count can be 1.
⛔ This is not a reason to hold or revert that repair: the announcement existing at all is the accessibility fix, and a wrong plural is strictly better than silence. It is the residue that repair leaves behind.
Blocked-by: objectui#9169 — before that PR lands, the one-lane form is unreachable and this card cannot be reproduced on main.
What a repair has to decide
Not obvious, and ⛔ it should not be guessed:
- Pluralise the key. The catalogue already uses i18next plural suffixes elsewhere (the
_one / _other convention appears in all ten locale files), so the shape exists. Cost: a new key on a published payload, and ten locale catalogues to keep in step — plus whatever the i18n drift and dead-key gates have to say about a key whose singular arm is reachable only from one call site.
- Withhold the description at exactly one lane. No published surface moves, but the region then says different things at different lane counts for a reason no reader can infer from the screen.
- Drop the lane-count description entirely. The lane count is visible on the board already; the announcement's job is "no cards".
Dedupe — with its control
Semantic search over this repository for the empty-state description wording returned 9 neighbours: #9045, #8509, #8913, #8307, #8448, #2792, #8534, #7742, #7303. All are plugin-kanban or kanban-adjacent and none is about the description's grammar. The control is that the query returned objectui#9045 itself as its top hit — a card whose text this query was built from — so the absence of a wording card is a reading rather than a dead query. A repository-scoped REST search was tried first and refused with 403 by the container's egress proxy (path allowlist, not a GitHub scope statement), so this reading came from the MCP search channel.
Filed by the os-dev seat working objectui#9045, session session_01UzHd6hDYatoDn17BuwKxnZ, with Claude Code.
Found by the
os-devseat while repairing objectui#9045 (the lane-count empty-state predicate). ⛔ Not repaired there: the grammatical repair needs a new key on the published@object-ui/i18ncatalogue, and that card was claimed with aClause-②: nodeclaration whose stated hard stop is any change to a published payload.Unclaimed and unprioritised on purpose — triage owns both.
The defect
KanbanImplcomposes the board-level empty state's description as the lane count followed byt('kanban.columns'). The English catalogue declares that key as the bare pluralcolumns, with no singular form and nocountpluralisation, so the description is assembled by concatenation and never agrees with the number in front of it.Measured in the DOM, reading the live region's own
textContentat three lane counts on the objectui#9045 branch:The
TWOrow is the CONTROL: it is grammatical, and it is what makes theONErow a reading about the plural form rather than about a broken probe.ZEROis grammatical too — English takes the plural for zero. Only the one-lane form is wrong.DataEmptyStatethere isrole="status" aria-live="polite", so this is read aloud, not merely printed.Why it is being filed NOW rather than earlier
⭐ The string is not new; its REACHABILITY at one lane is. The predicate used to require more than one lane, so the region never painted below two and the count in front of
columnswas always at least 2 — the bare plural was correct for every board that could reach it. objectui#9045 makes the region paint at zero and one lane, which is the first time the count can be 1.⛔ This is not a reason to hold or revert that repair: the announcement existing at all is the accessibility fix, and a wrong plural is strictly better than silence. It is the residue that repair leaves behind.
Blocked-by: objectui#9169 — before that PR lands, the one-lane form is unreachable and this card cannot be reproduced on
main.What a repair has to decide
Not obvious, and ⛔ it should not be guessed:
_one/_otherconvention appears in all ten locale files), so the shape exists. Cost: a new key on a published payload, and ten locale catalogues to keep in step — plus whatever the i18n drift and dead-key gates have to say about a key whose singular arm is reachable only from one call site.Dedupe — with its control
Semantic search over this repository for the empty-state description wording returned 9 neighbours: #9045, #8509, #8913, #8307, #8448, #2792, #8534, #7742, #7303. All are
plugin-kanbanor kanban-adjacent and none is about the description's grammar. The control is that the query returned objectui#9045 itself as its top hit — a card whose text this query was built from — so the absence of a wording card is a reading rather than a dead query. A repository-scoped REST search was tried first and refused with 403 by the container's egress proxy (path allowlist, not a GitHub scope statement), so this reading came from the MCP search channel.Filed by the
os-devseat working objectui#9045, sessionsession_01UzHd6hDYatoDn17BuwKxnZ, with Claude Code.