{"abstract":"After growing, the free share is still just below the minimum and the heap grows again next cycle.","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.","contract_signature":"lives, cap0, min_heap, max_heap, min_free, max_free, shrink_pct","evaluation_group":"w2-garbage-collector-invariants-heap-resizing-policy","failed_approach":"Adding one unconditionally overshoots when the division is exact.","family":"w2-garbage-collector-invariants-heap-resizing-policy-growth-target-rounding","id":"FA-90816","implementations":{"attempt":{"sha256":"0a0a063494ac1d7b83663c6f13a74359c31dbc3df890f5d0845e6becc5778eb9","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) + 1\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"},"broken":{"sha256":"3904501e1a7b51741ed1aacc581aec244e151f02d1934e9c943f9b1e1d0db77d","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-growth-target-rounding","generated_at":"2026-09-29T14:51:30.374533+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.","root_cause":"The target capacity uses floor division.","sha256":"92a98c1dbe19525bafca5a4a8d6917612b122f0ca2d345ef6d19dd11ae093361","title":"Heap resizing: growth target rounded down · 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":39.219,"exit_code":1,"observations":[{"actual":[251,251,228,164],"check":"regression: grow, hold and shrink","expected":[250,250,227,164],"passed":false},{"actual":[171],"check":"growth target rounds up","expected":[170],"passed":false},{"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":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: grow, hold and shrink\", \"actual\": [251, 251, 228, 164], \"expected\": [250, 250, 227, 164], \"passed\": false}, {\"check\": \"growth target rounds up\", \"actual\": [171], \"expected\": [170], \"passed\": false}, {\"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\": false}\n"},"broken":{"elapsed_ms":39.673,"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":[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,301],"check":"free ratio exactly at the minimum","expected":[200,302],"passed":false},{"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\": [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, 301], \"expected\": [200, 302], \"passed\": false}, {\"check\": \"control: within the band\", \"actual\": [200], \"expected\": [200], \"passed\": true}], \"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."}}