13e5170e9e
Nudge wording as data instead of generation. The wording lives in
internal/phraser/nudges_ru_v1.json (embedded), about 10 variants per rule:
water, meal, break, service_down, netdata_critical, routine:, morning:, plus
a contentless default. That JSON is long because it is data — the owner can
edit any line of Russian without touching Go.
The picker:
- random, but never the same variant twice in a row for the same rule
- deterministic when seeded (math/rand with an injectable source)
- fills {since} / {service} / {what} from the candidate, and skips any variant
whose value is missing, so no raw placeholder can reach the piper voice
- {since} is spelled out in words ("полтора часа", "семь часов"), because
"3 ч" is wrong in a Russian voice
Scores 15/15 on the existing nudge fixture, on every seed swept. Nothing is
wired yet — that is the next commit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CGeSZxh1DCtRxmFVSYVGvJ
130 lines
6.3 KiB
JSON
130 lines
6.3 KiB
JSON
{
|
||
"schema_version": 1,
|
||
"name": "russian nudge templates v1",
|
||
"notes": [
|
||
"Hand-written Russian nudges. Edit the wording here, no Go changes needed.",
|
||
"Rules: she is feminine about herself, he is a man addressed as ты. Never вы/вас/ваш, never plural imperatives (выпейте), never он/его about him.",
|
||
"One short sentence. No questions, no emoji, no pet names, no emotional support.",
|
||
"Placeholders: {since} how long it has been (only used when it is at least an hour), {service} the service name, {what} the routine name. A variant whose placeholder has no value is skipped, so every rule needs at least one variant with no placeholder. The exception is routine and morning: those only exist for rules like routine:таблетки that always carry a name, and a routine nudge that drops the name is useless.",
|
||
"mood must be one of: neutral, happy, thinking, tired, confused."
|
||
],
|
||
"rules": {
|
||
"water": {
|
||
"mood": "neutral",
|
||
"variants": [
|
||
"Ты не пил воду {since} — выпей стакан.",
|
||
"Пора выпить воды.",
|
||
"Стакан воды не помешает.",
|
||
"Воду ты не пил уже {since}.",
|
||
"Напоминаю про воду.",
|
||
"Сходи за водой, дела подождут.",
|
||
"Сделай глоток воды, пока помнишь.",
|
||
"Между делом выпей воды.",
|
||
"Вода — простое дело: выпей стакан.",
|
||
"Отвлекись на стакан воды."
|
||
]
|
||
},
|
||
"meal": {
|
||
"mood": "neutral",
|
||
"variants": [
|
||
"Ты не ел {since} — поешь.",
|
||
"Пора поесть, сделай перекус.",
|
||
"Еда важнее ещё одного часа за столом.",
|
||
"Без еды уже {since}, поешь.",
|
||
"Напоминаю про еду — поешь.",
|
||
"Возьми перерыв на обед.",
|
||
"Сделай себе перекус, это пять минут.",
|
||
"Поешь, потом вернёшься к работе.",
|
||
"Поешь нормально, а не на ходу.",
|
||
"Еды не было {since} — разогрей что-нибудь."
|
||
]
|
||
},
|
||
"break": {
|
||
"mood": "neutral",
|
||
"variants": [
|
||
"Ты за столом {since} — встань и разомнись.",
|
||
"Пора сделать перерыв.",
|
||
"Встань на пять минут.",
|
||
"{since} без перерыва — отойди от экрана.",
|
||
"Напоминаю про перерыв.",
|
||
"Разомни спину, потом продолжишь.",
|
||
"Короткая пауза не сорвёт дела.",
|
||
"Отойди от компьютера на минуту.",
|
||
"Сидишь без перерыва {since}.",
|
||
"Встань, пройдись, вернись."
|
||
]
|
||
},
|
||
"service_down": {
|
||
"mood": "neutral",
|
||
"variants": [
|
||
"Сервис {service} не отвечает.",
|
||
"{service} упал — сервис не отвечает.",
|
||
"{service} не отвечает, сервис нужно поднимать.",
|
||
"Сервис {service} недоступен.",
|
||
"Проверь {service}: сервис не отвечает.",
|
||
"Сервис перестал отвечать.",
|
||
"Сервис {service} лежит, нужно смотреть.",
|
||
"{service} не отвечает уже {since}.",
|
||
"Мониторинг сообщает: {service} лежит.",
|
||
"Сервис {service} не отвечает, посмотри логи."
|
||
]
|
||
},
|
||
"netdata_critical": {
|
||
"mood": "neutral",
|
||
"variants": [
|
||
"Netdata: критический алярм, проверь диск.",
|
||
"Критический алярм в netdata — посмотри диск.",
|
||
"Netdata поднял тревогу по диску.",
|
||
"Проверь диск: netdata ругается.",
|
||
"Алярм от netdata, критический.",
|
||
"Netdata: критический уровень, дело в диске.",
|
||
"Диск требует внимания — критический алярм в netdata.",
|
||
"Критический алярм: проверь место на диске.",
|
||
"Netdata сообщает о критической проблеме с диском.",
|
||
"Открой netdata: там критический алярм по диску."
|
||
]
|
||
},
|
||
"routine": {
|
||
"mood": "neutral",
|
||
"variants": [
|
||
"По распорядку: {what}.",
|
||
"Пора — {what}.",
|
||
"Напоминаю: {what}.",
|
||
"В списке на сейчас: {what}.",
|
||
"{what} — сейчас самое время.",
|
||
"Не пропусти: {what}.",
|
||
"{what}: пора сделать.",
|
||
"Сейчас по плану {what}.",
|
||
"Твой распорядок: {what}.",
|
||
"{what} — по распорядку сейчас."
|
||
]
|
||
},
|
||
"morning": {
|
||
"mood": "neutral",
|
||
"variants": [
|
||
"{what} — пора начать день.",
|
||
"{what}: пройди утренний список.",
|
||
"Начни {what} со списка.",
|
||
"{what}. Осталось пройти чеклист.",
|
||
"Утренний список ещё не пройден: {what}.",
|
||
"{what}: первый пункт списка за тобой.",
|
||
"{what} идёт, а список стоит.",
|
||
"{what}: не забудь про утренние дела.",
|
||
"По утреннему чеклисту ещё есть дела: {what}.",
|
||
"{what} — утренний список дел ещё ждёт."
|
||
]
|
||
},
|
||
"default": {
|
||
"mood": "neutral",
|
||
"variants": [
|
||
"Напоминаю: есть дело.",
|
||
"Пора вернуться к отложенному делу.",
|
||
"Одно дело ждёт тебя.",
|
||
"Напоминаю про дело из списка.",
|
||
"В списке осталось дело.",
|
||
"Дело всё ещё не сделано."
|
||
]
|
||
}
|
||
}
|
||
}
|