From be18c08756f415cb580f9f571117b9ca387ab18f Mon Sep 17 00:00:00 2001 From: Jan Svabenik Date: Sun, 22 Mar 2026 04:45:43 +0100 Subject: [PATCH] Use candidate hints for auto actions --- internal/pipeline/decisions.go | 21 ++++++++++++++++++--- internal/pipeline/decisions_test.go | 14 ++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/internal/pipeline/decisions.go b/internal/pipeline/decisions.go index c857f65..4e6a18a 100644 --- a/internal/pipeline/decisions.go +++ b/internal/pipeline/decisions.go @@ -1,6 +1,10 @@ package pipeline -import "sdr-wideband-suite/internal/classifier" +import ( + "strings" + + "sdr-wideband-suite/internal/classifier" +) type SignalDecision struct { Candidate Candidate `json:"candidate"` @@ -12,18 +16,29 @@ type SignalDecision struct { func DecideSignalAction(policy Policy, candidate Candidate, cls *classifier.Classification) SignalDecision { decision := SignalDecision{Candidate: candidate} + classTag := "" + hintTag := strings.TrimSpace(candidate.Hint) if cls != nil { decision.Class = string(cls.ModType) + classTag = decision.Class } - if cls != nil && WantsClass(policy.AutoRecordClasses, string(cls.ModType)) { + if classTag != "" && WantsClass(policy.AutoRecordClasses, classTag) { decision.ShouldRecord = true decision.Reason = "matched auto_record_classes" + } else if classTag == "" && hintTag != "" && WantsClass(policy.AutoRecordClasses, hintTag) { + decision.ShouldRecord = true + decision.Reason = "matched auto_record_classes (hint)" } - if cls != nil && WantsClass(policy.AutoDecodeClasses, string(cls.ModType)) { + if classTag != "" && WantsClass(policy.AutoDecodeClasses, classTag) { decision.ShouldAutoDecode = true if decision.Reason == "" { decision.Reason = "matched auto_decode_classes" } + } else if classTag == "" && hintTag != "" && WantsClass(policy.AutoDecodeClasses, hintTag) { + decision.ShouldAutoDecode = true + if decision.Reason == "" { + decision.Reason = "matched auto_decode_classes (hint)" + } } if decision.Reason == "" && candidate.Hint != "" { decision.Reason = "policy evaluated candidate hint" diff --git a/internal/pipeline/decisions_test.go b/internal/pipeline/decisions_test.go index c130c1f..78fece5 100644 --- a/internal/pipeline/decisions_test.go +++ b/internal/pipeline/decisions_test.go @@ -17,3 +17,17 @@ func TestDecideSignalAction(t *testing.T) { t.Fatalf("expected auto decode decision") } } + +func TestDecideSignalActionUsesHintWithoutClass(t *testing.T) { + policy := Policy{AutoRecordClasses: []string{"WFM"}, AutoDecodeClasses: []string{"FT8"}} + decision := DecideSignalAction(policy, Candidate{ID: 2, Hint: "WFM"}, nil) + if !decision.ShouldRecord { + t.Fatalf("expected record decision from hint") + } + if decision.ShouldAutoDecode { + t.Fatalf("unexpected auto decode decision from hint") + } + if decision.Reason == "" { + t.Fatalf("expected reason for hint-based decision") + } +}