Rulestead.Context (rulestead v1.0.0)

Copy Markdown View Source

Explicit evaluation context: who is asking, in which environment, and with what attributes.

Rulestead.Context is the second argument to every evaluation call. It is a plain struct you build once per request (or once per job) and pass into Rulestead.evaluate/3, Rulestead.Runtime.enabled?/3, and the other evaluation functions. Evaluation never reads ambient process state — context is always explicit, which is what makes a decision reproducible and explainable.

Building a context

iex> ctx =
...>   Rulestead.Context.new(
...>     environment: "production",
...>     targeting_key: "user-123",
...>     attributes: %{plan: :pro}
...>   )
iex> ctx.targeting_key
"user-123"

The :targeting_key is the stable identity used for deterministic, sticky bucketing — pass the same key and a flag resolves the same way every time. :attributes carry the traits your ordered rules match on.

Stable fields

See API Stability for the frozen field list. The supported fields are :actor, :targeting_key, :tenant_key, :environment, :attributes, :request_id, :session_id, and :strict?.

Summary

Functions

Builds a %Rulestead.Context{} from a keyword list, a map, or an existing context struct.

Normalizes a keyword list, map, or existing %Rulestead.Context{} into a fully-normalized struct.

Types

actor()

@type actor() :: map() | struct() | nil

t()

@type t() :: %Rulestead.Context{
  actor: actor(),
  attributes: map(),
  environment: String.t() | nil,
  request_id: String.t() | nil,
  session_id: String.t() | nil,
  strict?: boolean(),
  targeting_key: String.t() | nil,
  tenant_key: String.t() | nil
}

Functions

new(context)

@spec new(t() | keyword() | map()) :: t()

Builds a %Rulestead.Context{} from a keyword list, a map, or an existing context struct.

Accepts the following input shapes:

  • keyword() — e.g. [environment: "production", targeting_key: "u1"]
  • map() — e.g. %{environment: "production", targeting_key: "u1"}
  • %Rulestead.Context{} — idempotent; re-normalizes the struct

Normalizes legacy key aliases on the way in: :subject is promoted to :actor, and :traits is merged into :attributes (explicit :attributes wins on key conflicts).

When :targeting_key is not supplied, it defaults to the :key or :id field of the :actor map or struct, if present.

Returns a fully-normalized %Rulestead.Context{}.

normalize(context)

@spec normalize(t() | keyword() | map()) :: t()

Normalizes a keyword list, map, or existing %Rulestead.Context{} into a fully-normalized struct.

Accepts the same input union as new/1. Ensures:

  • All scalar fields (:targeting_key, :tenant_key, :environment, :request_id, :session_id) are strings or nil
  • :actor is a map or struct, or nil
  • :attributes is a map
  • :strict? is a boolean

This function is idempotent: calling it on an already-normalized %Rulestead.Context{} returns an equivalent struct.