@@ -15,13 +15,13 @@ Each event carries a small set of properties:
1515| ------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1616| ` cli_start ` | Once per used session (see First-run disclosure) | (none beyond common properties) |
1717| ` session_end ` | When a TUI session finishes | ` status ` , ` turn_count ` , ` duration_ms ` , ` session_mode ` , ` exit_reason ` |
18- | ` $ai_generation ` | Once per turn — on completion, and once for a turn that ends in an error instead | ` $ai_trace_id ` , ` $ai_provider ` , ` $ai_model ` , ` $ai_input_tokens ` , ` $ai_output_tokens ` , ` $ai_latency ` , ` $ai_is_error ` , ` $ai_error ` , ` $ai_cache_read_input_tokens ` , ` $ai_cache_creation_input_tokens ` , ` $ai_reasoning_tokens ` |
19- | ` $ai_span ` | Once per top-level tool call in a completed turn | ` $ai_trace_id ` , ` $ai_span_id ` , ` $ai_parent_id ` , ` $ai_span_name ` , ` $ai_is_error ` |
18+ | ` $ai_generation ` | Once per completed turn (may be sampled); always on turn failure | ` $ai_trace_id ` , ` $ai_provider ` , ` $ai_model ` , ` $ai_input_tokens ` , ` $ai_output_tokens ` , ` $ai_latency ` , ` $ai_is_error ` , ` $ai_error ` , ` $ai_cache_read_input_tokens ` , ` $ai_cache_creation_input_tokens ` , ` $ai_reasoning_tokens ` , ` tool_call_count ` , ` tool_error_count ` , ` subagent_call_count ` |
19+ | ` $ai_span ` | Opt-in only — once per top-level tool call when ` CORBITS_TELEMETRY_AI_SPANS ` is set | ` $ai_trace_id ` , ` $ai_span_id ` , ` $ai_parent_id ` , ` $ai_span_name ` , ` $ai_is_error ` |
2020| ` slash_command ` | A slash command is dispatched (shared product-event path) | ` command_name ` |
2121| ` skill_used ` | ` use_skill ` loads a skill that resolved | (none beyond common properties) |
22- | ` plugin_loaded ` | A plugin is discovered and loaded at startup | ` origin ` |
23- | ` subagent_start ` | A ` task ` dispatch begins | ` agent_name ` |
24- | ` subagent_end ` | A ` task ` dispatch finishes | ` agent_name ` , ` status ` , ` duration_ms ` |
22+ | ` plugin_loaded ` | First successful load of a plugin identity in this process | ` origin ` |
23+ | ` subagent_start ` | A ` task ` / fleet dispatch begins | ` agent_name ` |
24+ | ` subagent_end ` | A ` task ` / fleet dispatch finishes | ` agent_name ` , ` status ` , ` duration_ms ` , ` model ` , ` turn_count ` , ` input_tokens ` , ` output_tokens ` , ` cache_read_tokens ` , ` cache_write_tokens ` , ` reasoning_tokens ` , ` tool_call_count ` , ` tool_error_count ` , ` stop_reason ` , ` parent_trace_id ` |
2525| ` permission_prompt ` | An approval prompt is answered (or abandoned) | ` decision ` , ` permission_kind ` |
2626| ` compaction ` | The compactor actually folds turns away | ` mode ` , ` duration_ms ` , ` turns_before ` , ` turns_after ` |
2727| ` crash ` | A fatal error reaches the process-level handler | ` kind ` , ` error_class ` |
@@ -36,7 +36,11 @@ Common properties attached to every event: a random installation UUID
3636(` distinct_id ` ), ` session_id ` , ` $app_version ` (PostHog's standard Version
3737property, the running package version), ` service_version ` (same value, kept
3838for existing custom-property dashboards), ` os_type ` , ` os_arch ` , and a
39- ` schema_version ` for forward compatibility.
39+ ` schema_version ` for forward compatibility. Ambient product and AI events also
40+ carry ` $process_person_profile: false ` so PostHog treats them as anonymous
41+ (batch capture otherwise defaults to identified processing). Intentional
42+ ` survey sent ` omits that flag so ` /feedback ` can still join a person profile
43+ if one is ever created.
4044
4145Approximate country-level location is derived server-side by PostHog from the
4246request IP; no location data is collected by the client.
@@ -62,10 +66,14 @@ So none of them are transmitted. Each is matched against a fixed list of names
6266this project itself ships and reported as that name, or as ` custom ` when it
6367matches nothing — with ` mcp ` as its own bucket for ` permission_kind ` , so the
6468share of prompts driven by MCP stays visible without the server key coming
65- with it. ` skill_used ` and ` plugin_loaded ` go further: there is no first-party
66- list of skills or plugins to match against, so ` skill_used ` carries no name at
67- all and ` plugin_loaded ` carries only ` origin ` , the discovery tier
68- (` repo ` , ` user ` , ` project ` , ` path ` ).
69+ with it. ` agent_name ` on ` subagent_* ` is the same pattern: first-party
70+ director ids from ` DIRECTOR_IDS ` (and the legacy ` worker ` alias) are reported
71+ by id; project-defined or marketplace profile ids become ` custom ` .
72+ ` skill_used ` and ` plugin_loaded ` go further: there is no first-party list of
73+ skills or plugins to match against, so ` skill_used ` carries no name at all and
74+ ` plugin_loaded ` carries only ` origin ` , the discovery tier (` repo ` , ` user ` ,
75+ ` project ` , ` path ` ). The same plugin identity is emitted at most once per
76+ process — later rediscoveries or reloads are silent.
6977
7078` error_class ` is bucketed the same way: only the error types defined by the
7179language are reported by name, because an error subclass defined in
@@ -84,21 +92,34 @@ the payload are in `tests/unit/telemetry-product-events.test.ts`.
8492
8593## AI observability events
8694
87- ` $ai_generation ` and ` $ai_span ` are the two PostHog AI observability events,
88- emitted from ` src/telemetry/ai-observability.ts ` . PostHog's LLM analytics
89- views query the ` $ai_ ` -prefixed properties and nothing else, which is why
90- these names are not ours to choose. ` $ai_latency ` is a duration in ** seconds**
91- as a float, per PostHog's schema — the runtime measures milliseconds and
92- converts.
95+ ` $ai_generation ` and (optionally) ` $ai_span ` are the PostHog AI observability
96+ events, emitted from ` src/telemetry/ai-observability.ts ` . PostHog's LLM
97+ analytics views query the ` $ai_ ` -prefixed properties and nothing else, which
98+ is why these names are not ours to choose. ` $ai_latency ` is a duration in
99+ ** seconds** as a float, per PostHog's schema — the runtime measures
100+ milliseconds and converts.
101+
102+ ** Default volume shape (CL-6816):** each completed primary turn emits ** one**
103+ ` $ai_generation ` with tool/subagent aggregates folded onto it
104+ (` tool_call_count ` , ` tool_error_count ` , ` subagent_call_count ` ). Per-call
105+ ` $ai_span ` events are ** off by default** . Set ` CORBITS_TELEMETRY_AI_SPANS ` to
106+ a truthy value (` 1 ` , ` true ` , …) to restore per-call spans for debugging.
107+ Leaf ` runSubAgent ` workers do not emit ` $ai_* ` ; worker rollups travel on
108+ ` subagent_end ` instead.
109+
110+ Successful ` $ai_generation ` events may be sampled with
111+ ` CORBITS_TELEMETRY_GENERATION_SAMPLE_RATE ` (a float in ` 0 ` –` 1 ` , default ` 1.0 `
112+ = keep all). Errored generations (` $ai_is_error: true ` ), ` crash ` , and
113+ ` auth_failure ` always ship regardless of the sample rate.
93114
94115The trace is ** flat** . Every turn gets one ` $ai_trace_id ` derived from the
95116runtime's session id and the turn index; the turn's ` $ai_generation ` and each
96- of its ` $ai_span ` s carry it, and every span's ` $ai_parent_id ` is that same
97- trace id rather than another span. PostHog documents ` $ai_parent_id ` as
98- accepting either a trace id or a span id, so this is a legal trace, and it is
99- all the runtime can honestly describe: the turn record only exposes top-level
100- tool calls. No ` $ai_trace ` event is emitted — PostHog synthesises the trace
101- from its children.
117+ of its ` $ai_span ` s (when spans are enabled) carry it, and every span's
118+ ` $ai_parent_id ` is that same trace id rather than another span. PostHog
119+ documents ` $ai_parent_id ` as accepting either a trace id or a span id, so
120+ this is a legal trace, and it is all the runtime can honestly describe: the
121+ turn record only exposes top-level tool calls. No ` $ai_trace ` event is
122+ emitted — PostHog synthesises the trace from its children.
102123
103124` $ai_span_id ` is the provider-generated opaque tool call id. It identifies
104125the call within the trace and carries nothing else.
@@ -124,11 +145,11 @@ apart by `$ai_error`. A turn that never reaches inference at all — suspended
124145at an approval prompt and never resumed — emits nothing, because the runtime
125146raises no event for it.
126147
127- Exactly one ` $ai_generation ` is ever emitted per turn. A single give-up
128- usually surfaces twice at the event stream (the failed inference, then the
129- reactor terminating), and a turn that already reported completion is finished;
130- ` src/session/run-sink.ts ` latches on both so neither can double-count a turn
131- or append a phantom failure to a successful one.
148+ Exactly one ` $ai_generation ` is ever emitted per turn (when sampling keeps
149+ it). A single give-up usually surfaces twice at the event stream (the failed
150+ inference, then the reactor terminating), and a turn that already reported
151+ completion is finished; ` src/session/run-sink.ts ` latches on both so neither
152+ can double-count a turn or append a phantom failure to a successful one.
132153
133154## What's never collected
134155
@@ -159,6 +180,8 @@ is off (`settings.telemetry.enabled === false` or the Telemetry toggle Off),
159180because the operator typed the text for that purpose. Hard env kill switches
160181still win — ` DO_NOT_TRACK=1 ` or ` CORBITS_TELEMETRY=0/false/off/no ` block
161182` /feedback ` as well. Sending also requires an installation id and API key.
183+ Unlike ambient events, ` survey sent ` does not stamp `$process_person_profile:
184+ false`, so the response can join a person profile if one is ever created.
162185
163186Survey id / question id are ** baked into the client** (Corbits team survey
164187` Corbits Code Feedback ` ). Same trust class as the public PostHog project key —
0 commit comments