[AI-FSSDK] [FSSDK-12760] add localHoldouts to datafile for backward compatibility#453
Open
jaeopt wants to merge 3 commits into
Open
[AI-FSSDK] [FSSDK-12760] add localHoldouts to datafile for backward compatibility#453jaeopt wants to merge 3 commits into
jaeopt wants to merge 3 commits into
Conversation
- Log a warning when the same holdout ID appears in both datafile sections (the later entry overwrites the earlier one in the ID map) - Downgrade missing-includedRules log from Error to Warning — this is a data quality issue, not a runtime failure - Replace brittle TestMapHoldoutsErrorMessageWording (asserted on specific words) with TestMapHoldoutsDuplicateIDsAcrossSectionsLogsWarning Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.
Summary
Partitions holdouts into two top-level datafile sections so Gen 3 local holdouts ship safely alongside Gen 1/Gen 2 SDKs that would otherwise misapply them as global:
holdouts— global only; anyincludedRulesfield on these entries is stripped during parsing so section membership is the sole signal for scope.localHoldouts— new top-level section; rule-scoped holdouts that carry their realtrafficAllocation. Entries withoutincludedRulesare logged via the SDK logger and excluded from evaluation (never promoted to global).Older SDK versions in production ignore the unknown
localHoldoutskey entirely, so a single datafile artifact can serve every SDK generation.Changes
pkg/config/datafileprojectconfig/entities/entities.go— addLocalHoldouts []Holdoutto theDatafilestruct; tighten theHoldout.IncludedRulesdoc to reflect section-based scope.pkg/config/datafileprojectconfig/mappers/holdout.go— changeMapHoldoutsto take both sections plus anOptimizelyLogProducer; stripIncludedRuleson global-section entries; reject (log + skip) local-section entries with nilIncludedRules; nil-logger safe.pkg/config/datafileprojectconfig/config.go— wiredatafile.LocalHoldoutsand the logger intoMapHoldouts; tighten docstrings onGetGlobalHoldouts/GetHoldoutsForRuleand the internal field comments.pkg/entities/experiment.go— tighten theHoldout.IncludedRulesandIsGlobal()docstrings to note thatDatafileProjectConfigstripsIncludedRuleson global-section entries at parse time.pkg/config/datafileprojectconfig/mappers/holdout_test.go— refactor existing tests for the new signature and add 12 new tests covering the partitioned behavior, invalid local entries (logged and excluded),includedRulesstripping on global entries, mixed sections, backward compat, and a nil-logger guard.pkg/config/datafileprojectconfig/config_test.go— add 3 end-to-end JSON datafile tests (partitioning, backward compat withoutlocalHoldouts, strippingincludedRuleson global entries).Behavior
localHoldoutskey is ignored; onlyholdouts(global) is parsed and applied. No misapplication, no errors, no log noise.holdouts→ global (every entry,IncludedRulesstripped);localHoldouts→ local (rule-scoped viaIncludedRules).Test Plan
go build ./...— passesgo vet ./...— passesgo test ./...) — all packages pass, no regressionsReference Implementations
This change ports the FSSDK-12760 backward-compat partition that already shipped in:
The Go implementation follows Python's semantics on the corner case of an empty
includedRulesslice in thelocalHoldoutssection (valid local holdout that targets no rules, not an error), matching the priorIsGlobal()contract added in FSSDK-12369.Jira
FSSDK-12760