@@ -92,7 +92,8 @@ func evaluateAllocation(allocation *allocation, context map[string]any, currentT
9292 }
9393
9494 // Check if any rule matches (OR logic between rules)
95- ruleMatched := false
95+ // If there are no rules, the allocation matches everyone
96+ ruleMatched := len (allocation .Rules ) == 0
9697 for _ , rule := range allocation .Rules {
9798 if evaluateRule (rule , context ) {
9899 ruleMatched = true
@@ -128,6 +129,14 @@ func evaluateRule(rule *rule, context map[string]any) bool {
128129func evaluateCondition (condition * condition , context map [string ]any ) bool {
129130 attributeValue , exists := context [condition .Attribute ]
130131
132+ // Special handling for "id" attribute: if not explicitly provided, use targeting key
133+ if condition .Attribute == "id" && ! exists {
134+ if targetingKey , ok := context [of .TargetingKey ].(string ); ok {
135+ attributeValue = targetingKey
136+ exists = true
137+ }
138+ }
139+
131140 // Special handling for IS_NULL operator
132141 if condition .Operator == operatorIsNull {
133142 isNull := ! exists || attributeValue == nil
@@ -339,7 +348,7 @@ func evaluateShard(shard *shard, context map[string]any) bool {
339348// computeShardIndex computes the shard index using MD5 hash.
340349// This matches the Eppo SDK implementation for consistent behavior.
341350func computeShardIndex (salt , targetingKey string , totalShards int ) int {
342- input := salt + targetingKey
351+ input := salt + "-" + targetingKey
343352 hash := md5 .Sum ([]byte (input ))
344353 // Use first 4 bytes of MD5 hash as uint32
345354 intVal := binary .BigEndian .Uint32 (hash [:4 ])
0 commit comments