fix(ri-exchange): a convertible RI with all-zero prices reads as free in reshape math #1188
Copy link
Copy link
Closed
Labels
effort/xsTrivial / one-linerTrivial / one-linerimpact/fewLimited audienceLimited audiencepriority/p2Backlog-worthyBacklog-worthyseverity/mediumModerate harmModerate harmtriagedItem has been triagedItem has been triagedtype/bugDefectDefecturgency/this-quarterWithin the quarterWithin the quarter
Description
Summary
A convertible RI whose FixedPrice, UsagePrice and RecurringHourlyAmount are all zero gets MonthlyCost 0. In cloud-commitments-go pkg/exchange/reshape.go, pricingGatePasses (:678) returns true for MonthlyCost <= 0, and costComponent (:220) scores it as neutral 0.5. So the RI reads as free in reshape recommendations, the same failure #1181 / #1187 fixed for a non-positive duration.
Evidence
monthlyCostFromConvertibleRI(internal/api/handler_ri_exchange.go,internal/server/handler_ri_exchange.go) computes the cost asFixedPrice/term + (UsagePrice + RecurringHourlyAmount) * hours, with no check for an all-zero price set.- A fully-upfront RI has
FixedPrice > 0, so a real convertible RI with all three at zero is anomalous: it means missing pricing data, not a free RI. - Related: an RI whose
FixedPriceis missing while the hourly parts are populated is silently under-priced.
Proposed fix
Treat an all-zero price set like the non-positive duration in #1187: exclude the RI from cost-based reshape inputs with a warning. Alternatively, pass an explicit "price unknown" through the library so the pricing gate refuses rather than passes. Add tests for both shapes.
Found by review of #1187.
Metadata
Metadata
Assignees
Labels
effort/xsTrivial / one-linerTrivial / one-linerimpact/fewLimited audienceLimited audiencepriority/p2Backlog-worthyBacklog-worthyseverity/mediumModerate harmModerate harmtriagedItem has been triagedItem has been triagedtype/bugDefectDefecturgency/this-quarterWithin the quarterWithin the quarter
Activity
IAmJSD commentedon Oct 20, 2026
Claiming: working on this
Merge remote-tracking branch 'origin/main' into fix/issue-1188
Merge remote-tracking branch 'origin/main' into fix/issue-1206