{"abstract":"Note rates are pinned to the lifetime cap spread itself.","category":"Loan amortization schedules","checks":7,"contract":"x = {'initial_bp', 'index_path': index at each reset, 'margin_bp', 'round_to', 'initial_cap_bp', 'periodic_cap_bp', 'lifetime_cap_bp' (above initial), 'floor_bp'}. At each reset the fully indexed rate index + margin is rounded half-up to a multiple of round_to, limited to within the cap of the previous note rate (initial cap at the first reset, periodic afterwards, both directions), then limited to [floor_bp, initial + lifetime cap]. Return the list of note rates.","evaluation_group":"w2-loan-amortization-schedules-adjustable-rate-reset-caps","failed_approach":"Measuring the lifetime cap from the previous rate lets the ceiling ratchet up every reset.","family":"w2-loan-amortization-schedules-adjustable-rate-reset-caps-lifetime-ceiling-base","id":"FA-58546","implementations":{"attempt":{"sha256":"c3d370ca580bf473ef290737e89fffa4ad768f352ef3cf721f732ae2de663242","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    rate = x['initial_bp']\n    out = []\n    life_max = x['initial_bp'] + x['lifetime_cap_bp']\n    for i, idx in enumerate(x['index_path']):\n        fi = idx + x['margin_bp']\n        q, r = divmod(fi, x['round_to'])\n        fi = (q + (1 if 2 * r >= x['round_to'] else 0)) * x['round_to']\n        cap = x['initial_cap_bp'] if i == 0 else x['periodic_cap_bp']\n        new = max(rate - cap, min(fi, rate + cap))\n        new = max(x['floor_bp'], min(new, rate + x['lifetime_cap_bp']))\n        out.append(new)\n        rate = new\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression: lifetime ceiling base', {'initial_bp': 500, 'index_path': [212, 100, 50, 250, 700], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 400, 400, 500, 600]], ['regression: lifetime ceiling base, partial-repair probe', {'initial_bp': 300, 'index_path': [400, 650, 537, 650], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [650, 750, 800, 800]], ['control 1', {'initial_bp': 300, 'index_path': [212, 212], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [475, 475]], ['control 2', {'initial_bp': 300, 'index_path': [100, 50, 250], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [400, 350, 550]], ['control 3', {'initial_bp': 300, 'index_path': [650, 212, 100], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [500, 500, 400]], ['control 4', {'initial_bp': 450, 'index_path': [50, 100], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [300, 325]], ['control 5', {'initial_bp': 500, 'index_path': [212, 212, 250], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 500, 500]]], [['regression: lifetime ceiling base', {'initial_bp': 450, 'index_path': [650, 50, 212], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [650, 550, 500]], ['regression: lifetime ceiling base, partial-repair probe', {'initial_bp': 300, 'index_path': [100, 700, 537, 700, 650], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [375, 575, 750, 900, 875]], ['control 1', {'initial_bp': 450, 'index_path': [250, 100, 700], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [475, 325, 525]], ['control 2', {'initial_bp': 500, 'index_path': [212], 'margin_bp': 225, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [375]], ['control 3', {'initial_bp': 450, 'index_path': [50], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [400]], ['control 4', {'initial_bp': 500, 'index_path': [212], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500]], ['control 5', {'initial_bp': 450, 'index_path': [100, 50, 400, 700, 100], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [325, 275, 375, 475, 375]]], [['regression: lifetime ceiling base', {'initial_bp': 450, 'index_path': [212, 650, 50, 650], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [500, 700, 500, 700]], ['regression: lifetime ceiling base, partial-repair probe', {'initial_bp': 300, 'index_path': [537, 700, 50], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [800, 800, 600]], ['control 1', {'initial_bp': 450, 'index_path': [250, 250, 212], 'margin_bp': 225, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 500, 450]], ['control 2', {'initial_bp': 450, 'index_path': [100], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [400]], ['control 3', {'initial_bp': 300, 'index_path': [650], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [500]], ['control 4', {'initial_bp': 450, 'index_path': [250, 212, 100, 50, 700], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [475, 425, 400, 400, 500]], ['control 5', {'initial_bp': 300, 'index_path': [212, 50, 100, 50, 400], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [425, 400, 400, 400, 500]]], [['regression: lifetime ceiling base', {'initial_bp': 300, 'index_path': [400, 400, 537], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 675, 800]], ['regression: lifetime ceiling base, partial-repair probe', {'initial_bp': 300, 'index_path': [650, 700], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [800, 900]], ['control 1', {'initial_bp': 300, 'index_path': [650, 250, 50, 537, 50], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 500, 375, 575, 375]], ['control 2', {'initial_bp': 300, 'index_path': [250, 250, 250], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [500, 500, 500]], ['control 3', {'initial_bp': 500, 'index_path': [100, 212, 100], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [350, 450, 350]], ['control 4', {'initial_bp': 300, 'index_path': [400, 100, 400, 250, 50], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [500, 400, 500, 525, 425]], ['control 5', {'initial_bp': 450, 'index_path': [250, 50, 700], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 400, 500]]], [['regression: lifetime ceiling base', {'initial_bp': 450, 'index_path': [650], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [875]], ['regression: lifetime ceiling base, partial-repair probe', {'initial_bp': 300, 'index_path': [537, 50, 650, 537, 650], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [750, 550, 750, 750, 800]], ['control 1', {'initial_bp': 300, 'index_path': [250], 'margin_bp': 225, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [500]], ['control 2', {'initial_bp': 450, 'index_path': [250, 537, 250, 700], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 600, 500, 600]], ['control 3', {'initial_bp': 300, 'index_path': [50, 537, 250, 100], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [300, 400, 475, 375]], ['control 4', {'initial_bp': 300, 'index_path': [50, 50], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [400, 400]], ['control 5', {'initial_bp': 450, 'index_path': [100, 250, 100, 650], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [375, 525, 375, 575]]]]\nfor label, args, expected in fixtures[N-1]:\n    try:\n        actual = solve(args)\n    except Exception as exc:\n        actual = 'raised ' + type(exc).__name__\n    check(label, actual, 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":"1c139744ec7b008c499cb757cb709e6ae11538090d281d13266a209c17abc0e2","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    rate = x['initial_bp']\n    out = []\n    life_max = x['lifetime_cap_bp']\n    for i, idx in enumerate(x['index_path']):\n        fi = idx + x['margin_bp']\n        q, r = divmod(fi, x['round_to'])\n        fi = (q + (1 if 2 * r >= x['round_to'] else 0)) * x['round_to']\n        cap = x['initial_cap_bp'] if i == 0 else x['periodic_cap_bp']\n        new = max(rate - cap, min(fi, rate + cap))\n        new = max(x['floor_bp'], min(new, life_max))\n        out.append(new)\n        rate = new\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression: lifetime ceiling base', {'initial_bp': 500, 'index_path': [212, 100, 50, 250, 700], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 400, 400, 500, 600]], ['regression: lifetime ceiling base, partial-repair probe', {'initial_bp': 300, 'index_path': [400, 650, 537, 650], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [650, 750, 800, 800]], ['control 1', {'initial_bp': 300, 'index_path': [212, 212], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [475, 475]], ['control 2', {'initial_bp': 300, 'index_path': [100, 50, 250], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [400, 350, 550]], ['control 3', {'initial_bp': 300, 'index_path': [650, 212, 100], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [500, 500, 400]], ['control 4', {'initial_bp': 450, 'index_path': [50, 100], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [300, 325]], ['control 5', {'initial_bp': 500, 'index_path': [212, 212, 250], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 500, 500]]], [['regression: lifetime ceiling base', {'initial_bp': 450, 'index_path': [650, 50, 212], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [650, 550, 500]], ['regression: lifetime ceiling base, partial-repair probe', {'initial_bp': 300, 'index_path': [100, 700, 537, 700, 650], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [375, 575, 750, 900, 875]], ['control 1', {'initial_bp': 450, 'index_path': [250, 100, 700], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [475, 325, 525]], ['control 2', {'initial_bp': 500, 'index_path': [212], 'margin_bp': 225, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [375]], ['control 3', {'initial_bp': 450, 'index_path': [50], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [400]], ['control 4', {'initial_bp': 500, 'index_path': [212], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500]], ['control 5', {'initial_bp': 450, 'index_path': [100, 50, 400, 700, 100], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [325, 275, 375, 475, 375]]], [['regression: lifetime ceiling base', {'initial_bp': 450, 'index_path': [212, 650, 50, 650], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [500, 700, 500, 700]], ['regression: lifetime ceiling base, partial-repair probe', {'initial_bp': 300, 'index_path': [537, 700, 50], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [800, 800, 600]], ['control 1', {'initial_bp': 450, 'index_path': [250, 250, 212], 'margin_bp': 225, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 500, 450]], ['control 2', {'initial_bp': 450, 'index_path': [100], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [400]], ['control 3', {'initial_bp': 300, 'index_path': [650], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [500]], ['control 4', {'initial_bp': 450, 'index_path': [250, 212, 100, 50, 700], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [475, 425, 400, 400, 500]], ['control 5', {'initial_bp': 300, 'index_path': [212, 50, 100, 50, 400], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [425, 400, 400, 400, 500]]], [['regression: lifetime ceiling base', {'initial_bp': 300, 'index_path': [400, 400, 537], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 675, 800]], ['regression: lifetime ceiling base, partial-repair probe', {'initial_bp': 300, 'index_path': [650, 700], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [800, 900]], ['control 1', {'initial_bp': 300, 'index_path': [650, 250, 50, 537, 50], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 500, 375, 575, 375]], ['control 2', {'initial_bp': 300, 'index_path': [250, 250, 250], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [500, 500, 500]], ['control 3', {'initial_bp': 500, 'index_path': [100, 212, 100], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [350, 450, 350]], ['control 4', {'initial_bp': 300, 'index_path': [400, 100, 400, 250, 50], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [500, 400, 500, 525, 425]], ['control 5', {'initial_bp': 450, 'index_path': [250, 50, 700], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 400, 500]]], [['regression: lifetime ceiling base', {'initial_bp': 450, 'index_path': [650], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [875]], ['regression: lifetime ceiling base, partial-repair probe', {'initial_bp': 300, 'index_path': [537, 50, 650, 537, 650], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [750, 550, 750, 750, 800]], ['control 1', {'initial_bp': 300, 'index_path': [250], 'margin_bp': 225, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [500]], ['control 2', {'initial_bp': 450, 'index_path': [250, 537, 250, 700], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 600, 500, 600]], ['control 3', {'initial_bp': 300, 'index_path': [50, 537, 250, 100], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [300, 400, 475, 375]], ['control 4', {'initial_bp': 300, 'index_path': [50, 50], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [400, 400]], ['control 5', {'initial_bp': 450, 'index_path': [100, 250, 100, 650], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [375, 525, 375, 575]]]]\nfor label, args, expected in fixtures[N-1]:\n    try:\n        actual = solve(args)\n    except Exception as exc:\n        actual = 'raised ' + type(exc).__name__\n    check(label, actual, 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":"2c717c3ea8485af2a637e69a9be35cf8a1cbb1630569b35cd1ac323c1225e6d1","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    rate = x['initial_bp']\n    out = []\n    life_max = x['initial_bp'] + x['lifetime_cap_bp']\n    for i, idx in enumerate(x['index_path']):\n        fi = idx + x['margin_bp']\n        q, r = divmod(fi, x['round_to'])\n        fi = (q + (1 if 2 * r >= x['round_to'] else 0)) * x['round_to']\n        cap = x['initial_cap_bp'] if i == 0 else x['periodic_cap_bp']\n        new = max(rate - cap, min(fi, rate + cap))\n        new = max(x['floor_bp'], min(new, life_max))\n        out.append(new)\n        rate = new\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression: lifetime ceiling base', {'initial_bp': 500, 'index_path': [212, 100, 50, 250, 700], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 400, 400, 500, 600]], ['regression: lifetime ceiling base, partial-repair probe', {'initial_bp': 300, 'index_path': [400, 650, 537, 650], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [650, 750, 800, 800]], ['control 1', {'initial_bp': 300, 'index_path': [212, 212], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [475, 475]], ['control 2', {'initial_bp': 300, 'index_path': [100, 50, 250], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [400, 350, 550]], ['control 3', {'initial_bp': 300, 'index_path': [650, 212, 100], 'margin_bp': 275, 'round_to': 50, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [500, 500, 400]], ['control 4', {'initial_bp': 450, 'index_path': [50, 100], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [300, 325]], ['control 5', {'initial_bp': 500, 'index_path': [212, 212, 250], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 500, 500]]], [['regression: lifetime ceiling base', {'initial_bp': 450, 'index_path': [650, 50, 212], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [650, 550, 500]], ['regression: lifetime ceiling base, partial-repair probe', {'initial_bp': 300, 'index_path': [100, 700, 537, 700, 650], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [375, 575, 750, 900, 875]], ['control 1', {'initial_bp': 450, 'index_path': [250, 100, 700], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [475, 325, 525]], ['control 2', {'initial_bp': 500, 'index_path': [212], 'margin_bp': 225, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [375]], ['control 3', {'initial_bp': 450, 'index_path': [50], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [400]], ['control 4', {'initial_bp': 500, 'index_path': [212], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500]], ['control 5', {'initial_bp': 450, 'index_path': [100, 50, 400, 700, 100], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [325, 275, 375, 475, 375]]], [['regression: lifetime ceiling base', {'initial_bp': 450, 'index_path': [212, 650, 50, 650], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [500, 700, 500, 700]], ['regression: lifetime ceiling base, partial-repair probe', {'initial_bp': 300, 'index_path': [537, 700, 50], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [800, 800, 600]], ['control 1', {'initial_bp': 450, 'index_path': [250, 250, 212], 'margin_bp': 225, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 500, 450]], ['control 2', {'initial_bp': 450, 'index_path': [100], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [400]], ['control 3', {'initial_bp': 300, 'index_path': [650], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [500]], ['control 4', {'initial_bp': 450, 'index_path': [250, 212, 100, 50, 700], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [475, 425, 400, 400, 500]], ['control 5', {'initial_bp': 300, 'index_path': [212, 50, 100, 50, 400], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [425, 400, 400, 400, 500]]], [['regression: lifetime ceiling base', {'initial_bp': 300, 'index_path': [400, 400, 537], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 675, 800]], ['regression: lifetime ceiling base, partial-repair probe', {'initial_bp': 300, 'index_path': [650, 700], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [800, 900]], ['control 1', {'initial_bp': 300, 'index_path': [650, 250, 50, 537, 50], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 500, 375, 575, 375]], ['control 2', {'initial_bp': 300, 'index_path': [250, 250, 250], 'margin_bp': 250, 'round_to': 50, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [500, 500, 500]], ['control 3', {'initial_bp': 500, 'index_path': [100, 212, 100], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [350, 450, 350]], ['control 4', {'initial_bp': 300, 'index_path': [400, 100, 400, 250, 50], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 400}, [500, 400, 500, 525, 425]], ['control 5', {'initial_bp': 450, 'index_path': [250, 50, 700], 'margin_bp': 250, 'round_to': 25, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [500, 400, 500]]], [['regression: lifetime ceiling base', {'initial_bp': 450, 'index_path': [650], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 300}, [875]], ['regression: lifetime ceiling base, partial-repair probe', {'initial_bp': 300, 'index_path': [537, 50, 650, 537, 650], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 225}, [750, 550, 750, 750, 800]], ['control 1', {'initial_bp': 300, 'index_path': [250], 'margin_bp': 225, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [500]], ['control 2', {'initial_bp': 450, 'index_path': [250, 537, 250, 700], 'margin_bp': 275, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [500, 600, 500, 600]], ['control 3', {'initial_bp': 300, 'index_path': [50, 537, 250, 100], 'margin_bp': 225, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 100, 'lifetime_cap_bp': 600, 'floor_bp': 300}, [300, 400, 475, 375]], ['control 4', {'initial_bp': 300, 'index_path': [50, 50], 'margin_bp': 250, 'round_to': 125, 'initial_cap_bp': 200, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 500, 'floor_bp': 400}, [400, 400]], ['control 5', {'initial_bp': 450, 'index_path': [100, 250, 100, 650], 'margin_bp': 275, 'round_to': 25, 'initial_cap_bp': 500, 'periodic_cap_bp': 200, 'lifetime_cap_bp': 600, 'floor_bp': 225}, [375, 525, 375, 575]]]]\nfor label, args, expected in fixtures[N-1]:\n    try:\n        actual = solve(args)\n    except Exception as exc:\n        actual = 'raised ' + type(exc).__name__\n    check(label, actual, 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 with stipulated toy lending rules stated in the contract; money is integer cents and rates are basis points; it makes no claim of conformance to any regulation, servicing standard or product. 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-loan-amortization-schedules-adjustable-rate-reset-caps-lifetime-ceiling-base","generated_at":"2026-09-29T14:46:27.782183+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Amortization engines drive borrower statements, payoff quotes and investor remittances; a misplaced rounding step, boundary or ordering rule compounds across hundreds of periods.","repair":"Compute the ceiling as the initial rate plus the lifetime cap.","root_cause":"The lifetime cap is treated as an absolute ceiling instead of a spread over the initial rate.","sha256":"08af9094b1ef7a4be8238d3ebd69c626debde01c333dd7a489c544437884d64e","title":"Adjustable rate reset with caps: lifetime ceiling base · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":40.97,"exit_code":1,"observations":[{"actual":[500,400,400,500,600],"check":"regression: lifetime ceiling base","expected":[500,400,400,500,600],"passed":true},{"actual":[650,750,800,900],"check":"regression: lifetime ceiling base, partial-repair probe","expected":[650,750,800,800],"passed":false},{"actual":[475,475],"check":"control 1","expected":[475,475],"passed":true},{"actual":[400,350,550],"check":"control 2","expected":[400,350,550],"passed":true},{"actual":[500,500,400],"check":"control 3","expected":[500,500,400],"passed":true},{"actual":[300,325],"check":"control 4","expected":[300,325],"passed":true},{"actual":[500,500,500],"check":"control 5","expected":[500,500,500],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: lifetime ceiling base\", \"actual\": [500, 400, 400, 500, 600], \"expected\": [500, 400, 400, 500, 600], \"passed\": true}, {\"check\": \"regression: lifetime ceiling base, partial-repair probe\", \"actual\": [650, 750, 800, 900], \"expected\": [650, 750, 800, 800], \"passed\": false}, {\"check\": \"control 1\", \"actual\": [475, 475], \"expected\": [475, 475], \"passed\": true}, {\"check\": \"control 2\", \"actual\": [400, 350, 550], \"expected\": [400, 350, 550], \"passed\": true}, {\"check\": \"control 3\", \"actual\": [500, 500, 400], \"expected\": [500, 500, 400], \"passed\": true}, {\"check\": \"control 4\", \"actual\": [300, 325], \"expected\": [300, 325], \"passed\": true}, {\"check\": \"control 5\", \"actual\": [500, 500, 500], \"expected\": [500, 500, 500], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.114,"exit_code":1,"observations":[{"actual":[500,400,400,500,500],"check":"regression: lifetime ceiling base","expected":[500,400,400,500,600],"passed":false},{"actual":[500,500,500,500],"check":"regression: lifetime ceiling base, partial-repair probe","expected":[650,750,800,800],"passed":false},{"actual":[475,475],"check":"control 1","expected":[475,475],"passed":true},{"actual":[400,350,550],"check":"control 2","expected":[400,350,550],"passed":true},{"actual":[500,500,400],"check":"control 3","expected":[500,500,400],"passed":true},{"actual":[300,325],"check":"control 4","expected":[300,325],"passed":true},{"actual":[500,500,500],"check":"control 5","expected":[500,500,500],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: lifetime ceiling base\", \"actual\": [500, 400, 400, 500, 500], \"expected\": [500, 400, 400, 500, 600], \"passed\": false}, {\"check\": \"regression: lifetime ceiling base, partial-repair probe\", \"actual\": [500, 500, 500, 500], \"expected\": [650, 750, 800, 800], \"passed\": false}, {\"check\": \"control 1\", \"actual\": [475, 475], \"expected\": [475, 475], \"passed\": true}, {\"check\": \"control 2\", \"actual\": [400, 350, 550], \"expected\": [400, 350, 550], \"passed\": true}, {\"check\": \"control 3\", \"actual\": [500, 500, 400], \"expected\": [500, 500, 400], \"passed\": true}, {\"check\": \"control 4\", \"actual\": [300, 325], \"expected\": [300, 325], \"passed\": true}, {\"check\": \"control 5\", \"actual\": [500, 500, 500], \"expected\": [500, 500, 500], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":41.232,"exit_code":0,"observations":[{"actual":[500,400,400,500,600],"check":"regression: lifetime ceiling base","expected":[500,400,400,500,600],"passed":true},{"actual":[650,750,800,800],"check":"regression: lifetime ceiling base, partial-repair probe","expected":[650,750,800,800],"passed":true},{"actual":[475,475],"check":"control 1","expected":[475,475],"passed":true},{"actual":[400,350,550],"check":"control 2","expected":[400,350,550],"passed":true},{"actual":[500,500,400],"check":"control 3","expected":[500,500,400],"passed":true},{"actual":[300,325],"check":"control 4","expected":[300,325],"passed":true},{"actual":[500,500,500],"check":"control 5","expected":[500,500,500],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: lifetime ceiling base\", \"actual\": [500, 400, 400, 500, 600], \"expected\": [500, 400, 400, 500, 600], \"passed\": true}, {\"check\": \"regression: lifetime ceiling base, partial-repair probe\", \"actual\": [650, 750, 800, 800], \"expected\": [650, 750, 800, 800], \"passed\": true}, {\"check\": \"control 1\", \"actual\": [475, 475], \"expected\": [475, 475], \"passed\": true}, {\"check\": \"control 2\", \"actual\": [400, 350, 550], \"expected\": [400, 350, 550], \"passed\": true}, {\"check\": \"control 3\", \"actual\": [500, 500, 400], \"expected\": [500, 500, 400], \"passed\": true}, {\"check\": \"control 4\", \"actual\": [300, 325], \"expected\": [300, 325], \"passed\": true}, {\"check\": \"control 5\", \"actual\": [500, 500, 500], \"expected\": [500, 500, 500], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}