phraser: the act replies as review rewrote them (V-521)

The owner's wording from the PR 112 review, and the placeholder fixes under it.

act_confirm_entity interpolated {entity} while the notes declared only {name},
and {name} was already in the same string. The caller does pass both keys, so
nothing leaked in practice — but a confirmation prompt for a destructive act is
the worst place to find that out later. Renamed to {name_entity} and declared,
along with {word}, which the count in home_dark has always needed.

Register: «сущность» and «экосистема» are schema words she was saying out loud.
act_done_entity stops reporting in the passive and matches «готово.», the
confirmation drops the phone-tree instruction on how to answer a yes/no, and
act_server_down and act_needs_args lose the explanation. «угадывать не буду»
stays exactly as it was.

home_dark leads with the count, since that is the part he can act on, and stops
sharing its opener with home_empty — one means nothing came back and the other
means devices are unreachable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XGTGCWX33aX8SMBSRz9VmS
This commit is contained in:
2026-08-04 15:59:59 +04:00
parent 6ae1312ff1
commit 4c95b200e4
3 changed files with 134 additions and 40 deletions
+22 -18
View File
@@ -72,28 +72,30 @@ var actKeys = []string{
HomeUnreachable, HomeEmpty, HomeOn, HomeDark,
}
// actFloor — the literal each key falls back to when the file is unusable.
// These are the exact strings that lived in Go before this file existed.
// actFloor — the literal each key falls back to when the file is unusable. It
// started as the exact strings that lived in Go before this file existed and now
// tracks the file's first variant instead, because a floor that keeps the
// wording review threw out would say it back on the one turn nobody is watching.
var actFloor = map[string]string{
ActDone: "готово.",
ActDoneOut: "готово: {out}",
ActDoneEntity: "команда выполнена для {name}.",
ActConfirm: "выполнить «{name}»? скажи «да» или «нет».",
ActConfirmEntity: "выполнить «{name}» для {entity}? скажи «да» или «нет».",
ActDoneEntity: "готово: {name}.",
ActConfirm: "выполнить «{name}»? да или нет.",
ActConfirmEntity: "выполнить «{name}» для {name_entity}? да или нет.",
ActWhich: "какую команду для {name}: {items}?",
ActFail: "не получилось выполнить команду.",
ActFailOut: "не получилось выполнить команду: {out}",
ActFailEntity: "не получилось выполнить команду для {name}.",
ActServerDown: "этот инструмент включён, но сервер, который его выполняет, сейчас не подключён.",
ActWithdrawn: "сервер больше не предлагает этот инструмент — я сняла его с разрешённых, посмотри на /tools.",
ActNeedsArgs: "этому инструменту нужны аргументы, которые я из голоса не соберу — я не буду угадывать.",
ActServerDown: "инструмент есть, но сервер не подключён.",
ActWithdrawn: "сервер больше не отдаёт этот инструмент — сняла его с разрешённых, посмотри /tools.",
ActNeedsArgs: "тут нужны аргументы, из голоса не соберу. угадывать не буду.",
EcoDenied: "экосистема отклоняет доступ, проверь токен.",
EcoDown: "экосистема недоступна, попробуй ещё раз.",
EcoAmbiguous: "уточни, что именно: {items}?",
EcoUnknownEntity: "не знаю такой сущности.",
EcoNoNexus: "не могу связать это с сущностью — Nexus не настроен.",
EcoAboutWhat: "про что именно спросить?",
EcoDenied: "{name} отклоняет доступ, проверь токен.",
EcoDown: "{name} не отвечает, попробуй ещё раз.",
EcoAmbiguous: "что именно: {items}?",
EcoUnknownEntity: "не знаю, что это.",
EcoNoNexus: "не с чем связать — Nexus не настроен.",
EcoAboutWhat: "про что именно?",
EcoRecall: "я помню: {items}",
AttentionNone: "ничего не требует внимания.",
@@ -102,13 +104,13 @@ var actFloor = map[string]string{
AttentionNoneEntity: "по «{name}» ничего нет.",
AttentionListEntity: "по «{name}»: {items}",
AttentionFailEntity: "не могу сейчас узнать, что требует внимания по «{name}».",
ChangesNone: "нет изменений.",
ChangesNone: "изменений нет.",
ChangesList: "изменения: {items}",
ChangesFail: "не могу сейчас узнать об изменениях.",
HomeUnreachable: "не смогла достучаться до дома.",
HomeUnreachable: "дом не отвечает.",
HomeEmpty: "дом ничего не отдаёт.",
HomeOn: "включено: {items}",
HomeDark: "дом молчит: {count} {word} не отвечают.",
HomeDark: "не отвечают: {count} {word}.",
}
// Acts picks a hand-written Russian act reply. Safe for concurrent use.
@@ -126,10 +128,12 @@ func LoadActs(src rand.Source) (*Acts, error) {
for _, req := range []struct{ key, ph string }{
{ActDoneOut, "{out}"}, {ActDoneEntity, "{name}"}, {ActFailOut, "{out}"},
{ActFailEntity, "{name}"}, {ActConfirm, "{name}"},
{ActConfirmEntity, "{name}"}, {ActConfirmEntity, "{entity}"},
{ActConfirmEntity, "{name}"}, {ActConfirmEntity, "{name_entity}"},
{ActWhich, "{name}"}, {ActWhich, "{items}"},
{EcoAmbiguous, "{items}"}, {EcoRecall, "{items}"},
{AttentionList, "{items}"}, {ChangesList, "{items}"}, {HomeOn, "{items}"},
{EcoDenied, "{name}"}, {EcoDown, "{name}"},
{HomeDark, "{count}"}, {HomeDark, "{word}"},
{AttentionNoneEntity, "{name}"}, {AttentionListEntity, "{name}"},
{AttentionListEntity, "{items}"}, {AttentionFailEntity, "{name}"},
} {