The Execution Trace Telemetry Model
Intutic monitors, accounts for, and evaluates every AI agent request through a structured, append-only telemetry model known as the Execution Trace.
Telemetry Schema
Every trace tracks token counts, the requested and routed model, active cost profiles, anomalies, and policy enforcement decisions in the database:
interface ExecutionTrace {
traceId: string; // Unique trace ID (a UUIDv4 from the proxy on proxied traffic)
sessionId: string; // Owning agent session ID
requestId: string; // Unique ID generated per LLM exchange
timestamp: Date; // When the request occurred
// Model Routing & Selection
requestedModel: string; // Model requested by the agent harness
actualModelRouted: string; // Model actually used (after optimization routing)
routingTier: string; // Always 'frontier': a fixed value kept because traces' integrity hashes include it
complexityScore: number; // Inferred task complexity score (0.0 to 1.0)
// Token Auditing
rawInputTokens: number; // Original tokens sent
compressedInputTokens: number; // Tokens sent after prompt optimization compression
outputTokens: number; // Tokens generated by the model
reasoningTokens?: number; // Output tokens the provider reported as reasoning
// (OpenAI reasoning_tokens, Gemini thoughtsTokenCount),
// part of outputTokens; null when it reports none (Anthropic)
// Cost Accounting (Append-Only)
rawCostUsd: number; // Projected cost under raw model routing
actualCostUsd: number; // Actual cost incurred under the routed model
savingsUsd: number; // Total cost saved (rawCostUsd - actualCostUsd)
cacheHit: boolean; // Whether semantic prompt cache was hit
cacheSavingsUsd: number; // Savings generated via cache hits
cacheReadInputTokens?: number; // Provider-reported prompt-cache read
// tokens (Anthropic `cache_read_input_tokens`,
// OpenAI `prompt_tokens_details.cached_tokens`,
// Gemini `cachedContentTokenCount`); see note below
cacheCreationInputTokens?: number; // Provider-reported prompt-cache write
// tokens (Anthropic `cache_creation_input_tokens`;
// no other provider reports one); see note below
// Token Utility & Classification
tokenUtility: 'USEFUL' | 'WASTED' | null; // null = not classified
tokenUtilityScore: number | null; // a person's label: 1 USEFUL, 0 WASTED; null without one
// `wasteCategory` was documented here for a column that does not exist.
// Enforcement & Compliance
complianceScore: number; // Trust/rule alignment score (0.0 to 1.0)
enforcementAction: 'BYPASS' | 'ENHANCE' | 'HIJACK' | 'REASK' | 'KILL' | 'OBSERVED';
// Anomalies
anomalies?: string[] // categories raised on this request, most severe
// first, from the 12-value anomaly taxonomy
taskType?: string // task classification ("coding", ...)
tools?: string[] // tool calls newly observed on THIS request —
// the per-turn delta, not the cumulative history
graphId?: string // multi-agent graph coordinates; present only
nodeId?: string // when the request is part of a real graph
agentRole?: string
parentNodeId?: string
graphDepth?: number;
anomalyConfidenceScore?: number;
}Cost Calculations
Incurred and saved costs are dynamically calculated using the prices configured in the model registry:
Pricing Formulas
Costs are calculated by multiplying token usage against pricing weights. Input the provider read from or wrote to its prompt cache is priced at the model's cache-read or cache-write rate, or at the full input rate when the model has none:
Cost Savings
Cost savings are generated in two ways:
- Dynamic Routing Savings: Saved by routing tasks to a less expensive, yet functionally capable model instead of the requested premium model:
- Semantic Cache Savings: Saved when the semantic prompt cache is hit, resolving the query locally without making external calls:
Provider Prompt-Cache Tokens vs. Semantic Cache
cacheReadInputTokens and cacheCreationInputTokens are not related to cacheHit / cacheSavingsUsd, even though all four fields have "cache" in the name. They describe two different caches:
| Field | What it measures |
|---|---|
cacheHit / cacheSavingsUsd | The proxy's own semantic response cache — an exact/near-exact-match cache the proxy maintains so a repeated query can be answered locally without calling the provider at all. |
cacheReadInputTokens / cacheCreationInputTokens | The provider's own prompt cache (Anthropic's cache_read_input_tokens / cache_creation_input_tokens; OpenAI's prompt_tokens_details.cached_tokens and Gemini's cachedContentTokenCount are cache reads, and neither reports cache writes) — tokens the provider itself served from or wrote to its prompt cache on a request that still went out over the wire. cacheHit is false on these requests; the call still happened, it was just cheaper. |
A trace can have cacheHit: false and a nonzero cacheReadInputTokens in the same row — that is the normal case for a provider-side cache read.
Operator-visible behavior changes
Populating these two fields also changes cost accounting, in ways operators watching budgets or savings dashboards should expect:
- Anthropic cache-heavy tenants:
actualCostUsdgoes up. Cache-read tokens were previously not parsed out of the provider response at all, so they were dropped from cost accounting entirely and effectively billed as free. They are now priced at the provider's cache-read discount tier instead of $0. This is a billing-accuracy correction, not a regression — the prior number was undercounting real spend. One consequence is that budget and spend-cap gates may trip earlier than before on workloads that fit comfortably under the cap yesterday; that's the cap doing its job against a now-accurate cost figure, not a change in the cap itself. - OpenAI/Gemini cache-heavy tenants:
actualCostUsdgoes down. These providers' cache tokens were previously billed at full input-token price (no cache discount was ever applied). They are now priced at the model's cache-read rate.rawCostUsdfollows: when the router did not change the model it equalsactualCostUsd, sosavingsUsdstays 0; when it did, the requested model is repriced with the cache-read share last observed for it, or at full input price when there is none.
Token Utility
tokenUtility is a column on execution_traces with no default. At ingest a trace is written as WASTED when the proxy's response integrity score is below 60 (a malformed, truncated or unusable response) and is otherwise left null, meaning not classified: a clean response is not evidence the answer was useful, so nothing sets USEFUL automatically. A person can label traces USEFUL or WASTED through POST /api/v1/usage/classify. Because execution_traces is append-only, that label is stored in trace_token_utility and takes precedence over the column wherever a trace's utility is read: the trace detail, GET /api/v1/usage/events, and the routing reward, where a label overrides the trace's response integrity score (WASTED counts as 0, USEFUL as 100).
This section previously described an automatic classifier
It documented a five-rule pipeline — kill enforcement, anomaly detection, baseline overshoot, model mismatch, low compliance — writing a wasteCategory of TOKEN_WASTE, LOOP_WASTE, RETRY_WASTE, CONTEXT_BLOAT or MODEL_MISMATCH.
None of it exists. There is no waste_category column, and no code path in either repository has ever produced one of those five values. The trace classifier that does run at ingest (traceIngestClassifier.ts) writes anomaly fields — anomalyDetected, anomalySeverity, anomalyConfidenceScore, taxonomyMetadata — and does not touch tokenUtility at all.
This mattered beyond the documentation: while the column defaulted to USEFUL, the routing reward's useful/wasted ratio was 1.0 for every arm in managed deployments. The default has been dropped. The reward scores each arm from the response integrity score and cost, skips arms with no measured traffic, and lets a person's label stand in for the integrity score of the traces it covers.
What is actually recorded
| Field | Written by | Meaning |
|---|---|---|
tokenUtility | ingest, from the response integrity score; a human label via POST /api/v1/usage/classify (stored in trace_token_utility) overrides it | WASTED below integrity 60, otherwise null (not classified); a human label is USEFUL or WASTED |
tokenUtilityScore | a human label | 1 for USEFUL, 0 for WASTED; null when no one labelled the trace |
anomalyDetected | traceIngestClassifier at ingest | anomaly type, if one fired |
anomalyConfidenceScore | traceIngestClassifier at ingest | 0.0–1.0 |
taxonomyMetadata | traceIngestClassifier at ingest | every probe, not just the winner |
complianceScore | the control plane at ingest, from the proxy's verdict, anomaly and detector findings | 0.0–1.0 rule alignment |
toolResultBytesSaved | the proxy | bytes the compactor removed from the response |
upstreamAttempts | the proxy | every upstream call when it retried or fell back; null for a single call |
upstreamFallback | the proxy | the fallback target that answered, and the model whose retries ran out |
Waste patterns
Separately from per-trace utility, wastePatterns aggregates a workspace's traffic on a schedule. One detector ships: oversized prompt, a heuristic at confidence 0.6 flagging traces whose raw input exceeds three times the workspace median. See the Intelligence Engine guide.