Raxol.Telemetry (Raxol v2.8.0)

View Source

The registry of every :telemetry event the main raxol project emits, each classified as exactly one of :invariant, :peer or :operational.

Why this exists

A telemetry event is only a guard if something fails when it fires. The sibling raxol_agent_client_protocol package proved the negative case: it both logged a warning AND emitted an event when a turn completed with no output, and the defect shipped anyway, because no test asserted on the event (and, worse, the emit site was guarded by a Code.ensure_loaded? that was permanently false). The classification below is what converts "the system noticed" into "the suite fails":

  • :invariant -- can only fire if RAXOL ITSELF is wrong. Enforced: Raxol.Core.Telemetry.InvariantSentinel fails any test in which one fires unless the test declares it with @tag expect_invariant:.
  • :peer -- caused by a remote party misbehaving: a malformed or out-of-order inbound agent-stream event, wrong-shaped content from a producer we do not control. Expected in negative tests, so not enforced.
  • :operational -- normal life: startup timing, supervisor recovery, load shedding, cache bookkeeping, the terminal device or filesystem refusing something, and user/app-supplied styles, themes and props being invalid. Not enforced.

The criterion, applied literally

If a peer, the network, the filesystem, the clock, the terminal, or a user can cause it, it is NOT an invariant. Err toward :peer/:operational: a false invariant makes the suite flaky, and a flaky guard gets deleted, which is strictly worse than a missed one.

That criterion is why the two most invariant-SOUNDING events here are not invariants. [:raxol, :ui, :prominence, :floor_unreachable] fires when a contrast floor cannot be met by the full-strength seed color -- but both the floor and the seed come from a caller-supplied %ColorIntent{}, so it reports a palette-design gap in USER data (color_resolver_test.exs drives it on purpose with tier: :recede against a dark ground). [:raxol, :layout, :invalid_style] fires on overflow: :bogus or flex_grow: -1 -- values that arrive from an app's style map.

Events built at runtime

Three families compute their last segment at runtime, so a source scan cannot spell them and the sentinel could not subscribe to them; they are declared as dynamic: families and may not be :invariant (the kit enforces that at compile time).

Not this project's events

[:raxol, :runtime, :backpressure] appears in Raxol.UI.Rendering.RenderBatcher's moduledoc but is emitted by Raxol.Core.Runtime.Backpressure in packages/raxol_core, so it is that package's event to classify. Raxol.Performance.AdaptiveOptimizer and DevHints name a dozen more [:raxol, ...] events in their :telemetry.attach/4 / attach_many/4 SUBSCRIPTION lists (terminal parse/render, cache hit/miss). A subscription is not an emit site, and Raxol.Core.Telemetry.Invariants.scan_lib!/1 only reports first-argument literals of :telemetry.execute/span, so neither kind is mistaken for ours.

Completeness is asserted, not trusted

test/raxol/telemetry_registry_test.exs scans this project's lib/ for emit sites and fails if any of them is missing from events/0. A new event cannot be added without someone classifying it.

Summary

Functions

The classification of event: an exact registry hit, else the longest matching dynamic family, else nil for an event this package does not declare.

Event families whose final segment is computed at runtime, sorted. A source scan cannot enumerate their full names, so a completeness test must not demand them as static keys.

Every static telemetry event this package emits, mapped to its classification.

The :invariant subset of events/0, sorted. These are the events Raxol.Core.Telemetry.InvariantSentinel arms.

Functions

classification(event)

The classification of event: an exact registry hit, else the longest matching dynamic family, else nil for an event this package does not declare.

dynamic_families()

@spec dynamic_families() :: [Raxol.Core.Telemetry.Invariants.event()]

Event families whose final segment is computed at runtime, sorted. A source scan cannot enumerate their full names, so a completeness test must not demand them as static keys.

events()

Every static telemetry event this package emits, mapped to its classification.

invariant_events()

@spec invariant_events() :: [Raxol.Core.Telemetry.Invariants.event()]

The :invariant subset of events/0, sorted. These are the events Raxol.Core.Telemetry.InvariantSentinel arms.