feat(flags): minimize $feature_flag_called events for non-experiment flags#220
Open
haacked wants to merge 3 commits into
Open
feat(flags): minimize $feature_flag_called events for non-experiment flags#220haacked wants to merge 3 commits into
haacked wants to merge 3 commits into
Conversation
posthog-ruby Compliance ReportDate: 2026-07-18 05:22:04 UTC ✅ All Tests Passed!46/46 tests passed Capture Tests✅ 29/29 tests passed View Details
Feature_Flags Tests✅ 17/17 tests passed View Details
|
Emit a slim $feature_flag_called event when the server enables the minimal_flag_called_events gate and the evaluated flag has no linked experiment. Minimal events keep a strict allowlist of flag-evaluation properties and strip everything else, including context properties, $feature/<key>, payloads, and system metadata. The gate is read from the top-level minimalFlagCalledEvents field of the v2 /flags response and the top-level minimal_flag_called_events key of the local evaluation definitions payload, and is persisted through the flag definition cache provider. Any missing signal fails safe to the full event. Generated-By: PostHog Code Task-Id: ffe402fd-d75c-4043-8e5d-d2fe513cac6f
haacked
force-pushed
the
haacked/minimal-flag-called-events
branch
from
July 18, 2026 01:01
8881c0a to
6966273
Compare
Add a regression test for the mixed-snapshot case where the local poller's gate is true but the remote /flags response omits the field, the same bug class that shipped twice in the Python port of this feature. Add a missing 304-persistence test for the gate, dedupe a duplicated test helper, and document cache-provider backward compatibility.
haacked
marked this pull request as ready for review
July 18, 2026 05:22
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
💡 Motivation and Context
$feature_flag_calledevents carry the full enriched properties dict (rails request context, super/context properties, custom event properties) on every flag call, even for flags not linked to an experiment. This PR trims those events to a strict allowlist iff the server-controlled gate is on (minimalFlagCalledEventsin the v2/flagsresponse, or top-levelminimal_flag_called_eventsin the local-evaluation flag definitions payload) and the evaluated flag'shas_experimentis exactlyfalse. Any missing signal (gate absent,has_experimentunknown, legacy response shape, request failure) sends the full legacy shape unchanged.Server-gated because rolling this out unconditionally could break existing insights; announcement/comms come before enablement. The goal is to establish
$feature_flag_calledas a special system event.Implementation notes:
Client#captureafter context merge andFieldParserassembly, so context properties and parser-added metadata can never leak in. Kept:$feature_flag,$feature_flag_response,$feature_flag_has_experiment,$feature_flag_id,$feature_flag_version,$feature_flag_reason,$feature_flag_request_id,$feature_flag_evaluated_at,$feature_flag_error,locally_evaluated,$groups,$process_person_profile,$session_id,$is_server,$lib,$lib_version(string and symbol forms).flag_definition_cache_providerimplementations so it survives restarts in multi-worker setups./flagsresponse. For mixed snapshots (evaluate_flags), the team-level response gate supersedes the poller gate; a response without the gate fails the whole snapshot safe to full events.$feature_flag_calledemit paths are covered: the legacy single-flag path (get_feature_flag_resultand friends) and the snapshot path (evaluate_flags/FeatureFlagEvaluations).Part of a cross-SDK rollout; reference implementation and fuller context: PostHog/posthog-python#748
💚 How did you test it?
bundle exec rspec— 630 examples, 0 failuresbundle exec rubocop— 82 files inspected, no offensesbundle exec rake public_api:check— passing (no public API surface changes)Coverage added:
/flagsresponse), across both emit paths: gated + no experiment → minimal; gated + experiment → full; gate missing /has_experimentmissing → full.$session_idand$is_serverretention and stripping of context properties,$feature/<key>, and payload props._minimal_flag_called_eventkey insidecaptureproperties cannot trigger minimization.Released as a
minorchangeset forposthog-ruby.📝 Checklist
If releasing new changes
pnpm changesetto generate a changeset fileCreated with PostHog Code