FAILURE MAP
← Case archive

FA-73886 / Feature flag rollout bucketing / Open access

Weighted variant allocation: Fractional weights are truncated to basis points · case 01

A 0.29 percent arm covers only 28 buckets and 33.33 percent splits leak buckets.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

Each weight is converted with int(weight * 100), truncating float representation error.

VERIFIED REPAIR

Convert each weight with round(weight * 100).

Unsuccessful approach: Truncating the weight before scaling discards the fractional percent entirely.

Case contract

variants is an ordered list of [name, weight percent with at most two decimals]; bucket is an integer in [0, 10000). Walk variants in declared order, skipping non-positive weights, adding round(weight * 100) to a running total, and return the first variant whose total exceeds the bucket. Buckets beyond the total go to the last positively weighted variant; with none, None.

Why this case matters

Variant splits decide which arm of a flag a user receives and must honour declared weights exactly.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(variants, bucket):
    acc = 0
    last = None
    for name, weight in variants:
        if weight <= 0:
            continue
        last = name
        acc += int(weight * 100)
        if bucket < acc:
            return name
    return last
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('bucket at first cumulative edge goes to second arm',
   [[['control', 50], ['treatment', 50]], 5000],
   'treatment'),
  ('bucket just below first edge stays in first arm',
   [[['control', 50], ['treatment', 50]], 4999],
   'control'),
  ('zero weight arm is never selected', [[['control', 0], ['treatment', 100]], 0], 'treatment'),
  ('trailing zero weight arm does not absorb remainder',
   [[['control', 40], ['treatment', 40], ['off', 0]], 9000],
   'treatment'),
  ('declared order beats alphabetical order', [[['zeta', 10], ['alpha', 90]], 500], 'zeta'),
  ('fractional weight 0.29 covers 29 buckets', [[['tiny', 0.29], ['rest', 99.71]], 28], 'tiny'),
  ('weight table sample 1', [[['green', 1.15], ['holdout', 0], ['alpha', 1.15], ['blue', 50]], 1135], 'blue'),
  ('weight table sample 2', [[['blue', 50], ['treatment', 10]], 2986], 'blue')],
 [('bucket just below first edge stays in first arm',
   [[['control', 50], ['treatment', 50]], 4999],
   'control'),
  ('zero weight arm is never selected', [[['control', 0], ['treatment', 100]], 0], 'treatment'),
  ('trailing zero weight arm does not absorb remainder',
   [[['control', 40], ['treatment', 40], ['off', 0]], 9000],
   'treatment'),
  ('declared order beats alphabetical order', [[['zeta', 10], ['alpha', 90]], 500], 'zeta'),
  ('fractional weight 0.29 covers 29 buckets', [[['tiny', 0.29], ['rest', 99.71]], 28], 'tiny'),
  ('weight table sample 6',
   [[['alpha', 0.29], ['holdout', 12.5], ['blue', 0.57], ['treatment', 0]], 204],
   'holdout'),
  ('weight table sample 7', [[['treatment', -5], ['holdout', 10], ['green', 50]], 5999], 'green'),
  ('weight table sample 23', [[['blue', 33.33], ['treatment', 0.29], ['alpha', 10]], 3361], 'treatment')],
 [('zero weight arm is never selected', [[['control', 0], ['treatment', 100]], 0], 'treatment'),
  ('trailing zero weight arm does not absorb remainder',
   [[['control', 40], ['treatment', 40], ['off', 0]], 9000],
   'treatment'),
  ('declared order beats alphabetical order', [[['zeta', 10], ['alpha', 90]], 500], 'zeta'),
  ('fractional weight 0.29 covers 29 buckets', [[['tiny', 0.29], ['rest', 99.71]], 28], 'tiny'),
  ('no positive weights yields None', [[['a', 0], ['b', 0]], 10], None),
  ('weight table sample 11', [[['holdout', 12.5], ['blue', 12.5], ['alpha', 0.57]], 2500], 'alpha'),
  ('weight table sample 12', [[['blue', 12.5], ['holdout', 0]], 1249], 'blue'),
  ('weight table sample 31', [[['green', 1.15], ['blue', 33.33], ['treatment', 4.35]], 3447], 'blue')],
 [('trailing zero weight arm does not absorb remainder',
   [[['control', 40], ['treatment', 40], ['off', 0]], 9000],
   'treatment'),
  ('declared order beats alphabetical order', [[['zeta', 10], ['alpha', 90]], 500], 'zeta'),
  ('fractional weight 0.29 covers 29 buckets', [[['tiny', 0.29], ['rest', 99.71]], 28], 'tiny'),
  ('no positive weights yields None', [[['a', 0], ['b', 0]], 10], None),
  ('three way split middle arm', [[['a', 33.33], ['b', 33.33], ['c', 33.34]], 5000], 'b'),
  ('weight table sample 16', [[['green', 0.57], ['alpha', 12.5], ['control', 25]], 1307], 'control'),
  ('weight table sample 17', [[['treatment', 1.15], ['control', 0.29], ['blue', 0.29]], 2597], 'blue'),
  ('weight table sample 45',
   [[['control', 4.35], ['blue', 50], ['treatment', 50], ['alpha', 50]], 5434],
   'blue')],
 [('bucket at first cumulative edge goes to second arm',
   [[['control', 50], ['treatment', 50]], 5000],
   'treatment'),
  ('declared order beats alphabetical order', [[['zeta', 10], ['alpha', 90]], 500], 'zeta'),
  ('fractional weight 0.29 covers 29 buckets', [[['tiny', 0.29], ['rest', 99.71]], 28], 'tiny'),
  ('no positive weights yields None', [[['a', 0], ['b', 0]], 10], None),
  ('three way split middle arm', [[['a', 33.33], ['b', 33.33], ['c', 33.34]], 5000], 'b'),
  ('weight table sample 21', [[['green', 33.33], ['treatment', 0]], 0], 'green'),
  ('weight table sample 22', [[['alpha', 0], ['control', 4.35], ['blue', 1.15]], 9182], 'blue'),
  ('weight table sample 50',
   [[['blue', 12.5], ['control', 0.57], ['green', 4.35], ['holdout', 0.29]], 1741],
   'green')]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
