# PragmAI telemetry reference PragmAI emits one aggregate event after an exchange with measurable usage. The connector builds the event transiently and sends it directly; it does not create a local analytics history, CSV, retry queue, or transcript copy. The canonical synthetic example is [`examples/telemetry-event.json`](../examples/telemetry-event.json). Its values are invented and contain no customer activity. ## Identity and envelope | Field | Meaning | |---|---| | `event_id` | Random identifier for deduplication. It is not a conversation or session identifier. | | `occurred_at` | Completion timestamp. | | `company_id` | Stable company identifier assigned by PragmAI. | | `employee_id` | Lowercase email explicitly authorized by the employee. | | `client` | Closed client name, currently Codex or Claude Code. | | `connector_version` | Local connector version. | | `telemetry_version` | Event schema version. | ## Explicit automation attribution Telemetry v9 can include `execution_origin` from the closed set `scheduled`, `api_trigger`, or `other_automation`; `automation_slot`, an operator-assigned number from 1 to 9999 that must be unique for each bot within a company; and `automation_run_key`, an installation-keyed HMAC of an explicit scheduler run marker. The connector never infers automation from a time of day, prompt, or Claude session identifier. Missing markers remain absent, and neither bot names nor raw run markers are transmitted. This currently applies to local Claude Code processes that execute the installed hook. ## Model and usage counters The connector uses counters exposed by the local client. Missing data remains absent or null rather than being invented. | Field | Meaning | |---|---| | `model`, `reasoning_effort` | Model configuration reported by the client. | | `duration_ms` | Elapsed time covered by the exchange when observable. | | `active_time_ms`, `active_time_basis` | Claude Code active-time estimate from observed transcript intervals, with idle gaps capped at five minutes. It is not the provider OpenTelemetry metric. | | `tokens_input`, `tokens_output` | Aggregate input and output tokens. | | `tokens_cache_read`, `tokens_cache_write` | Aggregate cache counters when exposed. | | `tokens_cache_write_1h` | Subset of cache-write tokens using a one-hour TTL when the client exposes it. | | `tokens_reasoning` | Aggregate reasoning tokens when exposed. | | `model_calls` | Number of model calls observed inside the exchange. | | `max_input_tokens_per_call` | Largest observed input context. | | `calls_over_compaction_threshold` | Calls whose context crossed the configured threshold. | | `cache_miss_calls` | Calls with no observed cache read. | | `long_context_fresh_input_tokens`, `long_context_cached_input_tokens`, `long_context_cache_write_tokens`, `long_context_output_tokens` | Usage buckets from calls above the provider's long-context pricing threshold. They permit server-side per-call pricing without transmitting call sequences. | ## Closed work and tool categories `work_domain`, `task_type`, and `workflow_pattern` are selected locally from fixed enumerations. They are coarse technical categories, not stored task descriptions. `classification_version` identifies the deterministic ruleset. `tool_category_counts` contains counts for closed tool families such as file inspection, testing, version control, or filesystem writing. It never contains individual tool names, commands, arguments, or results. `tool_result_characters` is only the aggregate character count of observed local tool results. Codex telemetry v7 can emit `code_lines_added`, `code_lines_removed`, `plugin_calls`, and `plugin_category_counts`. Telemetry v8 adds `plugin_name_counts` and `skill_name_counts` using closed catalogs of approved public product labels. Any custom or unknown name becomes `other`; the original name is discarded locally. Claude Code telemetry v8 can additionally emit `active_time_ms`, `code_edit_calls`, `code_edit_successes`, `code_edit_failures`, `commits_created`, `pull_requests_created`, `skill_calls`, and `subagent_calls`. Line counts are derived transiently only for recognized code-file edits and are counted only when a structurally successful tool result is observed. Edit success means tool execution success, not human acceptance of a suggestion. Commits and pull-request creation are recognized transiently and emitted only as counts. Null means the client did not expose the signal; zero means it was measured and no matching activity occurred. File names, paths, diffs, content, arguments, commands, custom names, and individual agent tasks are always discarded locally. PragmAI does not enable Claude observability options that include prompts, tool details/content, raw API bodies, session identifiers, or trace identifiers. PragmAI Core does not emit automation scores, recommendations, quality judgments, or suggested improvements. Those are outside the public collection layer. ## Workflow and compacting counters | Field | Meaning | |---|---| | `post_tool_model_calls` | Model calls observed after a tool result. | | `continuation_model_calls` | Continuation calls observed inside the exchange. | | `compaction_measurements` | Closed numeric measurements around observed compacting boundaries. Claude assigns each native boundary to the first exchange with subsequent model usage, including idle/manual compactions; trailing boundaries wait for subsequent usage. The first post-compaction input is separate from the compacted context size, which is absent unless explicitly provided. Empty means no boundary was captured in this exchange, not proof of no compaction. | | `compaction_counterfactual` | Optional Codex v5 aggregate that replays the technical context trajectory against the original compaction threshold. It contains method, coverage, threshold and checkpoint bases, aggregate input, and estimated original compaction counters for the current exchange. It is emitted only in permanently enabled mode when the local session has enough compacting evidence. | | `compaction_sensitivity` | Optional Codex v6 aggregate that deterministically replays a closed grid at the current threshold, ±25,000 and ±50,000 tokens, plus the original limit. It contains only scenario totals and labeled threshold/checkpoint bases, including a profile checkpoint estimate for sessions that never compacted. | | `config_profile` | Closed public name of the active local profile. | | `compaction_threshold_tokens`, `compaction_scope` | Effective observed threshold and scope. | | `configured_compaction_threshold_tokens` | Threshold requested by the managed configuration. | | `config_status` | Whether observed and requested configuration match. | | `optimization_enabled` | Whether the managed optimization was active for this exchange. | | `billing_mode` | Subscription, API, or unknown; it is not a price or charge. | | `recurrence_key` | HMAC-derived shape identifier. It cannot be reversed into the source text and is not a session identifier. | The v5 counterfactual, v6 sensitivity grid, and v7/v8 activity counters read local technical records only transiently. The session identifier, call sequence, source records, file metadata, diffs, custom names, and conversation content never enter the event. The transformations run entirely as deterministic local software and do not call the model. The hosted service values these numeric aggregates and labels inferred values separately from observed counters. ## Explicitly forbidden The connector and server schema reject prompts, responses, free text, transcripts, commands, arguments, arbitrary tool names, custom plugin/skill names, tool output, file names, paths, URLs, session/thread/trace identifiers, and unknown fields. Only labels from the public closed catalogs are accepted. Privacy tests verify representative cases before every release.