{"abstract":"The heap grows past its configured maximum.","category":"Garbage collector invariants","checks":7,"contract":"After each full collection with live bytes L and capacity C: if the free share (C - L) / C is below min_free percent, grow to the smallest capacity whose free share is at least min_free, i.e. ceil(L * 100 / (100 - min_free)), never shrinking and never above max_heap; if the free share exceeds max_free percent, compute ceil(L * 100 / (100 - max_free)) floored at min_heap and move shrink_pct percent of the way from C toward it (integer arithmetic). Otherwise keep C. Return the capacity after each collection.","evaluation_group":"w2-garbage-collector-invariants-heap-resizing-policy","failed_approach":"Refusing to grow at all when the target exceeds the maximum leaves the heap too small.","family":"w2-garbage-collector-invariants-heap-resizing-policy-maximum-heap-clamp","id":"FA-90821","implementations":{"attempt":{"sha256":"deffd47282b53abc973374c13fa982c80ac5b47f302aaf836b3a05869e5eed1e","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(lives, cap0, min_heap, max_heap, min_free, max_free, shrink_pct):\n    cap = cap0\n    out = []\n    for live in lives:\n        free = cap - live\n        if free * 100 < min_free * cap:\n            want = -(-live * 100 // (100 - min_free))\n            cap = want if want <= max_heap else cap\n        elif free * 100 > max_free * cap:\n            want = -(-live * 100 // (100 - max_free))\n            want = max(want, min_heap)\n            cap = cap - (cap - want) * shrink_pct // 100\n        out.append(cap)\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = [[('regression: grow, hold and shrink',\n   ([150, 150, 61, 20], 200, 100, 1000, 40, 70, 50),\n   [250, 250, 227, 164]),\n  ('growth target rounds up', ([102], 150, 100, 1000, 40, 70, 50), [170]),\n  ('growth clamped at the maximum heap', ([701, 900], 800, 100, 1000, 40, 70, 50), [1000, 1000]),\n  ('shrinking stops at the minimum heap', ([11, 10, 10], 400, 150, 1000, 40, 70, 50), [275, 213, 182]),\n  ('shrink moves part of the way', ([31], 600, 100, 1000, 40, 70, 25), [476]),\n  ('free ratio exactly at the minimum', ([120, 181], 200, 100, 1000, 40, 70, 50), [200, 302]),\n  ('control: within the band', ([101], 200, 100, 1000, 40, 70, 50), [200])],\n [('regression: grow, hold and shrink',\n   ([150, 150, 62, 20], 200, 100, 1000, 40, 70, 50),\n   [250, 250, 229, 165]),\n  ('growth target rounds up', ([103], 150, 100, 1000, 40, 70, 50), [172]),\n  ('growth clamped at the maximum heap', ([702, 900], 800, 100, 1000, 40, 70, 50), [1000, 1000]),\n  ('shrinking stops at the minimum heap', ([12, 10, 10], 400, 150, 1000, 40, 70, 50), [275, 213, 182]),\n  ('shrink moves part of the way', ([32], 600, 100, 1000, 40, 70, 25), [477]),\n  ('free ratio exactly at the minimum', ([120, 182], 200, 100, 1000, 40, 70, 50), [200, 304]),\n  ('control: within the band', ([102], 200, 100, 1000, 40, 70, 50), [200])],\n [('regression: grow, hold and shrink',\n   ([150, 150, 63, 20], 200, 100, 1000, 40, 70, 50),\n   [250, 250, 230, 165]),\n  ('growth target rounds up', ([104], 150, 100, 1000, 40, 70, 50), [174]),\n  ('growth clamped at the maximum heap', ([703, 900], 800, 100, 1000, 40, 70, 50), [1000, 1000]),\n  ('shrinking stops at the minimum heap', ([13, 10, 10], 400, 150, 1000, 40, 70, 50), [275, 213, 182]),\n  ('shrink moves part of the way', ([33], 600, 100, 1000, 40, 70, 25), [478]),\n  ('free ratio exactly at the minimum', ([120, 183], 200, 100, 1000, 40, 70, 50), [200, 305]),\n  ('control: within the band', ([103], 200, 100, 1000, 40, 70, 50), [200])],\n [('regression: grow, hold and shrink',\n   ([150, 150, 64, 20], 200, 100, 1000, 40, 70, 50),\n   [250, 250, 232, 166]),\n  ('growth target rounds up', ([105], 150, 100, 1000, 40, 70, 50), [175]),\n  ('growth clamped at the maximum heap', ([704, 900], 800, 100, 1000, 40, 70, 50), [1000, 1000]),\n  ('shrinking stops at the minimum heap', ([14, 10, 10], 400, 150, 1000, 40, 70, 50), [275, 213, 182]),\n  ('shrink moves part of the way', ([34], 600, 100, 1000, 40, 70, 25), [479]),\n  ('free ratio exactly at the minimum', ([120, 184], 200, 100, 1000, 40, 70, 50), [200, 307]),\n  ('control: within the band', ([104], 200, 100, 1000, 40, 70, 50), [200])],\n [('regression: grow, hold and shrink',\n   ([150, 150, 65, 20], 200, 100, 1000, 40, 70, 50),\n   [250, 250, 234, 167]),\n  ('growth target rounds up', ([106], 150, 100, 1000, 40, 70, 50), [177]),\n  ('growth clamped at the maximum heap', ([705, 900], 800, 100, 1000, 40, 70, 50), [1000, 1000]),\n  ('shrinking stops at the minimum heap', ([15, 10, 10], 400, 150, 1000, 40, 70, 50), [275, 213, 182]),\n  ('shrink moves part of the way', ([35], 600, 100, 1000, 40, 70, 25), [480]),\n  ('free ratio exactly at the minimum', ([120, 185], 200, 100, 1000, 40, 70, 50), [200, 309]),\n  ('control: within the band', ([105], 200, 100, 1000, 40, 70, 50), [200])]]\nfor label, args, expected in cases[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":"3075c7909b45be1a846e5bad57f5643727535d6bc682deeefeb56c9f8a633cad","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(lives, cap0, min_heap, max_heap, min_free, max_free, shrink_pct):\n    cap = cap0\n    out = []\n    for live in lives:\n        free = cap - live\n        if free * 100 < min_free * cap:\n            want = -(-live * 100 // (100 - min_free))\n            cap = max(want, cap)\n        elif free * 100 > max_free * cap:\n            want = -(-live * 100 // (100 - max_free))\n            want = max(want, min_heap)\n            cap = cap - (cap - want) * shrink_pct // 100\n        out.append(cap)\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = [[('regression: grow, hold and shrink',\n   ([150, 150, 61, 20], 200, 100, 1000, 40, 70, 50),\n   [250, 250, 227, 164]),\n  ('growth target rounds up', ([102], 150, 100, 1000, 40, 70, 50), [170]),\n  ('growth clamped at the maximum heap', ([701, 900], 800, 100, 1000, 40, 70, 50), [1000, 1000]),\n  ('shrinking stops at the minimum heap', ([11, 10, 10], 400, 150, 1000, 40, 70, 50), [275, 213, 182]),\n  ('shrink moves part of the way', ([31], 600, 100, 1000, 40, 70, 25), [476]),\n  ('free ratio exactly at the minimum', ([120, 181], 200, 100, 1000, 40, 70, 50), [200, 302]),\n  ('control: within the band', ([101], 200, 100, 1000, 40, 70, 50), [200])],\n [('regression: grow, hold and shrink',\n   ([150, 150, 62, 20], 200, 100, 1000, 40, 70, 50),\n   [250, 250, 229, 165]),\n  ('growth target rounds up', ([103], 150, 100, 1000, 40, 70, 50), [172]),\n  ('growth clamped at the maximum heap', ([702, 900], 800, 100, 1000, 40, 70, 50), [1000, 1000]),\n  ('shrinking stops at the minimum heap', ([12, 10, 10], 400, 150, 1000, 40, 70, 50), [275, 213, 182]),\n  ('shrink moves part of the way', ([32], 600, 100, 1000, 40, 70, 25), [477]),\n  ('free ratio exactly at the minimum', ([120, 182], 200, 100, 1000, 40, 70, 50), [200, 304]),\n  ('control: within the band', ([102], 200, 100, 1000, 40, 70, 50), [200])],\n [('regression: grow, hold and shrink',\n   ([150, 150, 63, 20], 200, 100, 1000, 40, 70, 50),\n   [250, 250, 230, 165]),\n  ('growth target rounds up', ([104], 150, 100, 1000, 40, 70, 50), [174]),\n  ('growth clamped at the maximum heap', ([703, 900], 800, 100, 1000, 40, 70, 50), [1000, 1000]),\n  ('shrinking stops at the minimum heap', ([13, 10, 10], 400, 150, 1000, 40, 70, 50), [275, 213, 182]),\n  ('shrink moves part of the way', ([33], 600, 100, 1000, 40, 70, 25), [478]),\n  ('free ratio exactly at the minimum', ([120, 183], 200, 100, 1000, 40, 70, 50), [200, 305]),\n  ('control: within the band', ([103], 200, 100, 1000, 40, 70, 50), [200])],\n [('regression: grow, hold and shrink',\n   ([150, 150, 64, 20], 200, 100, 1000, 40, 70, 50),\n   [250, 250, 232, 166]),\n  ('growth target rounds up', ([105], 150, 100, 1000, 40, 70, 50), [175]),\n  ('growth clamped at the maximum heap', ([704, 900], 800, 100, 1000, 40, 70, 50), [1000, 1000]),\n  ('shrinking stops at the minimum heap', ([14, 10, 10], 400, 150, 1000, 40, 70, 50), [275, 213, 182]),\n  ('shrink moves part of the way', ([34], 600, 100, 1000, 40, 70, 25), [479]),\n  ('free ratio exactly at the minimum', ([120, 184], 200, 100, 1000, 40, 70, 50), [200, 307]),\n  ('control: within the band', ([104], 200, 100, 1000, 40, 70, 50), [200])],\n [('regression: grow, hold and shrink',\n   ([150, 150, 65, 20], 200, 100, 1000, 40, 70, 50),\n   [250, 250, 234, 167]),\n  ('growth target rounds up', ([106], 150, 100, 1000, 40, 70, 50), [177]),\n  ('growth clamped at the maximum heap', ([705, 900], 800, 100, 1000, 40, 70, 50), [1000, 1000]),\n  ('shrinking stops at the minimum heap', ([15, 10, 10], 400, 150, 1000, 40, 70, 50), [275, 213, 182]),\n  ('shrink moves part of the way', ([35], 600, 100, 1000, 40, 70, 25), [480]),\n  ('free ratio exactly at the minimum', ([120, 185], 200, 100, 1000, 40, 70, 50), [200, 309]),\n  ('control: within the band', ([105], 200, 100, 1000, 40, 70, 50), [200])]]\nfor label, args, expected in cases[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":"fd89ff53c5c2b06e6a4b623cc9dcce1577997d25a8f653da92d09555431b27ee","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(lives, cap0, min_heap, max_heap, min_free, max_free, shrink_pct):\n    cap = cap0\n    out = []\n    for live in lives:\n        free = cap - live\n        if free * 100 < min_free * cap:\n            want = -(-live * 100 // (100 - min_free))\n            cap = min(max(want, cap), max_heap)\n        elif free * 100 > max_free * cap:\n            want = -(-live * 100 // (100 - max_free))\n            want = max(want, min_heap)\n            cap = cap - (cap - want) * shrink_pct // 100\n        out.append(cap)\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = [[('regression: grow, hold and shrink',\n   ([150, 150, 61, 20], 200, 100, 1000, 40, 70, 50),\n   [250, 250, 227, 164]),\n  ('growth target rounds up', ([102], 150, 100, 1000, 40, 70, 50), [170]),\n  ('growth clamped at the maximum heap', ([701, 900], 800, 100, 1000, 40, 70, 50), [1000, 1000]),\n  ('shrinking stops at the minimum heap', ([11, 10, 10], 400, 150, 1000, 40, 70, 50), [275, 213, 182]),\n  ('shrink moves part of the way', ([31], 600, 100, 1000, 40, 70, 25), [476]),\n  ('free ratio exactly at the minimum', ([120, 181], 200, 100, 1000, 40, 70, 50), [200, 302]),\n  ('control: within the band', ([101], 200, 100, 1000, 40, 70, 50), [200])],\n [('regression: grow, hold and shrink',\n   ([150, 150, 62, 20], 200, 100, 1000, 40, 70, 50),\n   [250, 250, 229, 165]),\n  ('growth target rounds up', ([103], 150, 100, 1000, 40, 70, 50), [172]),\n  ('growth clamped at the maximum heap', ([702, 900], 800, 100, 1000, 40, 70, 50), [1000, 1000]),\n  ('shrinking stops at the minimum heap', ([12, 10, 10], 400, 150, 1000, 40, 70, 50), [275, 213, 182]),\n  ('shrink moves part of the way', ([32], 600, 100, 1000, 40, 70, 25), [477]),\n  ('free ratio exactly at the minimum', ([120, 182], 200, 100, 1000, 40, 70, 50), [200, 304]),\n  ('control: within the band', ([102], 200, 100, 1000, 40, 70, 50), [200])],\n [('regression: grow, hold and shrink',\n   ([150, 150, 63, 20], 200, 100, 1000, 40, 70, 50),\n   [250, 250, 230, 165]),\n  ('growth target rounds up', ([104], 150, 100, 1000, 40, 70, 50), [174]),\n  ('growth clamped at the maximum heap', ([703, 900], 800, 100, 1000, 40, 70, 50), [1000, 1000]),\n  ('shrinking stops at the minimum heap', ([13, 10, 10], 400, 150, 1000, 40, 70, 50), [275, 213, 182]),\n  ('shrink moves part of the way', ([33], 600, 100, 1000, 40, 70, 25), [478]),\n  ('free ratio exactly at the minimum', ([120, 183], 200, 100, 1000, 40, 70, 50), [200, 305]),\n  ('control: within the band', ([103], 200, 100, 1000, 40, 70, 50), [200])],\n [('regression: grow, hold and shrink',\n   ([150, 150, 64, 20], 200, 100, 1000, 40, 70, 50),\n   [250, 250, 232, 166]),\n  ('growth target rounds up', ([105], 150, 100, 1000, 40, 70, 50), [175]),\n  ('growth clamped at the maximum heap', ([704, 900], 800, 100, 1000, 40, 70, 50), [1000, 1000]),\n  ('shrinking stops at the minimum heap', ([14, 10, 10], 400, 150, 1000, 40, 70, 50), [275, 213, 182]),\n  ('shrink moves part of the way', ([34], 600, 100, 1000, 40, 70, 25), [479]),\n  ('free ratio exactly at the minimum', ([120, 184], 200, 100, 1000, 40, 70, 50), [200, 307]),\n  ('control: within the band', ([104], 200, 100, 1000, 40, 70, 50), [200])],\n [('regression: grow, hold and shrink',\n   ([150, 150, 65, 20], 200, 100, 1000, 40, 70, 50),\n   [250, 250, 234, 167]),\n  ('growth target rounds up', ([106], 150, 100, 1000, 40, 70, 50), [177]),\n  ('growth clamped at the maximum heap', ([705, 900], 800, 100, 1000, 40, 70, 50), [1000, 1000]),\n  ('shrinking stops at the minimum heap', ([15, 10, 10], 400, 150, 1000, 40, 70, 50), [275, 213, 182]),\n  ('shrink moves part of the way', ([35], 600, 100, 1000, 40, 70, 25), [480]),\n  ('free ratio exactly at the minimum', ([120, 185], 200, 100, 1000, 40, 70, 50), [200, 309]),\n  ('control: within the band', ([105], 200, 100, 1000, 40, 70, 50), [200])]]\nfor label, args, expected in cases[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 garbage-collector mechanism with stipulated rules; it is not a production collector and claims no conformance to any particular 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-garbage-collector-invariants-heap-resizing-policy-maximum-heap-clamp","generated_at":"2026-09-29T14:51:30.296205+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Heap sizing policies decide footprint and GC frequency; rounding and clamping errors oscillate or overshoot.","repair":"Clamp the new capacity at max_heap.","root_cause":"The expanded capacity is not clamped.","sha256":"6ca88d4c8a0a33a126df86f1b73fe59194040146cb450c3ecf6cf589a6dc0a30","title":"Heap resizing: growth ignores the maximum heap size · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":40.762,"exit_code":1,"observations":[{"actual":[250,250,227,164],"check":"regression: grow, hold and shrink","expected":[250,250,227,164],"passed":true},{"actual":[170],"check":"growth target rounds up","expected":[170],"passed":true},{"actual":[800,800],"check":"growth clamped at the maximum heap","expected":[1000,1000],"passed":false},{"actual":[275,213,182],"check":"shrinking stops at the minimum heap","expected":[275,213,182],"passed":true},{"actual":[476],"check":"shrink moves part of the way","expected":[476],"passed":true},{"actual":[200,302],"check":"free ratio exactly at the minimum","expected":[200,302],"passed":true},{"actual":[200],"check":"control: within the band","expected":[200],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: grow, hold and shrink\", \"actual\": [250, 250, 227, 164], \"expected\": [250, 250, 227, 164], \"passed\": true}, {\"check\": \"growth target rounds up\", \"actual\": [170], \"expected\": [170], \"passed\": true}, {\"check\": \"growth clamped at the maximum heap\", \"actual\": [800, 800], \"expected\": [1000, 1000], \"passed\": false}, {\"check\": \"shrinking stops at the minimum heap\", \"actual\": [275, 213, 182], \"expected\": [275, 213, 182], \"passed\": true}, {\"check\": \"shrink moves part of the way\", \"actual\": [476], \"expected\": [476], \"passed\": true}, {\"check\": \"free ratio exactly at the minimum\", \"actual\": [200, 302], \"expected\": [200, 302], \"passed\": true}, {\"check\": \"control: within the band\", \"actual\": [200], \"expected\": [200], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":37.607,"exit_code":1,"observations":[{"actual":[250,250,227,164],"check":"regression: grow, hold and shrink","expected":[250,250,227,164],"passed":true},{"actual":[170],"check":"growth target rounds up","expected":[170],"passed":true},{"actual":[1169,1500],"check":"growth clamped at the maximum heap","expected":[1000,1000],"passed":false},{"actual":[275,213,182],"check":"shrinking stops at the minimum heap","expected":[275,213,182],"passed":true},{"actual":[476],"check":"shrink moves part of the way","expected":[476],"passed":true},{"actual":[200,302],"check":"free ratio exactly at the minimum","expected":[200,302],"passed":true},{"actual":[200],"check":"control: within the band","expected":[200],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: grow, hold and shrink\", \"actual\": [250, 250, 227, 164], \"expected\": [250, 250, 227, 164], \"passed\": true}, {\"check\": \"growth target rounds up\", \"actual\": [170], \"expected\": [170], \"passed\": true}, {\"check\": \"growth clamped at the maximum heap\", \"actual\": [1169, 1500], \"expected\": [1000, 1000], \"passed\": false}, {\"check\": \"shrinking stops at the minimum heap\", \"actual\": [275, 213, 182], \"expected\": [275, 213, 182], \"passed\": true}, {\"check\": \"shrink moves part of the way\", \"actual\": [476], \"expected\": [476], \"passed\": true}, {\"check\": \"free ratio exactly at the minimum\", \"actual\": [200, 302], \"expected\": [200, 302], \"passed\": true}, {\"check\": \"control: within the band\", \"actual\": [200], \"expected\": [200], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":40.317,"exit_code":0,"observations":[{"actual":[250,250,227,164],"check":"regression: grow, hold and shrink","expected":[250,250,227,164],"passed":true},{"actual":[170],"check":"growth target rounds up","expected":[170],"passed":true},{"actual":[1000,1000],"check":"growth clamped at the maximum heap","expected":[1000,1000],"passed":true},{"actual":[275,213,182],"check":"shrinking stops at the minimum heap","expected":[275,213,182],"passed":true},{"actual":[476],"check":"shrink moves part of the way","expected":[476],"passed":true},{"actual":[200,302],"check":"free ratio exactly at the minimum","expected":[200,302],"passed":true},{"actual":[200],"check":"control: within the band","expected":[200],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: grow, hold and shrink\", \"actual\": [250, 250, 227, 164], \"expected\": [250, 250, 227, 164], \"passed\": true}, {\"check\": \"growth target rounds up\", \"actual\": [170], \"expected\": [170], \"passed\": true}, {\"check\": \"growth clamped at the maximum heap\", \"actual\": [1000, 1000], \"expected\": [1000, 1000], \"passed\": true}, {\"check\": \"shrinking stops at the minimum heap\", \"actual\": [275, 213, 182], \"expected\": [275, 213, 182], \"passed\": true}, {\"check\": \"shrink moves part of the way\", \"actual\": [476], \"expected\": [476], \"passed\": true}, {\"check\": \"free ratio exactly at the minimum\", \"actual\": [200, 302], \"expected\": [200, 302], \"passed\": true}, {\"check\": \"control: within the band\", \"actual\": [200], \"expected\": [200], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}