Separate observation from evaluation in blacklist sources

Each source's Query() method previously set r.Listed and r.Severity,
embedding verdict logic inside the prober. Evaluation now lives in a
dedicated Evaluate(SourceResult) (bool, string) method per source,
keeping Query() as pure observation.

A package-level EvaluateResult() helper looks up the source by ID and
delegates to its Evaluate method; rules.go, report.go, types.go, and
provider.go all call this instead of reading pre-set r.Listed/r.Severity
values. An unknownSource sentinel handles results whose source is no
longer registered.
This commit is contained in:
nemunaire 2026-05-15 18:04:10 +08:00
commit c437339bda
13 changed files with 123 additions and 44 deletions

View file

@ -63,8 +63,6 @@ func (s *openPhishSource) Query(ctx context.Context, domain, registered string,
// Fall through with whatever the cache could provide.
}
if len(urls) > 0 {
res.Listed = true
res.Severity = SeverityCrit
res.Reasons = []string{"Phishing"}
for _, u := range urls {
res.Evidence = append(res.Evidence, Evidence{Label: "URL", Value: u})
@ -73,6 +71,13 @@ func (s *openPhishSource) Query(ctx context.Context, domain, registered string,
return []SourceResult{res}
}
func (*openPhishSource) Evaluate(r SourceResult) (bool, string) {
if r.Enabled && r.Error == "" && len(r.Evidence) > 0 {
return true, SeverityCrit
}
return false, ""
}
func (*openPhishSource) Diagnose(res SourceResult) Diagnosis {
urls := make([]string, 0, len(res.Evidence))
for _, e := range res.Evidence {