// bucket 0..1 signal scores (probability, impact) into human labels. the // llm outputs a continuous number but the ui shouldnt pretend that number // means much beyond a rough band — "12.3%" reads as false precision. // // thresholds are deliberately a bit generous at the bottom so that the // failure-fallback path (0.0) lands clearly in NONE. enum SignalBucket { none, low, medium, high } SignalBucket bucketFor(double score) { if (score < 0.15) return SignalBucket.none; if (score < 0.40) return SignalBucket.low; if (score < 0.70) return SignalBucket.medium; return SignalBucket.high; } String bucketLabel(double score) { switch (bucketFor(score)) { case SignalBucket.none: return "None"; case SignalBucket.low: return "Low"; case SignalBucket.medium: return "Medium"; case SignalBucket.high: return "High"; } }