optimize: per-group subtotals in every finding render

Each class header now carries its own token/dollar subtotal and finding
count, so the apply-able slice is never mistaken for the whole board; the
headline savings line names that slice explicitly. CLI and TUI share one
classHeaderLine helper, the desktop app reads the same numbers from the
new summary.byClass in --format json (add-only; the three subtotals sum to
findingCount and potentialSavingsTokens).

Also scopes the SHELL_PROFILE_SCOPE comment to what is actually true: the
MCP deferral plans refuse to rewrite a shell profile, but bash-output-cap
appends its own marker block to one.
This commit is contained in:
iamtoruk 2026-08-18 02:39:50 -07:00
parent 6267c49c25
commit 5660909801
7 changed files with 82 additions and 12 deletions

View file

@ -139,6 +139,11 @@ function installDefaultMocks() {
healthScore: 100, healthGrade: 'A', findingCount: 0, periodCostUSD: 0,
sessions: 0, calls: 0, potentialSavingsTokens: 0, potentialSavingsCostUSD: 0,
potentialSavingsPercent: 0, costRateUSD: 0, measuredSavingsUSD: 0,
byClass: {
fix: { tokensSaved: 0, savingsUSD: 0, count: 0 },
nudge: { tokensSaved: 0, savingsUSD: 0, count: 0 },
keep: { tokensSaved: 0, savingsUSD: 0, count: 0 },
},
},
findings: [],
})

View file

