stage0: one rest-of-day grammar, not two (V-530)

The textual merge in fe489df left a second rest-of-day-query grammar inside
NarrativeQueryGrammars. buildRouter wires the agenda grammars first, so the
copy never claimed a turn, and narrative_test.go only ever indexed the
narrative rule beside it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-04 21:18:36 +04:00
parent be3e5cea25
commit d9ef9ecef2
2 changed files with 15 additions and 18 deletions
+1 -1
View File
@@ -15,7 +15,7 @@ func narrativeRouter(t *testing.T) *Router {
r.grammars = append(r.grammars, AgendaQueryGrammars()...) r.grammars = append(r.grammars, AgendaQueryGrammars()...)
r.grammars = append(r.grammars, TaskListGrammar()) r.grammars = append(r.grammars, TaskListGrammar())
r.grammars = append(r.grammars, TaskCaptureGrammar()) r.grammars = append(r.grammars, TaskCaptureGrammar())
r.grammars = append(r.grammars, NarrativeQueryGrammars()[1]) r.grammars = append(r.grammars, NarrativeQueryGrammars()...)
return r return r
} }
+14 -17
View File
@@ -230,27 +230,24 @@ func AgendaQueryGrammars() []Grammar {
// herself, and the query chain has no source for either. // herself, and the query chain has no source for either.
var chatNarrativeTopics = regexp.MustCompile(`(?i)(анекдот|шутк|сказк|истори[юи]\s+на\s+ночь|о\s+себе|про\s+себя|о\s+нас|про\s+нас)`) var chatNarrativeTopics = regexp.MustCompile(`(?i)(анекдот|шутк|сказк|истори[юи]\s+на\s+ночь|о\s+себе|про\s+себя|о\s+нас|про\s+нас)`)
// NarrativeQueryGrammars — stage-0 grammars for the two question shapes that // NarrativeQueryGrammars — the stage-0 grammar for "расскажи про X", a question
// carry no question mark and no interrogative, and so reached the resident // shape that carries no question mark and no interrogative, and so reached the
// model with nothing deterministic in front of them (Vikunja #498). // resident model with nothing deterministic in front of it (Vikunja #498).
// //
// Both were routed IntentFact by the model. The fact gate catches the write and // The model routed it IntentFact. The fact gate catches the write and re-runs
// re-runs the turn as a query, so nothing breaks today; what they cost is a full // the turn as a query, so nothing broke; what it cost is a full model round trip
// model round trip to reach a decision two patterns can make offline, and a // to reach a decision one pattern makes offline, and a wrong row on the routing
// wrong row on the routing fixture. // fixture.
// //
// Wired after the agenda grammars, which is where their overlap resolves: // It held a second grammar named rest-of-day-query until V-530. fe489df merged
// "расскажи, что у меня сегодня" is claimed here as a query either way. // task/467 into the sweep line and both sides had landed V-498, so the merge
// kept both blocks textually. buildRouter wires the agenda grammars first and
// the agenda copy claims every case this one did, so it could never fire.
//
// Wired after the agenda grammars, which is where the overlap resolves:
// "расскажи, что у меня сегодня" is claimed there as a query either way.
func NarrativeQueryGrammars() []Grammar { func NarrativeQueryGrammars() []Grammar {
return []Grammar{ return []Grammar{
{
// "что дальше?" — the rest of the day. IsRestOfDayQuery already
// recognises it downstream in the query chain, but that runs after
// the routing decision, and the routing decision was fact.
Name: "rest-of-day-query",
Pattern: regexp.MustCompile(`(?i)(^|\s)(что|чего)\s+(там\s+|потом\s+)?дальше(\s|[?!.]|$)|(^|\s)what'?s?\s+next(\s|[?!.]|$)`),
Build: agendaQueryBuild,
},
{ {
// "расскажи про X" — a world question phrased as an instruction. // "расскажи про X" — a world question phrased as an instruction.
// The lexicon is narrativeRequests, already written for the // The lexicon is narrativeRequests, already written for the