Goal
Make the Session Detail page actionable for diagnosing missing/zero token & cost data.
What to add
For every session, show:
- Token breakdown — input / output / cacheCreation / cacheRead and total. Per-model breakdown (
modelUsage) when present.
- Underlying SDK source file path — where the tokens came from:
- For `claude-code`: the `.jsonl` path under `~/.claude/projects/...` (or Mars-managed root)
- For `codex`: the rollout `.jsonl` path
- For `copilot-cli`: the chat session file path
- For Eureka orchestrator: also show the Eureka session directory and which file under it provided fallback tokens (`eureka-fallback.ts` resolution)
- Token provenance — surface the existing `tokenProvenance` field with a human-readable label:
- `sdk-cc-jsonl` → "Parsed from Claude Code JSONL"
- `sdk-codex-rollout` → "Parsed from Codex rollout"
- `sdk-shutdown` → "Parsed from Copilot CLI shutdown event"
- `telemetry` / `telemetry-incomplete` → "From Eureka telemetry (no SDK file matched)"
- `none` → "No token data available"
- Zero-cost / zero-token explanation — when both tokens and cost are zero, show a clearly labeled diagnostic:
- Why no cost? Possible reasons (one or more):
- Eureka entry matched but no SDK file produced tokens (`provenance=none`)
- SDK file exists but had 0 tokens (e.g. subagent-only file, no main-thread API messages)
- Pricing entry missing for model ``
- Cost calculation skipped (free tier, etc.)
- Show which one(s) apply.
Pipeline context
The new parse-then-attribute pipeline (`docs/design/DESIGN-parse-then-attribute.md`) sets these fields at:
- Phase 1 PARSE — SDK parsers populate `tokens`, `modelUsage`, source file path (currently the file path is consumed for cursor management but not retained on `Session`).
- Phase 3 ATTRIBUTE — `applyEurekaMeta` rekeys to Eureka session id; recently extended with `maybeUpgradeMatchedEurekaSession` to pull fallback tokens for matched sessions with weak provenance.
- Phase 4 ORPHAN-INGEST — `ingestEurekaOrphans` synthesizes sessions from Eureka entries; sets `tokenProvenance` based on what was found.
To support this issue, we likely need to add to `Session` (or a sibling debug payload returned by `/api/session/.../messages` or a new `/api/session/.../debug`):
- `sourcePath?: string` — primary SDK file
- `fallbackPath?: string` — Eureka fallback file when used
- `zeroCostReasons?: string[]` — populated when total cost is 0
UX
- New collapsible "Provenance & Diagnostics" section in Session Detail.
- Path values are clickable (or at least copy-friendly) — open in the macOS Finder via `file://`.
- Use a warning chip next to `provenance=none` or zero-cost sessions.
Out of scope
- Fixing the underlying root causes for zero-cost sessions (separate issues per cause once we can see them clearly).
- Persisting historical provenance changes.
Why now
The reset-vs-incremental investigation (today) showed several sessions with `provenance=none` and $0 cost where the underlying SDK file actually existed in some cases. Surfacing the source path in the UI would have made that 5-minute Python diff in the dashboard, not in a notebook.
Goal
Make the Session Detail page actionable for diagnosing missing/zero token & cost data.
What to add
For every session, show:
modelUsage) when present.Pipeline context
The new parse-then-attribute pipeline (`docs/design/DESIGN-parse-then-attribute.md`) sets these fields at:
To support this issue, we likely need to add to `Session` (or a sibling debug payload returned by `/api/session/.../messages` or a new `/api/session/.../debug`):
UX
Out of scope
Why now
The reset-vs-incremental investigation (today) showed several sessions with `provenance=none` and $0 cost where the underlying SDK file actually existed in some cases. Surfacing the source path in the UI would have made that 5-minute Python diff in the dashboard, not in a notebook.