| 187 | } |
| 188 | |
| 189 | function buildWhyBullets(result, summary, failedErrors, warningSignals) { |
| 190 | const bullets = []; |
| 191 | |
| 192 | if (failedErrors > 0) { |
| 193 | bullets.push(`${failedErrors} failing error check${failedErrors === 1 ? "" : "s"} are driving the highest-confidence problems.`); |
| 194 | } |
| 195 | |
| 196 | if (warningSignals > 0) { |
| 197 | bullets.push(`${warningSignals} warning signal${warningSignals === 1 ? "" : "s"} still need cleanup before this feels polished.`); |
| 198 | } |
| 199 | |
| 200 | if (summary.categoryDeductions.length > 0) { |
| 201 | const topCategory = summary.categoryDeductions[0]; |
| 202 | bullets.push(`${topCategory.category} is the largest source of score loss at -${topCategory.totalPenalty} points.`); |
| 203 | } |
| 204 | |
| 205 | if ( |
| 206 | ["heavy", "excessive"].includes(result.budgets?.trigger_cost_tokens?.band) || |
| 207 | ["heavy", "excessive"].includes(result.budgets?.invoke_cost_tokens?.band) |
| 208 | ) { |
| 209 | bullets.push("Active budget pressure is high enough that token cost may dominate the user experience."); |
| 210 | } else { |
| 211 | bullets.push("Budget pressure is not the dominant issue right now."); |
| 212 | } |
| 213 | |
| 214 | if (result.observedUsage?.sampleCount) { |
| 215 | bullets.push(`Observed usage is available from ${result.observedUsage.sampleCount} sample${result.observedUsage.sampleCount === 1 ? "" : "s"}.`); |
| 216 | } else { |
| 217 | bullets.push("No observed usage is attached yet, so budget conclusions are still based on static estimates."); |
| 218 | } |
| 219 | |
| 220 | if (bullets.length === 0) { |
| 221 | bullets.push(`Current grade is ${summary.grade} with ${summary.riskLevel} reported risk.`); |
| 222 | } |
| 223 | |
| 224 | return bullets.slice(0, 5); |
| 225 | } |
| 226 | |
| 227 | function buildRiskReasons({ score, failedErrors, warningSignals, deductions, checkSummary }) { |
| 228 | const reasons = []; |