{"abstract":"Charging continues one sample longer than the configured stop delay.","category":"EV charging session scheduling","checks":7,"contract":"samples are per-minute PV surplus watts. Charging starts on the sample completing start_delay consecutive samples >= start_w, and stops on the sample completing stop_delay consecutive samples < stop_w; counters reset on each transition and on any interrupting sample. While charging the power is the surplus clamped to [1380, 3680] W, else 0. Return [powers, number of starts].","evaluation_group":"w2-ev_charging_session_scheduling-pv-surplus-follow","failed_approach":"Subtracting one stops a sample too early.","family":"w2-ev_charging_session_scheduling-pv-surplus-follow-stop-delay-comparison","id":"FA-93021","implementations":{"attempt":{"sha256":"74992b9e27072f2434f31bc97c9b0e651d6ee62f1c20b7e2bb1989925891176b","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(samples, start_w, stop_w, start_delay, stop_delay):\n    on = False\n    run = 0\n    out = []\n    starts = 0\n    for s in samples:\n        if not on:\n            run = run + 1 if s >= start_w else 0\n            if run >= start_delay:\n                on = True\n                starts += 1\n                run = 0\n        else:\n            run = run + 1 if s < stop_w else 0\n            if run >= stop_delay - 1:\n                on = False\n                run = 0\n        out.append(min(max(s, 1380), 3680) if on else 0)\n    return [out, starts]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['boundary: surplus exactly at start threshold', [[2000, 2000, 2000, 500], 2000, 1000, 2, 1],\n   [[0, 2000, 2000, 0], 1]],\n  ['boundary: never enough sun', [[100, 200, 300, 400, 500, 600], 1400, 800, 1, 1],\n   [[0, 0, 0, 0, 0, 0], 0]],\n  ['boundary: cloud dip shorter than stop delay',\n   [[3000, 3000, 500, 3000, 500, 500, 3000], 1400, 800, 1, 2],\n   [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2]],\n  ['regression: stop delay comparison',\n   [[1686, 3340, 1407, 3891, 3528, 2938, 328, 2002, 686, 0, 2304, 1141, 635, 0, 3641, 1580], 2500,\n    1400, 2, 1],\n   [[0, 0, 0, 0, 3528, 2938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1]],\n  ['regression: stop delay comparison (partial repair)',\n   [[0, 0, 0, 2234, 3394, 627, 3397, 1759, 0, 0], 1400, 1000, 2, 3],\n   [[0, 0, 0, 0, 3394, 1380, 3397, 1759, 1380, 1380], 1]],\n  ['control 1', [[1632, 1402, 0, 1011, 1056, 2204, 0, 0, 0, 0, 0, 2059, 0], 1400, 1400, 3, 1],\n   [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 0]],\n  ['control 2',\n   [[5160, 1495, 4246, 2693, 3633, 943, 5200, 3902, 2959, 1685, 2602], 1400, 800, 3, 2],\n   [[0, 0, 3680, 2693, 3633, 1380, 3680, 3680, 2959, 1685, 2602], 1]]],\n [['boundary: surplus exactly at start threshold', [[2000, 2000, 2000, 500], 2000, 1000, 2, 1],\n   [[0, 2000, 2000, 0], 1]],\n  ['boundary: never enough sun', [[100, 200, 300, 400, 500, 600], 1400, 800, 1, 1],\n   [[0, 0, 0, 0, 0, 0], 0]],\n  ['boundary: cloud dip shorter than stop delay',\n   [[3000, 3000, 500, 3000, 500, 500, 3000], 1400, 800, 1, 2],\n   [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2]],\n  ['regression: stop delay comparison',\n   [[3009, 3188, 1176, 956, 2989, 1246, 110, 1401, 1727, 0, 2027], 2500, 800, 1, 1],\n   [[3009, 3188, 1380, 1380, 2989, 1380, 0, 0, 0, 0, 0], 1]],\n  ['regression: stop delay comparison (partial repair)',\n   [[4817, 2001, 3378, 6211, 4249, 4419, 4018, 3735, 5976, 5858, 1801, 2940, 2878, 5255, 4134,\n     4693],\n    1400, 800, 2, 1],\n   [[0, 2001, 3378, 3680, 3680, 3680, 3680, 3680, 3680, 3680, 1801, 2940, 2878, 3680, 3680, 3680],\n    1]],\n  ['control 1', [[2491, 6454, 5581, 5791, 7280, 4927, 5591, 6410], 1400, 1000, 1, 1],\n   [[2491, 3680, 3680, 3680, 3680, 3680, 3680, 3680], 1]],\n  ['control 2', [[3110, 2987, 3876, 6142, 2422, 5132, 2143, 6887, 4896, 4908], 2000, 1000, 3, 2],\n   [[0, 0, 3680, 3680, 2422, 3680, 2143, 3680, 3680, 3680], 1]]],\n [['boundary: surplus exactly at start threshold', [[2000, 2000, 2000, 500], 2000, 1000, 2, 1],\n   [[0, 2000, 2000, 0], 1]],\n  ['boundary: never enough sun', [[100, 200, 300, 400, 500, 600], 1400, 800, 1, 1],\n   [[0, 0, 0, 0, 0, 0], 0]],\n  ['boundary: cloud dip shorter than stop delay',\n   [[3000, 3000, 500, 3000, 500, 500, 3000], 1400, 800, 1, 2],\n   [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2]],\n  ['regression: stop delay comparison',\n   [[0, 0, 0, 422, 2620, 2189, 1006, 1799, 972, 0, 0, 121, 0, 0], 2000, 1000, 1, 1],\n   [[0, 0, 0, 0, 2620, 2189, 1380, 1799, 0, 0, 0, 0, 0, 0], 1]],\n  ['regression: stop delay comparison (partial repair)',\n   [[1961, 5023, 3923, 3896, 4035, 3052, 1335, 3723, 1391, 1973, 5218], 1400, 1000, 1, 1],\n   [[1961, 3680, 3680, 3680, 3680, 3052, 1380, 3680, 1391, 1973, 3680], 1]],\n  ['control 1', [[5534, 5945, 5877, 6991, 3580, 5525, 6786, 5530, 2720, 6795], 2000, 800, 1, 1],\n   [[3680, 3680, 3680, 3680, 3580, 3680, 3680, 3680, 2720, 3680], 1]],\n  ['control 2',\n   [[3289, 1459, 5221, 3468, 1247, 4575, 1243, 1923, 2108, 3912, 3417, 2756, 1675, 1378, 5487],\n    2000, 1400, 3, 2],\n   [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3417, 2756, 1675, 1380, 3680], 1]]],\n [['boundary: surplus exactly at start threshold', [[2000, 2000, 2000, 500], 2000, 1000, 2, 1],\n   [[0, 2000, 2000, 0], 1]],\n  ['boundary: never enough sun', [[100, 200, 300, 400, 500, 600], 1400, 800, 1, 1],\n   [[0, 0, 0, 0, 0, 0], 0]],\n  ['boundary: cloud dip shorter than stop delay',\n   [[3000, 3000, 500, 3000, 500, 500, 3000], 1400, 800, 1, 2],\n   [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2]],\n  ['regression: stop delay comparison',\n   [[1375, 4072, 3054, 2932, 1996, 2236, 194, 2264, 1091, 0], 2500, 1400, 1, 2],\n   [[0, 3680, 3054, 2932, 1996, 2236, 1380, 2264, 1380, 0], 1]],\n  ['regression: stop delay comparison (partial repair)',\n   [[2294, 2603, 2597, 3913, 3600, 2378, 4027, 3674, 5100, 4341], 2000, 1000, 1, 1],\n   [[2294, 2603, 2597, 3680, 3600, 2378, 3680, 3674, 3680, 3680], 1]],\n  ['control 1', [[2567, 1353, 0, 2085, 0, 0, 116, 324, 1725, 810], 1400, 1400, 1, 2],\n   [[2567, 1380, 0, 2085, 1380, 0, 0, 0, 1725, 1380], 3]],\n  ['control 2',\n   [[3612, 3481, 805, 1117, 2494, 200, 653, 4188, 280, 752, 4261, 4604], 1400, 1000, 1, 1],\n   [[3612, 3481, 0, 0, 2494, 0, 0, 3680, 0, 0, 3680, 3680], 4]]],\n [['boundary: surplus exactly at start threshold', [[2000, 2000, 2000, 500], 2000, 1000, 2, 1],\n   [[0, 2000, 2000, 0], 1]],\n  ['boundary: never enough sun', [[100, 200, 300, 400, 500, 600], 1400, 800, 1, 1],\n   [[0, 0, 0, 0, 0, 0], 0]],\n  ['boundary: cloud dip shorter than stop delay',\n   [[3000, 3000, 500, 3000, 500, 500, 3000], 1400, 800, 1, 2],\n   [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2]],\n  ['regression: stop delay comparison',\n   [[391, 1113, 0, 2478, 0, 0, 0, 0, 0, 0, 2459], 2000, 800, 1, 3],\n   [[0, 0, 0, 2478, 1380, 1380, 0, 0, 0, 0, 2459], 2]],\n  ['regression: stop delay comparison (partial repair)',\n   [[1556, 2553, 1392, 829, 1166, 3311, 4436, 560, 2803, 1972, 4425, 4180], 1400, 1000, 1, 2],\n   [[1556, 2553, 1392, 1380, 1380, 3311, 3680, 1380, 2803, 1972, 3680, 3680], 1]],\n  ['control 1', [[1756, 0, 1045, 0, 1278, 3133, 2829, 2511, 2201, 3176, 1898], 2000, 1400, 3, 3],\n   [[0, 0, 0, 0, 0, 0, 0, 2511, 2201, 3176, 1898], 1]],\n  ['control 2', [[3627, 2896, 3017, 2824, 6221, 3547, 1687, 5138], 1400, 800, 2, 2],\n   [[0, 2896, 3017, 2824, 3680, 3547, 1687, 3680], 1]]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"93ec94a68429fc4819489c543e2a28883f975d0711e38919638cac2e6b9b0619","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(samples, start_w, stop_w, start_delay, stop_delay):\n    on = False\n    run = 0\n    out = []\n    starts = 0\n    for s in samples:\n        if not on:\n            run = run + 1 if s >= start_w else 0\n            if run >= start_delay:\n                on = True\n                starts += 1\n                run = 0\n        else:\n            run = run + 1 if s < stop_w else 0\n            if run > stop_delay:\n                on = False\n                run = 0\n        out.append(min(max(s, 1380), 3680) if on else 0)\n    return [out, starts]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['boundary: surplus exactly at start threshold', [[2000, 2000, 2000, 500], 2000, 1000, 2, 1],\n   [[0, 2000, 2000, 0], 1]],\n  ['boundary: never enough sun', [[100, 200, 300, 400, 500, 600], 1400, 800, 1, 1],\n   [[0, 0, 0, 0, 0, 0], 0]],\n  ['boundary: cloud dip shorter than stop delay',\n   [[3000, 3000, 500, 3000, 500, 500, 3000], 1400, 800, 1, 2],\n   [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2]],\n  ['regression: stop delay comparison',\n   [[1686, 3340, 1407, 3891, 3528, 2938, 328, 2002, 686, 0, 2304, 1141, 635, 0, 3641, 1580], 2500,\n    1400, 2, 1],\n   [[0, 0, 0, 0, 3528, 2938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1]],\n  ['regression: stop delay comparison (partial repair)',\n   [[0, 0, 0, 2234, 3394, 627, 3397, 1759, 0, 0], 1400, 1000, 2, 3],\n   [[0, 0, 0, 0, 3394, 1380, 3397, 1759, 1380, 1380], 1]],\n  ['control 1', [[1632, 1402, 0, 1011, 1056, 2204, 0, 0, 0, 0, 0, 2059, 0], 1400, 1400, 3, 1],\n   [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 0]],\n  ['control 2',\n   [[5160, 1495, 4246, 2693, 3633, 943, 5200, 3902, 2959, 1685, 2602], 1400, 800, 3, 2],\n   [[0, 0, 3680, 2693, 3633, 1380, 3680, 3680, 2959, 1685, 2602], 1]]],\n [['boundary: surplus exactly at start threshold', [[2000, 2000, 2000, 500], 2000, 1000, 2, 1],\n   [[0, 2000, 2000, 0], 1]],\n  ['boundary: never enough sun', [[100, 200, 300, 400, 500, 600], 1400, 800, 1, 1],\n   [[0, 0, 0, 0, 0, 0], 0]],\n  ['boundary: cloud dip shorter than stop delay',\n   [[3000, 3000, 500, 3000, 500, 500, 3000], 1400, 800, 1, 2],\n   [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2]],\n  ['regression: stop delay comparison',\n   [[3009, 3188, 1176, 956, 2989, 1246, 110, 1401, 1727, 0, 2027], 2500, 800, 1, 1],\n   [[3009, 3188, 1380, 1380, 2989, 1380, 0, 0, 0, 0, 0], 1]],\n  ['regression: stop delay comparison (partial repair)',\n   [[4817, 2001, 3378, 6211, 4249, 4419, 4018, 3735, 5976, 5858, 1801, 2940, 2878, 5255, 4134,\n     4693],\n    1400, 800, 2, 1],\n   [[0, 2001, 3378, 3680, 3680, 3680, 3680, 3680, 3680, 3680, 1801, 2940, 2878, 3680, 3680, 3680],\n    1]],\n  ['control 1', [[2491, 6454, 5581, 5791, 7280, 4927, 5591, 6410], 1400, 1000, 1, 1],\n   [[2491, 3680, 3680, 3680, 3680, 3680, 3680, 3680], 1]],\n  ['control 2', [[3110, 2987, 3876, 6142, 2422, 5132, 2143, 6887, 4896, 4908], 2000, 1000, 3, 2],\n   [[0, 0, 3680, 3680, 2422, 3680, 2143, 3680, 3680, 3680], 1]]],\n [['boundary: surplus exactly at start threshold', [[2000, 2000, 2000, 500], 2000, 1000, 2, 1],\n   [[0, 2000, 2000, 0], 1]],\n  ['boundary: never enough sun', [[100, 200, 300, 400, 500, 600], 1400, 800, 1, 1],\n   [[0, 0, 0, 0, 0, 0], 0]],\n  ['boundary: cloud dip shorter than stop delay',\n   [[3000, 3000, 500, 3000, 500, 500, 3000], 1400, 800, 1, 2],\n   [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2]],\n  ['regression: stop delay comparison',\n   [[0, 0, 0, 422, 2620, 2189, 1006, 1799, 972, 0, 0, 121, 0, 0], 2000, 1000, 1, 1],\n   [[0, 0, 0, 0, 2620, 2189, 1380, 1799, 0, 0, 0, 0, 0, 0], 1]],\n  ['regression: stop delay comparison (partial repair)',\n   [[1961, 5023, 3923, 3896, 4035, 3052, 1335, 3723, 1391, 1973, 5218], 1400, 1000, 1, 1],\n   [[1961, 3680, 3680, 3680, 3680, 3052, 1380, 3680, 1391, 1973, 3680], 1]],\n  ['control 1', [[5534, 5945, 5877, 6991, 3580, 5525, 6786, 5530, 2720, 6795], 2000, 800, 1, 1],\n   [[3680, 3680, 3680, 3680, 3580, 3680, 3680, 3680, 2720, 3680], 1]],\n  ['control 2',\n   [[3289, 1459, 5221, 3468, 1247, 4575, 1243, 1923, 2108, 3912, 3417, 2756, 1675, 1378, 5487],\n    2000, 1400, 3, 2],\n   [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3417, 2756, 1675, 1380, 3680], 1]]],\n [['boundary: surplus exactly at start threshold', [[2000, 2000, 2000, 500], 2000, 1000, 2, 1],\n   [[0, 2000, 2000, 0], 1]],\n  ['boundary: never enough sun', [[100, 200, 300, 400, 500, 600], 1400, 800, 1, 1],\n   [[0, 0, 0, 0, 0, 0], 0]],\n  ['boundary: cloud dip shorter than stop delay',\n   [[3000, 3000, 500, 3000, 500, 500, 3000], 1400, 800, 1, 2],\n   [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2]],\n  ['regression: stop delay comparison',\n   [[1375, 4072, 3054, 2932, 1996, 2236, 194, 2264, 1091, 0], 2500, 1400, 1, 2],\n   [[0, 3680, 3054, 2932, 1996, 2236, 1380, 2264, 1380, 0], 1]],\n  ['regression: stop delay comparison (partial repair)',\n   [[2294, 2603, 2597, 3913, 3600, 2378, 4027, 3674, 5100, 4341], 2000, 1000, 1, 1],\n   [[2294, 2603, 2597, 3680, 3600, 2378, 3680, 3674, 3680, 3680], 1]],\n  ['control 1', [[2567, 1353, 0, 2085, 0, 0, 116, 324, 1725, 810], 1400, 1400, 1, 2],\n   [[2567, 1380, 0, 2085, 1380, 0, 0, 0, 1725, 1380], 3]],\n  ['control 2',\n   [[3612, 3481, 805, 1117, 2494, 200, 653, 4188, 280, 752, 4261, 4604], 1400, 1000, 1, 1],\n   [[3612, 3481, 0, 0, 2494, 0, 0, 3680, 0, 0, 3680, 3680], 4]]],\n [['boundary: surplus exactly at start threshold', [[2000, 2000, 2000, 500], 2000, 1000, 2, 1],\n   [[0, 2000, 2000, 0], 1]],\n  ['boundary: never enough sun', [[100, 200, 300, 400, 500, 600], 1400, 800, 1, 1],\n   [[0, 0, 0, 0, 0, 0], 0]],\n  ['boundary: cloud dip shorter than stop delay',\n   [[3000, 3000, 500, 3000, 500, 500, 3000], 1400, 800, 1, 2],\n   [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2]],\n  ['regression: stop delay comparison',\n   [[391, 1113, 0, 2478, 0, 0, 0, 0, 0, 0, 2459], 2000, 800, 1, 3],\n   [[0, 0, 0, 2478, 1380, 1380, 0, 0, 0, 0, 2459], 2]],\n  ['regression: stop delay comparison (partial repair)',\n   [[1556, 2553, 1392, 829, 1166, 3311, 4436, 560, 2803, 1972, 4425, 4180], 1400, 1000, 1, 2],\n   [[1556, 2553, 1392, 1380, 1380, 3311, 3680, 1380, 2803, 1972, 3680, 3680], 1]],\n  ['control 1', [[1756, 0, 1045, 0, 1278, 3133, 2829, 2511, 2201, 3176, 1898], 2000, 1400, 3, 3],\n   [[0, 0, 0, 0, 0, 0, 0, 2511, 2201, 3176, 1898], 1]],\n  ['control 2', [[3627, 2896, 3017, 2824, 6221, 3547, 1687, 5138], 1400, 800, 2, 2],\n   [[0, 2896, 3017, 2824, 3680, 3547, 1687, 3680], 1]]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"fixed":{"sha256":"43938d48be635aaec019b57ba83403ded3be59d5c290d3b71789e11fc63e9510","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(samples, start_w, stop_w, start_delay, stop_delay):\n    on = False\n    run = 0\n    out = []\n    starts = 0\n    for s in samples:\n        if not on:\n            run = run + 1 if s >= start_w else 0\n            if run >= start_delay:\n                on = True\n                starts += 1\n                run = 0\n        else:\n            run = run + 1 if s < stop_w else 0\n            if run >= stop_delay:\n                on = False\n                run = 0\n        out.append(min(max(s, 1380), 3680) if on else 0)\n    return [out, starts]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['boundary: surplus exactly at start threshold', [[2000, 2000, 2000, 500], 2000, 1000, 2, 1],\n   [[0, 2000, 2000, 0], 1]],\n  ['boundary: never enough sun', [[100, 200, 300, 400, 500, 600], 1400, 800, 1, 1],\n   [[0, 0, 0, 0, 0, 0], 0]],\n  ['boundary: cloud dip shorter than stop delay',\n   [[3000, 3000, 500, 3000, 500, 500, 3000], 1400, 800, 1, 2],\n   [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2]],\n  ['regression: stop delay comparison',\n   [[1686, 3340, 1407, 3891, 3528, 2938, 328, 2002, 686, 0, 2304, 1141, 635, 0, 3641, 1580], 2500,\n    1400, 2, 1],\n   [[0, 0, 0, 0, 3528, 2938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1]],\n  ['regression: stop delay comparison (partial repair)',\n   [[0, 0, 0, 2234, 3394, 627, 3397, 1759, 0, 0], 1400, 1000, 2, 3],\n   [[0, 0, 0, 0, 3394, 1380, 3397, 1759, 1380, 1380], 1]],\n  ['control 1', [[1632, 1402, 0, 1011, 1056, 2204, 0, 0, 0, 0, 0, 2059, 0], 1400, 1400, 3, 1],\n   [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 0]],\n  ['control 2',\n   [[5160, 1495, 4246, 2693, 3633, 943, 5200, 3902, 2959, 1685, 2602], 1400, 800, 3, 2],\n   [[0, 0, 3680, 2693, 3633, 1380, 3680, 3680, 2959, 1685, 2602], 1]]],\n [['boundary: surplus exactly at start threshold', [[2000, 2000, 2000, 500], 2000, 1000, 2, 1],\n   [[0, 2000, 2000, 0], 1]],\n  ['boundary: never enough sun', [[100, 200, 300, 400, 500, 600], 1400, 800, 1, 1],\n   [[0, 0, 0, 0, 0, 0], 0]],\n  ['boundary: cloud dip shorter than stop delay',\n   [[3000, 3000, 500, 3000, 500, 500, 3000], 1400, 800, 1, 2],\n   [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2]],\n  ['regression: stop delay comparison',\n   [[3009, 3188, 1176, 956, 2989, 1246, 110, 1401, 1727, 0, 2027], 2500, 800, 1, 1],\n   [[3009, 3188, 1380, 1380, 2989, 1380, 0, 0, 0, 0, 0], 1]],\n  ['regression: stop delay comparison (partial repair)',\n   [[4817, 2001, 3378, 6211, 4249, 4419, 4018, 3735, 5976, 5858, 1801, 2940, 2878, 5255, 4134,\n     4693],\n    1400, 800, 2, 1],\n   [[0, 2001, 3378, 3680, 3680, 3680, 3680, 3680, 3680, 3680, 1801, 2940, 2878, 3680, 3680, 3680],\n    1]],\n  ['control 1', [[2491, 6454, 5581, 5791, 7280, 4927, 5591, 6410], 1400, 1000, 1, 1],\n   [[2491, 3680, 3680, 3680, 3680, 3680, 3680, 3680], 1]],\n  ['control 2', [[3110, 2987, 3876, 6142, 2422, 5132, 2143, 6887, 4896, 4908], 2000, 1000, 3, 2],\n   [[0, 0, 3680, 3680, 2422, 3680, 2143, 3680, 3680, 3680], 1]]],\n [['boundary: surplus exactly at start threshold', [[2000, 2000, 2000, 500], 2000, 1000, 2, 1],\n   [[0, 2000, 2000, 0], 1]],\n  ['boundary: never enough sun', [[100, 200, 300, 400, 500, 600], 1400, 800, 1, 1],\n   [[0, 0, 0, 0, 0, 0], 0]],\n  ['boundary: cloud dip shorter than stop delay',\n   [[3000, 3000, 500, 3000, 500, 500, 3000], 1400, 800, 1, 2],\n   [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2]],\n  ['regression: stop delay comparison',\n   [[0, 0, 0, 422, 2620, 2189, 1006, 1799, 972, 0, 0, 121, 0, 0], 2000, 1000, 1, 1],\n   [[0, 0, 0, 0, 2620, 2189, 1380, 1799, 0, 0, 0, 0, 0, 0], 1]],\n  ['regression: stop delay comparison (partial repair)',\n   [[1961, 5023, 3923, 3896, 4035, 3052, 1335, 3723, 1391, 1973, 5218], 1400, 1000, 1, 1],\n   [[1961, 3680, 3680, 3680, 3680, 3052, 1380, 3680, 1391, 1973, 3680], 1]],\n  ['control 1', [[5534, 5945, 5877, 6991, 3580, 5525, 6786, 5530, 2720, 6795], 2000, 800, 1, 1],\n   [[3680, 3680, 3680, 3680, 3580, 3680, 3680, 3680, 2720, 3680], 1]],\n  ['control 2',\n   [[3289, 1459, 5221, 3468, 1247, 4575, 1243, 1923, 2108, 3912, 3417, 2756, 1675, 1378, 5487],\n    2000, 1400, 3, 2],\n   [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3417, 2756, 1675, 1380, 3680], 1]]],\n [['boundary: surplus exactly at start threshold', [[2000, 2000, 2000, 500], 2000, 1000, 2, 1],\n   [[0, 2000, 2000, 0], 1]],\n  ['boundary: never enough sun', [[100, 200, 300, 400, 500, 600], 1400, 800, 1, 1],\n   [[0, 0, 0, 0, 0, 0], 0]],\n  ['boundary: cloud dip shorter than stop delay',\n   [[3000, 3000, 500, 3000, 500, 500, 3000], 1400, 800, 1, 2],\n   [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2]],\n  ['regression: stop delay comparison',\n   [[1375, 4072, 3054, 2932, 1996, 2236, 194, 2264, 1091, 0], 2500, 1400, 1, 2],\n   [[0, 3680, 3054, 2932, 1996, 2236, 1380, 2264, 1380, 0], 1]],\n  ['regression: stop delay comparison (partial repair)',\n   [[2294, 2603, 2597, 3913, 3600, 2378, 4027, 3674, 5100, 4341], 2000, 1000, 1, 1],\n   [[2294, 2603, 2597, 3680, 3600, 2378, 3680, 3674, 3680, 3680], 1]],\n  ['control 1', [[2567, 1353, 0, 2085, 0, 0, 116, 324, 1725, 810], 1400, 1400, 1, 2],\n   [[2567, 1380, 0, 2085, 1380, 0, 0, 0, 1725, 1380], 3]],\n  ['control 2',\n   [[3612, 3481, 805, 1117, 2494, 200, 653, 4188, 280, 752, 4261, 4604], 1400, 1000, 1, 1],\n   [[3612, 3481, 0, 0, 2494, 0, 0, 3680, 0, 0, 3680, 3680], 4]]],\n [['boundary: surplus exactly at start threshold', [[2000, 2000, 2000, 500], 2000, 1000, 2, 1],\n   [[0, 2000, 2000, 0], 1]],\n  ['boundary: never enough sun', [[100, 200, 300, 400, 500, 600], 1400, 800, 1, 1],\n   [[0, 0, 0, 0, 0, 0], 0]],\n  ['boundary: cloud dip shorter than stop delay',\n   [[3000, 3000, 500, 3000, 500, 500, 3000], 1400, 800, 1, 2],\n   [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2]],\n  ['regression: stop delay comparison',\n   [[391, 1113, 0, 2478, 0, 0, 0, 0, 0, 0, 2459], 2000, 800, 1, 3],\n   [[0, 0, 0, 2478, 1380, 1380, 0, 0, 0, 0, 2459], 2]],\n  ['regression: stop delay comparison (partial repair)',\n   [[1556, 2553, 1392, 829, 1166, 3311, 4436, 560, 2803, 1972, 4425, 4180], 1400, 1000, 1, 2],\n   [[1556, 2553, 1392, 1380, 1380, 3311, 3680, 1380, 2803, 1972, 3680, 3680], 1]],\n  ['control 1', [[1756, 0, 1045, 0, 1278, 3133, 2829, 2511, 2201, 3176, 1898], 2000, 1400, 3, 3],\n   [[0, 0, 0, 0, 0, 0, 0, 2511, 2201, 3176, 1898], 1]],\n  ['control 2', [[3627, 2896, 3017, 2824, 6221, 3547, 1687, 5138], 1400, 800, 2, 2],\n   [[0, 2896, 3017, 2824, 3680, 3547, 1687, 3680], 1]]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"Deterministic stipulated toy contract for teaching; no claim of conformance with any standard, vendor protocol or production controller. 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-ev_charging_session_scheduling-pv-surplus-follow-stop-delay-comparison","generated_at":"2026-09-29T14:51:51.249212+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Depot, workplace and public EV chargers schedule sessions against prices, circuit limits and departure deadlines; a wrong decision silently strands a driver or overloads a feeder.","repair":"Stop when the streak reaches stop_delay.","root_cause":"The stop streak must exceed the delay instead of reach it.","sha256":"91d6661029c654a34e1803dd76560ea463cd8b2f0210507cfc734b0d0ac93a4e","title":"PV surplus following with hysteresis: stop delay comparison · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":39.98,"exit_code":1,"observations":[{"actual":[[0,2000,0,0],1],"check":"boundary: surplus exactly at start threshold","expected":[[0,2000,2000,0],1],"passed":false},{"actual":[[0,0,0,0,0,0],0],"check":"boundary: never enough sun","expected":[[0,0,0,0,0,0],0],"passed":true},{"actual":[[3000,3000,0,3000,0,0,3000],3],"check":"boundary: cloud dip shorter than stop delay","expected":[[3000,3000,1380,3000,1380,0,3000],2],"passed":false},{"actual":[[0,0,0,0,3528,0,0,0,0,0,0,0,0,0,0,0],1],"check":"regression: stop delay comparison","expected":[[0,0,0,0,3528,2938,0,0,0,0,0,0,0,0,0,0],1],"passed":false},{"actual":[[0,0,0,0,3394,1380,3397,1759,1380,0],1],"check":"regression: stop delay comparison (partial repair)","expected":[[0,0,0,0,3394,1380,3397,1759,1380,1380],1],"passed":false},{"actual":[[0,0,0,0,0,0,0,0,0,0,0,0,0],0],"check":"control 1","expected":[[0,0,0,0,0,0,0,0,0,0,0,0,0],0],"passed":true},{"actual":[[0,0,3680,2693,3633,1380,3680,3680,2959,1685,2602],1],"check":"control 2","expected":[[0,0,3680,2693,3633,1380,3680,3680,2959,1685,2602],1],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"boundary: surplus exactly at start threshold\", \"actual\": [[0, 2000, 0, 0], 1], \"expected\": [[0, 2000, 2000, 0], 1], \"passed\": false}, {\"check\": \"boundary: never enough sun\", \"actual\": [[0, 0, 0, 0, 0, 0], 0], \"expected\": [[0, 0, 0, 0, 0, 0], 0], \"passed\": true}, {\"check\": \"boundary: cloud dip shorter than stop delay\", \"actual\": [[3000, 3000, 0, 3000, 0, 0, 3000], 3], \"expected\": [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2], \"passed\": false}, {\"check\": \"regression: stop delay comparison\", \"actual\": [[0, 0, 0, 0, 3528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1], \"expected\": [[0, 0, 0, 0, 3528, 2938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1], \"passed\": false}, {\"check\": \"regression: stop delay comparison (partial repair)\", \"actual\": [[0, 0, 0, 0, 3394, 1380, 3397, 1759, 1380, 0], 1], \"expected\": [[0, 0, 0, 0, 3394, 1380, 3397, 1759, 1380, 1380], 1], \"passed\": false}, {\"check\": \"control 1\", \"actual\": [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 0], \"expected\": [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 0], \"passed\": true}, {\"check\": \"control 2\", \"actual\": [[0, 0, 3680, 2693, 3633, 1380, 3680, 3680, 2959, 1685, 2602], 1], \"expected\": [[0, 0, 3680, 2693, 3633, 1380, 3680, 3680, 2959, 1685, 2602], 1], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":41.912,"exit_code":1,"observations":[{"actual":[[0,2000,2000,1380],1],"check":"boundary: surplus exactly at start threshold","expected":[[0,2000,2000,0],1],"passed":false},{"actual":[[0,0,0,0,0,0],0],"check":"boundary: never enough sun","expected":[[0,0,0,0,0,0],0],"passed":true},{"actual":[[3000,3000,1380,3000,1380,1380,3000],1],"check":"boundary: cloud dip shorter than stop delay","expected":[[3000,3000,1380,3000,1380,0,3000],2],"passed":false},{"actual":[[0,0,0,0,3528,2938,1380,2002,1380,0,0,0,0,0,0,0],1],"check":"regression: stop delay comparison","expected":[[0,0,0,0,3528,2938,0,0,0,0,0,0,0,0,0,0],1],"passed":false},{"actual":[[0,0,0,0,3394,1380,3397,1759,1380,1380],1],"check":"regression: stop delay comparison (partial repair)","expected":[[0,0,0,0,3394,1380,3397,1759,1380,1380],1],"passed":true},{"actual":[[0,0,0,0,0,0,0,0,0,0,0,0,0],0],"check":"control 1","expected":[[0,0,0,0,0,0,0,0,0,0,0,0,0],0],"passed":true},{"actual":[[0,0,3680,2693,3633,1380,3680,3680,2959,1685,2602],1],"check":"control 2","expected":[[0,0,3680,2693,3633,1380,3680,3680,2959,1685,2602],1],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"boundary: surplus exactly at start threshold\", \"actual\": [[0, 2000, 2000, 1380], 1], \"expected\": [[0, 2000, 2000, 0], 1], \"passed\": false}, {\"check\": \"boundary: never enough sun\", \"actual\": [[0, 0, 0, 0, 0, 0], 0], \"expected\": [[0, 0, 0, 0, 0, 0], 0], \"passed\": true}, {\"check\": \"boundary: cloud dip shorter than stop delay\", \"actual\": [[3000, 3000, 1380, 3000, 1380, 1380, 3000], 1], \"expected\": [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2], \"passed\": false}, {\"check\": \"regression: stop delay comparison\", \"actual\": [[0, 0, 0, 0, 3528, 2938, 1380, 2002, 1380, 0, 0, 0, 0, 0, 0, 0], 1], \"expected\": [[0, 0, 0, 0, 3528, 2938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1], \"passed\": false}, {\"check\": \"regression: stop delay comparison (partial repair)\", \"actual\": [[0, 0, 0, 0, 3394, 1380, 3397, 1759, 1380, 1380], 1], \"expected\": [[0, 0, 0, 0, 3394, 1380, 3397, 1759, 1380, 1380], 1], \"passed\": true}, {\"check\": \"control 1\", \"actual\": [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 0], \"expected\": [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 0], \"passed\": true}, {\"check\": \"control 2\", \"actual\": [[0, 0, 3680, 2693, 3633, 1380, 3680, 3680, 2959, 1685, 2602], 1], \"expected\": [[0, 0, 3680, 2693, 3633, 1380, 3680, 3680, 2959, 1685, 2602], 1], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":40.165,"exit_code":0,"observations":[{"actual":[[0,2000,2000,0],1],"check":"boundary: surplus exactly at start threshold","expected":[[0,2000,2000,0],1],"passed":true},{"actual":[[0,0,0,0,0,0],0],"check":"boundary: never enough sun","expected":[[0,0,0,0,0,0],0],"passed":true},{"actual":[[3000,3000,1380,3000,1380,0,3000],2],"check":"boundary: cloud dip shorter than stop delay","expected":[[3000,3000,1380,3000,1380,0,3000],2],"passed":true},{"actual":[[0,0,0,0,3528,2938,0,0,0,0,0,0,0,0,0,0],1],"check":"regression: stop delay comparison","expected":[[0,0,0,0,3528,2938,0,0,0,0,0,0,0,0,0,0],1],"passed":true},{"actual":[[0,0,0,0,3394,1380,3397,1759,1380,1380],1],"check":"regression: stop delay comparison (partial repair)","expected":[[0,0,0,0,3394,1380,3397,1759,1380,1380],1],"passed":true},{"actual":[[0,0,0,0,0,0,0,0,0,0,0,0,0],0],"check":"control 1","expected":[[0,0,0,0,0,0,0,0,0,0,0,0,0],0],"passed":true},{"actual":[[0,0,3680,2693,3633,1380,3680,3680,2959,1685,2602],1],"check":"control 2","expected":[[0,0,3680,2693,3633,1380,3680,3680,2959,1685,2602],1],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"boundary: surplus exactly at start threshold\", \"actual\": [[0, 2000, 2000, 0], 1], \"expected\": [[0, 2000, 2000, 0], 1], \"passed\": true}, {\"check\": \"boundary: never enough sun\", \"actual\": [[0, 0, 0, 0, 0, 0], 0], \"expected\": [[0, 0, 0, 0, 0, 0], 0], \"passed\": true}, {\"check\": \"boundary: cloud dip shorter than stop delay\", \"actual\": [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2], \"expected\": [[3000, 3000, 1380, 3000, 1380, 0, 3000], 2], \"passed\": true}, {\"check\": \"regression: stop delay comparison\", \"actual\": [[0, 0, 0, 0, 3528, 2938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1], \"expected\": [[0, 0, 0, 0, 3528, 2938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1], \"passed\": true}, {\"check\": \"regression: stop delay comparison (partial repair)\", \"actual\": [[0, 0, 0, 0, 3394, 1380, 3397, 1759, 1380, 1380], 1], \"expected\": [[0, 0, 0, 0, 3394, 1380, 3397, 1759, 1380, 1380], 1], \"passed\": true}, {\"check\": \"control 1\", \"actual\": [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 0], \"expected\": [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 0], \"passed\": true}, {\"check\": \"control 2\", \"actual\": [[0, 0, 3680, 2693, 3633, 1380, 3680, 3680, 2959, 1685, 2602], 1], \"expected\": [[0, 0, 3680, 2693, 3633, 1380, 3680, 3680, 2959, 1685, 2602], 1], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}