package research_runtime_test import ( "context" "testing" "git.cin.su/m/Assistant/contracts/epistemics" app "git.cin.su/m/Assistant/modules/epistemics/application" domain "git.cin.su/m/Assistant/modules/epistemics/domain" ) type connector struct { candidates []epistemics.ResearchCandidate } func (c connector) Collect(context.Context, epistemics.ResearchPlan) ([]epistemics.ResearchCandidate, error) { return c.candidates, nil } func candidate(statement string, freshness epistemics.FreshnessState, source, snapshot, excerpt string) epistemics.ResearchCandidate { return epistemics.ResearchCandidate{PropositionKey: "domovoy", Statement: statement, Evidence: epistemics.EvidenceObserved, Coverage: epistemics.CoverageComplete, Conflict: epistemics.ConflictNone, Source: epistemics.Source{ID: epistemics.SourceID(source), Locator: "https://example.test/" + source}, Snapshot: epistemics.SourceSnapshot{ID: epistemics.SourceSnapshotID(snapshot), SourceID: epistemics.SourceID(source), ContentDigest: "sha256:" + snapshot, CapturedAtUnixMillis: 10, Freshness: freshness}, Excerpt: epistemics.SourceExcerpt{ID: epistemics.SourceExcerptID(excerpt), SnapshotID: epistemics.SourceSnapshotID(snapshot), Text: statement, Start: 0, End: int64(len(statement))}} } func TestResearchServiceKeepsUnknownStaleAndConflictExplicit(t *testing.T) { plan := epistemics.ResearchPlan{ID: "plan-1", Question: "question", SourceClasses: []string{"repository"}, FreshnessPolicy: "current"} unknown, err := (app.ResearchService{Connector: connector{}}).Evaluate(context.Background(), plan, 100) if err != nil || len(unknown.Findings) != 1 || unknown.Findings[0].State != epistemics.FindingUnknown { t.Fatalf("unknown evidence was not explicit: %#v %v", unknown, err) } result, err := (app.ResearchService{Connector: connector{candidates: []epistemics.ResearchCandidate{ candidate("one answer", epistemics.FreshnessStale, "s1", "ss1", "e1"), candidate("another answer", epistemics.FreshnessCurrent, "s2", "ss2", "e2"), }}}).Evaluate(context.Background(), plan, 100) if err != nil || len(result.Findings) != 1 || result.Findings[0].State != epistemics.FindingConflicted || len(result.Findings[0].Citations) != 2 { t.Fatalf("conflict was not retained: %#v %v", result, err) } } func TestEvaluateResearchRejectsFabricatedEvidenceChain(t *testing.T) { value := candidate("answer", epistemics.FreshnessCurrent, "s1", "ss1", "e1") value.Excerpt.SnapshotID = "other-snapshot" plan := epistemics.ResearchPlan{ID: "plan-1", Question: "question", SourceClasses: []string{"web"}, FreshnessPolicy: "current"} if _, err := domain.EvaluateResearch(plan, []epistemics.ResearchCandidate{value}, 100); err != domain.ErrInvalidResearchCandidate { t.Fatalf("fabricated evidence was accepted: %v", err) } } func TestResearchServiceKeepsAssumptionAndUnknownFreshnessVisible(t *testing.T) { plan := epistemics.ResearchPlan{ID: "plan-1", Question: "question", SourceClasses: []string{"web"}, FreshnessPolicy: "current"} value := candidate("assumed answer", epistemics.FreshnessCurrent, "s1", "ss1", "e1") value.Evidence = epistemics.EvidenceAssumed result, err := (app.ResearchService{Connector: connector{candidates: []epistemics.ResearchCandidate{value}}}).Evaluate(context.Background(), plan, 100) if err != nil || result.Findings[0].State != epistemics.FindingUnknown { t.Fatalf("assumption was promoted: %#v %v", result, err) } value = candidate("unknown answer", epistemics.FreshnessUnknown, "s2", "ss2", "e2") value.Conflict = epistemics.ConflictUnknown result, err = (app.ResearchService{Connector: connector{candidates: []epistemics.ResearchCandidate{value}}}).Evaluate(context.Background(), plan, 100) if err != nil || result.Findings[0].State != epistemics.FindingUnknown { t.Fatalf("unknown freshness was promoted: %#v %v", result, err) } }