{"abstract":"Turning the flag off leaves users on the rollout variation instead of the safe off variation.","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":"Returning None when off ignores the configured off variation.","family":"w2-feature-flag-rollout-bucketing-targeting-precedence-off-variation","id":"FA-73901","implementations":{"attempt":{"sha256":"e37f18d1bffb181a6880fedd77742e8bbb65865190cd22d1a5cef44595586072","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 [None, '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.startswith(v) 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  ('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  ('targeting sample 3',\n   [{'on': True,\n     'off': 'v1',\n     'fallthrough': 'v0',\n     'targets': {'v1': ['k3'], 'v3': ['k3']},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['Ann', 'a'],\n                'negate': False,\n                'variation': 'v1'},\n               {'attr': 'email',\n                'op': 'startsWith',\n                'values': ['Ann', 'a'],\n                'negate': False,\n                'variation': 'v1'}]},\n    {'key': 'k1', 'country': 'US', 'email': 'ann@x.io', 'age': 40, 'plan': 'pro'}],\n   ['v1', 'RULE', 0])],\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  ('targeting sample 6',\n   [{'on': True,\n     'off': 'v1',\n     'fallthrough': 'v3',\n     'targets': {},\n     'rules': [{'attr': 'age', 'op': 'lt', 'values': [18, 65], 'negate': False, 'variation': 'v1'},\n               {'attr': 'plan', 'op': 'in', 'values': ['DE', 'free'], 'negate': True, 'variation': 'v2'}]},\n    {'key': 'k5', 'country': 'DE', 'plan': 'team'}],\n   ['v2', 'RULE', 1]),\n  ('targeting sample 7',\n   [{'on': True,\n     'off': 'v1',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'plan', 'op': 'in', 'values': ['FR', 'free'], 'negate': True, 'variation': 'v1'},\n               {'attr': 'plan', 'op': 'in', 'values': ['FR', 'US'], 'negate': False, 'variation': 'v0'}]},\n    {'key': 'k6', 'country': 'JP', 'email': 'annie', 'age': 17, 'plan': 'free'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('targeting sample 32',\n   [{'on': False,\n     'off': 'v1',\n     'fallthrough': 'v3',\n     'targets': {'v3': [], 'v1': ['k4']},\n     'rules': [{'attr': 'plan', 'op': 'lt', 'values': [21, 65], 'negate': True, 'variation': 'v1'},\n               {'attr': 'country', 'op': 'in', 'values': ['US', 'pro'], 'negate': False, 'variation': 'v0'},\n               {'attr': 'country', 'op': 'in', 'values': ['FR', 'free'], 'negate': True, 'variation': 'v2'},\n               {'attr': 'plan', 'op': 'lt', 'values': [21, 65], 'negate': True, 'variation': 'v1'}]},\n    {'key': 'k5', 'plan': 'pro'}],\n   ['v1', 'OFF', -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  ('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 9',\n   [{'on': False,\n     'off': 'v1',\n     'fallthrough': 'v0',\n     'targets': {'v3': ['k1', 'k4'], 'v1': ['k2']},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['bob', 'ann'],\n                'negate': False,\n                'variation': 'v1'},\n               {'attr': 'email',\n                'op': 'startsWith',\n                'values': ['bob', 'ann'],\n                'negate': False,\n                'variation': 'v1'}]},\n    {'key': 'k6', 'country': 'JP', 'email': 'ann@x.io', 'age': 70, 'plan': 'team'}],\n   ['v1', 'OFF', -1]),\n  ('targeting sample 10',\n   [{'on': False,\n     'off': 'v0',\n     'fallthrough': 'v2',\n     'targets': {'v3': ['k5'], 'v1': ['k2', 'k3']},\n     'rules': []},\n    {'key': 'k2', 'country': 'US', 'email': 'Ann@x.io'}],\n   ['v0', 'OFF', -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 [('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 40',\n   [{'on': False,\n     'off': 'v0',\n     'fallthrough': 'v2',\n     'targets': {'v2': ['k1', 'k2'], 'v1': ['k1', 'k2']},\n     'rules': []},\n    {'key': 'k6', 'country': 'JP', 'email': 'annie', 'age': 40, 'plan': 'pro'}],\n   ['v0', 'OFF', -1]),\n  ('targeting sample 42',\n   [{'on': False,\n     'off': 'v0',\n     'fallthrough': 'v2',\n     'targets': {'v1': []},\n     'rules': [{'attr': 'country', 'op': 'in', 'values': ['US', 'pro'], 'negate': False, 'variation': 'v3'},\n               {'attr': 'email',\n                'op': 'startsWith',\n                'values': ['qa-', 'a'],\n                'negate': False,\n                'variation': 'v0'},\n               {'attr': 'age', 'op': 'lt', 'values': [18, 30], 'negate': False, 'variation': 'v1'},\n               {'attr': 'country', 'op': 'in', 'values': ['US', 'pro'], 'negate': False, 'variation': 'v3'}]},\n    {'key': 'k5', 'email': 'bob@y.io', 'age': 20, 'plan': 'team'}],\n   ['v0', 'OFF', -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 10',\n   [{'on': False,\n     'off': 'v0',\n     'fallthrough': 'v2',\n     'targets': {'v3': ['k5'], 'v1': ['k2', 'k3']},\n     'rules': []},\n    {'key': 'k2', 'country': 'US', 'email': 'Ann@x.io'}],\n   ['v0', 'OFF', -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 25',\n   [{'on': False,\n     'off': 'v1',\n     'fallthrough': 'v3',\n     'targets': {'v1': []},\n     'rules': [{'attr': 'age', 'op': 'lt', 'values': [18, 30], 'negate': False, 'variation': 'v2'},\n               {'attr': 'country', 'op': 'in', 'values': ['DE', 'free'], 'negate': True, 'variation': 'v0'}]},\n    {'key': 'k6', 'country': 'JP', 'email': 'qa-1@z.io', 'age': 17}],\n   ['v1', 'OFF', -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":"117c5c4c2633a0cf2a0fd88d9a5937897bd1d8c53d7175b205b4d98579425b48","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('fallthrough'), '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.startswith(v) 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  ('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  ('targeting sample 3',\n   [{'on': True,\n     'off': 'v1',\n     'fallthrough': 'v0',\n     'targets': {'v1': ['k3'], 'v3': ['k3']},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['Ann', 'a'],\n                'negate': False,\n                'variation': 'v1'},\n               {'attr': 'email',\n                'op': 'startsWith',\n                'values': ['Ann', 'a'],\n                'negate': False,\n                'variation': 'v1'}]},\n    {'key': 'k1', 'country': 'US', 'email': 'ann@x.io', 'age': 40, 'plan': 'pro'}],\n   ['v1', 'RULE', 0])],\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  ('targeting sample 6',\n   [{'on': True,\n     'off': 'v1',\n     'fallthrough': 'v3',\n     'targets': {},\n     'rules': [{'attr': 'age', 'op': 'lt', 'values': [18, 65], 'negate': False, 'variation': 'v1'},\n               {'attr': 'plan', 'op': 'in', 'values': ['DE', 'free'], 'negate': True, 'variation': 'v2'}]},\n    {'key': 'k5', 'country': 'DE', 'plan': 'team'}],\n   ['v2', 'RULE', 1]),\n  ('targeting sample 7',\n   [{'on': True,\n     'off': 'v1',\n     'fallthrough': 'v0',\n     'targets': {},\n     'rules': [{'attr': 'plan', 'op': 'in', 'values': ['FR', 'free'], 'negate': True, 'variation': 'v1'},\n               {'attr': 'plan', 'op': 'in', 'values': ['FR', 'US'], 'negate': False, 'variation': 'v0'}]},\n    {'key': 'k6', 'country': 'JP', 'email': 'annie', 'age': 17, 'plan': 'free'}],\n   ['v0', 'FALLTHROUGH', -1]),\n  ('targeting sample 32',\n   [{'on': False,\n     'off': 'v1',\n     'fallthrough': 'v3',\n     'targets': {'v3': [], 'v1': ['k4']},\n     'rules': [{'attr': 'plan', 'op': 'lt', 'values': [21, 65], 'negate': True, 'variation': 'v1'},\n               {'attr': 'country', 'op': 'in', 'values': ['US', 'pro'], 'negate': False, 'variation': 'v0'},\n               {'attr': 'country', 'op': 'in', 'values': ['FR', 'free'], 'negate': True, 'variation': 'v2'},\n               {'attr': 'plan', 'op': 'lt', 'values': [21, 65], 'negate': True, 'variation': 'v1'}]},\n    {'key': 'k5', 'plan': 'pro'}],\n   ['v1', 'OFF', -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  ('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 9',\n   [{'on': False,\n     'off': 'v1',\n     'fallthrough': 'v0',\n     'targets': {'v3': ['k1', 'k4'], 'v1': ['k2']},\n     'rules': [{'attr': 'email',\n                'op': 'startsWith',\n                'values': ['bob', 'ann'],\n                'negate': False,\n                'variation': 'v1'},\n               {'attr': 'email',\n                'op': 'startsWith',\n                'values': ['bob', 'ann'],\n                'negate': False,\n                'variation': 'v1'}]},\n    {'key': 'k6', 'country': 'JP', 'email': 'ann@x.io', 'age': 70, 'plan': 'team'}],\n   ['v1', 'OFF', -1]),\n  ('targeting sample 10',\n   [{'on': False,\n     'off': 'v0',\n     'fallthrough': 'v2',\n     'targets': {'v3': ['k5'], 'v1': ['k2', 'k3']},\n     'rules': []},\n    {'key': 'k2', 'country': 'US', 'email': 'Ann@x.io'}],\n   ['v0', 'OFF', -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 [('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 40',\n   [{'on': False,\n     'off': 'v0',\n     'fallthrough': 'v2',\n     'targets': {'v2': ['k1', 'k2'], 'v1': ['k1', 'k2']},\n     'rules': []},\n    {'key': 'k6', 'country': 'JP', 'email': 'annie', 'age': 40, 'plan': 'pro'}],\n   ['v0', 'OFF', -1]),\n  ('targeting sample 42',\n   [{'on': False,\n     'off': 'v0',\n     'fallthrough': 'v2',\n     'targets': {'v1': []},\n     'rules': [{'attr': 'country', 'op': 'in', 'values': ['US', 'pro'], 'negate': False, 'variation': 'v3'},\n               {'attr': 'email',\n                'op': 'startsWith',\n                'values': ['qa-', 'a'],\n                'negate': False,\n                'variation': 'v0'},\n               {'attr': 'age', 'op': 'lt', 'values': [18, 30], 'negate': False, 'variation': 'v1'},\n               {'attr': 'country', 'op': 'in', 'values': ['US', 'pro'], 'negate': False, 'variation': 'v3'}]},\n    {'key': 'k5', 'email': 'bob@y.io', 'age': 20, 'plan': 'team'}],\n   ['v0', 'OFF', -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 10',\n   [{'on': False,\n     'off': 'v0',\n     'fallthrough': 'v2',\n     'targets': {'v3': ['k5'], 'v1': ['k2', 'k3']},\n     'rules': []},\n    {'key': 'k2', 'country': 'US', 'email': 'Ann@x.io'}],\n   ['v0', 'OFF', -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 25',\n   [{'on': False,\n     'off': 'v1',\n     'fallthrough': 'v3',\n     'targets': {'v1': []},\n     'rules': [{'attr': 'age', 'op': 'lt', 'values': [18, 30], 'negate': False, 'variation': 'v2'},\n               {'attr': 'country', 'op': 'in', 'values': ['DE', 'free'], 'negate': True, 'variation': 'v0'}]},\n    {'key': 'k6', 'country': 'JP', 'email': 'qa-1@z.io', 'age': 17}],\n   ['v1', 'OFF', -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-off-variation","generated_at":"2026-09-29T14:48:51.851622+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 off branch returns flag[\"fallthrough\"] while still labelling the reason OFF.","sha256":"8be873ff8ead972a1a5063a512c99db7f4262a160d5f105f051cfa84d42acda4","title":"Flag targeting precedence: A disabled flag serves its fallthrough · 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":43.199,"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":[null,"OFF",-1],"check":"off flag serves off variation","expected":["v1","OFF",-1],"passed":false},{"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":["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},{"actual":["v1","RULE",0],"check":"targeting sample 3","expected":["v1","RULE",0],"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\": [null, \"OFF\", -1], \"expected\": [\"v1\", \"OFF\", -1], \"passed\": false}, {\"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\": \"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}, {\"check\": \"targeting sample 3\", \"actual\": [\"v1\", \"RULE\", 0], \"expected\": [\"v1\", \"RULE\", 0], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":42.914,"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":["v2","OFF",-1],"check":"off flag serves off variation","expected":["v1","OFF",-1],"passed":false},{"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":["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},{"actual":["v1","RULE",0],"check":"targeting sample 3","expected":["v1","RULE",0],"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\": [\"v2\", \"OFF\", -1], \"expected\": [\"v1\", \"OFF\", -1], \"passed\": false}, {\"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\": \"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}, {\"check\": \"targeting sample 3\", \"actual\": [\"v1\", \"RULE\", 0], \"expected\": [\"v1\", \"RULE\", 0], \"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."}}