From d9ef9ecef2865e3878fef7e5430195d3e6ec36fa Mon Sep 17 00:00:00 2001 From: claude Date: Tue, 4 Aug 2026 21:18:36 +0400 Subject: [PATCH] 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 --- internal/router/narrative_test.go | 2 +- internal/router/stage0.go | 31 ++++++++++++++----------------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/internal/router/narrative_test.go b/internal/router/narrative_test.go index dacca0c..b357a9f 100644 --- a/internal/router/narrative_test.go +++ b/internal/router/narrative_test.go @@ -15,7 +15,7 @@ func narrativeRouter(t *testing.T) *Router { r.grammars = append(r.grammars, AgendaQueryGrammars()...) r.grammars = append(r.grammars, TaskListGrammar()) r.grammars = append(r.grammars, TaskCaptureGrammar()) - r.grammars = append(r.grammars, NarrativeQueryGrammars()[1]) + r.grammars = append(r.grammars, NarrativeQueryGrammars()...) return r } diff --git a/internal/router/stage0.go b/internal/router/stage0.go index 64973ff..82f58ab 100644 --- a/internal/router/stage0.go +++ b/internal/router/stage0.go @@ -230,27 +230,24 @@ func AgendaQueryGrammars() []Grammar { // herself, and the query chain has no source for either. var chatNarrativeTopics = regexp.MustCompile(`(?i)(анекдот|шутк|сказк|истори[юи]\s+на\s+ночь|о\s+себе|про\s+себя|о\s+нас|про\s+нас)`) -// NarrativeQueryGrammars — stage-0 grammars for the two question shapes that -// carry no question mark and no interrogative, and so reached the resident -// model with nothing deterministic in front of them (Vikunja #498). +// NarrativeQueryGrammars — the stage-0 grammar for "расскажи про X", a question +// shape that carries no question mark and no interrogative, and so reached the +// 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 -// re-runs the turn as a query, so nothing breaks today; what they cost is a full -// model round trip to reach a decision two patterns can make offline, and a -// wrong row on the routing fixture. +// The model routed it IntentFact. The fact gate catches the write and re-runs +// the turn as a query, so nothing broke; what it cost is a full model round trip +// to reach a decision one pattern makes offline, and a wrong row on the routing +// fixture. // -// Wired after the agenda grammars, which is where their overlap resolves: -// "расскажи, что у меня сегодня" is claimed here as a query either way. +// It held a second grammar named rest-of-day-query until V-530. fe489df merged +// 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 { 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. // The lexicon is narrativeRequests, already written for the