Reject generic pages for concrete research identifiers #391

Merged
m merged 1 commits from codex/household-travel-query-fix into main 2026-08-26 00:17:04 +00:00
2 changed files with 45 additions and 0 deletions
+21
View File
@@ -1812,6 +1812,9 @@ func nearestFlightQuery(query string) bool {
// search-engine snippets from becoming a human-facing answer when a search
// term has a common non-travel meaning.
func researchFindingMatchesIntent(query string, finding epistemics.ResearchFinding) bool {
if !findingContainsRequestedIdentifier(query, finding) {
return false
}
if !nearestFlightQuery(query) {
return true
}
@@ -1841,6 +1844,24 @@ func researchFindingMatchesIntent(query string, finding epistemics.ResearchFindi
return true
}
// findingContainsRequestedIdentifier prevents a generic landing page from
// being presented as a result for a concrete model, article or brand request.
// Identifiers are detected by their syntax, not by a catalogue of providers or
// entities, so the rule stays valid as user vocabulary changes.
func findingContainsRequestedIdentifier(query string, finding epistemics.ResearchFinding) bool {
identifiers := regexp.MustCompile(`(?i)[a-z0-9][a-z0-9._-]{3,}`).FindAllString(query, -1)
if len(identifiers) == 0 {
return true
}
evidence := strings.ToLower(strings.Join([]string{finding.Source.Title, finding.Source.Locator, finding.Excerpt.Text}, " "))
for _, identifier := range identifiers {
if !strings.Contains(evidence, strings.ToLower(identifier)) {
return false
}
}
return true
}
// nearestFlightRouteTerms retains only the two endpoint-shaped terms from a
// structured flight search. It has no city or provider vocabulary: endpoint
// relevance is determined from the request itself.
+24
View File
@@ -58,6 +58,30 @@ func TestNearestFlightEvidenceRequiresBothRouteEndpointsWhenKnown(t *testing.T)
}
}
func TestResearchReplyRejectsGenericLandingPageForConcreteIdentifier(t *testing.T) {
result := epistemics.ResearchResult{Findings: []epistemics.ResearchFinding{{
State: epistemics.FindingSupported,
Source: epistemics.Source{Locator: "https://market.example", Title: "Интернет-магазин"},
Excerpt: epistemics.SourceExcerpt{Text: "Широкий ассортимент товаров и услуг."},
}}}
reply, backed := renderResearchReply("на WB бренд marka-wear", result, nil)
if backed || !strings.Contains(reply, "Проверяемых данных") {
t.Fatalf("generic page was presented as a brand result: %q", reply)
}
}
func TestResearchReplyKeepsFindingContainingConcreteIdentifier(t *testing.T) {
result := epistemics.ResearchResult{Findings: []epistemics.ResearchFinding{{
State: epistemics.FindingSupported,
Source: epistemics.Source{Locator: "https://market.example/marka-wear", Title: "Marka-wear"},
Excerpt: epistemics.SourceExcerpt{Text: "Бренд marka-wear: товары и карточки."},
}}}
reply, backed := renderResearchReply("на WB бренд marka-wear", result, nil)
if !backed || !strings.Contains(strings.ToLower(reply), "marka-wear") {
t.Fatalf("concrete identifier finding was rejected: %q", reply)
}
}
func TestResponseReviewPreservesAttemptedResearchOutcome(t *testing.T) {
if reviewMayReplacePlanningReply(false, true, false, "Уточните аэропорт.", "Пока не смог получить проверяемый ответ.") {
t.Fatal("review replaced an honest unbacked research outcome")