Skip to content

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:

typescript
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:

Costin=Uncached Input×Input Price+Cache Reads×Cache-Read Price+Cache Writes×Cache-Write PriceCostout=Output Tokens×Price per Output TokenActual Cost=Costin+Costout

Cost Savings ​

Cost savings are generated in two ways:

  1. Dynamic Routing Savings: Saved by routing tasks to a less expensive, yet functionally capable model instead of the requested premium model: Savingsrouting=Raw Cost−Actual Cost
  2. Semantic Cache Savings: Saved when the semantic prompt cache is hit, resolving the query locally without making external calls: Savingscache=Cache Hit Savings

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:

FieldWhat it measures
cacheHit / cacheSavingsUsdThe 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 / cacheCreationInputTokensThe 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: actualCostUsd goes 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: actualCostUsd goes 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. rawCostUsd follows: when the router did not change the model it equals actualCostUsd, so savingsUsd stays 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 ​

FieldWritten byMeaning
tokenUtilityingest, from the response integrity score; a human label via POST /api/v1/usage/classify (stored in trace_token_utility) overrides itWASTED below integrity 60, otherwise null (not classified); a human label is USEFUL or WASTED
tokenUtilityScorea human label1 for USEFUL, 0 for WASTED; null when no one labelled the trace
anomalyDetectedtraceIngestClassifier at ingestanomaly type, if one fired
anomalyConfidenceScoretraceIngestClassifier at ingest0.0–1.0
taxonomyMetadatatraceIngestClassifier at ingestevery probe, not just the winner
complianceScorethe control plane at ingest, from the proxy's verdict, anomaly and detector findings0.0–1.0 rule alignment
toolResultBytesSavedthe proxybytes the compactor removed from the response
upstreamAttemptsthe proxyevery upstream call when it retried or fell back; null for a single call
upstreamFallbackthe proxythe 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.

The circuit breaker for AI agents