Repository navigation
feat(flags): accept a caller default in FeatureFlagEvaluations.IsEnabled - #344
Conversation
Adds an `IsEnabled(string key, bool defaultValue)` overload that returns the caller-supplied default when the flag has no value in the snapshot, while a flag that has a value — including `false` — still wins over the default. The existing single-argument overload delegates with `defaultValue: false`, so its behavior is unchanged. Co-Authored-By: Claude Opus 5 <[email protected]> Generated-By: PostHog Desktop Task-Id: bcbae7c3-319c-4322-aacc-a2838b43287d
posthog-dotnet Compliance ReportDate: 2026-10-11T06:09:28.797632+00:00 ✅ All Tests Passed!47/47 tests passed Capture Tests✅ 30/30 tests passed View Details
Feature_Flags Tests✅ 17/17 tests passed View Details
|
Checked the miss paths (unknown key, a failed One small thing for whoever touches this file next: the |
💡 Motivation and Context
Contract:
is-feature-enabled— "Canonical is-feature-enabled behavior".The posthog-dotnet compliance matrix records this as ❌ Fail (note
n20):Other SDKs already have this: posthog-ruby (#285), posthog-js/node (#4484), posthog-go (#349).
🔨 What changed
FeatureFlagEvaluations.IsEnabled(string key, bool defaultValue). It still records snapshot access and fires$feature_flag_calledexactly as before, then returnsrecord is null ? defaultValue : record.Enabled.IsEnabled(string key)now delegates withdefaultValue: false, so a present-but-disabled flag returnsfalseand a missing flag returnsfalse— byte-for-byte the old behavior.Why this is backwards-compatible
It is purely additive via C# overloading. No existing signature, return type, or value changes: the one-argument overload's observable behavior is identical, and the new overload only exists once a caller opts in by passing a default. The
PublicAPI.Unshipped.txtdiff is a single added line.💚 How did you test it?
TheSnapshotAccessMethodsintests/UnitTests/Features/FeatureFlagEvaluationsTests.cs, mirroring the spec's scenarios: a missing flag resolves to the caller default (falseandtrue), and a presentfalse/variant-aflag wins over an opposing default.UnknownKeyReturnsFalsyValuetest continues to pin the no-default behavior.dotnet test tests/UnitTests/UnitTests.csproj— 1239 passed / 0 failed onnet8.0, 1229 passed / 0 failed onnetcoreapp3.1.minorchangeset forPostHog.📝 Checklist
If releasing new changes
pnpm changesetto generate a changeset file👣 Follow-up work (not in this PR)
Compliance note
n20also flags thatIsFeatureEnabledAsync(featureKey, distinctId, options)has nodefaultValueon its options object, and that an XML doc on abool?-returning extension overload claimsnull-on-miss semantics it does not implement. Both were left out to keep this change to the single canonical surface; they are worth a separate pass.🤖 Agent context
Autonomy: Fully autonomous
Opened by a scheduled PostHog agent run that reads the
PostHog/sdk-specscompliance matrices and implements one backwards-compatible gap per run. This gap was picked over the other open posthog-dotnet gaps because it is a hardSHALLon a widely-used, user-facing flag API, the remediation is concrete and self-contained, and the fix is additive. Candidates in other SDKs for the same contract were skipped as already merged or in flight. Verified locally with the repo's unit test suite; no manual/integration testing was performed.Created with PostHog Desktop
🤖 Generated with Claude Code