{"abstract":"Bins that still carry a stale SKU label after being emptied are never reused.","category":"Warehouse slotting and bin packing","checks":8,"contract":"bins [[bin, sku|None, lot, expiry_day, qty, capacity, distance]]; receipt [sku, lot, expiry_day, qty]. A bin is empty when sku is None or qty is 0. Preference: (1) non-empty bin with same sku and lot and room (capacity-qty >= receipt qty), nearest then id; (2) same sku, different lot, expiry within 30 days either way, room; smallest expiry gap, nearest, id; (3) empty bin with capacity >= qty, nearest then id; else \"HOLD\".","evaluation_group":"w2-warehouse-slotting-fefo-putaway","failed_approach":"Only reusing zero-quantity bins labelled with the same SKU still strands bins labelled for other SKUs.","family":"w2-warehouse-slotting-fefo-putaway-empty-definition","id":"FA-95061","implementations":{"attempt":{"sha256":"b42370c992e9bb5b57cd7e0b9f6a80ff92c8c268b2089c5aca16e745e63f4220","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(bins, receipt):\n    sku, lot, exp, q = receipt\n    def room(b):\n        return b[5] - b[4] >= q\n    def empty(b):\n        return b[4] == 0 and b[1] in (None, sku)\n    same_lot = [b for b in bins if not empty(b) and b[1] == sku and b[2] == lot and room(b)]\n    if same_lot:\n        return min(same_lot, key=lambda b: (b[6], b[0]))[0]\n    mixed = [b for b in bins if not empty(b) and b[1] == sku and b[2] != lot and abs(b[3] - exp) <= 30 and room(b)]\n    if mixed:\n        return min(mixed, key=lambda b: (abs(b[3] - exp), b[6], b[0]))[0]\n    free = [b for b in bins if empty(b) and b[5] >= q]\n    if free:\n        return min(free, key=lambda b: (b[6], b[0]))[0]\n    return 'HOLD'\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['residual label empty', [[['R', 'S9', 'L7', 50, 0, 60, 2], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'R'], ['generated mix 7', [[['B0', 'S1', 'L1', 130, 10, 40, 3], ['B1', 'S2', 'L3', 160, 30, 20, 2], ['B2', 'S1', 'L2', 145, 0, 20, 1]], ['S2', 'L4', 130, 20]], 'B2'], ['same lot preferred', [[['A', 'S1', 'L1', 100, 10, 40, 9], ['B', 'S1', 'L2', 100, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['expiry 30 days later', [[['A', 'S1', 'L2', 130, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'A'], ['lot code on other sku', [[['X', 'S2', 'L1', 100, 5, 60, 1], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'E'], ['room exact', [[['A', 'S1', 'L1', 100, 20, 40, 9], ['E', None, None, 0, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['generated mix 6', [[['B0', 'S1', 'L1', 160, 40, 20, 6], ['B1', 'S2', 'L2', 131, 40, 20, 7]], ['S1', 'L4', 100, 30]], 'HOLD'], ['generated mix 15', [[['B0', 'S1', 'L2', 145, 40, 20, 2], ['B1', 'S2', 'L1', 145, 40, 60, 3], ['B2', 'S1', 'L1', 100, 30, 40, 3], ['B3', 'S1', 'L2', 145, 5, 60, 3], ['B4', 'S1', 'L1', 131, 0, 20, 6], ['B5', None, None, 0, 0, 40, 9]], ['S2', 'L4', 150, 20]], 'B1']], [['generated mix 28', [[['B0', 'S1', 'L3', 131, 10, 60, 9], ['B1', 'S2', 'L2', 131, 0, 20, 2], ['B2', 'S2', 'L2', 160, 40, 40, 5]], ['S2', 'L1', 100, 10]], 'B1'], ['generated mix 71', [[['B0', 'S1', 'L3', 160, 5, 40, 5], ['B1', 'S1', 'L1', 130, 0, 60, 7], ['B2', 'S1', 'L3', 120, 0, 60, 2]], ['S2', 'L1', 100, 10]], 'B2'], ['expiry 31 days', [[['A', 'S1', 'L2', 131, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'E'], ['lot code on other sku', [[['X', 'S2', 'L1', 100, 5, 60, 1], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'E'], ['same lot preferred', [[['A', 'S1', 'L1', 100, 10, 40, 9], ['B', 'S1', 'L2', 100, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['expiry 30 days later', [[['A', 'S1', 'L2', 130, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'A'], ['generated mix 9', [[['B0', 'S1', 'L2', 160, 40, 40, 1], ['B1', 'S1', 'L1', 131, 40, 40, 1], ['B2', 'S1', 'L3', 145, 0, 60, 1], ['B3', 'S1', 'L2', 100, 10, 20, 7], ['B4', 'S2', 'L1', 100, 30, 60, 5]], ['S1', 'L4', 150, 20]], 'B2'], ['generated mix 17', [[['B0', 'S2', 'L2', 120, 0, 20, 8], ['B1', 'S1', 'L2', 131, 5, 40, 3], ['B2', 'S2', 'L2', 100, 10, 20, 8], ['B3', 'S2', 'L2', 100, 10, 60, 6], ['B4', 'S1', 'L3', 100, 30, 40, 3], ['B5', 'S1', 'L1', 145, 10, 60, 5]], ['S1', 'L4', 150, 20]], 'B5']], [['generated mix 69', [[['B0', 'S1', 'L2', 160, 0, 60, 7], ['B1', 'S1', 'L3', 160, 0, 60, 8], ['B2', None, None, 0, 0, 60, 6], ['B3', 'S2', 'L3', 130, 0, 60, 7], ['B4', None, None, 0, 0, 60, 5], ['B5', 'S1', 'L2', 160, 10, 20, 4], ['B6', 'S2', 'L1', 145, 30, 20, 9]], ['S2', 'L4', 100, 10]], 'B4'], ['generated mix 22', [[['B0', 'S2', 'L3', 131, 40, 40, 2], ['B1', 'S2', 'L1', 160, 0, 20, 8], ['B2', 'S2', 'L1', 100, 40, 60, 8], ['B3', 'S2', 'L1', 131, 0, 60, 2], ['B4', 'S2', 'L1', 130, 5, 20, 7]], ['S1', 'L1', 150, 20]], 'B3'], ['nothing', [[['X', 'S2', 'L1', 100, 5, 10, 1]], ['S1', 'L1', 100, 20]], 'HOLD'], ['room exact', [[['A', 'S1', 'L1', 100, 20, 40, 9], ['E', None, None, 0, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['expiry 31 days', [[['A', 'S1', 'L2', 131, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'E'], ['lot code on other sku', [[['X', 'S2', 'L1', 100, 5, 60, 1], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'E'], ['generated mix 20', [[['B0', None, None, 0, 0, 20, 8], ['B1', 'S1', 'L1', 131, 30, 40, 6], ['B2', None, None, 0, 0, 20, 6], ['B3', 'S1', 'L3', 160, 0, 40, 6], ['B4', 'S1', 'L3', 160, 10, 20, 4], ['B5', 'S1', 'L3', 131, 30, 40, 9], ['B6', None, None, 0, 0, 60, 5]], ['S1', 'L4', 130, 20]], 'B6'], ['generated mix 29', [[['B0', None, None, 0, 0, 60, 5], ['B1', 'S1', 'L3', 100, 0, 60, 7], ['B2', 'S2', 'L2', 160, 40, 60, 7], ['B3', 'S1', 'L3', 131, 30, 60, 3], ['B4', 'S1', 'L1', 145, 10, 20, 4], ['B5', 'S2', 'L1', 130, 5, 40, 3], ['B6', 'S2', 'L2', 160, 40, 60, 5]], ['S1', 'L2', 100, 30]], 'B0']], [['generated mix 14', [[['B0', 'S2', 'L1', 130, 5, 60, 3], ['B1', 'S2', 'L1', 120, 0, 60, 8], ['B2', None, None, 0, 0, 60, 9]], ['S1', 'L1', 100, 30]], 'B1'], ['generated mix 12', [[['B0', 'S1', 'L3', 145, 0, 60, 4], ['B1', 'S1', 'L3', 160, 30, 40, 7], ['B2', 'S1', 'L2', 100, 40, 40, 4], ['B3', 'S1', 'L1', 130, 0, 60, 3]], ['S2', 'L2', 150, 20]], 'B3'], ['expiry 30 days later', [[['A', 'S1', 'L2', 130, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'A'], ['residual label empty', [[['R', 'S9', 'L7', 50, 0, 60, 2], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'R'], ['nothing', [[['X', 'S2', 'L1', 100, 5, 10, 1]], ['S1', 'L1', 100, 20]], 'HOLD'], ['room exact', [[['A', 'S1', 'L1', 100, 20, 40, 9], ['E', None, None, 0, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['generated mix 33', [[['B0', 'S1', 'L1', 130, 10, 40, 6], ['B1', 'S1', 'L3', 160, 40, 40, 3], ['B2', None, None, 0, 0, 20, 1], ['B3', 'S2', 'L2', 160, 5, 60, 8], ['B4', None, None, 0, 0, 40, 4], ['B5', 'S2', 'L2', 131, 5, 60, 8]], ['S1', 'L1', 130, 30]], 'B0'], ['generated mix 41', [[['B0', 'S1', 'L2', 160, 30, 60, 7], ['B1', 'S1', 'L2', 160, 40, 60, 3], ['B2', 'S1', 'L3', 100, 0, 60, 7], ['B3', 'S2', 'L2', 130, 10, 60, 9], ['B4', 'S1', 'L2', 160, 0, 20, 4], ['B5', 'S2', 'L2', 100, 30, 40, 4]], ['S2', 'L1', 130, 30]], 'B3']], [['generated mix 53', [[['B0', None, None, 0, 0, 40, 1], ['B1', 'S2', 'L1', 130, 0, 20, 4], ['B2', 'S1', 'L2', 100, 5, 60, 3], ['B3', None, None, 0, 0, 20, 1], ['B4', 'S1', 'L1', 100, 30, 20, 4], ['B5', 'S2', 'L3', 130, 5, 60, 7], ['B6', 'S2', 'L1', 120, 0, 60, 1]], ['S2', 'L1', 150, 10]], 'B5'], ['residual label empty', [[['R', 'S9', 'L7', 50, 0, 60, 2], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'R'], ['same lot preferred', [[['A', 'S1', 'L1', 100, 10, 40, 9], ['B', 'S1', 'L2', 100, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['expiry 30 days later', [[['A', 'S1', 'L2', 130, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'A'], ['lot code on other sku', [[['X', 'S2', 'L1', 100, 5, 60, 1], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'E'], ['generated mix 42', [[['B0', 'S1', 'L2', 100, 30, 20, 3], ['B1', 'S1', 'L1', 131, 30, 40, 9], ['B2', 'S1', 'L2', 100, 10, 60, 1], ['B3', 'S1', 'L2', 131, 30, 20, 1]], ['S1', 'L1', 100, 20]], 'B2'], ['generated mix 50', [[['B0', 'S2', 'L3', 160, 0, 40, 6], ['B1', 'S1', 'L2', 130, 0, 40, 1], ['B2', 'S2', 'L1', 130, 10, 60, 1]], ['S1', 'L1', 100, 30]], 'B1'], ['generated mix 59', [[['B0', 'S1', 'L3', 160, 10, 60, 4], ['B1', None, None, 0, 0, 60, 1], ['B2', 'S1', 'L3', 145, 5, 20, 4], ['B3', 'S1', 'L3', 100, 40, 60, 5], ['B4', None, None, 0, 0, 20, 8]], ['S2', 'L2', 130, 20]], 'B1']]]\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":"8b152c8b88ba167e0e7223b3bde7e4dea73a5eabcbfe99b7d036013c1690639c","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(bins, receipt):\n    sku, lot, exp, q = receipt\n    def room(b):\n        return b[5] - b[4] >= q\n    def empty(b):\n        return b[1] is None\n    same_lot = [b for b in bins if not empty(b) and b[1] == sku and b[2] == lot and room(b)]\n    if same_lot:\n        return min(same_lot, key=lambda b: (b[6], b[0]))[0]\n    mixed = [b for b in bins if not empty(b) and b[1] == sku and b[2] != lot and abs(b[3] - exp) <= 30 and room(b)]\n    if mixed:\n        return min(mixed, key=lambda b: (abs(b[3] - exp), b[6], b[0]))[0]\n    free = [b for b in bins if empty(b) and b[5] >= q]\n    if free:\n        return min(free, key=lambda b: (b[6], b[0]))[0]\n    return 'HOLD'\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['residual label empty', [[['R', 'S9', 'L7', 50, 0, 60, 2], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'R'], ['generated mix 7', [[['B0', 'S1', 'L1', 130, 10, 40, 3], ['B1', 'S2', 'L3', 160, 30, 20, 2], ['B2', 'S1', 'L2', 145, 0, 20, 1]], ['S2', 'L4', 130, 20]], 'B2'], ['same lot preferred', [[['A', 'S1', 'L1', 100, 10, 40, 9], ['B', 'S1', 'L2', 100, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['expiry 30 days later', [[['A', 'S1', 'L2', 130, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'A'], ['lot code on other sku', [[['X', 'S2', 'L1', 100, 5, 60, 1], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'E'], ['room exact', [[['A', 'S1', 'L1', 100, 20, 40, 9], ['E', None, None, 0, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['generated mix 6', [[['B0', 'S1', 'L1', 160, 40, 20, 6], ['B1', 'S2', 'L2', 131, 40, 20, 7]], ['S1', 'L4', 100, 30]], 'HOLD'], ['generated mix 15', [[['B0', 'S1', 'L2', 145, 40, 20, 2], ['B1', 'S2', 'L1', 145, 40, 60, 3], ['B2', 'S1', 'L1', 100, 30, 40, 3], ['B3', 'S1', 'L2', 145, 5, 60, 3], ['B4', 'S1', 'L1', 131, 0, 20, 6], ['B5', None, None, 0, 0, 40, 9]], ['S2', 'L4', 150, 20]], 'B1']], [['generated mix 28', [[['B0', 'S1', 'L3', 131, 10, 60, 9], ['B1', 'S2', 'L2', 131, 0, 20, 2], ['B2', 'S2', 'L2', 160, 40, 40, 5]], ['S2', 'L1', 100, 10]], 'B1'], ['generated mix 71', [[['B0', 'S1', 'L3', 160, 5, 40, 5], ['B1', 'S1', 'L1', 130, 0, 60, 7], ['B2', 'S1', 'L3', 120, 0, 60, 2]], ['S2', 'L1', 100, 10]], 'B2'], ['expiry 31 days', [[['A', 'S1', 'L2', 131, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'E'], ['lot code on other sku', [[['X', 'S2', 'L1', 100, 5, 60, 1], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'E'], ['same lot preferred', [[['A', 'S1', 'L1', 100, 10, 40, 9], ['B', 'S1', 'L2', 100, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['expiry 30 days later', [[['A', 'S1', 'L2', 130, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'A'], ['generated mix 9', [[['B0', 'S1', 'L2', 160, 40, 40, 1], ['B1', 'S1', 'L1', 131, 40, 40, 1], ['B2', 'S1', 'L3', 145, 0, 60, 1], ['B3', 'S1', 'L2', 100, 10, 20, 7], ['B4', 'S2', 'L1', 100, 30, 60, 5]], ['S1', 'L4', 150, 20]], 'B2'], ['generated mix 17', [[['B0', 'S2', 'L2', 120, 0, 20, 8], ['B1', 'S1', 'L2', 131, 5, 40, 3], ['B2', 'S2', 'L2', 100, 10, 20, 8], ['B3', 'S2', 'L2', 100, 10, 60, 6], ['B4', 'S1', 'L3', 100, 30, 40, 3], ['B5', 'S1', 'L1', 145, 10, 60, 5]], ['S1', 'L4', 150, 20]], 'B5']], [['generated mix 69', [[['B0', 'S1', 'L2', 160, 0, 60, 7], ['B1', 'S1', 'L3', 160, 0, 60, 8], ['B2', None, None, 0, 0, 60, 6], ['B3', 'S2', 'L3', 130, 0, 60, 7], ['B4', None, None, 0, 0, 60, 5], ['B5', 'S1', 'L2', 160, 10, 20, 4], ['B6', 'S2', 'L1', 145, 30, 20, 9]], ['S2', 'L4', 100, 10]], 'B4'], ['generated mix 22', [[['B0', 'S2', 'L3', 131, 40, 40, 2], ['B1', 'S2', 'L1', 160, 0, 20, 8], ['B2', 'S2', 'L1', 100, 40, 60, 8], ['B3', 'S2', 'L1', 131, 0, 60, 2], ['B4', 'S2', 'L1', 130, 5, 20, 7]], ['S1', 'L1', 150, 20]], 'B3'], ['nothing', [[['X', 'S2', 'L1', 100, 5, 10, 1]], ['S1', 'L1', 100, 20]], 'HOLD'], ['room exact', [[['A', 'S1', 'L1', 100, 20, 40, 9], ['E', None, None, 0, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['expiry 31 days', [[['A', 'S1', 'L2', 131, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'E'], ['lot code on other sku', [[['X', 'S2', 'L1', 100, 5, 60, 1], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'E'], ['generated mix 20', [[['B0', None, None, 0, 0, 20, 8], ['B1', 'S1', 'L1', 131, 30, 40, 6], ['B2', None, None, 0, 0, 20, 6], ['B3', 'S1', 'L3', 160, 0, 40, 6], ['B4', 'S1', 'L3', 160, 10, 20, 4], ['B5', 'S1', 'L3', 131, 30, 40, 9], ['B6', None, None, 0, 0, 60, 5]], ['S1', 'L4', 130, 20]], 'B6'], ['generated mix 29', [[['B0', None, None, 0, 0, 60, 5], ['B1', 'S1', 'L3', 100, 0, 60, 7], ['B2', 'S2', 'L2', 160, 40, 60, 7], ['B3', 'S1', 'L3', 131, 30, 60, 3], ['B4', 'S1', 'L1', 145, 10, 20, 4], ['B5', 'S2', 'L1', 130, 5, 40, 3], ['B6', 'S2', 'L2', 160, 40, 60, 5]], ['S1', 'L2', 100, 30]], 'B0']], [['generated mix 14', [[['B0', 'S2', 'L1', 130, 5, 60, 3], ['B1', 'S2', 'L1', 120, 0, 60, 8], ['B2', None, None, 0, 0, 60, 9]], ['S1', 'L1', 100, 30]], 'B1'], ['generated mix 12', [[['B0', 'S1', 'L3', 145, 0, 60, 4], ['B1', 'S1', 'L3', 160, 30, 40, 7], ['B2', 'S1', 'L2', 100, 40, 40, 4], ['B3', 'S1', 'L1', 130, 0, 60, 3]], ['S2', 'L2', 150, 20]], 'B3'], ['expiry 30 days later', [[['A', 'S1', 'L2', 130, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'A'], ['residual label empty', [[['R', 'S9', 'L7', 50, 0, 60, 2], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'R'], ['nothing', [[['X', 'S2', 'L1', 100, 5, 10, 1]], ['S1', 'L1', 100, 20]], 'HOLD'], ['room exact', [[['A', 'S1', 'L1', 100, 20, 40, 9], ['E', None, None, 0, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['generated mix 33', [[['B0', 'S1', 'L1', 130, 10, 40, 6], ['B1', 'S1', 'L3', 160, 40, 40, 3], ['B2', None, None, 0, 0, 20, 1], ['B3', 'S2', 'L2', 160, 5, 60, 8], ['B4', None, None, 0, 0, 40, 4], ['B5', 'S2', 'L2', 131, 5, 60, 8]], ['S1', 'L1', 130, 30]], 'B0'], ['generated mix 41', [[['B0', 'S1', 'L2', 160, 30, 60, 7], ['B1', 'S1', 'L2', 160, 40, 60, 3], ['B2', 'S1', 'L3', 100, 0, 60, 7], ['B3', 'S2', 'L2', 130, 10, 60, 9], ['B4', 'S1', 'L2', 160, 0, 20, 4], ['B5', 'S2', 'L2', 100, 30, 40, 4]], ['S2', 'L1', 130, 30]], 'B3']], [['generated mix 53', [[['B0', None, None, 0, 0, 40, 1], ['B1', 'S2', 'L1', 130, 0, 20, 4], ['B2', 'S1', 'L2', 100, 5, 60, 3], ['B3', None, None, 0, 0, 20, 1], ['B4', 'S1', 'L1', 100, 30, 20, 4], ['B5', 'S2', 'L3', 130, 5, 60, 7], ['B6', 'S2', 'L1', 120, 0, 60, 1]], ['S2', 'L1', 150, 10]], 'B5'], ['residual label empty', [[['R', 'S9', 'L7', 50, 0, 60, 2], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'R'], ['same lot preferred', [[['A', 'S1', 'L1', 100, 10, 40, 9], ['B', 'S1', 'L2', 100, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['expiry 30 days later', [[['A', 'S1', 'L2', 130, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'A'], ['lot code on other sku', [[['X', 'S2', 'L1', 100, 5, 60, 1], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'E'], ['generated mix 42', [[['B0', 'S1', 'L2', 100, 30, 20, 3], ['B1', 'S1', 'L1', 131, 30, 40, 9], ['B2', 'S1', 'L2', 100, 10, 60, 1], ['B3', 'S1', 'L2', 131, 30, 20, 1]], ['S1', 'L1', 100, 20]], 'B2'], ['generated mix 50', [[['B0', 'S2', 'L3', 160, 0, 40, 6], ['B1', 'S1', 'L2', 130, 0, 40, 1], ['B2', 'S2', 'L1', 130, 10, 60, 1]], ['S1', 'L1', 100, 30]], 'B1'], ['generated mix 59', [[['B0', 'S1', 'L3', 160, 10, 60, 4], ['B1', None, None, 0, 0, 60, 1], ['B2', 'S1', 'L3', 145, 5, 20, 4], ['B3', 'S1', 'L3', 100, 40, 60, 5], ['B4', None, None, 0, 0, 20, 8]], ['S2', 'L2', 130, 20]], 'B1']]]\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":"1d84939cb18fa932b7de06bf8d18d2333013c8a89df540d728c191e14e2a6bbe","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(bins, receipt):\n    sku, lot, exp, q = receipt\n    def room(b):\n        return b[5] - b[4] >= q\n    def empty(b):\n        return b[1] is None or b[4] == 0\n    same_lot = [b for b in bins if not empty(b) and b[1] == sku and b[2] == lot and room(b)]\n    if same_lot:\n        return min(same_lot, key=lambda b: (b[6], b[0]))[0]\n    mixed = [b for b in bins if not empty(b) and b[1] == sku and b[2] != lot and abs(b[3] - exp) <= 30 and room(b)]\n    if mixed:\n        return min(mixed, key=lambda b: (abs(b[3] - exp), b[6], b[0]))[0]\n    free = [b for b in bins if empty(b) and b[5] >= q]\n    if free:\n        return min(free, key=lambda b: (b[6], b[0]))[0]\n    return 'HOLD'\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['residual label empty', [[['R', 'S9', 'L7', 50, 0, 60, 2], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'R'], ['generated mix 7', [[['B0', 'S1', 'L1', 130, 10, 40, 3], ['B1', 'S2', 'L3', 160, 30, 20, 2], ['B2', 'S1', 'L2', 145, 0, 20, 1]], ['S2', 'L4', 130, 20]], 'B2'], ['same lot preferred', [[['A', 'S1', 'L1', 100, 10, 40, 9], ['B', 'S1', 'L2', 100, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['expiry 30 days later', [[['A', 'S1', 'L2', 130, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'A'], ['lot code on other sku', [[['X', 'S2', 'L1', 100, 5, 60, 1], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'E'], ['room exact', [[['A', 'S1', 'L1', 100, 20, 40, 9], ['E', None, None, 0, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['generated mix 6', [[['B0', 'S1', 'L1', 160, 40, 20, 6], ['B1', 'S2', 'L2', 131, 40, 20, 7]], ['S1', 'L4', 100, 30]], 'HOLD'], ['generated mix 15', [[['B0', 'S1', 'L2', 145, 40, 20, 2], ['B1', 'S2', 'L1', 145, 40, 60, 3], ['B2', 'S1', 'L1', 100, 30, 40, 3], ['B3', 'S1', 'L2', 145, 5, 60, 3], ['B4', 'S1', 'L1', 131, 0, 20, 6], ['B5', None, None, 0, 0, 40, 9]], ['S2', 'L4', 150, 20]], 'B1']], [['generated mix 28', [[['B0', 'S1', 'L3', 131, 10, 60, 9], ['B1', 'S2', 'L2', 131, 0, 20, 2], ['B2', 'S2', 'L2', 160, 40, 40, 5]], ['S2', 'L1', 100, 10]], 'B1'], ['generated mix 71', [[['B0', 'S1', 'L3', 160, 5, 40, 5], ['B1', 'S1', 'L1', 130, 0, 60, 7], ['B2', 'S1', 'L3', 120, 0, 60, 2]], ['S2', 'L1', 100, 10]], 'B2'], ['expiry 31 days', [[['A', 'S1', 'L2', 131, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'E'], ['lot code on other sku', [[['X', 'S2', 'L1', 100, 5, 60, 1], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'E'], ['same lot preferred', [[['A', 'S1', 'L1', 100, 10, 40, 9], ['B', 'S1', 'L2', 100, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['expiry 30 days later', [[['A', 'S1', 'L2', 130, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'A'], ['generated mix 9', [[['B0', 'S1', 'L2', 160, 40, 40, 1], ['B1', 'S1', 'L1', 131, 40, 40, 1], ['B2', 'S1', 'L3', 145, 0, 60, 1], ['B3', 'S1', 'L2', 100, 10, 20, 7], ['B4', 'S2', 'L1', 100, 30, 60, 5]], ['S1', 'L4', 150, 20]], 'B2'], ['generated mix 17', [[['B0', 'S2', 'L2', 120, 0, 20, 8], ['B1', 'S1', 'L2', 131, 5, 40, 3], ['B2', 'S2', 'L2', 100, 10, 20, 8], ['B3', 'S2', 'L2', 100, 10, 60, 6], ['B4', 'S1', 'L3', 100, 30, 40, 3], ['B5', 'S1', 'L1', 145, 10, 60, 5]], ['S1', 'L4', 150, 20]], 'B5']], [['generated mix 69', [[['B0', 'S1', 'L2', 160, 0, 60, 7], ['B1', 'S1', 'L3', 160, 0, 60, 8], ['B2', None, None, 0, 0, 60, 6], ['B3', 'S2', 'L3', 130, 0, 60, 7], ['B4', None, None, 0, 0, 60, 5], ['B5', 'S1', 'L2', 160, 10, 20, 4], ['B6', 'S2', 'L1', 145, 30, 20, 9]], ['S2', 'L4', 100, 10]], 'B4'], ['generated mix 22', [[['B0', 'S2', 'L3', 131, 40, 40, 2], ['B1', 'S2', 'L1', 160, 0, 20, 8], ['B2', 'S2', 'L1', 100, 40, 60, 8], ['B3', 'S2', 'L1', 131, 0, 60, 2], ['B4', 'S2', 'L1', 130, 5, 20, 7]], ['S1', 'L1', 150, 20]], 'B3'], ['nothing', [[['X', 'S2', 'L1', 100, 5, 10, 1]], ['S1', 'L1', 100, 20]], 'HOLD'], ['room exact', [[['A', 'S1', 'L1', 100, 20, 40, 9], ['E', None, None, 0, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['expiry 31 days', [[['A', 'S1', 'L2', 131, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'E'], ['lot code on other sku', [[['X', 'S2', 'L1', 100, 5, 60, 1], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'E'], ['generated mix 20', [[['B0', None, None, 0, 0, 20, 8], ['B1', 'S1', 'L1', 131, 30, 40, 6], ['B2', None, None, 0, 0, 20, 6], ['B3', 'S1', 'L3', 160, 0, 40, 6], ['B4', 'S1', 'L3', 160, 10, 20, 4], ['B5', 'S1', 'L3', 131, 30, 40, 9], ['B6', None, None, 0, 0, 60, 5]], ['S1', 'L4', 130, 20]], 'B6'], ['generated mix 29', [[['B0', None, None, 0, 0, 60, 5], ['B1', 'S1', 'L3', 100, 0, 60, 7], ['B2', 'S2', 'L2', 160, 40, 60, 7], ['B3', 'S1', 'L3', 131, 30, 60, 3], ['B4', 'S1', 'L1', 145, 10, 20, 4], ['B5', 'S2', 'L1', 130, 5, 40, 3], ['B6', 'S2', 'L2', 160, 40, 60, 5]], ['S1', 'L2', 100, 30]], 'B0']], [['generated mix 14', [[['B0', 'S2', 'L1', 130, 5, 60, 3], ['B1', 'S2', 'L1', 120, 0, 60, 8], ['B2', None, None, 0, 0, 60, 9]], ['S1', 'L1', 100, 30]], 'B1'], ['generated mix 12', [[['B0', 'S1', 'L3', 145, 0, 60, 4], ['B1', 'S1', 'L3', 160, 30, 40, 7], ['B2', 'S1', 'L2', 100, 40, 40, 4], ['B3', 'S1', 'L1', 130, 0, 60, 3]], ['S2', 'L2', 150, 20]], 'B3'], ['expiry 30 days later', [[['A', 'S1', 'L2', 130, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'A'], ['residual label empty', [[['R', 'S9', 'L7', 50, 0, 60, 2], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'R'], ['nothing', [[['X', 'S2', 'L1', 100, 5, 10, 1]], ['S1', 'L1', 100, 20]], 'HOLD'], ['room exact', [[['A', 'S1', 'L1', 100, 20, 40, 9], ['E', None, None, 0, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['generated mix 33', [[['B0', 'S1', 'L1', 130, 10, 40, 6], ['B1', 'S1', 'L3', 160, 40, 40, 3], ['B2', None, None, 0, 0, 20, 1], ['B3', 'S2', 'L2', 160, 5, 60, 8], ['B4', None, None, 0, 0, 40, 4], ['B5', 'S2', 'L2', 131, 5, 60, 8]], ['S1', 'L1', 130, 30]], 'B0'], ['generated mix 41', [[['B0', 'S1', 'L2', 160, 30, 60, 7], ['B1', 'S1', 'L2', 160, 40, 60, 3], ['B2', 'S1', 'L3', 100, 0, 60, 7], ['B3', 'S2', 'L2', 130, 10, 60, 9], ['B4', 'S1', 'L2', 160, 0, 20, 4], ['B5', 'S2', 'L2', 100, 30, 40, 4]], ['S2', 'L1', 130, 30]], 'B3']], [['generated mix 53', [[['B0', None, None, 0, 0, 40, 1], ['B1', 'S2', 'L1', 130, 0, 20, 4], ['B2', 'S1', 'L2', 100, 5, 60, 3], ['B3', None, None, 0, 0, 20, 1], ['B4', 'S1', 'L1', 100, 30, 20, 4], ['B5', 'S2', 'L3', 130, 5, 60, 7], ['B6', 'S2', 'L1', 120, 0, 60, 1]], ['S2', 'L1', 150, 10]], 'B5'], ['residual label empty', [[['R', 'S9', 'L7', 50, 0, 60, 2], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'R'], ['same lot preferred', [[['A', 'S1', 'L1', 100, 10, 40, 9], ['B', 'S1', 'L2', 100, 0, 40, 1]], ['S1', 'L1', 100, 20]], 'A'], ['expiry 30 days later', [[['A', 'S1', 'L2', 130, 10, 60, 5], ['E', None, None, 0, 0, 60, 1]], ['S1', 'L1', 100, 20]], 'A'], ['lot code on other sku', [[['X', 'S2', 'L1', 100, 5, 60, 1], ['E', None, None, 0, 0, 60, 4]], ['S1', 'L1', 100, 20]], 'E'], ['generated mix 42', [[['B0', 'S1', 'L2', 100, 30, 20, 3], ['B1', 'S1', 'L1', 131, 30, 40, 9], ['B2', 'S1', 'L2', 100, 10, 60, 1], ['B3', 'S1', 'L2', 131, 30, 20, 1]], ['S1', 'L1', 100, 20]], 'B2'], ['generated mix 50', [[['B0', 'S2', 'L3', 160, 0, 40, 6], ['B1', 'S1', 'L2', 130, 0, 40, 1], ['B2', 'S2', 'L1', 130, 10, 60, 1]], ['S1', 'L1', 100, 30]], 'B1'], ['generated mix 59', [[['B0', 'S1', 'L3', 160, 10, 60, 4], ['B1', None, None, 0, 0, 60, 1], ['B2', 'S1', 'L3', 145, 5, 20, 4], ['B3', 'S1', 'L3', 100, 40, 60, 5], ['B4', None, None, 0, 0, 20, 8]], ['S2', 'L2', 130, 20]], 'B1']]]\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":"Stipulated day-number expiries and a single receipt; no quarantine or multi-bin splits. 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-warehouse-slotting-fefo-putaway-empty-definition","generated_at":"2026-09-29T14:52:10.266741+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"FEFO storage keeps lots with similar expiry together so the earliest expiring stock ships first.","repair":"Treat a bin as empty when it has no SKU label or holds zero units.","root_cause":"Emptiness is determined only by a missing SKU label; zero quantity is ignored.","sha256":"4caccece90c34840c4648dadddf2480ea939bb183e0e8ef7a727896b77005278","title":"FEFO putaway: zero-quantity labelled bin not empty · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":42.55,"exit_code":1,"observations":[{"actual":"E","check":"residual label empty","expected":"R","passed":false},{"actual":"HOLD","check":"generated mix 7","expected":"B2","passed":false},{"actual":"A","check":"same lot preferred","expected":"A","passed":true},{"actual":"A","check":"expiry 30 days later","expected":"A","passed":true},{"actual":"E","check":"lot code on other sku","expected":"E","passed":true},{"actual":"A","check":"room exact","expected":"A","passed":true},{"actual":"HOLD","check":"generated mix 6","expected":"HOLD","passed":true},{"actual":"B1","check":"generated mix 15","expected":"B1","passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"residual label empty\", \"actual\": \"E\", \"expected\": \"R\", \"passed\": false}, {\"check\": \"generated mix 7\", \"actual\": \"HOLD\", \"expected\": \"B2\", \"passed\": false}, {\"check\": \"same lot preferred\", \"actual\": \"A\", \"expected\": \"A\", \"passed\": true}, {\"check\": \"expiry 30 days later\", \"actual\": \"A\", \"expected\": \"A\", \"passed\": true}, {\"check\": \"lot code on other sku\", \"actual\": \"E\", \"expected\": \"E\", \"passed\": true}, {\"check\": \"room exact\", \"actual\": \"A\", \"expected\": \"A\", \"passed\": true}, {\"check\": \"generated mix 6\", \"actual\": \"HOLD\", \"expected\": \"HOLD\", \"passed\": true}, {\"check\": \"generated mix 15\", \"actual\": \"B1\", \"expected\": \"B1\", \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":42.162,"exit_code":1,"observations":[{"actual":"E","check":"residual label empty","expected":"R","passed":false},{"actual":"HOLD","check":"generated mix 7","expected":"B2","passed":false},{"actual":"A","check":"same lot preferred","expected":"A","passed":true},{"actual":"A","check":"expiry 30 days later","expected":"A","passed":true},{"actual":"E","check":"lot code on other sku","expected":"E","passed":true},{"actual":"A","check":"room exact","expected":"A","passed":true},{"actual":"HOLD","check":"generated mix 6","expected":"HOLD","passed":true},{"actual":"B1","check":"generated mix 15","expected":"B1","passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"residual label empty\", \"actual\": \"E\", \"expected\": \"R\", \"passed\": false}, {\"check\": \"generated mix 7\", \"actual\": \"HOLD\", \"expected\": \"B2\", \"passed\": false}, {\"check\": \"same lot preferred\", \"actual\": \"A\", \"expected\": \"A\", \"passed\": true}, {\"check\": \"expiry 30 days later\", \"actual\": \"A\", \"expected\": \"A\", \"passed\": true}, {\"check\": \"lot code on other sku\", \"actual\": \"E\", \"expected\": \"E\", \"passed\": true}, {\"check\": \"room exact\", \"actual\": \"A\", \"expected\": \"A\", \"passed\": true}, {\"check\": \"generated mix 6\", \"actual\": \"HOLD\", \"expected\": \"HOLD\", \"passed\": true}, {\"check\": \"generated mix 15\", \"actual\": \"B1\", \"expected\": \"B1\", \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":40.974,"exit_code":0,"observations":[{"actual":"R","check":"residual label empty","expected":"R","passed":true},{"actual":"B2","check":"generated mix 7","expected":"B2","passed":true},{"actual":"A","check":"same lot preferred","expected":"A","passed":true},{"actual":"A","check":"expiry 30 days later","expected":"A","passed":true},{"actual":"E","check":"lot code on other sku","expected":"E","passed":true},{"actual":"A","check":"room exact","expected":"A","passed":true},{"actual":"HOLD","check":"generated mix 6","expected":"HOLD","passed":true},{"actual":"B1","check":"generated mix 15","expected":"B1","passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"residual label empty\", \"actual\": \"R\", \"expected\": \"R\", \"passed\": true}, {\"check\": \"generated mix 7\", \"actual\": \"B2\", \"expected\": \"B2\", \"passed\": true}, {\"check\": \"same lot preferred\", \"actual\": \"A\", \"expected\": \"A\", \"passed\": true}, {\"check\": \"expiry 30 days later\", \"actual\": \"A\", \"expected\": \"A\", \"passed\": true}, {\"check\": \"lot code on other sku\", \"actual\": \"E\", \"expected\": \"E\", \"passed\": true}, {\"check\": \"room exact\", \"actual\": \"A\", \"expected\": \"A\", \"passed\": true}, {\"check\": \"generated mix 6\", \"actual\": \"HOLD\", \"expected\": \"HOLD\", \"passed\": true}, {\"check\": \"generated mix 15\", \"actual\": \"B1\", \"expected\": \"B1\", \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}