strings family 5: the confirmation answers move, the prompt does not (V-505)

The task asked to decide first whether this family should move at all. It
moves, but only half of it, and the half that stays put is the important one.

The prompt is already in acts_ru_v1.json. act_confirm and act_confirm_entity
went there with family 4, which is where they belong: the sentence he has to
hear before he says yes is an act line, and it loads with {name} required, so a
variant that dropped the capability cannot exist. Nothing about that needed
redoing.

What was left in cmd/mavend/confirm.go is the answers. Those are now
confirm_ru_v1.json: cancelled, the two routine answers, and the four
propose-gap lines. Every entry is fixed at one wording. He answered a question
about one specific thing, so variety buys nothing here and costs the property
that matters, which is that the same act reports the same outcome every time.
The three propose lines that name the verb have {name} required, for the same
reason the prompt does.

Two literals also stopped being duplicates. The confirmed tool run said
"готово." and "не получилось выполнить команду." word for word from the acts
family, so it now reports through ActDone and ActFail rather than keeping a
second copy to drift from.

Family 5 was the last one open. The persona scorer sweeps the new variants with
the other five, and the single-variant-means-fixed test now covers it.
This commit is contained in:
2026-08-05 16:07:50 +04:00
parent 0d8cbaec01
commit 33032b859a
6 changed files with 255 additions and 13 deletions
+14 -12
View File
@@ -6,6 +6,7 @@ import (
"strings"
"time"
"github.com/kami/maven/internal/phraser"
"github.com/kami/maven/internal/router"
)
@@ -118,13 +119,13 @@ func (h *reactiveHandler) confirmResolvers(ctx context.Context) []confirmResolve
//
// Acceptance itself is recorded by /routines, and the tick
// loop nudges on the interval from there (Vikunja #366).
return "поняла — подтверди на странице рутин, и начну напоминать."
return phraser.C(phraser.ConfirmRoutineAuthed, nil)
},
no: func() string {
if err := h.dataStore.DismissProposedRoutine(ctx, pr.routineID); err != nil {
log.Printf("voice: dismiss proposed routine: %v", err)
}
return "хорошо, не буду."
return phraser.C(phraser.ConfirmRoutineNo, nil)
},
},
// Hexis execution confirm. Bound to the exact capability + target that
@@ -137,7 +138,7 @@ func (h *reactiveHandler) confirmResolvers(ctx context.Context) []confirmResolve
yes: func() string {
return h.execHexis(ctx, hx.capabilityID, hx.capName, hx.entityID, hx.displayName)
},
no: func() string { return "отменила." },
no: func() string { return phraser.C(phraser.ConfirmCancelled, nil) },
},
// Tool confirm.
{
@@ -150,16 +151,16 @@ func (h *reactiveHandler) confirmResolvers(ctx context.Context) []confirmResolve
if err != nil {
log.Printf("voice: tool %s (confirmed): %v", p.fn, err)
if out != "" {
return "не получилось выполнить команду: " + firstLine(out)
return phraser.A(phraser.ActFailOut, map[string]string{"out": firstLine(out)})
}
return "не получилось выполнить команду."
return phraser.A(phraser.ActFail, nil)
}
if out != "" {
return "готово: " + firstLine(out)
return phraser.A(phraser.ActDoneOut, map[string]string{"out": firstLine(out)})
}
return "готово."
return phraser.A(phraser.ActDone, nil)
},
no: func() string { return "отменила." },
no: func() string { return phraser.C(phraser.ConfirmCancelled, nil) },
},
}
}
@@ -170,17 +171,18 @@ func (h *reactiveHandler) confirmResolvers(ctx context.Context) []confirmResolve
func (h *reactiveHandler) proposeGap(ctx context.Context, dec router.Decision) string {
name := firstWord(stripWake(dec.Utterance))
if name == "" {
return "не разобрала команду — попробуй иначе."
return phraser.C(phraser.ProposeNoVerb, nil)
}
vars := map[string]string{"name": name}
newly, err := h.api.ProposeTool(ctx, name, dec.Utterance, "", h.now())
if err != nil {
log.Printf("voice: propose tool %q: %v", name, err)
return "команды «" + name + "» нет в списке разрешённых."
return phraser.C(phraser.ProposeFailed, vars)
}
if newly {
return "команды «" + name + "» нет в списке. Предложила её добавить — включи через клиент."
return phraser.C(phraser.ProposeNew, vars)
}
return "команды «" + name + "» пока нет в списке — она уже предложена, включи через клиент."
return phraser.C(phraser.ProposeAlready, vars)
}
// confirmVerdict — the parse of a y/n confirm answer.