Tier A metrics
Trove emits telemetry in two tiers. Tier A is the harness-agnostic layer that Trove generates: a fixed set of five metrics every harness contributes to, so you can compare wildly different tools in a single query. Tier B is each harness’s own native metrics, passed straight through. This page is about Tier A — the normalization layer that makes cross-vendor dashboards possible.
Why normalization matters
Section titled “Why normalization matters”Every AI coding vendor invented its own telemetry dialect. Claude Code emits
claude_code.token.usage; Cursor and Antigravity CLI emit hook events;
best-effort tools emit nothing at all until Trove derives records for them. Without
a common schema, a dashboard that answers “cost per turn across all our tools” is
impossible — you’d be joining five incompatible namespaces by hand.
Tier A fixes that. Every enabled harness — native or best-effort — contributes to
the same five metrics, tagged with the same harness.id. Cost per turn for
Claude Code becomes directly comparable to cost per turn for Copilot CLI, in your
own backend, with no vendor-specific exporter to maintain.
The five Tier A metrics
Section titled “The five Tier A metrics”| Metric | Type | Unit | Key attributes |
|---|---|---|---|
trove.harness.events | Sum (Δ, monotonic) | 1 | event.kind ∈ {chat.turn, tool.call, shell.exec, file.edit, session.start, session.end} |
trove.harness.tokens | Sum (Δ, monotonic) | {token} | direction ∈ {input, output}, model |
trove.harness.cost.usd | Sum (Δ, monotonic) | USD | model, cost.method ∈ {exact, estimated} |
trove.harness.turn.duration | Histogram | s | event.kind |
trove.harness.errors | Sum (Δ, monotonic) | 1 | error.kind ∈ {rate_limit, auth, tool_failure, network, policy, unknown} |
Every Tier A data point also carries a set of resource attributes — set once at
adapter startup, not per point — that scope a series to one harness (and,
optionally, one person) without inflating cardinality: service.name,
harness.id, harness.name, trove.source, and the opt-in user.name /
user.email from identity tagging.
Exact vs estimated cost
Section titled “Exact vs estimated cost”The cost.method attribute on trove.harness.cost.usd tells you how a cost figure
was derived:
exact— for native-OTel harnesses and the Cline watcher, token counts come from the harness itself, so cost is computed from real token usage × a per-model rate.estimated— for hook- and wrapper-based harnesses (Cursor, Aider, Copilot CLI, OpenCode), Trove only observes prompt/response byte length, so it approximates tokens (abytes / 4heuristic) and multiplies by the rate table.
Dashboards default to summing both — directionally useful for “did I spend $5 or
$50 today?” — while anyone who needs invoice-accurate numbers filters to
cost.method = "exact".
Tier A vs Tier B
Section titled “Tier A vs Tier B”| Tier A | Tier B | |
|---|---|---|
| Source | Generated by Trove | Native to the harness |
| Schema | Fixed five-metric set | Whatever the vendor emits |
| Purpose | Cross-harness comparison | Vendor-native drill-down |
| Naming | trove.harness.* | e.g. claude_code.*, telemetry.* |
| Trove’s handling | Synthesized / classified onto the schema | Passed through untouched |
The two tiers are additive, not exclusive. Trove’s collector overlay uses
action: insert, so synthesizing a Tier A metric from a native one never removes
the native (Tier B) metric — it still reaches your backend unchanged. You keep the
normalized cross-tool view and the full-fidelity per-tool view.