Skip to content

v0.5.0 — Show sub-agent delegation on the dashboard - #18

Merged
smolinari merged 2 commits into
mainfrom
dev
Oct 15, 2026
Merged

smolinari merged 2 commits into
mainfrom
dev

Conversation

@smolinari

Copy link
Copy Markdown
Member

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:

  • Headline, measured never counterfactual: "Sub-agents handled 5.0% of turns for 1.6% of the cost."
  • Two 100% proportion bars (turn share vs cost share) — the asymmetry between them is the point.
  • Per-population table: turns, cost/turn, total — each population on its own denominator.
  • Per-day trend reusing the existing two-panel chart, keyed by population instead of model, fixed hues (blue = main thread, green = sub-agents).

Model comparison: all sub-agent / N sub-agent pills, so a model used only by sub-agents no longer reads as one the developer chose for work.

Honest-gap handling: turns predating isSidechain capture belong to neither population (the stored false is 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 of buildChart extracted to assembleChart and shared.
  • src/ui/protocol.ts — DelegationView / DelegationSliceView; everything pre-formatted, the webview still computes nothing.
  • src/webview/ — rendering only; theme variables only (lint:theme clean).
  • Docs: DESIGN.md §10.5 added; PRD Q23 and the §4 confound bullet marked resolved; CHANGELOG 0.5.0.

MCP figures remain blended; get_definitions already 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-capture true believed / false not, unpriced handling, mixed-source refusal, population-keyed daily series, and four service-level dashboard tests).
  • Smoke-tested headlessly against the real local store: 1,982 turns / 30 days → 95%/5% by turn, 98.4%/1.6% by cost, delegation trend over 25 days, pills on three models.
  • Not yet eyeballed in the Extension Development Host — worth an F5 pass on the new section before publishing.

🤖 Generated with Claude Code

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).
@smolinari
smolinari merged commit 9237ead into main Oct 15, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dashboard shows no sub-agent (sidechain) activity — PRD §11 Q23 now has a motivating incident

1 participant