Phase 4 locks Rulestead telemetry as a versioned public API. The event names in this guide are additive-only for the rest of v0.1.x.

Principles

  • All events live under [:rulestead, ...].
  • The shared metadata spine is bounded and redacted at emission time.
  • Runtime evaluation stays DB-free on the hot path once a snapshot is applied.
  • Handler failures must not crash the instrumented operation when attached through Rulestead.Telemetry.attach_many/4.

Event Catalog

Evaluation

  • [:rulestead, :eval, :decide, :start]
  • [:rulestead, :eval, :decide, :stop]
  • [:rulestead, :eval, :decide, :exception]

Emitted by the pure evaluator surface in Rulestead.evaluate/3 and the keyed runtime evaluation surface.

Runtime Cache

  • [:rulestead, :runtime, :cache, :hit]
  • [:rulestead, :runtime, :cache, :miss]
  • [:rulestead, :runtime, :cache, :refresh]
  • [:rulestead, :runtime, :cache, :stale_used]

cache:hit and cache:miss describe ETS lookup outcomes. cache:refresh marks refresh loop fetch/apply work. cache:stale_used is emitted when the runtime serves a last-known-good snapshot while refresh status is stale.

Runtime Snapshots

  • [:rulestead, :runtime, :snapshot, :published]
  • [:rulestead, :runtime, :snapshot, :applied]

snapshot:published is emitted when a store write publishes a new runtime snapshot version. snapshot:applied is emitted when a node applies that snapshot into ETS.

Store Boundaries

  • [:rulestead, :store, :read, :start]
  • [:rulestead, :store, :read, :stop]
  • [:rulestead, :store, :read, :exception]
  • [:rulestead, :store, :write, :start]
  • [:rulestead, :store, :write, :stop]
  • [:rulestead, :store, :write, :exception]

These cover the public store facade plus the runtime refresh store fetch boundary.

Admin-Coarse Mutations

  • [:rulestead, :admin, :mutation, :start]
  • [:rulestead, :admin, :mutation, :stop]

These wrap the current Phase 4 public mutation verbs: save draft, publish ruleset, and archive flag.

Shared Metadata Spine

Handlers must tolerate missing optional keys and additive future keys. The stable shared metadata keys are:

  • :flag_key
  • :flag_type
  • :environment
  • :snapshot_version
  • :cache_age_ms
  • :reason
  • :has_targeting_key?
  • :matched_rule_count

Domain-specific additions remain bounded. Today that includes keys like :operation, :source, :refresh_status, and :audit_action.

Redaction Rules

Telemetry metadata never includes:

  • Raw attributes
  • Raw resolved flag values
  • Actor payloads
  • Plug/Phoenix/Oban structs
  • Secrets or arbitrary payload blobs

If a handler needs more context, derive it from the stable metadata or look it up in your own system of record.

Safe Handlers

Use Rulestead.Telemetry.attach_many/4 to isolate handler failures from the runtime, store, and admin operations they observe.

Rulestead.Telemetry.attach_many(
  "my-rulestead-handlers",
  [
    [:rulestead, :eval, :decide, :stop],
    [:rulestead, :runtime, :cache, :stale_used]
  ],
  fn event, measurements, metadata, _config ->
    IO.inspect({event, measurements, metadata}, label: "rulestead")
  end,
  nil
)

Direct :telemetry.attach/4 handlers still follow normal Telemetry semantics. If you want handler isolation, use the Rulestead wrapper.