bucket at first cumulative edge goes to second armtreatmenttreatmentPassed
bucket just below first edge stays in first armcontrolcontrolPassed
zero weight arm is never selectedtreatmenttreatmentPassed
trailing zero weight arm does not absorb remaindertreatmenttreatmentPassed
declared order beats alphabetical orderzetazetaPassed
fractional weight 0.29 covers 29 bucketsresttinyFailed
weight table sample 1bluebluePassed
weight table sample 2bluebluePassed

SHA-256 / 41689de092f6a3ece57ed6023ea151dd4abbb521996041293a08e22405b2be99

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(variants, bucket):
    acc = 0
    last = None
    for name, weight in variants:
        if weight <= 0:
            continue
        last = name
        acc += int(weight) * 100
        if bucket < acc:
            return name
    return last
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('bucket at first cumulative edge goes to second arm',
   [[['control', 50], ['treatment', 50]], 5000],
   'treatment'),
  ('bucket just below first edge stays in first arm',
   [[['control', 50], ['treatment', 50]], 4999],
   'control'),
  ('zero weight arm is never selected', [[['control', 0], ['treatment', 100]], 0], 'treatment'),
  ('trailing zero weight arm does not absorb remainder',
   [[['control', 40], ['treatment', 40], ['off', 0]], 9000],
   'treatment'),
  ('declared order beats alphabetical order', [[['zeta', 10], ['alpha', 90]], 500], 'zeta'),
  ('fractional weight 0.29 covers 29 buckets', [[['tiny', 0.29], ['rest', 99.71]], 28], 'tiny'),
  ('weight table sample 1', [[['green', 1.15], ['holdout', 0], ['alpha', 1.15], ['blue', 50]], 1135], 'blue'),
  ('weight table sample 2', [[['blue', 50], ['treatment', 10]], 2986], 'blue')],
 [('bucket just below first edge stays in first arm',
   [[['control', 50], ['treatment', 50]], 4999],
   'control'),
  ('zero weight arm is never selected', [[['control', 0], ['treatment', 100]], 0], 'treatment'),
  ('trailing zero weight arm does not absorb remainder',
   [[['control', 40], ['treatment', 40], ['off', 0]], 9000],
   'treatment'),
  ('declared order beats alphabetical order', [[['zeta', 10], ['alpha', 90]], 500], 'zeta'),
  ('fractional weight 0.29 covers 29 buckets', [[['tiny', 0.29], ['rest', 99.71]], 28], 'tiny'),
  ('weight table sample 6',
   [[['alpha', 0.29], ['holdout', 12.5], ['blue', 0.57], ['treatment', 0]], 204],
   'holdout'),
  ('weight table sample 7', [[['treatment', -5], ['holdout', 10], ['green', 50]], 5999], 'green'),
  ('weight table sample 23', [[['blue', 33.33], ['treatment', 0.29], ['alpha', 10]], 3361], 'treatment')],
 [('zero weight arm is never selected', [[['control', 0], ['treatment', 100]], 0], 'treatment'),
  ('trailing zero weight arm does not absorb remainder',
   [[['control', 40], ['treatment', 40], ['off', 0]], 9000],
   'treatment'),
  ('declared order beats alphabetical order', [[['zeta', 10], ['alpha', 90]], 500], 'zeta'),
  ('fractional weight 0.29 covers 29 buckets', [[['tiny', 0.29], ['rest', 99.71]], 28], 'tiny'),
  ('no positive weights yields None', [[['a', 0], ['b', 0]], 10], None),
  ('weight table sample 11', [[['holdout', 12.5], ['blue', 12.5], ['alpha', 0.57]], 2500], 'alpha'),
  ('weight table sample 12', [[['blue', 12.5], ['holdout', 0]], 1249], 'blue'),
  ('weight table sample 31', [[['green', 1.15], ['blue', 33.33], ['treatment', 4.35]], 3447], 'blue')],
 [('trailing zero weight arm does not absorb remainder',
   [[['control', 40], ['treatment', 40], ['off', 0]], 9000],
   'treatment'),
  ('declared order beats alphabetical order', [[['zeta', 10], ['alpha', 90]], 500], 'zeta'),
  ('fractional weight 0.29 covers 29 buckets', [[['tiny', 0.29], ['rest', 99.71]], 28], 'tiny'),
  ('no positive weights yields None', [[['a', 0], ['b', 0]], 10], None),
  ('three way split middle arm', [[['a', 33.33], ['b', 33.33], ['c', 33.34]], 5000], 'b'),
  ('weight table sample 16', [[['green', 0.57], ['alpha', 12.5], ['control', 25]], 1307], 'control'),
  ('weight table sample 17', [[['treatment', 1.15], ['control', 0.29], ['blue', 0.29]], 2597], 'blue'),
  ('weight table sample 45',
   [[['control', 4.35], ['blue', 50], ['treatment', 50], ['alpha', 50]], 5434],
   'blue')],
 [('bucket at first cumulative edge goes to second arm',
   [[['control', 50], ['treatment', 50]], 5000],
   'treatment'),
  ('declared order beats alphabetical order', [[['zeta', 10], ['alpha', 90]], 500], 'zeta'),
  ('fractional weight 0.29 covers 29 buckets', [[['tiny', 0.29], ['rest', 99.71]], 28], 'tiny'),
  ('no positive weights yields None', [[['a', 0], ['b', 0]], 10], None),
  ('three way split middle arm', [[['a', 33.33], ['b', 33.33], ['c', 33.34]], 5000], 'b'),
  ('weight table sample 21', [[['green', 33.33], ['treatment', 0]], 0], 'green'),
  ('weight table sample 22', [[['alpha', 0], ['control', 4.35], ['blue', 1.15]], 9182], 'blue'),
  ('weight table sample 50',
   [[['blue', 12.5], ['control', 0.57], ['green', 4.35], ['holdout', 0.29]], 1741],
   'green')]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
