Skip to content

feat: add evaluate_flags() API for single-call flag evaluation#137

Open
dmarticus wants to merge 1 commit intomainfrom
posthog-code/ruby-evaluate-flags-api
Open

feat: add evaluate_flags() API for single-call flag evaluation#137
dmarticus wants to merge 1 commit intomainfrom
posthog-code/ruby-evaluate-flags-api

Conversation

@dmarticus
Copy link
Copy Markdown
Contributor

@dmarticus dmarticus commented Apr 27, 2026

Summary

  • Adds Client#evaluate_flags(distinct_id, …) returning a FeatureFlagEvaluations snapshot — one /flags round-trip powers both branching and event enrichment.
  • Snapshot exposes is_enabled / get_flag / get_flag_payload for branching, plus only_accessed / only([keys]) to narrow what gets attached to a captured event.
  • Adds flags: option on capture — when present, attaches $feature/<key> and $active_feature_flags from the snapshot without any extra /flags call.
  • flag_keys: on evaluate_flags scopes the underlying /flags request itself (sent as flag_keys_to_evaluate).
  • Existing is_feature_enabled, get_feature_flag, get_feature_flag_result, get_feature_flag_payload, and capture(send_feature_flags:) remain unchanged.

References

RFC: https://github.com/PostHog/requests-for-comments-internal/pull/1020 · mirrors posthog-python#539 and posthog-js#3476.

Design decisions

  • is_enabled returns false for unknown flags, get_flag returns nil — matches the legacy single-flag methods so existing branching code is structurally interchangeable.
  • get_flag_payload deliberately does not record access or fire $feature_flag_called — payload-only reads shouldn't count as an exposure.
  • only_accessed() falls back to all flags with a warning when nothing has been accessed; silently dropping every flag from the captured event would be an easy footgun.
  • Filtered snapshot clones get a copy of the parent's accessed set, so calls on a clone don't back-propagate exposures into the parent.
  • A small Host struct (two lambdas: capture_flag_called_event_if_needed, log_warning) is passed to the snapshot instead of a back-reference to the full Client — keeps the snapshot decoupled and testable.
  • Locally-evaluated flags are tagged with locally_evaluated: true, reason "Evaluated locally", and $feature_flag_definitions_loaded_at on emitted events, matching the existing single-flag local path.

Phase 2 follow-ups (out of scope here)

  • Runtime deprecation warnings on is_feature_enabled, get_feature_flag, get_feature_flag_payload, and capture(send_feature_flags:).
  • Equivalent migration guidance in the README / docs.

Created with PostHog Code

Add Client#evaluate_flags(distinct_id, ...) returning a
FeatureFlagEvaluations snapshot, and a flags: option on capture so
a single /flags call can power both flag branching and event
enrichment per request.

The snapshot exposes is_enabled, get_flag, get_flag_payload, plus
only_accessed / only([keys]) filter helpers. flag_keys: scopes the
underlying /flags request itself. is_enabled and get_flag fire
$feature_flag_called events with full metadata (id, version, reason,
request_id), deduped through the existing per-distinct_id cache.
get_flag_payload does not record access or fire an event.

The dedup + capture in get_feature_flag_result is extracted into
_capture_feature_flag_called_if_needed and shared between the existing
path and the snapshot's access-recording.

Existing is_feature_enabled, get_feature_flag, get_feature_flag_result,
get_feature_flag_payload, and capture(send_feature_flags:) continue
to work unchanged.

Generated-By: PostHog Code
Task-Id: fe67a5bd-7d33-4568-9148-39d181660a5a
@dmarticus dmarticus marked this pull request as ready for review April 27, 2026 22:11
@dmarticus dmarticus requested a review from a team as a code owner April 27, 2026 22:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant