Repository navigation
Conversation
Closes #17. Blended cost-per-turn mixes two populations: the developer's own conversation and sub-agent (isSidechain) traffic. Cheap sub-agent calls drag the blended average down without the developer's own turns getting any cheaper, which is exactly the misleading comparison that motivated the issue. The decision, recorded against PRD §11 Q23: segment everywhere, count cost everywhere. - metrics: delegationSplit() gives each population its own cost-per-turn denominator; turns predating isSidechain capture land in an explicit unknown bucket — the stored false is a column default, not an observation. dailySeries() gains a key function so the same daily bucketing serves populations as well as models. - dashboard: a Delegation section with a measured share headline ("Sub-agents handled X% of turns for Y% of the cost" — never a counterfactual saving), turn-share vs cost-share proportion bars, a per-population table, and a per-day trend reusing the existing two-panel chart keyed by population with fixed hues. - model comparison: rows carry an "all sub-agent" / "N sub-agent" pill, so a model used only by sub-agents no longer reads as one the developer chose for work. - MCP figures stay blended; get_definitions already states so. Verified headlessly against the real local store: 1,982 turns over 30 days split 95%/5% by turn and 98.4%/1.6% by cost, sub-agent traffic on three models, zero unpriced. Assisted by Claude Code (Claude Fable 5).
Both panels share one set of days across two separately-instanced category axes. The cost panel's axis had boundaryGap: false (a carryover from making its line touch the plot edges), while the turns panel's axis was left at the category-axis default, boundaryGap: true. Different layouts put each day at a different x position per panel, so every bar sat visibly off from its matching line point. Bars need boundaryGap: true — a bar fills a per-category cell, and forcing one onto a boundaryGap: false axis is undefined territory, not a fix (confirmed: it did not resolve the misalignment). The line axis loses its override instead, falling back to the same default the bar axis already uses, so a day's point and its bar now share one position. Trades the line's previous edge-to-edge look for correctness; affects both the model trend and the new Delegation trend, since both go through buildOption(). Assisted by Claude Code (Claude Sonnet 5).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #17. Resolves PRD §11 Q23: segment everywhere, count cost everywhere.
Why
Blended cost-per-turn mixes two populations — the developer's own conversation and sub-agent (
isSidechain) traffic. Dozens of cheap sub-agent calls drag the blended average down without the developer's own turns getting any cheaper. That confound was observable only over MCP, never in the dashboard (the motivating incident in #17).What
Delegation section between the trend chart and the model comparison:
Model comparison:
all sub-agent/N sub-agentpills, so a model used only by sub-agents no longer reads as one the developer chose for work.Honest-gap handling: turns predating
isSidechaincapture belong to neither population (the storedfalseis a column default, not an observation) and the section says how many exist. Sub-agent cost stays in every total — real calls, real money.Where the logic lives
src/metrics/aggregate.ts—delegationSplit()(three buckets: main / sub / unknown),dailySeries()gains a series-key function.src/service.ts— view-model assembly; the chart-finishing tail ofbuildChartextracted toassembleChartand shared.src/ui/protocol.ts—DelegationView/DelegationSliceView; everything pre-formatted, the webview still computes nothing.src/webview/— rendering only; theme variables only (lint:themeclean).MCP figures remain blended;
get_definitionsalready states so. Segmenting those is a separate decision.Verification
npm run check— 345 tests pass, including 10 new delegation tests (per-population denominators, the unknown-capture bucket, pre-capturetruebelieved /falsenot, unpriced handling, mixed-source refusal, population-keyed daily series, and four service-level dashboard tests).🤖 Generated with Claude Code