{"abstract":"Signals between 3.6 and 4 mA or between 20 and 20.5 mA report values outside the calibrated range.","category":"PLC ladder logic scan cycles","checks":8,"contract":"Scale a 4-20 mA analog channel read once per scan. Raw counts are proportional to 0-20 mA with 20 mA = 31208 counts, so 4 mA = 6242. Below 3.6 mA (raw*200 < 36*31208) the channel reports open wire and above 20.5 mA (raw*40 > 41*31208) over-range; in both cases it returns the last good value (None before any). Otherwise the engineering value in tenths is eng_lo*10 + (raw-6242)*(eng_hi-eng_lo)*10 / 24966 rounded half up, clamped to the configured range (reverse-acting ranges allowed). Return [status, tenths] per scan.","contract_signature":"eng_lo, eng_hi, raws","evaluation_group":"w2-plc-ladder-logic-scan-cycles-analog-4-20ma-scaling","failed_approach":"Clamping only the upper limit still reports below-range values.","family":"w2-plc-ladder-logic-scan-cycles-analog-4-20ma-scaling-range-clamp","id":"FA-92231","implementations":{"attempt":{"sha256":"e3020e7009939a179924ef57723ef3bcfc6ceafe79c0a013b5121ca6f5507261","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(eng_lo, eng_hi, raws):\n    last = None\n    lo10, hi10 = sorted([eng_lo * 10, eng_hi * 10])\n    out = []\n    for raw in raws:\n        if raw * 200 < 36 * 31208:\n            out.append(['open', last])\n            continue\n        if raw * 40 > 41 * 31208:\n            out.append(['over', last])\n            continue\n        num = (raw - 6242) * (eng_hi - eng_lo) * 10\n        tenths = eng_lo * 10 + (2 * num + 24966) // (2 * 24966)\n        tenths = min(tenths, hi10)\n        last = tenths\n        out.append(['ok', tenths])\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression: span points and faults',\n   [0, 100, [6242, 31208, 18725, 5000, 32000, 5800]],\n   [['ok', 0], ['ok', 1000], ['ok', 500], ['open', 500], ['over', 500], ['ok', 0]]],\n  ['regression: reverse acting valve',\n   [100, 0, [6242, 12483, 31208, 31600, 5700]],\n   [['ok', 1000], ['ok', 750], ['ok', 0], ['ok', 0], ['ok', 1000]]],\n  ['regression: under-range tolerance',\n   [-40, 120, [5700, 6100, 6242, 6243, 31900]],\n   [['ok', -400], ['ok', -400], ['ok', -400], ['ok', -400], ['ok', 1200]]],\n  ['control: rounding half',\n   [0, 1, [7490, 7491, 18725, 3000, 31950]],\n   [['ok', 0], ['ok', 1], ['ok', 5], ['open', 5], ['ok', 10]]],\n  ['regression: scenario 1',\n   [100, 0, [31500, 8288, 22627, 22870, 5618, 13683, 31500, 18942]],\n   [['ok', 0], ['ok', 918], ['ok', 344], ['ok', 334], ['ok', 1000], ['ok', 702], ['ok', 0], ['ok', 491]]],\n  ['control: scenario 2',\n   [0, 250, [5617, 10253, 31208, 20785, 15236, 31208]],\n   [['open', None], ['ok', 402], ['ok', 2500], ['ok', 1456], ['ok', 901], ['ok', 2500]]],\n  ['regression: scenario 3',\n   [-40, 120, [32767, 6000, 6242, 24089, 32767, 26567, 26190, 22883]],\n   [['over', None],\n    ['ok', -400],\n    ['ok', -400],\n    ['ok', 744],\n    ['over', 744],\n    ['ok', 903],\n    ['ok', 878],\n    ['ok', 666]]],\n  ['regression: scenario 4',\n   [-40, 120, [29499, 18725, 0, 11927, 7165, 31988, 5618, 28746, 31807]],\n   [['ok', 1090],\n    ['ok', 400],\n    ['open', 400],\n    ['ok', -36],\n    ['ok', -341],\n    ['ok', 1200],\n    ['ok', -400],\n    ['ok', 1042],\n    ['ok', 1200]]]],\n [['regression: reverse acting valve',\n   [100, 0, [6242, 12483, 31208, 31600, 5700]],\n   [['ok', 1000], ['ok', 750], ['ok', 0], ['ok', 0], ['ok', 1000]]],\n  ['regression: under-range tolerance',\n   [-40, 120, [5700, 6100, 6242, 6243, 31900]],\n   [['ok', -400], ['ok', -400], ['ok', -400], ['ok', -400], ['ok', 1200]]],\n  ['regression: span points and faults',\n   [0, 100, [6242, 31208, 18725, 5000, 32000, 5800]],\n   [['ok', 0], ['ok', 1000], ['ok', 500], ['open', 500], ['over', 500], ['ok', 0]]],\n  ['control: rounding half',\n   [0, 1, [7490, 7491, 18725, 3000, 31950]],\n   [['ok', 0], ['ok', 1], ['ok', 5], ['open', 5], ['ok', 10]]],\n  ['regression: scenario 1',\n   [0, 100, [31500, 12465, 31988, 14808, 13503, 27085, 21673, 31500]],\n   [['ok', 1000],\n    ['ok', 249],\n    ['ok', 1000],\n    ['ok', 343],\n    ['ok', 291],\n    ['ok', 835],\n    ['ok', 618],\n    ['ok', 1000]]],\n  ['regression: scenario 2',\n   [4, 20, [10220, 9382, 7184, 5618, 28096, 3000, 31208, 6242, 5617, 6452]],\n   [['ok', 65],\n    ['ok', 60],\n    ['ok', 46],\n    ['ok', 40],\n    ['ok', 180],\n    ['open', 180],\n    ['ok', 200],\n    ['ok', 40],\n    ['open', 40],\n    ['ok', 41]]],\n  ['regression: scenario 3',\n   [100, 0, [6000, 25570, 31208, 14262, 10000]],\n   [['ok', 1000], ['ok', 226], ['ok', 0], ['ok', 679], ['ok', 849]]],\n  ['control: scenario 4',\n   [0, 1000, [25458, 32767, 3000, 26377, 18190, 14636, 32767, 10000]],\n   [['ok', 7697],\n    ['over', 7697],\n    ['open', 7697],\n    ['ok', 8065],\n    ['ok', 4786],\n    ['ok', 3362],\n    ['over', 3362],\n    ['ok', 1505]]]],\n [['regression: under-range tolerance',\n   [-40, 120, [5700, 6100, 6242, 6243, 31900]],\n   [['ok', -400], ['ok', -400], ['ok', -400], ['ok', -400], ['ok', 1200]]],\n  ['regression: scenario 3',\n   [0, 100, [31989, 22472, 5618, 23809, 20211, 3000, 6242, 12935, 28379, 31989]],\n   [['over', None],\n    ['ok', 650],\n    ['ok', 0],\n    ['ok', 704],\n    ['ok', 560],\n    ['open', 560],\n    ['ok', 0],\n    ['ok', 268],\n    ['ok', 887],\n    ['over', 887]]],\n  ['regression: span points and faults',\n   [0, 100, [6242, 31208, 18725, 5000, 32000, 5800]],\n   [['ok', 0], ['ok', 1000], ['ok', 500], ['open', 500], ['over', 500], ['ok', 0]]],\n  ['regression: reverse acting valve',\n   [100, 0, [6242, 12483, 31208, 31600, 5700]],\n   [['ok', 1000], ['ok', 750], ['ok', 0], ['ok', 0], ['ok', 1000]]],\n  ['control: rounding half',\n   [0, 1, [7490, 7491, 18725, 3000, 31950]],\n   [['ok', 0], ['ok', 1], ['ok', 5], ['open', 5], ['ok', 10]]],\n  ['regression: scenario 1',\n   [-40, 120, [3000, 16471, 17868, 31500, 31989, 18725, 31989, 10136]],\n   [['open', None],\n    ['ok', 256],\n    ['ok', 345],\n    ['ok', 1200],\n    ['over', 1200],\n    ['ok', 400],\n    ['over', 400],\n    ['ok', -150]]],\n  ['control: scenario 2',\n   [4, 20, [27643, 11003, 3000, 32767, 3000]],\n   [['ok', 177], ['ok', 71], ['open', 71], ['over', 71], ['open', 71]]],\n  ['regression: scenario 4',\n   [4, 20, [11825, 32767, 10576, 27128, 10066, 5618, 12778, 6000, 10000]],\n   [['ok', 76],\n    ['over', 76],\n    ['ok', 68],\n    ['ok', 174],\n    ['ok', 65],\n    ['ok', 40],\n    ['ok', 82],\n    ['ok', 40],\n    ['ok', 64]]]],\n [['regression: scenario 1',\n   [0, 250, [3000, 5618, 31500, 27302, 12019]],\n   [['open', None], ['ok', 0], ['ok', 2500], ['ok', 2109], ['ok', 578]]],\n  ['regression: scenario 2',\n   [0, 250, [30430, 16995, 0, 10000, 6000, 10979]],\n   [['ok', 2422], ['ok', 1077], ['open', 1077], ['ok', 376], ['ok', 0], ['ok', 474]]],\n  ['regression: span points and faults',\n   [0, 100, [6242, 31208, 18725, 5000, 32000, 5800]],\n   [['ok', 0], ['ok', 1000], ['ok', 500], ['open', 500], ['over', 500], ['ok', 0]]],\n  ['regression: reverse acting valve',\n   [100, 0, [6242, 12483, 31208, 31600, 5700]],\n   [['ok', 1000], ['ok', 750], ['ok', 0], ['ok', 0], ['ok', 1000]]],\n  ['regression: under-range tolerance',\n   [-40, 120, [5700, 6100, 6242, 6243, 31900]],\n   [['ok', -400], ['ok', -400], ['ok', -400], ['ok', -400], ['ok', 1200]]],\n  ['control: rounding half',\n   [0, 1, [7490, 7491, 18725, 3000, 31950]],\n   [['ok', 0], ['ok', 1], ['ok', 5], ['open', 5], ['ok', 10]]],\n  ['regression: scenario 3',\n   [0, 250, [31456, 13455, 24788, 8289, 14213, 18164, 10000, 0, 20991]],\n   [['ok', 2500],\n    ['ok', 722],\n    ['ok', 1857],\n    ['ok', 205],\n    ['ok', 798],\n    ['ok', 1194],\n    ['ok', 376],\n    ['open', 376],\n    ['ok', 1477]]],\n  ['regression: scenario 4',\n   [0, 100, [3000, 5633, 7891, 18725, 19352, 30730, 10000, 31208, 25959]],\n   [['open', None],\n    ['ok', 0],\n    ['ok', 66],\n    ['ok', 500],\n    ['ok', 525],\n    ['ok', 981],\n    ['ok', 151],\n    ['ok', 1000],\n    ['ok', 790]]]],\n [['regression: scenario 4',\n   [0, 250, [27893, 24340, 19137, 9936, 26279, 31500, 28004, 10000]],\n   [['ok', 2168],\n    ['ok', 1812],\n    ['ok', 1291],\n    ['ok', 370],\n    ['ok', 2006],\n    ['ok', 2500],\n    ['ok', 2179],\n    ['ok', 376]]],\n  ['regression: scenario 5',\n   [100, 0, [5618, 10474, 18027, 31947, 19308, 31083, 26603, 16118, 11612, 5618]],\n   [['ok', 1000],\n    ['ok', 830],\n    ['ok', 528],\n    ['ok', 0],\n    ['ok', 477],\n    ['ok', 5],\n    ['ok', 184],\n    ['ok', 604],\n    ['ok', 785],\n    ['ok', 1000]]],\n  ['regression: span points and faults',\n   [0, 100, [6242, 31208, 18725, 5000, 32000, 5800]],\n   [['ok', 0], ['ok', 1000], ['ok', 500], ['open', 500], ['over', 500], ['ok', 0]]],\n  ['regression: reverse acting valve',\n   [100, 0, [6242, 12483, 31208, 31600, 5700]],\n   [['ok', 1000], ['ok', 750], ['ok', 0], ['ok', 0], ['ok', 1000]]],\n  ['regression: under-range tolerance',\n   [-40, 120, [5700, 6100, 6242, 6243, 31900]],\n   [['ok', -400], ['ok', -400], ['ok', -400], ['ok', -400], ['ok', 1200]]],\n  ['control: rounding half',\n   [0, 1, [7490, 7491, 18725, 3000, 31950]],\n   [['ok', 0], ['ok', 1], ['ok', 5], ['open', 5], ['ok', 10]]],\n  ['regression: scenario 1',\n   [0, 250, [15441, 21456, 3000, 0, 6000, 5618]],\n   [['ok', 921], ['ok', 1523], ['open', 1523], ['open', 1523], ['ok', 0], ['ok', 0]]],\n  ['control: scenario 2',\n   [0, 100, [31078, 6242, 18725, 18727, 19134, 13243, 18725, 21879, 0, 19240]],\n   [['ok', 995],\n    ['ok', 0],\n    ['ok', 500],\n    ['ok', 500],\n    ['ok', 516],\n    ['ok', 280],\n    ['ok', 500],\n    ['ok', 626],\n    ['open', 626],\n    ['ok', 521]]]]]\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":"644c2800ac88341a8f674e73deffe9dd5653b96c6c7f6b1533d0be98b220d916","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(eng_lo, eng_hi, raws):\n    last = None\n    lo10, hi10 = sorted([eng_lo * 10, eng_hi * 10])\n    out = []\n    for raw in raws:\n        if raw * 200 < 36 * 31208:\n            out.append(['open', last])\n            continue\n        if raw * 40 > 41 * 31208:\n            out.append(['over', last])\n            continue\n        num = (raw - 6242) * (eng_hi - eng_lo) * 10\n        tenths = eng_lo * 10 + (2 * num + 24966) // (2 * 24966)\n        last = tenths\n        out.append(['ok', tenths])\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression: span points and faults',\n   [0, 100, [6242, 31208, 18725, 5000, 32000, 5800]],\n   [['ok', 0], ['ok', 1000], ['ok', 500], ['open', 500], ['over', 500], ['ok', 0]]],\n  ['regression: reverse acting valve',\n   [100, 0, [6242, 12483, 31208, 31600, 5700]],\n   [['ok', 1000], ['ok', 750], ['ok', 0], ['ok', 0], ['ok', 1000]]],\n  ['regression: under-range tolerance',\n   [-40, 120, [5700, 6100, 6242, 6243, 31900]],\n   [['ok', -400], ['ok', -400], ['ok', -400], ['ok', -400], ['ok', 1200]]],\n  ['control: rounding half',\n   [0, 1, [7490, 7491, 18725, 3000, 31950]],\n   [['ok', 0], ['ok', 1], ['ok', 5], ['open', 5], ['ok', 10]]],\n  ['regression: scenario 1',\n   [100, 0, [31500, 8288, 22627, 22870, 5618, 13683, 31500, 18942]],\n   [['ok', 0], ['ok', 918], ['ok', 344], ['ok', 334], ['ok', 1000], ['ok', 702], ['ok', 0], ['ok', 491]]],\n  ['control: scenario 2',\n   [0, 250, [5617, 10253, 31208, 20785, 15236, 31208]],\n   [['open', None], ['ok', 402], ['ok', 2500], ['ok', 1456], ['ok', 901], ['ok', 2500]]],\n  ['regression: scenario 3',\n   [-40, 120, [32767, 6000, 6242, 24089, 32767, 26567, 26190, 22883]],\n   [['over', None],\n    ['ok', -400],\n    ['ok', -400],\n    ['ok', 744],\n    ['over', 744],\n    ['ok', 903],\n    ['ok', 878],\n    ['ok', 666]]],\n  ['regression: scenario 4',\n   [-40, 120, [29499, 18725, 0, 11927, 7165, 31988, 5618, 28746, 31807]],\n   [['ok', 1090],\n    ['ok', 400],\n    ['open', 400],\n    ['ok', -36],\n    ['ok', -341],\n    ['ok', 1200],\n    ['ok', -400],\n    ['ok', 1042],\n    ['ok', 1200]]]],\n [['regression: reverse acting valve',\n   [100, 0, [6242, 12483, 31208, 31600, 5700]],\n   [['ok', 1000], ['ok', 750], ['ok', 0], ['ok', 0], ['ok', 1000]]],\n  ['regression: under-range tolerance',\n   [-40, 120, [5700, 6100, 6242, 6243, 31900]],\n   [['ok', -400], ['ok', -400], ['ok', -400], ['ok', -400], ['ok', 1200]]],\n  ['regression: span points and faults',\n   [0, 100, [6242, 31208, 18725, 5000, 32000, 5800]],\n   [['ok', 0], ['ok', 1000], ['ok', 500], ['open', 500], ['over', 500], ['ok', 0]]],\n  ['control: rounding half',\n   [0, 1, [7490, 7491, 18725, 3000, 31950]],\n   [['ok', 0], ['ok', 1], ['ok', 5], ['open', 5], ['ok', 10]]],\n  ['regression: scenario 1',\n   [0, 100, [31500, 12465, 31988, 14808, 13503, 27085, 21673, 31500]],\n   [['ok', 1000],\n    ['ok', 249],\n    ['ok', 1000],\n    ['ok', 343],\n    ['ok', 291],\n    ['ok', 835],\n    ['ok', 618],\n    ['ok', 1000]]],\n  ['regression: scenario 2',\n   [4, 20, [10220, 9382, 7184, 5618, 28096, 3000, 31208, 6242, 5617, 6452]],\n   [['ok', 65],\n    ['ok', 60],\n    ['ok', 46],\n    ['ok', 40],\n    ['ok', 180],\n    ['open', 180],\n    ['ok', 200],\n    ['ok', 40],\n    ['open', 40],\n    ['ok', 41]]],\n  ['regression: scenario 3',\n   [100, 0, [6000, 25570, 31208, 14262, 10000]],\n   [['ok', 1000], ['ok', 226], ['ok', 0], ['ok', 679], ['ok', 849]]],\n  ['control: scenario 4',\n   [0, 1000, [25458, 32767, 3000, 26377, 18190, 14636, 32767, 10000]],\n   [['ok', 7697],\n    ['over', 7697],\n    ['open', 7697],\n    ['ok', 8065],\n    ['ok', 4786],\n    ['ok', 3362],\n    ['over', 3362],\n    ['ok', 1505]]]],\n [['regression: under-range tolerance',\n   [-40, 120, [5700, 6100, 6242, 6243, 31900]],\n   [['ok', -400], ['ok', -400], ['ok', -400], ['ok', -400], ['ok', 1200]]],\n  ['regression: scenario 3',\n   [0, 100, [31989, 22472, 5618, 23809, 20211, 3000, 6242, 12935, 28379, 31989]],\n   [['over', None],\n    ['ok', 650],\n    ['ok', 0],\n    ['ok', 704],\n    ['ok', 560],\n    ['open', 560],\n    ['ok', 0],\n    ['ok', 268],\n    ['ok', 887],\n    ['over', 887]]],\n  ['regression: span points and faults',\n   [0, 100, [6242, 31208, 18725, 5000, 32000, 5800]],\n   [['ok', 0], ['ok', 1000], ['ok', 500], ['open', 500], ['over', 500], ['ok', 0]]],\n  ['regression: reverse acting valve',\n   [100, 0, [6242, 12483, 31208, 31600, 5700]],\n   [['ok', 1000], ['ok', 750], ['ok', 0], ['ok', 0], ['ok', 1000]]],\n  ['control: rounding half',\n   [0, 1, [7490, 7491, 18725, 3000, 31950]],\n   [['ok', 0], ['ok', 1], ['ok', 5], ['open', 5], ['ok', 10]]],\n  ['regression: scenario 1',\n   [-40, 120, [3000, 16471, 17868, 31500, 31989, 18725, 31989, 10136]],\n   [['open', None],\n    ['ok', 256],\n    ['ok', 345],\n    ['ok', 1200],\n    ['over', 1200],\n    ['ok', 400],\n    ['over', 400],\n    ['ok', -150]]],\n  ['control: scenario 2',\n   [4, 20, [27643, 11003, 3000, 32767, 3000]],\n   [['ok', 177], ['ok', 71], ['open', 71], ['over', 71], ['open', 71]]],\n  ['regression: scenario 4',\n   [4, 20, [11825, 32767, 10576, 27128, 10066, 5618, 12778, 6000, 10000]],\n   [['ok', 76],\n    ['over', 76],\n    ['ok', 68],\n    ['ok', 174],\n    ['ok', 65],\n    ['ok', 40],\n    ['ok', 82],\n    ['ok', 40],\n    ['ok', 64]]]],\n [['regression: scenario 1',\n   [0, 250, [3000, 5618, 31500, 27302, 12019]],\n   [['open', None], ['ok', 0], ['ok', 2500], ['ok', 2109], ['ok', 578]]],\n  ['regression: scenario 2',\n   [0, 250, [30430, 16995, 0, 10000, 6000, 10979]],\n   [['ok', 2422], ['ok', 1077], ['open', 1077], ['ok', 376], ['ok', 0], ['ok', 474]]],\n  ['regression: span points and faults',\n   [0, 100, [6242, 31208, 18725, 5000, 32000, 5800]],\n   [['ok', 0], ['ok', 1000], ['ok', 500], ['open', 500], ['over', 500], ['ok', 0]]],\n  ['regression: reverse acting valve',\n   [100, 0, [6242, 12483, 31208, 31600, 5700]],\n   [['ok', 1000], ['ok', 750], ['ok', 0], ['ok', 0], ['ok', 1000]]],\n  ['regression: under-range tolerance',\n   [-40, 120, [5700, 6100, 6242, 6243, 31900]],\n   [['ok', -400], ['ok', -400], ['ok', -400], ['ok', -400], ['ok', 1200]]],\n  ['control: rounding half',\n   [0, 1, [7490, 7491, 18725, 3000, 31950]],\n   [['ok', 0], ['ok', 1], ['ok', 5], ['open', 5], ['ok', 10]]],\n  ['regression: scenario 3',\n   [0, 250, [31456, 13455, 24788, 8289, 14213, 18164, 10000, 0, 20991]],\n   [['ok', 2500],\n    ['ok', 722],\n    ['ok', 1857],\n    ['ok', 205],\n    ['ok', 798],\n    ['ok', 1194],\n    ['ok', 376],\n    ['open', 376],\n    ['ok', 1477]]],\n  ['regression: scenario 4',\n   [0, 100, [3000, 5633, 7891, 18725, 19352, 30730, 10000, 31208, 25959]],\n   [['open', None],\n    ['ok', 0],\n    ['ok', 66],\n    ['ok', 500],\n    ['ok', 525],\n    ['ok', 981],\n    ['ok', 151],\n    ['ok', 1000],\n    ['ok', 790]]]],\n [['regression: scenario 4',\n   [0, 250, [27893, 24340, 19137, 9936, 26279, 31500, 28004, 10000]],\n   [['ok', 2168],\n    ['ok', 1812],\n    ['ok', 1291],\n    ['ok', 370],\n    ['ok', 2006],\n    ['ok', 2500],\n    ['ok', 2179],\n    ['ok', 376]]],\n  ['regression: scenario 5',\n   [100, 0, [5618, 10474, 18027, 31947, 19308, 31083, 26603, 16118, 11612, 5618]],\n   [['ok', 1000],\n    ['ok', 830],\n    ['ok', 528],\n    ['ok', 0],\n    ['ok', 477],\n    ['ok', 5],\n    ['ok', 184],\n    ['ok', 604],\n    ['ok', 785],\n    ['ok', 1000]]],\n  ['regression: span points and faults',\n   [0, 100, [6242, 31208, 18725, 5000, 32000, 5800]],\n   [['ok', 0], ['ok', 1000], ['ok', 500], ['open', 500], ['over', 500], ['ok', 0]]],\n  ['regression: reverse acting valve',\n   [100, 0, [6242, 12483, 31208, 31600, 5700]],\n   [['ok', 1000], ['ok', 750], ['ok', 0], ['ok', 0], ['ok', 1000]]],\n  ['regression: under-range tolerance',\n   [-40, 120, [5700, 6100, 6242, 6243, 31900]],\n   [['ok', -400], ['ok', -400], ['ok', -400], ['ok', -400], ['ok', 1200]]],\n  ['control: rounding half',\n   [0, 1, [7490, 7491, 18725, 3000, 31950]],\n   [['ok', 0], ['ok', 1], ['ok', 5], ['open', 5], ['ok', 10]]],\n  ['regression: scenario 1',\n   [0, 250, [15441, 21456, 3000, 0, 6000, 5618]],\n   [['ok', 921], ['ok', 1523], ['open', 1523], ['open', 1523], ['ok', 0], ['ok', 0]]],\n  ['control: scenario 2',\n   [0, 100, [31078, 6242, 18725, 18727, 19134, 13243, 18725, 21879, 0, 19240]],\n   [['ok', 995],\n    ['ok', 0],\n    ['ok', 500],\n    ['ok', 500],\n    ['ok', 516],\n    ['ok', 280],\n    ['ok', 500],\n    ['ok', 626],\n    ['open', 626],\n    ['ok', 521]]]]]\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 bounded teaching model of one PLC instruction or rung pattern evaluated scan by scan. The stated contract is a stipulated toy convention, not a claim of conformance to any vendor controller or IEC 61131-3 runtime. 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-plc-ladder-logic-scan-cycles-analog-4-20ma-scaling-range-clamp","generated_at":"2026-09-29T14:51:43.812648+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Ladder programs are executed as repeated scans; each defect here changes what a rung, timer, counter or data-table instruction reports on a particular scan, which is how commissioning and field faults are actually observed.","root_cause":"The clamp to the configured range is missing.","sha256":"6aba8f536162ef8d974f3c1ebac065a1337ef9f3be0243996dccda4e503033b2","title":"Scaled analog value escapes the engineering range · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verified":true,"visibility":"public","verification":{"attempt":{"elapsed_ms":41.788,"exit_code":1,"observations":[{"actual":[["ok",0],["ok",1000],["ok",500],["open",500],["over",500],["ok",-18]],"check":"regression: span points and faults","expected":[["ok",0],["ok",1000],["ok",500],["open",500],["over",500],["ok",0]],"passed":false},{"actual":[["ok",1000],["ok",750],["ok",0],["ok",-16],["ok",1000]],"check":"regression: reverse acting valve","expected":[["ok",1000],["ok",750],["ok",0],["ok",0],["ok",1000]],"passed":false},{"actual":[["ok",-435],["ok",-409],["ok",-400],["ok",-400],["ok",1200]],"check":"regression: under-range tolerance","expected":[["ok",-400],["ok",-400],["ok",-400],["ok",-400],["ok",1200]],"passed":false},{"actual":[["ok",0],["ok",1],["ok",5],["open",5],["ok",10]],"check":"control: rounding half","expected":[["ok",0],["ok",1],["ok",5],["open",5],["ok",10]],"passed":true},{"actual":[["ok",-12],["ok",918],["ok",344],["ok",334],["ok",1000],["ok",702],["ok",-12],["ok",491]],"check":"regression: scenario 1","expected":[["ok",0],["ok",918],["ok",344],["ok",334],["ok",1000],["ok",702],["ok",0],["ok",491]],"passed":false},{"actual":[["open",null],["ok",402],["ok",2500],["ok",1456],["ok",901],["ok",2500]],"check":"control: scenario 2","expected":[["open",null],["ok",402],["ok",2500],["ok",1456],["ok",901],["ok",2500]],"passed":true},{"actual":[["over",null],["ok",-416],["ok",-400],["ok",744],["over",744],["ok",903],["ok",878],["ok",666]],"check":"regression: scenario 3","expected":[["over",null],["ok",-400],["ok",-400],["ok",744],["over",744],["ok",903],["ok",878],["ok",666]],"passed":false},{"actual":[["ok",1090],["ok",400],["open",400],["ok",-36],["ok",-341],["ok",1200],["ok",-440],["ok",1042],["ok",1200]],"check":"regression: scenario 4","expected":[["ok",1090],["ok",400],["open",400],["ok",-36],["ok",-341],["ok",1200],["ok",-400],["ok",1042],["ok",1200]],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: span points and faults\", \"actual\": [[\"ok\", 0], [\"ok\", 1000], [\"ok\", 500], [\"open\", 500], [\"over\", 500], [\"ok\", -18]], \"expected\": [[\"ok\", 0], [\"ok\", 1000], [\"ok\", 500], [\"open\", 500], [\"over\", 500], [\"ok\", 0]], \"passed\": false}, {\"check\": \"regression: reverse acting valve\", \"actual\": [[\"ok\", 1000], [\"ok\", 750], [\"ok\", 0], [\"ok\", -16], [\"ok\", 1000]], \"expected\": [[\"ok\", 1000], [\"ok\", 750], [\"ok\", 0], [\"ok\", 0], [\"ok\", 1000]], \"passed\": false}, {\"check\": \"regression: under-range tolerance\", \"actual\": [[\"ok\", -435], [\"ok\", -409], [\"ok\", -400], [\"ok\", -400], [\"ok\", 1200]], \"expected\": [[\"ok\", -400], [\"ok\", -400], [\"ok\", -400], [\"ok\", -400], [\"ok\", 1200]], \"passed\": false}, {\"check\": \"control: rounding half\", \"actual\": [[\"ok\", 0], [\"ok\", 1], [\"ok\", 5], [\"open\", 5], [\"ok\", 10]], \"expected\": [[\"ok\", 0], [\"ok\", 1], [\"ok\", 5], [\"open\", 5], [\"ok\", 10]], \"passed\": true}, {\"check\": \"regression: scenario 1\", \"actual\": [[\"ok\", -12], [\"ok\", 918], [\"ok\", 344], [\"ok\", 334], [\"ok\", 1000], [\"ok\", 702], [\"ok\", -12], [\"ok\", 491]], \"expected\": [[\"ok\", 0], [\"ok\", 918], [\"ok\", 344], [\"ok\", 334], [\"ok\", 1000], [\"ok\", 702], [\"ok\", 0], [\"ok\", 491]], \"passed\": false}, {\"check\": \"control: scenario 2\", \"actual\": [[\"open\", null], [\"ok\", 402], [\"ok\", 2500], [\"ok\", 1456], [\"ok\", 901], [\"ok\", 2500]], \"expected\": [[\"open\", null], [\"ok\", 402], [\"ok\", 2500], [\"ok\", 1456], [\"ok\", 901], [\"ok\", 2500]], \"passed\": true}, {\"check\": \"regression: scenario 3\", \"actual\": [[\"over\", null], [\"ok\", -416], [\"ok\", -400], [\"ok\", 744], [\"over\", 744], [\"ok\", 903], [\"ok\", 878], [\"ok\", 666]], \"expected\": [[\"over\", null], [\"ok\", -400], [\"ok\", -400], [\"ok\", 744], [\"over\", 744], [\"ok\", 903], [\"ok\", 878], [\"ok\", 666]], \"passed\": false}, {\"check\": \"regression: scenario 4\", \"actual\": [[\"ok\", 1090], [\"ok\", 400], [\"open\", 400], [\"ok\", -36], [\"ok\", -341], [\"ok\", 1200], [\"ok\", -440], [\"ok\", 1042], [\"ok\", 1200]], \"expected\": [[\"ok\", 1090], [\"ok\", 400], [\"open\", 400], [\"ok\", -36], [\"ok\", -341], [\"ok\", 1200], [\"ok\", -400], [\"ok\", 1042], [\"ok\", 1200]], \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":41.146,"exit_code":1,"observations":[{"actual":[["ok",0],["ok",1000],["ok",500],["open",500],["over",500],["ok",-18]],"check":"regression: span points and faults","expected":[["ok",0],["ok",1000],["ok",500],["open",500],["over",500],["ok",0]],"passed":false},{"actual":[["ok",1000],["ok",750],["ok",0],["ok",-16],["ok",1022]],"check":"regression: reverse acting valve","expected":[["ok",1000],["ok",750],["ok",0],["ok",0],["ok",1000]],"passed":false},{"actual":[["ok",-435],["ok",-409],["ok",-400],["ok",-400],["ok",1244]],"check":"regression: under-range tolerance","expected":[["ok",-400],["ok",-400],["ok",-400],["ok",-400],["ok",1200]],"passed":false},{"actual":[["ok",0],["ok",1],["ok",5],["open",5],["ok",10]],"check":"control: rounding half","expected":[["ok",0],["ok",1],["ok",5],["open",5],["ok",10]],"passed":true},{"actual":[["ok",-12],["ok",918],["ok",344],["ok",334],["ok",1025],["ok",702],["ok",-12],["ok",491]],"check":"regression: scenario 1","expected":[["ok",0],["ok",918],["ok",344],["ok",334],["ok",1000],["ok",702],["ok",0],["ok",491]],"passed":false},{"actual":[["open",null],["ok",402],["ok",2500],["ok",1456],["ok",901],["ok",2500]],"check":"control: scenario 2","expected":[["open",null],["ok",402],["ok",2500],["ok",1456],["ok",901],["ok",2500]],"passed":true},{"actual":[["over",null],["ok",-416],["ok",-400],["ok",744],["over",744],["ok",903],["ok",878],["ok",666]],"check":"regression: scenario 3","expected":[["over",null],["ok",-400],["ok",-400],["ok",744],["over",744],["ok",903],["ok",878],["ok",666]],"passed":false},{"actual":[["ok",1090],["ok",400],["open",400],["ok",-36],["ok",-341],["ok",1250],["ok",-440],["ok",1042],["ok",1238]],"check":"regression: scenario 4","expected":[["ok",1090],["ok",400],["open",400],["ok",-36],["ok",-341],["ok",1200],["ok",-400],["ok",1042],["ok",1200]],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: span points and faults\", \"actual\": [[\"ok\", 0], [\"ok\", 1000], [\"ok\", 500], [\"open\", 500], [\"over\", 500], [\"ok\", -18]], \"expected\": [[\"ok\", 0], [\"ok\", 1000], [\"ok\", 500], [\"open\", 500], [\"over\", 500], [\"ok\", 0]], \"passed\": false}, {\"check\": \"regression: reverse acting valve\", \"actual\": [[\"ok\", 1000], [\"ok\", 750], [\"ok\", 0], [\"ok\", -16], [\"ok\", 1022]], \"expected\": [[\"ok\", 1000], [\"ok\", 750], [\"ok\", 0], [\"ok\", 0], [\"ok\", 1000]], \"passed\": false}, {\"check\": \"regression: under-range tolerance\", \"actual\": [[\"ok\", -435], [\"ok\", -409], [\"ok\", -400], [\"ok\", -400], [\"ok\", 1244]], \"expected\": [[\"ok\", -400], [\"ok\", -400], [\"ok\", -400], [\"ok\", -400], [\"ok\", 1200]], \"passed\": false}, {\"check\": \"control: rounding half\", \"actual\": [[\"ok\", 0], [\"ok\", 1], [\"ok\", 5], [\"open\", 5], [\"ok\", 10]], \"expected\": [[\"ok\", 0], [\"ok\", 1], [\"ok\", 5], [\"open\", 5], [\"ok\", 10]], \"passed\": true}, {\"check\": \"regression: scenario 1\", \"actual\": [[\"ok\", -12], [\"ok\", 918], [\"ok\", 344], [\"ok\", 334], [\"ok\", 1025], [\"ok\", 702], [\"ok\", -12], [\"ok\", 491]], \"expected\": [[\"ok\", 0], [\"ok\", 918], [\"ok\", 344], [\"ok\", 334], [\"ok\", 1000], [\"ok\", 702], [\"ok\", 0], [\"ok\", 491]], \"passed\": false}, {\"check\": \"control: scenario 2\", \"actual\": [[\"open\", null], [\"ok\", 402], [\"ok\", 2500], [\"ok\", 1456], [\"ok\", 901], [\"ok\", 2500]], \"expected\": [[\"open\", null], [\"ok\", 402], [\"ok\", 2500], [\"ok\", 1456], [\"ok\", 901], [\"ok\", 2500]], \"passed\": true}, {\"check\": \"regression: scenario 3\", \"actual\": [[\"over\", null], [\"ok\", -416], [\"ok\", -400], [\"ok\", 744], [\"over\", 744], [\"ok\", 903], [\"ok\", 878], [\"ok\", 666]], \"expected\": [[\"over\", null], [\"ok\", -400], [\"ok\", -400], [\"ok\", 744], [\"over\", 744], [\"ok\", 903], [\"ok\", 878], [\"ok\", 666]], \"passed\": false}, {\"check\": \"regression: scenario 4\", \"actual\": [[\"ok\", 1090], [\"ok\", 400], [\"open\", 400], [\"ok\", -36], [\"ok\", -341], [\"ok\", 1250], [\"ok\", -440], [\"ok\", 1042], [\"ok\", 1238]], \"expected\": [[\"ok\", 1090], [\"ok\", 400], [\"open\", 400], [\"ok\", -36], [\"ok\", -341], [\"ok\", 1200], [\"ok\", -400], [\"ok\", 1042], [\"ok\", 1200]], \"passed\": false}], \"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."}}