{"abstract":"A rule for emails starting with \"ann\" also captures \"Ann@...\" addresses.","category":"Feature flag rollout bucketing","checks":8,"contract":"An off flag serves its off variation (reason OFF). Otherwise individual targets (checked by sorted variation name) win with reason TARGET, then rules in order, then the fallthrough. A rule matches only when the user has its attribute: op in = membership, startsWith = case-sensitive string prefix, lt = numeric less-than any value; negate inverts a present attribute result. Return [variation, reason, zero-based rule index or -1].","contract_signature":"flag, user","evaluation_group":"w2-feature-flag-rollout-bucketing-targeting-precedence","failed_approach":"Swapping the operands tests whether the clause value starts with the attribute instead.","family":"w2-feature-flag-rollout-bucketing-targeting-precedence-prefix-case","id":"FA-73911","implementations":{"attempt":{"sha256":"4f08898ed5a420d873b7039e57a8b92e574658c07276cc63fe5bfe56ca1783c6","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(flag, user):\n    if not flag.get('on'):\n        return [flag.get('off'), 'OFF', -1]\n    key = user.get('key')\n    for variation in sorted(flag.get('targets', {})):\n        if key in flag['targets'][variation]:\n            return [variation, 'TARGET', -1]\n    for index, rule in enumerate(flag.get('rules', [])):\n        if rule['attr'] not in user:\n            continue\n        value = user[rule['attr']]\n        if rule['op'] == 'in':\n            hit = value in rule['values']\n        elif rule['op'] == 'startsWith':\n            hit = isinstance(value, str) and any(v.startswith(value) for v in rule['values'])\n        else:\n            hit = isinstance(value, (int, float)) and not isinstance(value, bool) and any(value < v for v in rule['values'])\n        if rule.get('negate'):\n            hit = not hit\n        if hit:\n            return [rule['variation'], 'RULE', index]\n    return [flag.get('fallthrough'), 'FALLTHROUGH', -1]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('individual target beats a matching rule',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {'v1': ['k1']},\n     'rules': [{'attr': 'country', 'op': 'in', 'values': ['US'], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k1', 'country': 'US'}],\n   ['v1', 'TARGET', -1]),\n  ('negated rule does not match a missing attribute',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v3',\n     'targets': {},\n     'rules': [{'attr': 'plan', 'op': 'in', 'values': ['pro'], 'negate': True, 'variation': 'v2'}]},\n    {'key': 'k2'}],\n   ['v3', 'FALLTHROUGH', -1]),\n  ('off flag serves off variation',\n   [{'on': False, 'off': 'v1', 'fallthrough': 'v2', 'targets': {}, 'rules': []}, {'key': 'k1'}],\n   ['v1', 'OFF', -1]),\n  ('second rule reports index one',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'country', 'op': 'in', 'values': ['FR'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'country', 'op': 'in', 'values': ['DE'], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k3', 'country': 'DE'}],\n   ['v2', 'RULE', 1]),\n  ('prefix match is case sensitive',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'email', 'op': 'startsWith', 'values': ['ann'], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k4', 'email': 'Ann@x.io'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('prefix operand order matters',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['annie@corp'],\n                'negate': False,\n                'variation': 'v1'}]},\n    {'key': 'k2', 'email': 'annie'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('targeting sample 1',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {'v1': []},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['a', 'Ann'],\n                'negate': False,\n                'variation': 'v2'},\n               {'attr': 'age', 'op': 'lt', 'values': [21, 18], 'negate': False, 'variation': 'v0'},\n               {'attr': 'age', 'op': 'lt', 'values': [18, 30], 'negate': True, 'variation': 'v2'},\n               {'attr': 'email',\n                'op': 'startsWith',\n                'values': ['a', 'Ann'],\n                'negate': False,\n                'variation': 'v2'}]},\n    {'key': 'k2', 'country': 'DE', 'age': 20, 'plan': 'team'}],\n   ['v0', 'RULE', 1]),\n  ('targeting sample 2',\n   [{'on': True, 'off': 'v1', 'fallthrough': 'v0', 'targets': {'v2': []}, 'rules': []},\n    {'key': 'k6', 'age': 40, 'plan': 'pro'}],\n   ['v0', 'FALLTHROUGH', -1])],\n [('negated rule does not match a missing attribute',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v3',\n     'targets': {},\n     'rules': [{'attr': 'plan', 'op': 'in', 'values': ['pro'], 'negate': True, 'variation': 'v2'}]},\n    {'key': 'k2'}],\n   ['v3', 'FALLTHROUGH', -1]),\n  ('off flag serves off variation',\n   [{'on': False, 'off': 'v1', 'fallthrough': 'v2', 'targets': {}, 'rules': []}, {'key': 'k1'}],\n   ['v1', 'OFF', -1]),\n  ('second rule reports index one',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'country', 'op': 'in', 'values': ['FR'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'country', 'op': 'in', 'values': ['DE'], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k3', 'country': 'DE'}],\n   ['v2', 'RULE', 1]),\n  ('prefix match is case sensitive',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'email', 'op': 'startsWith', 'values': ['ann'], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k4', 'email': 'Ann@x.io'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('rule index skips rules on absent attributes',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'plan', 'op': 'in', 'values': ['pro'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'age', 'op': 'lt', 'values': [21], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k5', 'age': 19}],\n   ['v2', 'RULE', 1]),\n  ('prefix operand order matters',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['annie@corp'],\n                'negate': False,\n                'variation': 'v1'}]},\n    {'key': 'k2', 'email': 'annie'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('targeting sample 35',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {'v1': [], 'v3': ['k3', 'k4']},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['ann', 'qa-'],\n                'negate': False,\n                'variation': 'v2'},\n               {'attr': 'age', 'op': 'lt', 'values': [65, 18], 'negate': True, 'variation': 'v2'}]},\n    {'key': 'k1', 'email': 'Ann@x.io', 'age': 70}],\n   ['v2', 'RULE', 1]),\n  ('targeting sample 56',\n   [{'on': True,\n     'off': 'v1',\n     'fallthrough': 'v2',\n     'targets': {'v1': ['k3']},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['bob', 'qa-'],\n                'negate': False,\n                'variation': 'v2'}]},\n    {'key': 'k6', 'email': 'bob@y.io', 'age': 30, 'plan': 'free'}],\n   ['v2', 'RULE', 0])],\n [('off flag serves off variation',\n   [{'on': False, 'off': 'v1', 'fallthrough': 'v2', 'targets': {}, 'rules': []}, {'key': 'k1'}],\n   ['v1', 'OFF', -1]),\n  ('second rule reports index one',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'country', 'op': 'in', 'values': ['FR'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'country', 'op': 'in', 'values': ['DE'], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k3', 'country': 'DE'}],\n   ['v2', 'RULE', 1]),\n  ('prefix match is case sensitive',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'email', 'op': 'startsWith', 'values': ['ann'], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k4', 'email': 'Ann@x.io'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('rule index skips rules on absent attributes',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'plan', 'op': 'in', 'values': ['pro'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'age', 'op': 'lt', 'values': [21], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k5', 'age': 19}],\n   ['v2', 'RULE', 1]),\n  ('target to fallthrough variation still reports TARGET',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v2',\n     'targets': {'v2': ['k1']},\n     'rules': [{'attr': 'age', 'op': 'lt', 'values': [30], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k1', 'age': 20}],\n   ['v2', 'TARGET', -1]),\n  ('targeting sample 11',\n   [{'on': True,\n     'off': 'v1',\n     'fallthrough': 'v3',\n     'targets': {'v3': ['k2'], 'v2': ['k4', 'k2']},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['qa-', 'a'],\n                'negate': False,\n                'variation': 'v1'},\n               {'attr': 'country', 'op': 'in', 'values': ['DE', 'FR'], 'negate': True, 'variation': 'v3'},\n               {'attr': 'email',\n                'op': 'startsWith',\n                'values': ['qa-', 'a'],\n                'negate': False,\n                'variation': 'v1'}]},\n    {'key': 'k6', 'email': 'annie', 'age': 40, 'plan': 'free'}],\n   ['v1', 'RULE', 0]),\n  ('targeting sample 12',\n   [{'on': True, 'off': 'v1', 'fallthrough': 'v0', 'targets': {'v1': ['k1', 'k4'], 'v2': []}, 'rules': []},\n    {'key': 'k1', 'age': 30, 'plan': 'free'}],\n   ['v1', 'TARGET', -1]),\n  ('targeting sample 47',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v2',\n     'targets': {},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['Ann', 'bob'],\n                'negate': True,\n                'variation': 'v2'},\n               {'attr': 'country', 'op': 'in', 'values': ['US', 'pro'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'plan', 'op': 'in', 'values': ['FR', 'DE'], 'negate': False, 'variation': 'v0'},\n               {'attr': 'email',\n                'op': 'startsWith',\n                'values': ['Ann', 'bob'],\n                'negate': True,\n                'variation': 'v2'}]},\n    {'key': 'k2', 'country': 'JP', 'email': 'Ann@x.io', 'plan': 'team'}],\n   ['v2', 'FALLTHROUGH', -1])],\n [('second rule reports index one',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'country', 'op': 'in', 'values': ['FR'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'country', 'op': 'in', 'values': ['DE'], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k3', 'country': 'DE'}],\n   ['v2', 'RULE', 1]),\n  ('prefix match is case sensitive',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'email', 'op': 'startsWith', 'values': ['ann'], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k4', 'email': 'Ann@x.io'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('rule index skips rules on absent attributes',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'plan', 'op': 'in', 'values': ['pro'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'age', 'op': 'lt', 'values': [21], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k5', 'age': 19}],\n   ['v2', 'RULE', 1]),\n  ('target to fallthrough variation still reports TARGET',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v2',\n     'targets': {'v2': ['k1']},\n     'rules': [{'attr': 'age', 'op': 'lt', 'values': [30], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k1', 'age': 20}],\n   ['v2', 'TARGET', -1]),\n  ('no rule matches uses fallthrough',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v3',\n     'targets': {'v1': ['k9']},\n     'rules': [{'attr': 'age', 'op': 'lt', 'values': [18], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k1', 'age': 40}],\n   ['v3', 'FALLTHROUGH', -1]),\n  ('targeting sample 16',\n   [{'on': True, 'off': 'v0', 'fallthrough': 'v2', 'targets': {}, 'rules': []},\n    {'key': 'k5', 'age': 40, 'plan': 'free'}],\n   ['v2', 'FALLTHROUGH', -1]),\n  ('targeting sample 35',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {'v1': [], 'v3': ['k3', 'k4']},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['ann', 'qa-'],\n                'negate': False,\n                'variation': 'v2'},\n               {'attr': 'age', 'op': 'lt', 'values': [65, 18], 'negate': True, 'variation': 'v2'}]},\n    {'key': 'k1', 'email': 'Ann@x.io', 'age': 70}],\n   ['v2', 'RULE', 1]),\n  ('targeting sample 36',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {'v1': [], 'v2': ['k2', 'k3']},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['a', 'qa-'],\n                'negate': True,\n                'variation': 'v1'},\n               {'attr': 'plan', 'op': 'in', 'values': ['pro', 'free'], 'negate': True, 'variation': 'v0'}]},\n    {'key': 'k1', 'country': 'US', 'email': 'qa-1@z.io', 'age': 70}],\n   ['v0', 'FALLTHROUGH', -1])],\n [('prefix match is case sensitive',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'email', 'op': 'startsWith', 'values': ['ann'], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k4', 'email': 'Ann@x.io'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('rule index skips rules on absent attributes',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'plan', 'op': 'in', 'values': ['pro'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'age', 'op': 'lt', 'values': [21], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k5', 'age': 19}],\n   ['v2', 'RULE', 1]),\n  ('target to fallthrough variation still reports TARGET',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v2',\n     'targets': {'v2': ['k1']},\n     'rules': [{'attr': 'age', 'op': 'lt', 'values': [30], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k1', 'age': 20}],\n   ['v2', 'TARGET', -1]),\n  ('no rule matches uses fallthrough',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v3',\n     'targets': {'v1': ['k9']},\n     'rules': [{'attr': 'age', 'op': 'lt', 'values': [18], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k1', 'age': 40}],\n   ['v3', 'FALLTHROUGH', -1]),\n  ('prefix operand order matters',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['annie@corp'],\n                'negate': False,\n                'variation': 'v1'}]},\n    {'key': 'k2', 'email': 'annie'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('targeting sample 21',\n   [{'on': True, 'off': 'v1', 'fallthrough': 'v2', 'targets': {}, 'rules': []},\n    {'key': 'k3', 'email': 'qa-1@z.io', 'plan': 'free'}],\n   ['v2', 'FALLTHROUGH', -1]),\n  ('targeting sample 22',\n   [{'on': False, 'off': 'v0', 'fallthrough': 'v2', 'targets': {'v1': [], 'v3': ['k3']}, 'rules': []},\n    {'key': 'k6', 'country': 'DE', 'email': 'Ann@x.io', 'plan': 'team'}],\n   ['v0', 'OFF', -1]),\n  ('targeting sample 30',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {'v1': ['k3']},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['bob', 'ann'],\n                'negate': False,\n                'variation': 'v0'},\n               {'attr': 'email',\n                'op': 'startsWith',\n                'values': ['Ann', 'qa-'],\n                'negate': False,\n                'variation': 'v1'}]},\n    {'key': 'k6', 'email': 'qa-1@z.io', 'age': 30}],\n   ['v1', 'RULE', 1])]]\nfor label, args, expected in fixtures[N - 1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"a250d77992fa0aa67035dda6648717158fa3381e27a8710b2b8a33f8fcbcc3b4","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(flag, user):\n    if not flag.get('on'):\n        return [flag.get('off'), 'OFF', -1]\n    key = user.get('key')\n    for variation in sorted(flag.get('targets', {})):\n        if key in flag['targets'][variation]:\n            return [variation, 'TARGET', -1]\n    for index, rule in enumerate(flag.get('rules', [])):\n        if rule['attr'] not in user:\n            continue\n        value = user[rule['attr']]\n        if rule['op'] == 'in':\n            hit = value in rule['values']\n        elif rule['op'] == 'startsWith':\n            hit = isinstance(value, str) and any(value.lower().startswith(v.lower()) for v in rule['values'])\n        else:\n            hit = isinstance(value, (int, float)) and not isinstance(value, bool) and any(value < v for v in rule['values'])\n        if rule.get('negate'):\n            hit = not hit\n        if hit:\n            return [rule['variation'], 'RULE', index]\n    return [flag.get('fallthrough'), 'FALLTHROUGH', -1]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('individual target beats a matching rule',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {'v1': ['k1']},\n     'rules': [{'attr': 'country', 'op': 'in', 'values': ['US'], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k1', 'country': 'US'}],\n   ['v1', 'TARGET', -1]),\n  ('negated rule does not match a missing attribute',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v3',\n     'targets': {},\n     'rules': [{'attr': 'plan', 'op': 'in', 'values': ['pro'], 'negate': True, 'variation': 'v2'}]},\n    {'key': 'k2'}],\n   ['v3', 'FALLTHROUGH', -1]),\n  ('off flag serves off variation',\n   [{'on': False, 'off': 'v1', 'fallthrough': 'v2', 'targets': {}, 'rules': []}, {'key': 'k1'}],\n   ['v1', 'OFF', -1]),\n  ('second rule reports index one',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'country', 'op': 'in', 'values': ['FR'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'country', 'op': 'in', 'values': ['DE'], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k3', 'country': 'DE'}],\n   ['v2', 'RULE', 1]),\n  ('prefix match is case sensitive',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'email', 'op': 'startsWith', 'values': ['ann'], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k4', 'email': 'Ann@x.io'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('prefix operand order matters',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['annie@corp'],\n                'negate': False,\n                'variation': 'v1'}]},\n    {'key': 'k2', 'email': 'annie'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('targeting sample 1',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {'v1': []},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['a', 'Ann'],\n                'negate': False,\n                'variation': 'v2'},\n               {'attr': 'age', 'op': 'lt', 'values': [21, 18], 'negate': False, 'variation': 'v0'},\n               {'attr': 'age', 'op': 'lt', 'values': [18, 30], 'negate': True, 'variation': 'v2'},\n               {'attr': 'email',\n                'op': 'startsWith',\n                'values': ['a', 'Ann'],\n                'negate': False,\n                'variation': 'v2'}]},\n    {'key': 'k2', 'country': 'DE', 'age': 20, 'plan': 'team'}],\n   ['v0', 'RULE', 1]),\n  ('targeting sample 2',\n   [{'on': True, 'off': 'v1', 'fallthrough': 'v0', 'targets': {'v2': []}, 'rules': []},\n    {'key': 'k6', 'age': 40, 'plan': 'pro'}],\n   ['v0', 'FALLTHROUGH', -1])],\n [('negated rule does not match a missing attribute',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v3',\n     'targets': {},\n     'rules': [{'attr': 'plan', 'op': 'in', 'values': ['pro'], 'negate': True, 'variation': 'v2'}]},\n    {'key': 'k2'}],\n   ['v3', 'FALLTHROUGH', -1]),\n  ('off flag serves off variation',\n   [{'on': False, 'off': 'v1', 'fallthrough': 'v2', 'targets': {}, 'rules': []}, {'key': 'k1'}],\n   ['v1', 'OFF', -1]),\n  ('second rule reports index one',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'country', 'op': 'in', 'values': ['FR'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'country', 'op': 'in', 'values': ['DE'], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k3', 'country': 'DE'}],\n   ['v2', 'RULE', 1]),\n  ('prefix match is case sensitive',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'email', 'op': 'startsWith', 'values': ['ann'], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k4', 'email': 'Ann@x.io'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('rule index skips rules on absent attributes',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'plan', 'op': 'in', 'values': ['pro'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'age', 'op': 'lt', 'values': [21], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k5', 'age': 19}],\n   ['v2', 'RULE', 1]),\n  ('prefix operand order matters',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['annie@corp'],\n                'negate': False,\n                'variation': 'v1'}]},\n    {'key': 'k2', 'email': 'annie'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('targeting sample 35',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {'v1': [], 'v3': ['k3', 'k4']},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['ann', 'qa-'],\n                'negate': False,\n                'variation': 'v2'},\n               {'attr': 'age', 'op': 'lt', 'values': [65, 18], 'negate': True, 'variation': 'v2'}]},\n    {'key': 'k1', 'email': 'Ann@x.io', 'age': 70}],\n   ['v2', 'RULE', 1]),\n  ('targeting sample 56',\n   [{'on': True,\n     'off': 'v1',\n     'fallthrough': 'v2',\n     'targets': {'v1': ['k3']},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['bob', 'qa-'],\n                'negate': False,\n                'variation': 'v2'}]},\n    {'key': 'k6', 'email': 'bob@y.io', 'age': 30, 'plan': 'free'}],\n   ['v2', 'RULE', 0])],\n [('off flag serves off variation',\n   [{'on': False, 'off': 'v1', 'fallthrough': 'v2', 'targets': {}, 'rules': []}, {'key': 'k1'}],\n   ['v1', 'OFF', -1]),\n  ('second rule reports index one',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'country', 'op': 'in', 'values': ['FR'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'country', 'op': 'in', 'values': ['DE'], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k3', 'country': 'DE'}],\n   ['v2', 'RULE', 1]),\n  ('prefix match is case sensitive',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'email', 'op': 'startsWith', 'values': ['ann'], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k4', 'email': 'Ann@x.io'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('rule index skips rules on absent attributes',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'plan', 'op': 'in', 'values': ['pro'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'age', 'op': 'lt', 'values': [21], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k5', 'age': 19}],\n   ['v2', 'RULE', 1]),\n  ('target to fallthrough variation still reports TARGET',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v2',\n     'targets': {'v2': ['k1']},\n     'rules': [{'attr': 'age', 'op': 'lt', 'values': [30], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k1', 'age': 20}],\n   ['v2', 'TARGET', -1]),\n  ('targeting sample 11',\n   [{'on': True,\n     'off': 'v1',\n     'fallthrough': 'v3',\n     'targets': {'v3': ['k2'], 'v2': ['k4', 'k2']},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['qa-', 'a'],\n                'negate': False,\n                'variation': 'v1'},\n               {'attr': 'country', 'op': 'in', 'values': ['DE', 'FR'], 'negate': True, 'variation': 'v3'},\n               {'attr': 'email',\n                'op': 'startsWith',\n                'values': ['qa-', 'a'],\n                'negate': False,\n                'variation': 'v1'}]},\n    {'key': 'k6', 'email': 'annie', 'age': 40, 'plan': 'free'}],\n   ['v1', 'RULE', 0]),\n  ('targeting sample 12',\n   [{'on': True, 'off': 'v1', 'fallthrough': 'v0', 'targets': {'v1': ['k1', 'k4'], 'v2': []}, 'rules': []},\n    {'key': 'k1', 'age': 30, 'plan': 'free'}],\n   ['v1', 'TARGET', -1]),\n  ('targeting sample 47',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v2',\n     'targets': {},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['Ann', 'bob'],\n                'negate': True,\n                'variation': 'v2'},\n               {'attr': 'country', 'op': 'in', 'values': ['US', 'pro'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'plan', 'op': 'in', 'values': ['FR', 'DE'], 'negate': False, 'variation': 'v0'},\n               {'attr': 'email',\n                'op': 'startsWith',\n                'values': ['Ann', 'bob'],\n                'negate': True,\n                'variation': 'v2'}]},\n    {'key': 'k2', 'country': 'JP', 'email': 'Ann@x.io', 'plan': 'team'}],\n   ['v2', 'FALLTHROUGH', -1])],\n [('second rule reports index one',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'country', 'op': 'in', 'values': ['FR'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'country', 'op': 'in', 'values': ['DE'], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k3', 'country': 'DE'}],\n   ['v2', 'RULE', 1]),\n  ('prefix match is case sensitive',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'email', 'op': 'startsWith', 'values': ['ann'], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k4', 'email': 'Ann@x.io'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('rule index skips rules on absent attributes',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'plan', 'op': 'in', 'values': ['pro'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'age', 'op': 'lt', 'values': [21], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k5', 'age': 19}],\n   ['v2', 'RULE', 1]),\n  ('target to fallthrough variation still reports TARGET',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v2',\n     'targets': {'v2': ['k1']},\n     'rules': [{'attr': 'age', 'op': 'lt', 'values': [30], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k1', 'age': 20}],\n   ['v2', 'TARGET', -1]),\n  ('no rule matches uses fallthrough',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v3',\n     'targets': {'v1': ['k9']},\n     'rules': [{'attr': 'age', 'op': 'lt', 'values': [18], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k1', 'age': 40}],\n   ['v3', 'FALLTHROUGH', -1]),\n  ('targeting sample 16',\n   [{'on': True, 'off': 'v0', 'fallthrough': 'v2', 'targets': {}, 'rules': []},\n    {'key': 'k5', 'age': 40, 'plan': 'free'}],\n   ['v2', 'FALLTHROUGH', -1]),\n  ('targeting sample 35',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {'v1': [], 'v3': ['k3', 'k4']},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['ann', 'qa-'],\n                'negate': False,\n                'variation': 'v2'},\n               {'attr': 'age', 'op': 'lt', 'values': [65, 18], 'negate': True, 'variation': 'v2'}]},\n    {'key': 'k1', 'email': 'Ann@x.io', 'age': 70}],\n   ['v2', 'RULE', 1]),\n  ('targeting sample 36',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {'v1': [], 'v2': ['k2', 'k3']},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['a', 'qa-'],\n                'negate': True,\n                'variation': 'v1'},\n               {'attr': 'plan', 'op': 'in', 'values': ['pro', 'free'], 'negate': True, 'variation': 'v0'}]},\n    {'key': 'k1', 'country': 'US', 'email': 'qa-1@z.io', 'age': 70}],\n   ['v0', 'FALLTHROUGH', -1])],\n [('prefix match is case sensitive',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'email', 'op': 'startsWith', 'values': ['ann'], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k4', 'email': 'Ann@x.io'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('rule index skips rules on absent attributes',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'plan', 'op': 'in', 'values': ['pro'], 'negate': False, 'variation': 'v1'},\n               {'attr': 'age', 'op': 'lt', 'values': [21], 'negate': False, 'variation': 'v2'}]},\n    {'key': 'k5', 'age': 19}],\n   ['v2', 'RULE', 1]),\n  ('target to fallthrough variation still reports TARGET',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v2',\n     'targets': {'v2': ['k1']},\n     'rules': [{'attr': 'age', 'op': 'lt', 'values': [30], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k1', 'age': 20}],\n   ['v2', 'TARGET', -1]),\n  ('no rule matches uses fallthrough',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v3',\n     'targets': {'v1': ['k9']},\n     'rules': [{'attr': 'age', 'op': 'lt', 'values': [18], 'negate': False, 'variation': 'v1'}]},\n    {'key': 'k1', 'age': 40}],\n   ['v3', 'FALLTHROUGH', -1]),\n  ('prefix operand order matters',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['annie@corp'],\n                'negate': False,\n                'variation': 'v1'}]},\n    {'key': 'k2', 'email': 'annie'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('targeting sample 21',\n   [{'on': True, 'off': 'v1', 'fallthrough': 'v2', 'targets': {}, 'rules': []},\n    {'key': 'k3', 'email': 'qa-1@z.io', 'plan': 'free'}],\n   ['v2', 'FALLTHROUGH', -1]),\n  ('targeting sample 22',\n   [{'on': False, 'off': 'v0', 'fallthrough': 'v2', 'targets': {'v1': [], 'v3': ['k3']}, 'rules': []},\n    {'key': 'k6', 'country': 'DE', 'email': 'Ann@x.io', 'plan': 'team'}],\n   ['v0', 'OFF', -1]),\n  ('targeting sample 30',\n   [{'on': True,\n     'off': 'v0',\n     'fallthrough': 'v0',\n     'targets': {'v1': ['k3']},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['bob', 'ann'],\n                'negate': False,\n                'variation': 'v0'},\n               {'attr': 'email',\n                'op': 'startsWith',\n                'values': ['Ann', 'qa-'],\n                'negate': False,\n                'variation': 'v1'}]},\n    {'key': 'k6', 'email': 'qa-1@z.io', 'age': 30}],\n   ['v1', 'RULE', 1])]]\nfor label, args, expected in fixtures[N - 1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"A deterministic toy flag-evaluation model with a stipulated contract; it does not reproduce any vendor SDK byte for byte. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"w2-feature-flag-rollout-bucketing-targeting-precedence-prefix-case","generated_at":"2026-09-29T14:48:51.939496+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Evaluation order decides whether QA allowlists, segment rules and defaults behave predictably.","root_cause":"The startsWith operator lowercases both the attribute and the clause value.","sha256":"a290a8ebee075a339515d32c20a65ac1d211af2b09434394186eb71086e99a81","title":"Flag targeting precedence: Prefix clauses ignore letter case · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verified":true,"visibility":"public","verification":{"attempt":{"elapsed_ms":41.116,"exit_code":1,"observations":[{"actual":["v1","TARGET",-1],"check":"individual target beats a matching rule","expected":["v1","TARGET",-1],"passed":true},{"actual":["v3","FALLTHROUGH",-1],"check":"negated rule does not match a missing attribute","expected":["v3","FALLTHROUGH",-1],"passed":true},{"actual":["v1","OFF",-1],"check":"off flag serves off variation","expected":["v1","OFF",-1],"passed":true},{"actual":["v2","RULE",1],"check":"second rule reports index one","expected":["v2","RULE",1],"passed":true},{"actual":["v0","FALLTHROUGH",-1],"check":"prefix match is case sensitive","expected":["v0","FALLTHROUGH",-1],"passed":true},{"actual":["v1","RULE",0],"check":"prefix operand order matters","expected":["v0","FALLTHROUGH",-1],"passed":false},{"actual":["v0","RULE",1],"check":"targeting sample 1","expected":["v0","RULE",1],"passed":true},{"actual":["v0","FALLTHROUGH",-1],"check":"targeting sample 2","expected":["v0","FALLTHROUGH",-1],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"individual target beats a matching rule\", \"actual\": [\"v1\", \"TARGET\", -1], \"expected\": [\"v1\", \"TARGET\", -1], \"passed\": true}, {\"check\": \"negated rule does not match a missing attribute\", \"actual\": [\"v3\", \"FALLTHROUGH\", -1], \"expected\": [\"v3\", \"FALLTHROUGH\", -1], \"passed\": true}, {\"check\": \"off flag serves off variation\", \"actual\": [\"v1\", \"OFF\", -1], \"expected\": [\"v1\", \"OFF\", -1], \"passed\": true}, {\"check\": \"second rule reports index one\", \"actual\": [\"v2\", \"RULE\", 1], \"expected\": [\"v2\", \"RULE\", 1], \"passed\": true}, {\"check\": \"prefix match is case sensitive\", \"actual\": [\"v0\", \"FALLTHROUGH\", -1], \"expected\": [\"v0\", \"FALLTHROUGH\", -1], \"passed\": true}, {\"check\": \"prefix operand order matters\", \"actual\": [\"v1\", \"RULE\", 0], \"expected\": [\"v0\", \"FALLTHROUGH\", -1], \"passed\": false}, {\"check\": \"targeting sample 1\", \"actual\": [\"v0\", \"RULE\", 1], \"expected\": [\"v0\", \"RULE\", 1], \"passed\": true}, {\"check\": \"targeting sample 2\", \"actual\": [\"v0\", \"FALLTHROUGH\", -1], \"expected\": [\"v0\", \"FALLTHROUGH\", -1], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.325,"exit_code":1,"observations":[{"actual":["v1","TARGET",-1],"check":"individual target beats a matching rule","expected":["v1","TARGET",-1],"passed":true},{"actual":["v3","FALLTHROUGH",-1],"check":"negated rule does not match a missing attribute","expected":["v3","FALLTHROUGH",-1],"passed":true},{"actual":["v1","OFF",-1],"check":"off flag serves off variation","expected":["v1","OFF",-1],"passed":true},{"actual":["v2","RULE",1],"check":"second rule reports index one","expected":["v2","RULE",1],"passed":true},{"actual":["v1","RULE",0],"check":"prefix match is case sensitive","expected":["v0","FALLTHROUGH",-1],"passed":false},{"actual":["v0","FALLTHROUGH",-1],"check":"prefix operand order matters","expected":["v0","FALLTHROUGH",-1],"passed":true},{"actual":["v0","RULE",1],"check":"targeting sample 1","expected":["v0","RULE",1],"passed":true},{"actual":["v0","FALLTHROUGH",-1],"check":"targeting sample 2","expected":["v0","FALLTHROUGH",-1],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"individual target beats a matching rule\", \"actual\": [\"v1\", \"TARGET\", -1], \"expected\": [\"v1\", \"TARGET\", -1], \"passed\": true}, {\"check\": \"negated rule does not match a missing attribute\", \"actual\": [\"v3\", \"FALLTHROUGH\", -1], \"expected\": [\"v3\", \"FALLTHROUGH\", -1], \"passed\": true}, {\"check\": \"off flag serves off variation\", \"actual\": [\"v1\", \"OFF\", -1], \"expected\": [\"v1\", \"OFF\", -1], \"passed\": true}, {\"check\": \"second rule reports index one\", \"actual\": [\"v2\", \"RULE\", 1], \"expected\": [\"v2\", \"RULE\", 1], \"passed\": true}, {\"check\": \"prefix match is case sensitive\", \"actual\": [\"v1\", \"RULE\", 0], \"expected\": [\"v0\", \"FALLTHROUGH\", -1], \"passed\": false}, {\"check\": \"prefix operand order matters\", \"actual\": [\"v0\", \"FALLTHROUGH\", -1], \"expected\": [\"v0\", \"FALLTHROUGH\", -1], \"passed\": true}, {\"check\": \"targeting sample 1\", \"actual\": [\"v0\", \"RULE\", 1], \"expected\": [\"v0\", \"RULE\", 1], \"passed\": true}, {\"check\": \"targeting sample 2\", \"actual\": [\"v0\", \"FALLTHROUGH\", -1], \"expected\": [\"v0\", \"FALLTHROUGH\", -1], \"passed\": true}], \"passed\": false}\n"}},"member_only":{"stages":["fixed"],"fields":["implementations.fixed","verification.fixed","harness","repair"],"note":"The verified repair, its recorded checks, the repair description, and the scoring harness are available to members."}}