bucket at first cumulative edge goes to second armtreatmenttreatmentPassed
bucket just below first edge stays in first armcontrolcontrolPassed
zero weight arm is never selectedtreatmenttreatmentPassed
trailing zero weight arm does not absorb remaindertreatmenttreatmentPassed
declared order beats alphabetical orderzetazetaPassed
fractional weight 0.29 covers 29 bucketsresttinyFailed
weight table sample 1bluebluePassed
weight table sample 2bluebluePassed

SHA-256 / af20589ca4cab4f377794d54ecd264813ae6ecc57d7a2bae484eb26aca9c7e34

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(variants, bucket):
    acc = 0
    last = None
    for name, weight in variants:
        if weight <= 0:
            continue
        last = name
        acc += round(weight * 100)
        if bucket < acc:
            return name
    return last
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('bucket at first cumulative edge goes to second arm',
   [[['control', 50], ['treatment', 50]], 5000],
   'treatment'),
  ('bucket just below first edge stays in first arm',
   [[['control', 50], ['treatment', 50]], 4999],
   'control'),
  ('zero weight arm is never selected', [[['control', 0], ['treatment', 100]], 0], 'treatment'),
  ('trailing zero weight arm does not absorb remainder',
   [[['control', 40], ['treatment', 40], ['off', 0]], 9000],
   'treatment'),
  ('declared order beats alphabetical order', [[['zeta', 10], ['alpha', 90]], 500], 'zeta'),
  ('fractional weight 0.29 covers 29 buckets', [[['tiny', 0.29], ['rest', 99.71]], 28], 'tiny'),
  ('weight table sample 1', [[['green', 1.15], ['holdout', 0], ['alpha', 1.15], ['blue', 50]], 1135], 'blue'),
  ('weight table sample 2', [[['blue', 50], ['treatment', 10]], 2986], 'blue')],
 [('bucket just below first edge stays in first arm',
   [[['control', 50], ['treatment', 50]], 4999],
   'control'),
  ('zero weight arm is never selected', [[['control', 0], ['treatment', 100]], 0], 'treatment'),
  ('trailing zero weight arm does not absorb remainder',
   [[['control', 40], ['treatment', 40], ['off', 0]], 9000],
   'treatment'),
  ('declared order beats alphabetical order', [[['zeta', 10], ['alpha', 90]], 500], 'zeta'),
  ('fractional weight 0.29 covers 29 buckets', [[['tiny', 0.29], ['rest', 99.71]], 28], 'tiny'),
  ('weight table sample 6',
   [[['alpha', 0.29], ['holdout', 12.5], ['blue', 0.57], ['treatment', 0]], 204],
   'holdout'),
  ('weight table sample 7', [[['treatment', -5], ['holdout', 10], ['green', 50]], 5999], 'green'),
  ('weight table sample 23', [[['blue', 33.33], ['treatment', 0.29], ['alpha', 10]], 3361], 'treatment')],
 [('zero weight arm is never selected', [[['control', 0], ['treatment', 100]], 0], 'treatment'),
  ('trailing zero weight arm does not absorb remainder',
   [[['control', 40], ['treatment', 40], ['off', 0]], 9000],
   'treatment'),
  ('declared order beats alphabetical order', [[['zeta', 10], ['alpha', 90]], 500], 'zeta'),
  ('fractional weight 0.29 covers 29 buckets', [[['tiny', 0.29], ['rest', 99.71]], 28], 'tiny'),
  ('no positive weights yields None', [[['a', 0], ['b', 0]], 10], None),
  ('weight table sample 11', [[['holdout', 12.5], ['blue', 12.5], ['alpha', 0.57]], 2500], 'alpha'),
  ('weight table sample 12', [[['blue', 12.5], ['holdout', 0]], 1249], 'blue'),
  ('weight table sample 31', [[['green', 1.15], ['blue', 33.33], ['treatment', 4.35]], 3447], 'blue')],
 [('trailing zero weight arm does not absorb remainder',
   [[['control', 40], ['treatment', 40], ['off', 0]], 9000],
   'treatment'),
  ('declared order beats alphabetical order', [[['zeta', 10], ['alpha', 90]], 500], 'zeta'),
  ('fractional weight 0.29 covers 29 buckets', [[['tiny', 0.29], ['rest', 99.71]], 28], 'tiny'),
  ('no positive weights yields None', [[['a', 0], ['b', 0]], 10], None),
  ('three way split middle arm', [[['a', 33.33], ['b', 33.33], ['c', 33.34]], 5000], 'b'),
  ('weight table sample 16', [[['green', 0.57], ['alpha', 12.5], ['control', 25]], 1307], 'control'),
  ('weight table sample 17', [[['treatment', 1.15], ['control', 0.29], ['blue', 0.29]], 2597], 'blue'),
  ('weight table sample 45',
   [[['control', 4.35], ['blue', 50], ['treatment', 50], ['alpha', 50]], 5434],
   'blue')],
 [('bucket at first cumulative edge goes to second arm',
   [[['control', 50], ['treatment', 50]], 5000],
   'treatment'),
  ('declared order beats alphabetical order', [[['zeta', 10], ['alpha', 90]], 500], 'zeta'),
  ('fractional weight 0.29 covers 29 buckets', [[['tiny', 0.29], ['rest', 99.71]], 28], 'tiny'),
  ('no positive weights yields None', [[['a', 0], ['b', 0]], 10], None),
  ('three way split middle arm', [[['a', 33.33], ['b', 33.33], ['c', 33.34]], 5000], 'b'),
  ('weight table sample 21', [[['green', 33.33], ['treatment', 0]], 0], 'green'),
  ('weight table sample 22', [[['alpha', 0], ['control', 4.35], ['blue', 1.15]], 9182], 'blue'),
  ('weight table sample 50',
   [[['blue', 12.5], ['control', 0.57], ['green', 4.35], ['holdout', 0.29]], 1741],
   'green')]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
bucket at first cumulative edge goes to second armtreatmenttreatmentPassed
bucket just below first edge stays in first armcontrolcontrolPassed
zero weight arm is never selectedtreatmenttreatmentPassed
trailing zero weight arm does not absorb remaindertreatmenttreatmentPassed
declared order beats alphabetical orderzetazetaPassed
fractional weight 0.29 covers 29 bucketstinytinyPassed
weight table sample 1bluebluePassed
weight table sample 2bluebluePassed

SHA-256 / 6c90d5f86d825b721e5294b420c7362bb21bcede7131c0f55eb0a3a6e0d31cfe

Verification & scope

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.

Observations recorded using Python 3.12.14 at 2026-09-29T14:48:51.687509+00:00.

Case digest / 0d07f5bbdedf35f5f282a7f4caf6615da907bf83545aee2152fa07050d760796