Repository navigation
Description
Problem Statement
A Human cannot tell which provider and model a PersonaBot actually used or how many tokens each consumed across Orchestrator, Assignment, and DSH Subagent work. The current token card combines a multi-model Turn into a mixed label, and rebuilding its daily table from surviving Session logs would erase statistics after ordinary Session deletion. Permission to use a model is not evidence that the model was called.
Solution
Show retained, observed model usage in the PersonaBot Profile. Attribute actual DSH model attempts to the owning PersonaBot, execution role, exact provider/model, and Host-local day. Show input, output, cache-read, and cache-write tokens separately; mark missing provider usage as unknown. Keep daily aggregate statistics after ordinary Session deletion, remove identifiable usage after thorough PersonaBot purge, and let the Human filter the Profile chart and totals by route and role.
User Stories
- As a Human, I want to see which provider/model a PersonaBot actually used, so that I can verify its execution rather than infer use from its allowed plan.
- As a Human, I want usage grouped by exact provider and model, so that similarly named models from different providers stay distinct.
- As a Human, I want to see input tokens, so that I can understand prompt consumption.
- As a Human, I want to see output tokens, so that I can understand generation consumption.
- As a Human, I want to see cache-read and cache-write tokens separately, so that cached activity is visible rather than hidden in one total.
- As a Human, I want missing provider usage marked unknown, so that I do not mistake an absent report for zero consumption.
- As a Human, I want Orchestrator, Assignment, and DSH Subagent work attributed to the same owning PersonaBot, so that its complete workload is visible.
- As a Human, I want to filter those three execution roles, so that I can distinguish routine conversation from delegated work.
- As a Human, I want to filter by provider/model, so that I can inspect one route or compare several routes used by a Bot.
- As a Human, I want a daily activity chart that initially shows 26 weeks, so that recent use is easy to scan.
- As a Human, I want to choose another bounded time range and see an all-time total, so that I can inspect both short-term and cumulative use.
- As a Human, I want a Turn that calls multiple models to contribute to each model separately, so that no usage disappears into
mixed. - As a Human, I want reported usage from retries and failed attempts counted when the provider reports it, so that the statistic follows actual model consumption.
- As a Human, I want an ordinary Session deletion to preserve daily usage totals without preserving identifiable deleted-Session detail, so that I can clear conversation history without falsifying statistics.
- As a Human, I want archiving a PersonaBot to preserve its usage for inspection, so that archived activity remains understandable.
- As a Human, I want a thorough PersonaBot purge to remove its identifiable usage, so that the Bot's data can be cleared completely.
- As a Human, I want empty, partial, unknown, and temporarily degraded states explained in the Profile, so that I know whether a blank chart means no calls or a reporting problem.
- As a Human, I want a refreshed Profile to show newly recorded usage without reading private DSH logs in the browser, so that the UI stays within the trusted Host boundary.
Implementation Decisions
- DSH SessionEvents and provider-reported attempt usage are the source facts. Trusted Session ownership attributes each Orchestrator, Assignment, and DSH Subagent attempt to a PersonaBot. BotHarness owns the application-defined retained statistic, not the DSH transcript or provider credentials (ADR-0094).
- Aggregate by PersonaBot, Host-local calendar day, execution role, exact provider, and exact model. Keep uncached input, output, cache-read, and cache-write buckets plus an unknown-usage indicator or count. The reported provider route of each actual attempt wins over the Bot's configured Model Plan.
- A Turn using multiple routes contributes its attempts to their individual route buckets. Reported usage from failed or retried attempts is included exactly once. Unknown usage is not converted into zero or an invented estimate.
- Incremental folding is idempotent per durable attempt. Reconciliation may correct only intervals with complete source evidence; it cannot clear retained history or double-count remaining Session logs after an ordinary Session is deleted.
- Ordinary Session deletion preserves the daily aggregate while removing deleted-Session identifiable detail from the retained statistic. A thorough PersonaBot purge removes its identifiable aggregates; archiving leaves them readable.
- The Host exposes bounded typed queries through the existing Typert remote and API Gateway. Queries include route/role/date filters, totals, daily series, freshness, and explicit empty/partial/degraded information. The browser consumes this read model; it does not read DSH Session logs or the operational database directly. Refresh may start with bounded polling; later push frames may invalidate but never own usage facts.
- The existing Profile activity area is the consumer: default 26-week chart, selectable range, all-time total, and provider/model plus role breakdown. Detailed results are paginated or range-limited. Model permissions and actual use appear as different concepts.
- v1.0 reports token buckets, not monetary estimates. The Host's local time zone defines the day boundary. Cost, currency, and price-era decisions remain in 价格与计费口径:官方来源、币种/时段/缓存规则 #35.
- Delivery begins with one real PersonaBot model attempt visible under its exact provider/model in Profile. Expand to multi-route Turns, Assignment and Subagent attribution, retention across deletion, and purge, validating each runnable slice before the next. Each UI PR includes screenshots and an operable Human QA state.
Testing Decisions
- Test observable usage through the highest existing seam: execute a real DSH model request, read the Host's Profile usage query, and confirm the visible route and reported buckets. Do not assert private table layout as the primary acceptance criterion.
- Extend existing usage, bridge-method, and PersonaBot Profile tests for query shape and UI states. Use DSH adapter and Assignment tests for trusted ownership and role attribution. Focus coverage on behavior: exact provider/model, four token buckets, unknown usage, filters, and bounded date ranges.
- Exercise a multi-model Turn, reported retry or failure, duplicate/late delivery, ordinary Session deletion followed by reconciliation, PersonaBot archiving, and thorough purge. Confirm totals change only when the underlying observed consumption or purge semantics require it.
- Verify the first cross-layer slice against an isolated DSH instance with a real model reply. Give the Human a Profile path to inspect the model breakdown and screenshot the resulting UI.
Out of Scope
- Monetary cost, currency conversion, provider price eras, and spending limits (价格与计费口径:官方来源、币种/时段/缓存规则 #35).
- A separate Dashboard page or Session-level drill-down as the primary v1.0 surface.
- Treating allowed routes in a Model Plan as if they were actual usage (PersonaBot model presets and per-Session model routing #488).
- Retaining prompts, responses, credentials, or deleted-Session identifiers in the usage statistic.
- Using a second browser transport or a second usage authority.
Further Notes
- This issue is part of Wayfinder: per-PersonaBot 费用与用量可见性 #34 and follows ADR-0094. PersonaBot model presets and per-Session model routing #488 specifies model permission and selection; this issue specifies observed consumption.
- The existing Profile token card and daily usage fold are starting points. Their
mixedroute and whole-table rebuild behavior must change to meet this contract.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
[-]Dashboard 与 botharness/usage 桥契约[/-][+]Usage read model / Typert remote / Dashboard contract[/+]5 remaining items
[-]Usage read model / Typert remote / Dashboard contract[/-][+]Usage read model / Typert remote / Profile contract[/+]Match bilingual model glossary term headings
DoodleBears commentedon Sep 29, 2026
Agent work outcome
codex/local/01a0e445-0c0f-70e1-bad4-fd99c8cfaa21Document PersonaBot model presets and retained model usage (#489)
DoodleBears commentedon Sep 29, 2026
Agent work outcome update
codex/local/01a0e445-0c0f-70e1-bad4-fd99c8cfaa21ready-for-agent.DoodleBears commentedon Oct 1, 2026
Usage delivery completion
All implementation children are now merged: #499, #502, #503, #507 and the coordinated chart UI #592. The final slice #507 passed Human QA and merged via #641 (
dfe8b637b0515959e1ab706d9b99dbb0c1c9024c). Profile defaults to seven days, filters actual models or providers and execution categories, shows retained all-time totals, and refreshes on demand without polling. Ordinary Session deletion preserves token statistics; PersonaBot purge follows the established privacy contract. Real DSH evidence is included in each UI PR.Task:
codex/local/01a0e445-0c0f-70e1-bad4-fd99c8cfaa21. #488 remains open because #505 still needs full Profile Backup/Restore and PersonaBot Export prerequisites.