{"abstract":"Pausing an experiment pours its users into an overlapping experiment listed later.","category":"Feature flag rollout bucketing","checks":8,"contract":"bucket = int(md5(layer_salt + \":\" + user) hex, 16) % 1000. experiments is an ordered list of {name, start, end, paused?} with start/end in percent (one decimal) converted to permille by round(x * 10); ranges are half-open [start, end). The first listed range containing the bucket decides: a paused experiment reserves its range (user gets None). Return [bucket, name or None].","evaluation_group":"w2-feature-flag-rollout-bucketing-exclusive-layer","failed_approach":"Reporting a paused marker name still labels the user as allocated.","family":"w2-feature-flag-rollout-bucketing-exclusive-layer-paused-range","id":"FA-74071","implementations":{"attempt":{"sha256":"d75fba5ba5c8220aca07e83bd152e68e6892dd451d964dbc9312df160662aae1","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport hashlib\nN = 1\nobservations = []\ndef solve(layer_salt, user, experiments):\n    bucket = int(hashlib.md5((layer_salt + ':' + user).encode()).hexdigest(), 16) % 1000\n    for exp in experiments:\n        lo = round(exp['start'] * 10)\n        hi = round(exp['end'] * 10)\n        if lo <= bucket < hi:\n            if exp.get('paused'):\n                return [bucket, exp['name'] + ':paused']\n            return [bucket, exp['name']]\n    return [bucket, None]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('bucket at range end belongs to next range',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 0, 'end': 98.8}, {'name': 'y', 'start': 98.8, 'end': 100}]],\n   [988, 'y']),\n  ('bucket at range start is included',\n   ['layer-b', 'bob', [{'name': 'x', 'start': 30.9, 'end': 100}]],\n   [309, 'x']),\n  ('paused range reserves its users',\n   ['layer-a',\n    'alice',\n    [{'name': 'x', 'start': 0, 'end': 100, 'paused': True}, {'name': 'y', 'start': 0, 'end': 100}]],\n   [988, None]),\n  ('first listed overlapping range wins',\n   ['layer-b',\n    'bob',\n    [{'name': 'wide', 'start': 0, 'end': 100}, {'name': 'narrow', 'start': 30.9, 'end': 31.0}]],\n   [309, 'wide']),\n  ('percent bounds convert to permille',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 98.3, 'end': 99.3}]],\n   [988, 'x']),\n  ('layer sample 1',\n   ['layer-a',\n    'u295',\n    [{'name': 'exp0', 'start': 50, 'end': 57.7, 'paused': False},\n     {'name': 'exp1', 'start': 0, 'end': 57.7, 'paused': False}]],\n   [576, 'exp0']),\n  ('layer sample 2',\n   ['layer-b',\n    'u4435',\n    [{'name': 'exp0', 'start': 0, 'end': 75.0, 'paused': True},\n     {'name': 'exp1', 'start': 0, 'end': 74.9, 'paused': False}]],\n   [750, None]),\n  ('layer sample 3',\n   ['layer-a',\n    'u3828',\n    [{'name': 'exp0', 'start': 1.72, 'end': 17.3, 'paused': False},\n     {'name': 'exp1', 'start': 0, 'end': 17.3, 'paused': True}]],\n   [172, 'exp0'])],\n [('bucket at range start is included',\n   ['layer-b', 'bob', [{'name': 'x', 'start': 30.9, 'end': 100}]],\n   [309, 'x']),\n  ('paused range reserves its users',\n   ['layer-a',\n    'alice',\n    [{'name': 'x', 'start': 0, 'end': 100, 'paused': True}, {'name': 'y', 'start': 0, 'end': 100}]],\n   [988, None]),\n  ('first listed overlapping range wins',\n   ['layer-b',\n    'bob',\n    [{'name': 'wide', 'start': 0, 'end': 100}, {'name': 'narrow', 'start': 30.9, 'end': 31.0}]],\n   [309, 'wide']),\n  ('percent bounds convert to permille',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 98.3, 'end': 99.3}]],\n   [988, 'x']),\n  ('no range matches', ['layer-b', 'bob', [{'name': 'x', 'start': 0, 'end': 0}]], [309, None]),\n  ('layer sample 6',\n   ['layer-a', 'u2869', [{'name': 'exp0', 'start': 28.1, 'end': 50, 'paused': False}]],\n   [282, 'exp0']),\n  ('layer sample 18',\n   ['layer-b',\n    'u4000',\n    [{'name': 'exp0', 'start': 0, 'end': 2.83, 'paused': False},\n     {'name': 'exp1', 'start': 0, 'end': 100, 'paused': True},\n     {'name': 'exp2', 'start': 28.2, 'end': 28.4, 'paused': False}]],\n   [283, None]),\n  ('layer sample 34',\n   ['layer-b', 'u91', [{'name': 'exp0', 'start': 41.6, 'end': 41.8, 'paused': True}]],\n   [417, None])],\n [('paused range reserves its users',\n   ['layer-a',\n    'alice',\n    [{'name': 'x', 'start': 0, 'end': 100, 'paused': True}, {'name': 'y', 'start': 0, 'end': 100}]],\n   [988, None]),\n  ('first listed overlapping range wins',\n   ['layer-b',\n    'bob',\n    [{'name': 'wide', 'start': 0, 'end': 100}, {'name': 'narrow', 'start': 30.9, 'end': 31.0}]],\n   [309, 'wide']),\n  ('percent bounds convert to permille',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 98.3, 'end': 99.3}]],\n   [988, 'x']),\n  ('no range matches', ['layer-b', 'bob', [{'name': 'x', 'start': 0, 'end': 0}]], [309, None]),\n  ('empty experiment list', ['layer-a', 'carol', []], [970, None]),\n  ('layer sample 11',\n   ['layer-b',\n    'u3995',\n    [{'name': 'exp0', 'start': 50, 'end': 84.5, 'paused': True},\n     {'name': 'exp1', 'start': 8.45, 'end': 84.5, 'paused': True}]],\n   [845, None]),\n  ('layer sample 12',\n   ['layer-a', 'u3185', [{'name': 'exp0', 'start': 50, 'end': 98.8, 'paused': False}]],\n   [344, None]),\n  ('layer sample 50',\n   ['layer-b',\n    'u369',\n    [{'name': 'exp0', 'start': 8.27, 'end': 90.0, 'paused': True},\n     {'name': 'exp1', 'start': 8.27, 'end': 82.8, 'paused': False}]],\n   [827, None])],\n [('bucket at range end belongs to next range',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 0, 'end': 98.8}, {'name': 'y', 'start': 98.8, 'end': 100}]],\n   [988, 'y']),\n  ('first listed overlapping range wins',\n   ['layer-b',\n    'bob',\n    [{'name': 'wide', 'start': 0, 'end': 100}, {'name': 'narrow', 'start': 30.9, 'end': 31.0}]],\n   [309, 'wide']),\n  ('percent bounds convert to permille',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 98.3, 'end': 99.3}]],\n   [988, 'x']),\n  ('no range matches', ['layer-b', 'bob', [{'name': 'x', 'start': 0, 'end': 0}]], [309, None]),\n  ('empty experiment list', ['layer-a', 'carol', []], [970, None]),\n  ('layer sample 16',\n   ['layer-a',\n    'u4745',\n    [{'name': 'exp0', 'start': 81.9, 'end': 100, 'paused': True},\n     {'name': 'exp1', 'start': 8.19, 'end': 82.0, 'paused': True},\n     {'name': 'exp2', 'start': 50, 'end': 82.0, 'paused': False}]],\n   [819, None]),\n  ('layer sample 17',\n   ['layer-a',\n    'u1058',\n    [{'name': 'exp0', 'start': 39.5, 'end': 100, 'paused': False},\n     {'name': 'exp1', 'start': 39.3, 'end': 39.4, 'paused': False}]],\n   [394, None]),\n  ('layer sample 34',\n   ['layer-b', 'u91', [{'name': 'exp0', 'start': 41.6, 'end': 41.8, 'paused': True}]],\n   [417, None])],\n [('bucket at range end belongs to next range',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 0, 'end': 98.8}, {'name': 'y', 'start': 98.8, 'end': 100}]],\n   [988, 'y']),\n  ('bucket at range start is included',\n   ['layer-b', 'bob', [{'name': 'x', 'start': 30.9, 'end': 100}]],\n   [309, 'x']),\n  ('paused range reserves its users',\n   ['layer-a',\n    'alice',\n    [{'name': 'x', 'start': 0, 'end': 100, 'paused': True}, {'name': 'y', 'start': 0, 'end': 100}]],\n   [988, None]),\n  ('percent bounds convert to permille',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 98.3, 'end': 99.3}]],\n   [988, 'x']),\n  ('no range matches', ['layer-b', 'bob', [{'name': 'x', 'start': 0, 'end': 0}]], [309, None]),\n  ('empty experiment list', ['layer-a', 'carol', []], [970, None]),\n  ('layer sample 21',\n   ['layer-a',\n    'u505',\n    [{'name': 'exp0', 'start': 0, 'end': 100, 'paused': False},\n     {'name': 'exp1', 'start': 54.1, 'end': 100, 'paused': False}]],\n   [540, 'exp0']),\n  ('layer sample 23',\n   ['layer-b',\n    'u3183',\n    [{'name': 'exp0', 'start': 0, 'end': 50, 'paused': True},\n     {'name': 'exp1', 'start': 23.6, 'end': 100, 'paused': False},\n     {'name': 'exp2', 'start': 23.7, 'end': 50, 'paused': False}]],\n   [236, None])]]\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":"43b5b6ff6839ae2f0b4f96ce74f3985a57eda70f8d44e284e4a7b7e966e48157","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport hashlib\nN = 1\nobservations = []\ndef solve(layer_salt, user, experiments):\n    bucket = int(hashlib.md5((layer_salt + ':' + user).encode()).hexdigest(), 16) % 1000\n    for exp in experiments:\n        lo = round(exp['start'] * 10)\n        hi = round(exp['end'] * 10)\n        if lo <= bucket < hi:\n            if exp.get('paused'):\n                continue\n            return [bucket, exp['name']]\n    return [bucket, None]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('bucket at range end belongs to next range',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 0, 'end': 98.8}, {'name': 'y', 'start': 98.8, 'end': 100}]],\n   [988, 'y']),\n  ('bucket at range start is included',\n   ['layer-b', 'bob', [{'name': 'x', 'start': 30.9, 'end': 100}]],\n   [309, 'x']),\n  ('paused range reserves its users',\n   ['layer-a',\n    'alice',\n    [{'name': 'x', 'start': 0, 'end': 100, 'paused': True}, {'name': 'y', 'start': 0, 'end': 100}]],\n   [988, None]),\n  ('first listed overlapping range wins',\n   ['layer-b',\n    'bob',\n    [{'name': 'wide', 'start': 0, 'end': 100}, {'name': 'narrow', 'start': 30.9, 'end': 31.0}]],\n   [309, 'wide']),\n  ('percent bounds convert to permille',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 98.3, 'end': 99.3}]],\n   [988, 'x']),\n  ('layer sample 1',\n   ['layer-a',\n    'u295',\n    [{'name': 'exp0', 'start': 50, 'end': 57.7, 'paused': False},\n     {'name': 'exp1', 'start': 0, 'end': 57.7, 'paused': False}]],\n   [576, 'exp0']),\n  ('layer sample 2',\n   ['layer-b',\n    'u4435',\n    [{'name': 'exp0', 'start': 0, 'end': 75.0, 'paused': True},\n     {'name': 'exp1', 'start': 0, 'end': 74.9, 'paused': False}]],\n   [750, None]),\n  ('layer sample 3',\n   ['layer-a',\n    'u3828',\n    [{'name': 'exp0', 'start': 1.72, 'end': 17.3, 'paused': False},\n     {'name': 'exp1', 'start': 0, 'end': 17.3, 'paused': True}]],\n   [172, 'exp0'])],\n [('bucket at range start is included',\n   ['layer-b', 'bob', [{'name': 'x', 'start': 30.9, 'end': 100}]],\n   [309, 'x']),\n  ('paused range reserves its users',\n   ['layer-a',\n    'alice',\n    [{'name': 'x', 'start': 0, 'end': 100, 'paused': True}, {'name': 'y', 'start': 0, 'end': 100}]],\n   [988, None]),\n  ('first listed overlapping range wins',\n   ['layer-b',\n    'bob',\n    [{'name': 'wide', 'start': 0, 'end': 100}, {'name': 'narrow', 'start': 30.9, 'end': 31.0}]],\n   [309, 'wide']),\n  ('percent bounds convert to permille',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 98.3, 'end': 99.3}]],\n   [988, 'x']),\n  ('no range matches', ['layer-b', 'bob', [{'name': 'x', 'start': 0, 'end': 0}]], [309, None]),\n  ('layer sample 6',\n   ['layer-a', 'u2869', [{'name': 'exp0', 'start': 28.1, 'end': 50, 'paused': False}]],\n   [282, 'exp0']),\n  ('layer sample 18',\n   ['layer-b',\n    'u4000',\n    [{'name': 'exp0', 'start': 0, 'end': 2.83, 'paused': False},\n     {'name': 'exp1', 'start': 0, 'end': 100, 'paused': True},\n     {'name': 'exp2', 'start': 28.2, 'end': 28.4, 'paused': False}]],\n   [283, None]),\n  ('layer sample 34',\n   ['layer-b', 'u91', [{'name': 'exp0', 'start': 41.6, 'end': 41.8, 'paused': True}]],\n   [417, None])],\n [('paused range reserves its users',\n   ['layer-a',\n    'alice',\n    [{'name': 'x', 'start': 0, 'end': 100, 'paused': True}, {'name': 'y', 'start': 0, 'end': 100}]],\n   [988, None]),\n  ('first listed overlapping range wins',\n   ['layer-b',\n    'bob',\n    [{'name': 'wide', 'start': 0, 'end': 100}, {'name': 'narrow', 'start': 30.9, 'end': 31.0}]],\n   [309, 'wide']),\n  ('percent bounds convert to permille',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 98.3, 'end': 99.3}]],\n   [988, 'x']),\n  ('no range matches', ['layer-b', 'bob', [{'name': 'x', 'start': 0, 'end': 0}]], [309, None]),\n  ('empty experiment list', ['layer-a', 'carol', []], [970, None]),\n  ('layer sample 11',\n   ['layer-b',\n    'u3995',\n    [{'name': 'exp0', 'start': 50, 'end': 84.5, 'paused': True},\n     {'name': 'exp1', 'start': 8.45, 'end': 84.5, 'paused': True}]],\n   [845, None]),\n  ('layer sample 12',\n   ['layer-a', 'u3185', [{'name': 'exp0', 'start': 50, 'end': 98.8, 'paused': False}]],\n   [344, None]),\n  ('layer sample 50',\n   ['layer-b',\n    'u369',\n    [{'name': 'exp0', 'start': 8.27, 'end': 90.0, 'paused': True},\n     {'name': 'exp1', 'start': 8.27, 'end': 82.8, 'paused': False}]],\n   [827, None])],\n [('bucket at range end belongs to next range',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 0, 'end': 98.8}, {'name': 'y', 'start': 98.8, 'end': 100}]],\n   [988, 'y']),\n  ('first listed overlapping range wins',\n   ['layer-b',\n    'bob',\n    [{'name': 'wide', 'start': 0, 'end': 100}, {'name': 'narrow', 'start': 30.9, 'end': 31.0}]],\n   [309, 'wide']),\n  ('percent bounds convert to permille',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 98.3, 'end': 99.3}]],\n   [988, 'x']),\n  ('no range matches', ['layer-b', 'bob', [{'name': 'x', 'start': 0, 'end': 0}]], [309, None]),\n  ('empty experiment list', ['layer-a', 'carol', []], [970, None]),\n  ('layer sample 16',\n   ['layer-a',\n    'u4745',\n    [{'name': 'exp0', 'start': 81.9, 'end': 100, 'paused': True},\n     {'name': 'exp1', 'start': 8.19, 'end': 82.0, 'paused': True},\n     {'name': 'exp2', 'start': 50, 'end': 82.0, 'paused': False}]],\n   [819, None]),\n  ('layer sample 17',\n   ['layer-a',\n    'u1058',\n    [{'name': 'exp0', 'start': 39.5, 'end': 100, 'paused': False},\n     {'name': 'exp1', 'start': 39.3, 'end': 39.4, 'paused': False}]],\n   [394, None]),\n  ('layer sample 34',\n   ['layer-b', 'u91', [{'name': 'exp0', 'start': 41.6, 'end': 41.8, 'paused': True}]],\n   [417, None])],\n [('bucket at range end belongs to next range',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 0, 'end': 98.8}, {'name': 'y', 'start': 98.8, 'end': 100}]],\n   [988, 'y']),\n  ('bucket at range start is included',\n   ['layer-b', 'bob', [{'name': 'x', 'start': 30.9, 'end': 100}]],\n   [309, 'x']),\n  ('paused range reserves its users',\n   ['layer-a',\n    'alice',\n    [{'name': 'x', 'start': 0, 'end': 100, 'paused': True}, {'name': 'y', 'start': 0, 'end': 100}]],\n   [988, None]),\n  ('percent bounds convert to permille',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 98.3, 'end': 99.3}]],\n   [988, 'x']),\n  ('no range matches', ['layer-b', 'bob', [{'name': 'x', 'start': 0, 'end': 0}]], [309, None]),\n  ('empty experiment list', ['layer-a', 'carol', []], [970, None]),\n  ('layer sample 21',\n   ['layer-a',\n    'u505',\n    [{'name': 'exp0', 'start': 0, 'end': 100, 'paused': False},\n     {'name': 'exp1', 'start': 54.1, 'end': 100, 'paused': False}]],\n   [540, 'exp0']),\n  ('layer sample 23',\n   ['layer-b',\n    'u3183',\n    [{'name': 'exp0', 'start': 0, 'end': 50, 'paused': True},\n     {'name': 'exp1', 'start': 23.6, 'end': 100, 'paused': False},\n     {'name': 'exp2', 'start': 23.7, 'end': 50, 'paused': False}]],\n   [236, None])]]\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"},"fixed":{"sha256":"d667c550ef131eadf04eb52abed74bcf2182e1cf0f05b172f8aa720df057ea29","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport hashlib\nN = 1\nobservations = []\ndef solve(layer_salt, user, experiments):\n    bucket = int(hashlib.md5((layer_salt + ':' + user).encode()).hexdigest(), 16) % 1000\n    for exp in experiments:\n        lo = round(exp['start'] * 10)\n        hi = round(exp['end'] * 10)\n        if lo <= bucket < hi:\n            if exp.get('paused'):\n                return [bucket, None]\n            return [bucket, exp['name']]\n    return [bucket, None]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('bucket at range end belongs to next range',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 0, 'end': 98.8}, {'name': 'y', 'start': 98.8, 'end': 100}]],\n   [988, 'y']),\n  ('bucket at range start is included',\n   ['layer-b', 'bob', [{'name': 'x', 'start': 30.9, 'end': 100}]],\n   [309, 'x']),\n  ('paused range reserves its users',\n   ['layer-a',\n    'alice',\n    [{'name': 'x', 'start': 0, 'end': 100, 'paused': True}, {'name': 'y', 'start': 0, 'end': 100}]],\n   [988, None]),\n  ('first listed overlapping range wins',\n   ['layer-b',\n    'bob',\n    [{'name': 'wide', 'start': 0, 'end': 100}, {'name': 'narrow', 'start': 30.9, 'end': 31.0}]],\n   [309, 'wide']),\n  ('percent bounds convert to permille',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 98.3, 'end': 99.3}]],\n   [988, 'x']),\n  ('layer sample 1',\n   ['layer-a',\n    'u295',\n    [{'name': 'exp0', 'start': 50, 'end': 57.7, 'paused': False},\n     {'name': 'exp1', 'start': 0, 'end': 57.7, 'paused': False}]],\n   [576, 'exp0']),\n  ('layer sample 2',\n   ['layer-b',\n    'u4435',\n    [{'name': 'exp0', 'start': 0, 'end': 75.0, 'paused': True},\n     {'name': 'exp1', 'start': 0, 'end': 74.9, 'paused': False}]],\n   [750, None]),\n  ('layer sample 3',\n   ['layer-a',\n    'u3828',\n    [{'name': 'exp0', 'start': 1.72, 'end': 17.3, 'paused': False},\n     {'name': 'exp1', 'start': 0, 'end': 17.3, 'paused': True}]],\n   [172, 'exp0'])],\n [('bucket at range start is included',\n   ['layer-b', 'bob', [{'name': 'x', 'start': 30.9, 'end': 100}]],\n   [309, 'x']),\n  ('paused range reserves its users',\n   ['layer-a',\n    'alice',\n    [{'name': 'x', 'start': 0, 'end': 100, 'paused': True}, {'name': 'y', 'start': 0, 'end': 100}]],\n   [988, None]),\n  ('first listed overlapping range wins',\n   ['layer-b',\n    'bob',\n    [{'name': 'wide', 'start': 0, 'end': 100}, {'name': 'narrow', 'start': 30.9, 'end': 31.0}]],\n   [309, 'wide']),\n  ('percent bounds convert to permille',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 98.3, 'end': 99.3}]],\n   [988, 'x']),\n  ('no range matches', ['layer-b', 'bob', [{'name': 'x', 'start': 0, 'end': 0}]], [309, None]),\n  ('layer sample 6',\n   ['layer-a', 'u2869', [{'name': 'exp0', 'start': 28.1, 'end': 50, 'paused': False}]],\n   [282, 'exp0']),\n  ('layer sample 18',\n   ['layer-b',\n    'u4000',\n    [{'name': 'exp0', 'start': 0, 'end': 2.83, 'paused': False},\n     {'name': 'exp1', 'start': 0, 'end': 100, 'paused': True},\n     {'name': 'exp2', 'start': 28.2, 'end': 28.4, 'paused': False}]],\n   [283, None]),\n  ('layer sample 34',\n   ['layer-b', 'u91', [{'name': 'exp0', 'start': 41.6, 'end': 41.8, 'paused': True}]],\n   [417, None])],\n [('paused range reserves its users',\n   ['layer-a',\n    'alice',\n    [{'name': 'x', 'start': 0, 'end': 100, 'paused': True}, {'name': 'y', 'start': 0, 'end': 100}]],\n   [988, None]),\n  ('first listed overlapping range wins',\n   ['layer-b',\n    'bob',\n    [{'name': 'wide', 'start': 0, 'end': 100}, {'name': 'narrow', 'start': 30.9, 'end': 31.0}]],\n   [309, 'wide']),\n  ('percent bounds convert to permille',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 98.3, 'end': 99.3}]],\n   [988, 'x']),\n  ('no range matches', ['layer-b', 'bob', [{'name': 'x', 'start': 0, 'end': 0}]], [309, None]),\n  ('empty experiment list', ['layer-a', 'carol', []], [970, None]),\n  ('layer sample 11',\n   ['layer-b',\n    'u3995',\n    [{'name': 'exp0', 'start': 50, 'end': 84.5, 'paused': True},\n     {'name': 'exp1', 'start': 8.45, 'end': 84.5, 'paused': True}]],\n   [845, None]),\n  ('layer sample 12',\n   ['layer-a', 'u3185', [{'name': 'exp0', 'start': 50, 'end': 98.8, 'paused': False}]],\n   [344, None]),\n  ('layer sample 50',\n   ['layer-b',\n    'u369',\n    [{'name': 'exp0', 'start': 8.27, 'end': 90.0, 'paused': True},\n     {'name': 'exp1', 'start': 8.27, 'end': 82.8, 'paused': False}]],\n   [827, None])],\n [('bucket at range end belongs to next range',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 0, 'end': 98.8}, {'name': 'y', 'start': 98.8, 'end': 100}]],\n   [988, 'y']),\n  ('first listed overlapping range wins',\n   ['layer-b',\n    'bob',\n    [{'name': 'wide', 'start': 0, 'end': 100}, {'name': 'narrow', 'start': 30.9, 'end': 31.0}]],\n   [309, 'wide']),\n  ('percent bounds convert to permille',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 98.3, 'end': 99.3}]],\n   [988, 'x']),\n  ('no range matches', ['layer-b', 'bob', [{'name': 'x', 'start': 0, 'end': 0}]], [309, None]),\n  ('empty experiment list', ['layer-a', 'carol', []], [970, None]),\n  ('layer sample 16',\n   ['layer-a',\n    'u4745',\n    [{'name': 'exp0', 'start': 81.9, 'end': 100, 'paused': True},\n     {'name': 'exp1', 'start': 8.19, 'end': 82.0, 'paused': True},\n     {'name': 'exp2', 'start': 50, 'end': 82.0, 'paused': False}]],\n   [819, None]),\n  ('layer sample 17',\n   ['layer-a',\n    'u1058',\n    [{'name': 'exp0', 'start': 39.5, 'end': 100, 'paused': False},\n     {'name': 'exp1', 'start': 39.3, 'end': 39.4, 'paused': False}]],\n   [394, None]),\n  ('layer sample 34',\n   ['layer-b', 'u91', [{'name': 'exp0', 'start': 41.6, 'end': 41.8, 'paused': True}]],\n   [417, None])],\n [('bucket at range end belongs to next range',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 0, 'end': 98.8}, {'name': 'y', 'start': 98.8, 'end': 100}]],\n   [988, 'y']),\n  ('bucket at range start is included',\n   ['layer-b', 'bob', [{'name': 'x', 'start': 30.9, 'end': 100}]],\n   [309, 'x']),\n  ('paused range reserves its users',\n   ['layer-a',\n    'alice',\n    [{'name': 'x', 'start': 0, 'end': 100, 'paused': True}, {'name': 'y', 'start': 0, 'end': 100}]],\n   [988, None]),\n  ('percent bounds convert to permille',\n   ['layer-a', 'alice', [{'name': 'x', 'start': 98.3, 'end': 99.3}]],\n   [988, 'x']),\n  ('no range matches', ['layer-b', 'bob', [{'name': 'x', 'start': 0, 'end': 0}]], [309, None]),\n  ('empty experiment list', ['layer-a', 'carol', []], [970, None]),\n  ('layer sample 21',\n   ['layer-a',\n    'u505',\n    [{'name': 'exp0', 'start': 0, 'end': 100, 'paused': False},\n     {'name': 'exp1', 'start': 54.1, 'end': 100, 'paused': False}]],\n   [540, 'exp0']),\n  ('layer sample 23',\n   ['layer-b',\n    'u3183',\n    [{'name': 'exp0', 'start': 0, 'end': 50, 'paused': True},\n     {'name': 'exp1', 'start': 23.6, 'end': 100, 'paused': False},\n     {'name': 'exp2', 'start': 23.7, 'end': 50, 'paused': False}]],\n   [236, None])]]\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-exclusive-layer-paused-range","generated_at":"2026-09-29T14:48:53.247649+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Layers keep concurrent experiments from overlapping on the same users.","repair":"Return no experiment for users inside a paused experiment's range.","root_cause":"A paused experiment is skipped with continue instead of reserving its range.","sha256":"392332a94d6e4c17b0374625993fac47289088b6aed6d3f8d489c95c93552fd4","title":"Mutually exclusive layer allocation: Paused experiments release their range · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":42.322,"exit_code":1,"observations":[{"actual":[988,"y"],"check":"bucket at range end belongs to next range","expected":[988,"y"],"passed":true},{"actual":[309,"x"],"check":"bucket at range start is included","expected":[309,"x"],"passed":true},{"actual":[988,"x:paused"],"check":"paused range reserves its users","expected":[988,null],"passed":false},{"actual":[309,"wide"],"check":"first listed overlapping range wins","expected":[309,"wide"],"passed":true},{"actual":[988,"x"],"check":"percent bounds convert to permille","expected":[988,"x"],"passed":true},{"actual":[576,"exp0"],"check":"layer sample 1","expected":[576,"exp0"],"passed":true},{"actual":[750,null],"check":"layer sample 2","expected":[750,null],"passed":true},{"actual":[172,"exp0"],"check":"layer sample 3","expected":[172,"exp0"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"bucket at range end belongs to next range\", \"actual\": [988, \"y\"], \"expected\": [988, \"y\"], \"passed\": true}, {\"check\": \"bucket at range start is included\", \"actual\": [309, \"x\"], \"expected\": [309, \"x\"], \"passed\": true}, {\"check\": \"paused range reserves its users\", \"actual\": [988, \"x:paused\"], \"expected\": [988, null], \"passed\": false}, {\"check\": \"first listed overlapping range wins\", \"actual\": [309, \"wide\"], \"expected\": [309, \"wide\"], \"passed\": true}, {\"check\": \"percent bounds convert to permille\", \"actual\": [988, \"x\"], \"expected\": [988, \"x\"], \"passed\": true}, {\"check\": \"layer sample 1\", \"actual\": [576, \"exp0\"], \"expected\": [576, \"exp0\"], \"passed\": true}, {\"check\": \"layer sample 2\", \"actual\": [750, null], \"expected\": [750, null], \"passed\": true}, {\"check\": \"layer sample 3\", \"actual\": [172, \"exp0\"], \"expected\": [172, \"exp0\"], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":41.089,"exit_code":1,"observations":[{"actual":[988,"y"],"check":"bucket at range end belongs to next range","expected":[988,"y"],"passed":true},{"actual":[309,"x"],"check":"bucket at range start is included","expected":[309,"x"],"passed":true},{"actual":[988,"y"],"check":"paused range reserves its users","expected":[988,null],"passed":false},{"actual":[309,"wide"],"check":"first listed overlapping range wins","expected":[309,"wide"],"passed":true},{"actual":[988,"x"],"check":"percent bounds convert to permille","expected":[988,"x"],"passed":true},{"actual":[576,"exp0"],"check":"layer sample 1","expected":[576,"exp0"],"passed":true},{"actual":[750,null],"check":"layer sample 2","expected":[750,null],"passed":true},{"actual":[172,"exp0"],"check":"layer sample 3","expected":[172,"exp0"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"bucket at range end belongs to next range\", \"actual\": [988, \"y\"], \"expected\": [988, \"y\"], \"passed\": true}, {\"check\": \"bucket at range start is included\", \"actual\": [309, \"x\"], \"expected\": [309, \"x\"], \"passed\": true}, {\"check\": \"paused range reserves its users\", \"actual\": [988, \"y\"], \"expected\": [988, null], \"passed\": false}, {\"check\": \"first listed overlapping range wins\", \"actual\": [309, \"wide\"], \"expected\": [309, \"wide\"], \"passed\": true}, {\"check\": \"percent bounds convert to permille\", \"actual\": [988, \"x\"], \"expected\": [988, \"x\"], \"passed\": true}, {\"check\": \"layer sample 1\", \"actual\": [576, \"exp0\"], \"expected\": [576, \"exp0\"], \"passed\": true}, {\"check\": \"layer sample 2\", \"actual\": [750, null], \"expected\": [750, null], \"passed\": true}, {\"check\": \"layer sample 3\", \"actual\": [172, \"exp0\"], \"expected\": [172, \"exp0\"], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":40.26,"exit_code":0,"observations":[{"actual":[988,"y"],"check":"bucket at range end belongs to next range","expected":[988,"y"],"passed":true},{"actual":[309,"x"],"check":"bucket at range start is included","expected":[309,"x"],"passed":true},{"actual":[988,null],"check":"paused range reserves its users","expected":[988,null],"passed":true},{"actual":[309,"wide"],"check":"first listed overlapping range wins","expected":[309,"wide"],"passed":true},{"actual":[988,"x"],"check":"percent bounds convert to permille","expected":[988,"x"],"passed":true},{"actual":[576,"exp0"],"check":"layer sample 1","expected":[576,"exp0"],"passed":true},{"actual":[750,null],"check":"layer sample 2","expected":[750,null],"passed":true},{"actual":[172,"exp0"],"check":"layer sample 3","expected":[172,"exp0"],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"bucket at range end belongs to next range\", \"actual\": [988, \"y\"], \"expected\": [988, \"y\"], \"passed\": true}, {\"check\": \"bucket at range start is included\", \"actual\": [309, \"x\"], \"expected\": [309, \"x\"], \"passed\": true}, {\"check\": \"paused range reserves its users\", \"actual\": [988, null], \"expected\": [988, null], \"passed\": true}, {\"check\": \"first listed overlapping range wins\", \"actual\": [309, \"wide\"], \"expected\": [309, \"wide\"], \"passed\": true}, {\"check\": \"percent bounds convert to permille\", \"actual\": [988, \"x\"], \"expected\": [988, \"x\"], \"passed\": true}, {\"check\": \"layer sample 1\", \"actual\": [576, \"exp0\"], \"expected\": [576, \"exp0\"], \"passed\": true}, {\"check\": \"layer sample 2\", \"actual\": [750, null], \"expected\": [750, null], \"passed\": true}, {\"check\": \"layer sample 3\", \"actual\": [172, \"exp0\"], \"expected\": [172, \"exp0\"], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}