@@ -163,12 +163,12 @@ func writeRecommendations(b *strings.Builder, recs []model.Recommendation, opts
163163 // Flushing to an in-memory strings.Builder cannot fail.
164164 _ , _ = fmt .Fprintf (tw , " WORKLOAD\t CPU\t MEM\t SAVINGS\t CONF\n " )
165165 for _ , rec := range recs {
166- _ , _ = fmt .Fprintf (tw , " %s\t %s\t %s\t %s\t %d%% \n " ,
166+ _ , _ = fmt .Fprintf (tw , " %s\t %s\t %s\t %s\t %s \n " ,
167167 workloadLabel (rec ),
168168 cpuTransition (rec ),
169169 memTransition (rec ),
170170 savingsCell (rec ),
171- rec . Confidence . Percent ( ),
171+ confidenceCell ( rec ),
172172 )
173173 }
174174 _ = tw .Flush ()
@@ -199,7 +199,7 @@ func writeRecommendations(b *strings.Builder, recs []model.Recommendation, opts
199199func writeLegend (b * strings.Builder , opts Options ) {
200200 lines := []string {
201201 "CPU/MEM = current → proposed request · SAVINGS = $/mo (↑ grow = reliability, not a saving)" ,
202- "conf = confidence in this recommendation; higher data tiers (Prometheus, OpenCost) score higher ." ,
202+ "CONF = confidence: ▒ low · ▓ med · █ high — grows with data history (tier, window, samples). --explain shows the % ." ,
203203 }
204204 for _ , l := range lines {
205205 if opts .Color {
@@ -234,6 +234,20 @@ func savingsCell(rec model.Recommendation) string {
234234 return fmt .Sprintf ("%s/mo" , formatDollarsAbs (rec .MonthlySavings ))
235235}
236236
237+ // confidenceCell renders the qualitative confidence band with a shaded glyph that reads as a
238+ // fill level even without color. A precise percentage is intentionally omitted here (it implies
239+ // false precision); the number is available under --explain.
240+ func confidenceCell (rec model.Recommendation ) string {
241+ switch rec .Confidence .Band () {
242+ case model .ConfidenceHigh :
243+ return "█ high"
244+ case model .ConfidenceMedium :
245+ return "▓ med"
246+ default :
247+ return "▒ low"
248+ }
249+ }
250+
237251// JSON renders a stable machine-readable schema of the scan result.
238252//
239253// The schema is exactly the JSON encoding of model.ScanResult: an object with
@@ -265,7 +279,7 @@ func Explain(w io.Writer, rec model.Recommendation) error {
265279 } else {
266280 fmt .Fprintf (& b , " savings: %s / month\n " , formatSignedDollars (rec .MonthlySavings ))
267281 }
268- fmt .Fprintf (& b , " confidence: %d%% (%s) \n " , rec .Confidence .Percent (), rec .Confidence .Reason )
282+ fmt .Fprintf (& b , " confidence: %s (% d%%) — %s \n " , rec . Confidence . Band () , rec .Confidence .Percent (), rec .Confidence .Reason )
269283 fmt .Fprintf (& b , " tier: %s\n " , rec .Tier .String ())
270284 if rec .Evidence != "" {
271285 fmt .Fprintf (& b , " evidence: %s\n " , rec .Evidence )
0 commit comments