Report the stale keys that are stale, and remove them

The check reported 41 stale keys per catalogue. Ten of them were.

The other 31 were strings held in constants and translated where they render --
t(b.description), t(group), t(c.label) -- so they reach t() as a variable and
there is no literal at the call site to find. The script already chased two of
those shapes, `label:` and objects named *_LABELS, with a comment about crying
wolf 33 times. The shapes kept coming: `description:` and `group:` on the
keyboard bindings, the calendar's view names, the read-receipt refusals, the
palette names.

Chasing them one at a time is the wrong shape of fix. Stale detection now asks
only "is this key still written down anywhere in the source" -- any string
literal counts. That under-reports, and that is the right way round: a missed
stale key costs a line of dead translation, a false one costs the credibility
of the check and every real finding after it. Which is what happened here --
these sat unread long enough to need a commit of their own.

Coverage keeps the strict set. The two questions need different nets, and
widening the one that measures what a catalogue *owes* would count every CSS
class and JMAP method name as an untranslated string -- it read 29% while I had
them sharing a set. `wanted` is the obligation, `seen` is the evidence.

What was actually dead, removed from all nine: "Availability on {date}",
"Import vCard", "PDF", two settings hints replaced by rewordings that are still
live, the Catppuccin palette description, and Tuesday through Friday -- left
behind when the week-start dropdown narrowed to the three days a week actually
starts on, and appearing since only in comments.

Coverage is unchanged at 1269/1285: none of the ten was ever owed.
This commit is contained in:
2026-09-10 16:00:00 -07:00
parent 3c4f6a9f8e
commit 54b316ae36
10 changed files with 41 additions and 99 deletions
-10
View File
@@ -321,7 +321,6 @@ export const catalog: Catalog = {
"Busy": "Занят",
"Free/busy": "Занятость",
"Show as": "Показывать как",
"Availability on {date}": "Занятость на {date}",
"Count all events as busy": "Считать все события занятостью",
"Only events I'm attending": "Только события, где я участвую",
"Don't include in availability": "Не учитывать в занятости",
@@ -360,7 +359,6 @@ export const catalog: Catalog = {
"New address book": "Новая адресная книга",
"No address books yet.": "Адресных книг пока нет.",
"Choose from address books": "Выбрать из адресных книг",
"Import vCard": "Импорт vCard",
"Export all contacts": "Экспортировать все контакты",
"Export address book": "Экспортировать эту адресную книгу",
"Import contacts…": "Импортировать контакты…",
@@ -435,7 +433,6 @@ export const catalog: Catalog = {
"Make ihasmail yours.": "Настройте ihasmail под себя.",
"Reading": "Чтение",
"Reading pane": "Область чтения",
"Reading, sending and list behaviour. Settings are stored in this browser.": "Поведение при чтении, отправке и в списке. Настройки хранятся в этом браузере.",
"Right of the list": "Справа от списка",
"Below the list": "Под списком",
"Hidden (open full width)": "Скрыта (открывать во всю ширину)",
@@ -478,10 +475,6 @@ export const catalog: Catalog = {
"Time zone": "Часовой пояс",
"Week starts on": "Неделя начинается с",
"Monday": "Понедельник",
"Tuesday": "Вторник",
"Wednesday": "Среда",
"Thursday": "Четверг",
"Friday": "Пятница",
"Saturday": "Суббота",
"Sunday": "Воскресенье",
"12-hour clock (6:23 PM)": "12-часовой формат (6:23 PM)",
@@ -727,10 +720,8 @@ export const catalog: Catalog = {
"Manage labels": "Управление ярлыками",
"Create “{name}”": "Создать «{name}»",
"Type a name to create your first label.": "Введите название, чтобы создать первый ярлык.",
"Labels are IMAP keywords stored on your messages, so they sync to other clients. Names and colours are kept in this browser.": "Ярлыки — это ключевые слова IMAP, которые хранятся в самих письмах и синхронизируются с другими клиентами. Названия и цвета остаются в этом браузере.",
"New label": "Новый ярлык",
"Delete label": "Удалить ярлык",
"PDF": "PDF",
"Large attachments may be rejected by some servers": "Некоторые серверы отклоняют большие вложения",
"Images are stored in your Files (folder “ihasmail”) and embedded when you send.": "Изображения хранятся в ваших Файлах (папка «ihasmail») и вставляются при отправке.",
"Thanks for your message. I'm away until … and will reply when I'm back.": "Спасибо за письмо. Я отсутствую до … и отвечу после возвращения.",
@@ -864,7 +855,6 @@ export const catalog: Catalog = {
"Only languages ihasmail has been translated into appear here, so this list grows as translations land rather than ahead of them — a language offered without strings behind it would leave the page claiming to be in a language it is not.": "Здесь показаны только языки, на которые ihasmail переведён, поэтому список растёт вместе с переводами, а не опережает их: язык без текстов заставил бы страницу утверждать, что она написана на языке, которым не является.",
"tell us about it": "сообщите нам",
"This translation was generated by AI and has not been checked by a native speaker, so it is marked Beta until somebody who speaks it signs it off. Anything that reads wrongly is worth reporting — {report}.": "Этот перевод сделан ИИ и не проверен носителем языка, поэтому помечен как Beta до тех пор, пока кто-нибудь его не подтвердит. Обо всём, что звучит неправильно, стоит сообщить — {report}.",
"{name} is the palette from {site}, and what a new account starts on. It is a dark theme, so it counts as dark wherever that matters, and the accent colour below still applies on top of it.": "{name} — это палитра с {site}, с которой начинает новая учётная запись. Тема тёмная, поэтому везде, где это важно, считается тёмной, а акцентный цвет ниже применяется поверх неё.",
"ihasmail's own version is the date of the commit it was built from, followed by where that commit came from: {example} was built from a commit dated the 30th of August 2026 that arrived through pull request 129. A commit that did not come through one carries its short SHA instead — {sha}. The version deliberately says nothing about Stalwart; what this build needs from the server is the line above.": "Собственная версия ihasmail — это дата коммита, из которого он собран, и указание, откуда этот коммит взялся: {example} собран из коммита от 30 августа 2026 года, пришедшего через pull request 129. Коммит, пришедший иначе, несёт вместо этого короткий SHA — {sha}. Версия намеренно ничего не сообщает о Stalwart; то, что этой сборке нужно от сервера, указано строкой выше.",
// ── Composer status, calendar title ────────────────────────────────