@ -423,6 +423,7 @@ export type OptimizeJsonReport = {
potentialSavingsPercent: number | null
costRateUSD: number
measuredSavingsUSD: number
byClass: Record<FindingClass, { tokensSaved: number; savingsUSD: number; count: number }>
}
findings: Array<{
id: string

View file

@ -49,6 +49,11 @@ function makeOptimizeReport(): OptimizeJsonReport {
sessions: 88, calls: 1220, potentialSavingsTokens: 184_000,
potentialSavingsCostUSD: 94.4, potentialSavingsPercent: 15.4, costRateUSD: 0.0005,
measuredSavingsUSD: 27.8,
byClass: {
fix: { tokensSaved: 18_200, savingsUSD: 9.1, count: 1 },
nudge: { tokensSaved: 17_400, savingsUSD: 8.7, count: 1 },
keep: { tokensSaved: 4_800, savingsUSD: 2.4, count: 1 },
},
},
findings: [
{
@ -129,7 +134,11 @@ describe('Optimize', () => {
await screen.findByText('Opus is doing your small talk')
const groups = document.querySelectorAll('.opt-group')
expect([...groups].map(g => g.textContent)).toEqual(['Fix now (apply-able)', 'Habits', 'FYI'])
expect([...groups].map(g => g.textContent)).toEqual([
'Fix now (apply-able) · 18.2K tokens · $9.10 · 1 finding',
'Habits · 17.4K tokens · $8.70 · 1 finding',
'FYI · 4.8K tokens · $2.40 · 1 finding',
])
})
it('renders tabs and actionable Waste findings with impact, savings, explanation, and copy-paste fix', async () => {

View file

@ -101,7 +101,7 @@ function WasteRows({ report }: { report: Polled<OptimizeJsonReport> }) {
<div className="opt-summary">
{report.data.summary.findingCount.toLocaleString('en-US')} findings · {formatUsd(report.data.summary.potentialSavingsCostUSD)} potential · health {report.data.summary.healthScore}/100
</div>
<ActionableFindingRows findings={report.data.findings} />
<ActionableFindingRows findings={report.data.findings} byClass={report.data.summary.byClass} />
</div>
)
}
@ -124,7 +124,7 @@ function actionText(fix: WasteAction): string {
return fix.type === 'file-content' ? fix.content : fix.text
}
function ActionableFindingRows({ findings }: { findings: OptimizeFinding[] }) {
function ActionableFindingRows({ findings, byClass }: { findings: OptimizeFinding[]; byClass: OptimizeJsonReport['summary']['byClass'] }) {
const [expandedId, setExpandedId] = useState<string | null>(null)
const [copiedId, setCopiedId] = useState<string | null>(null)
@ -145,7 +145,11 @@ function ActionableFindingRows({ findings }: { findings: OptimizeFinding[] }) {
const showHeader = finding.class !== findings[i - 1]?.class
return (
<Fragment key={finding.id}>
{showHeader && <div className="opt-group">{CLASS_HEADERS[finding.class]}</div>}
{showHeader && (
<div className="opt-group">
{CLASS_HEADERS[finding.class]} · {formatCompact(byClass[finding.class].tokensSaved)} tokens · {formatUsd(byClass[finding.class].savingsUSD)} · {byClass[finding.class].count} {byClass[finding.class].count === 1 ? 'finding' : 'findings'}
</div>
)}
<button
className="opt-finding opt-finding-toggle"
type="button"

View file

@ -10,7 +10,7 @@ import { findUnpricedModels, isExpectedFreeModel, loadPricing } from './models.j
import { aggregateModelTotals } from './model-breakdown.js'
import { buildDurablePeriod } from './usage-aggregator.js'
import { getAllProviders } from './providers/index.js'
import { CLASS_HEADERS, findingBasis, findingClass, scanAndDetect, type FindingClass, type WasteFinding, type WasteAction, type OptimizeResult } from './optimize.js'
import { classHeaderLine, classTotals, findingBasis, findingClass, scanAndDetect, type FindingClass, type WasteFinding, type WasteAction, type OptimizeResult } from './optimize.js'
import { aggregateFileChurn, buildCoachingNotes, computePricingCoverage, medianTimeToFirstEditMs, scanUserCorrections, worstOneShotCategory, type ReworkedFile } from './workflow-insights.js'
import { estimateContextBudget, type ContextBudget } from './context-budget.js'
import { dateKey } from './day-aggregator.js'
@ -1105,6 +1105,7 @@ function OptimizeView({ findings, costRate, projects, label, width, healthScore,
const start = total === 0 ? 0 : Math.min(cursor, Math.max(0, total - FINDINGS_WINDOW_SIZE))
const end = Math.min(start + FINDINGS_WINDOW_SIZE, total)
const visible = findings.slice(start, end)
const totals = classTotals(findings, costRate)
return (
<Box flexDirection="column" width={width}>
<Box flexDirection="column" borderStyle="round" borderColor={ORANGE} paddingX={1} width={width}>
@ -1126,7 +1127,7 @@ function OptimizeView({ findings, costRate, projects, label, width, healthScore,
const previous: FindingClass | null = i > 0 ? findingClass(visible[i - 1]!) : null
return (
<Fragment key={start + i}>
{cls !== previous && <Box paddingX={1} width={width}><Text bold color={ORANGE}>{CLASS_HEADERS[cls]}</Text></Box>}
{cls !== previous && <Box paddingX={1} width={width}><Text bold color={ORANGE} wrap="truncate-end">{classHeaderLine(cls, totals[cls], costRate)}</Text></Box>}
<FindingPanel index={start + i + 1} finding={f} costRate={costRate} width={width} />
</Fragment>
)

View file

@ -341,8 +341,10 @@ export const FINDING_BASIS: Record<FindingId, FindingBasis> = {
'unused-commands': 'estimated', // count x TOKENS_PER_COMMAND_DEF
}
/// Scope label for a setting that lives in ~/.zshrc / ~/.bashrc. Plans never
/// rewrite shell profiles, they only report them.
/// Scope label for a setting that lives in ~/.zshrc / ~/.bashrc. The MCP
/// deferral plans (defer-enable, defer-threshold) refuse to rewrite an
/// override found there and report it instead; bash-output-cap does append
/// its own marker block to the shell rc.
export const SHELL_PROFILE_SCOPE = 'shell profile'
export function findingClass(f: WasteFinding): FindingClass {
@ -366,11 +368,36 @@ export function findingBasis(f: WasteFinding): FindingBasis {
const CLASS_ORDER: Record<FindingClass, number> = { fix: 0, nudge: 1, keep: 2 }
export const CLASS_HEADERS: Record<FindingClass, string> = {
fix: 'Fix now (apply-able) — codeburn optimize --apply',
fix: 'Fix now (apply-able)',
nudge: 'Habits',
keep: 'FYI',
}
export type ClassTotals = { tokensSaved: number; savingsUSD: number; count: number }
export function classTotals(findings: WasteFinding[], costRate: number): Record<FindingClass, ClassTotals> {
const totals: Record<FindingClass, ClassTotals> = {
fix: { tokensSaved: 0, savingsUSD: 0, count: 0 },
nudge: { tokensSaved: 0, savingsUSD: 0, count: 0 },
keep: { tokensSaved: 0, savingsUSD: 0, count: 0 },
}
for (const f of findings) {
const t = totals[findingClass(f)]
t.tokensSaved += f.tokensSaved
t.savingsUSD += f.tokensSaved * costRate
t.count++
}
return totals
}
/// Group header with its own subtotal, shared by the CLI and the TUI so the
/// two never drift apart.
export function classHeaderLine(cls: FindingClass, totals: ClassTotals, costRate: number): string {
const cost = costRate > 0 ? ` (~${formatCost(totals.savingsUSD)})` : ''
const suffix = cls === 'fix' ? ' — codeburn optimize --apply' : ''
return `${CLASS_HEADERS[cls]} · ~${formatTokens(totals.tokensSaved)} tokens${cost} · ${totals.count} finding${totals.count === 1 ? '' : 's'}${suffix}`
}
// Cause taxonomy for defer-enable plans (mcp-deferral-off findings).
// 'proxy-verified' is never produced by the detector today: it is reserved
// for the #614 part-3 proxy verifier, which upgrades 'proxy-unknown' once a
@ -443,6 +470,9 @@ export type OptimizeJsonReport = {
/// Portion of `potentialSavingsCostUSD` coming from `measured`-basis
/// findings. The total keeps its old meaning: measured plus estimated.
measuredSavingsUSD: number
/// Per-class subtotals; the three counts and token sums add up to
/// `findingCount` and `potentialSavingsTokens`.
byClass: Record<FindingClass, ClassTotals>
}
findings: Array<{
id: FindingId
@ -3385,8 +3415,12 @@ export function renderOptimize(
const pctRaw = periodCost > 0 ? (totalCost / periodCost) * 100 : 0
const pct = pctRaw >= 1 ? pctRaw.toFixed(0) : pctRaw.toFixed(1)
const totals = classTotals(findings, costRate)
const costText = costRate > 0 ? ` (~${formatCost(totalCost)}, ~${pct}% of spend)` : ''
lines.push(chalk.hex(GREEN)(` Potential savings: ~${formatTokens(totalTokens)} tokens${costText}`))
// The headline is the whole board; name the apply-able slice separately so
// it never reads as "what CodeBurn can fix for you".
const applyable = costRate > 0 && totals.fix.count > 0 ? ` — apply-able: ~${formatCost(totals.fix.savingsUSD)}` : ''
lines.push(chalk.hex(GREEN)(` Potential savings: ~${formatTokens(totalTokens)} tokens${costText}${applyable}`))
lines.push('')
// One block per class, in fix -> nudge -> keep order; numbering runs
@ -3395,7 +3429,7 @@ export function renderOptimize(
for (const cls of ['fix', 'nudge', 'keep'] as const) {
const group = findings.filter(f => findingClass(f) === cls)
if (group.length === 0) continue
lines.push(chalk.bold.hex(ORANGE)(` ${CLASS_HEADERS[cls]}`))
lines.push(chalk.bold.hex(ORANGE)(` ${classHeaderLine(cls, totals[cls], costRate)}`))
lines.push('')
for (const f of group) {
const appliedOn = previouslyApplied?.[f.id]
@ -3507,6 +3541,7 @@ export function buildOptimizeJsonReport(
measuredSavingsUSD: result.findings
.filter(f => findingBasis(f) === 'measured')
.reduce((s, f) => s + f.tokensSaved * result.costRate, 0),
byClass: classTotals(result.findings, result.costRate),
},
findings: result.findings.map(f => ({
id: f.id,

View file

@ -1311,6 +1311,15 @@ describe('buildOptimizeJsonReport', () => {
costRateUSD: 0.00002,
})
expect(report.summary.measuredSavingsUSD).toBe(0)
expect(report.summary.byClass).toEqual({
fix: { tokensSaved: 0, savingsUSD: 0, count: 0 },
nudge: { tokensSaved: 50_000, savingsUSD: 1, count: 1 },
keep: { tokensSaved: 0, savingsUSD: 0, count: 0 },
})
const classes = Object.values(report.summary.byClass)
expect(classes.reduce((s, c) => s + c.tokensSaved, 0)).toBe(report.summary.potentialSavingsTokens)
expect(classes.reduce((s, c) => s + c.savingsUSD, 0)).toBeCloseTo(report.summary.potentialSavingsCostUSD, 10)
expect(classes.reduce((s, c) => s + c.count, 0)).toBe(report.summary.findingCount)
expect(report.findings[0]).toMatchObject({
title: 'Trim stale context',
severity: 'medium',
@ -1349,9 +1358,15 @@ describe('renderOptimize grouping', () => {
]
const out = plain(renderOptimize(findings, 0.00001, '7 Days', 10, 5, 100, 80, 'B', [], []))
const headers = ['Fix now (apply-able)', 'Habits', 'FYI'].map(h => out.indexOf(h))
const headers = [
'Fix now (apply-able) · ~1.0K tokens (~$0.010) · 1 finding — codeburn optimize --apply',
'Habits · ~1.0K tokens (~$0.010) · 1 finding',
'FYI · ~1.0K tokens (~$0.010) · 1 finding',
].map(h => out.indexOf(h))
expect(headers.every(i => i >= 0)).toBe(true)
expect(headers).toEqual([...headers].sort((a, b) => a - b))
// Headline is the whole board; the apply-able slice is named separately.
expect(out).toContain('Potential savings: ~3.0K tokens (~$0.030, ~0.3% of spend) — apply-able: ~$0.010')
expect(out).toContain('1. Cap bash output')
expect(out).toContain('2. Trim CLAUDE.md')
expect(out).toContain('3. Context-heavy sessions')