FAILURE MAP
← Case archive

FA-97281 / Recipe scaling and nutrition / Open access

Macronutrient target splitter: carb-fat ratio · case 01

Fat grams fall short when protein takes a larger share.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

Fat's share of the remainder divides by 100 instead of by the carb+fat total.

VERIFIED REPAIR

Split the remainder by f/(c+f).

Unsuccessful approach: Dividing by p+f mixes the protein share into the carb-fat ratio.

Case contract

split = [protein%, carb%, fat%] must sum to 100 else "error: split". protein_g = max(half-up kcal*p/400, ceiling(1.6*weight_kg)). Remaining kcal = kcal - 4*protein_g is divided between carb and fat in the ratio c:f; fat_g = half-up(rem*f/(c+f)/9); carb_g = half-up((rem - 9*fat_g)/4). Return [protein_g, carb_g, fat_g].

Why this case matters

Meal-plan generators turn calorie targets into gram targets with a protein floor by body weight.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(kcal, weight_kg, split):
    p, c, f = split
    if p + c + f != 100:
        return 'error: split'
    def r(x):
        return math.floor(x + Fraction(1, 2))
    protein_g = max(r(Fraction(kcal * p, 400)), math.ceil(Fraction(16, 10) * weight_kg))
    rem = kcal - 4 * protein_g
    fat_g = r(Fraction(rem * f, 100) / 9)
    carb_g = r(Fraction(rem - 9 * fat_g, 4))
    return [protein_g, carb_g, fat_g]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['balanced', [2000, 70, [30, 40, 30]], [150, 199, 67]],
  ['protein floor binds', [1500, 120, [15, 55, 30]], [192, 118, 29]],
  ['bad split', [2000, 70, [30, 40, 31]], 'error: split'],
  ['regression: carb-fat ratio', [3000, 100, [20, 50, 30]], [160, 370, 98]],
  ['repair check: carb-fat ratio', [2500, 118, [10, 60, 30]], [189, 290, 65]],
  ['generated control 1', [3000, 50, [35, 35, 30]], [263, 262, 100]],
  ['generated control 2', [1800, 83, [30, 40, 31]], 'error: split'],
  ['generated control 3', [1800, 91, [20, 50, 25]], 'error: split']],
 [['protein floor binds', [1500, 120, [15, 55, 30]], [192, 118, 29]],
  ['bad split', [2000, 70, [30, 40, 31]], 'error: split'],
  ['split under 100', [2000, 70, [30, 40, 20]], 'error: split'],
  ['regression: carb-fat ratio', [2500, 120, [30, 40, 30]], [192, 249, 82]],
  ['repair check: carb-fat ratio', [1500, 72, [40, 30, 30]], [150, 113, 50]],
  ['generated control 1', [2200, 83, [30, 40, 29]], 'error: split'],
  ['generated control 2', [2500, 100, [30, 40, 31]], 'error: split'],
  ['generated control 3', [2000, 60, [20, 50, 30]], [100, 249, 67]]],
 [['bad split', [2000, 70, [30, 40, 31]], 'error: split'],
  ['split under 100', [2000, 70, [30, 40, 20]], 'error: split'],
  ['fractional floor', [1200, 83, [20, 50, 30]], [133, 104, 28]],
  ['regression: carb-fat ratio', [2000, 72, [40, 30, 30]], [200, 149, 67]],
  ['repair check: carb-fat ratio', [3000, 72, [20, 50, 30]], [150, 375, 100]],
  ['generated control 1', [3000, 72, [20, 50, 25]], 'error: split'],
  ['generated control 2', [2000, 72, [30, 40, 29]], 'error: split'],
  ['generated control 3', [2500, 72, [30, 40, 30]], [188, 250, 83]]],
 [['split under 100', [2000, 70, [30, 40, 20]], 'error: split'],
  ['fractional floor', [1200, 83, [20, 50, 30]], [133, 104, 28]],
  ['balanced', [2000, 70, [30, 40, 30]], [150, 199, 67]],
  ['regression: carb-fat ratio', [3000, 83, [35, 35, 30]], [263, 262, 100]],
  ['repair check: carb-fat ratio', [1500, 120, [25, 45, 30]], [192, 109, 33]],
  ['generated control 1', [1800, 120, [35, 35, 30]], [192, 139, 53]],
  ['generated control 2', [3000, 91, [40, 30, 30]], [300, 225, 100]],
  ['generated control 3', [3000, 118, [30, 40, 30]], [225, 300, 100]]],
 [['fractional floor', [1200, 83, [20, 50, 30]], [133, 104, 28]],
  ['balanced', [2000, 70, [30, 40, 30]], [150, 199, 67]],
  ['protein floor binds', [1500, 120, [15, 55, 30]], [192, 118, 29]],
  ['regression: carb-fat ratio', [1800, 83, [35, 35, 30]], [158, 157, 60]],
  ['repair check: carb-fat ratio', [1800, 120, [30, 40, 30]], [192, 148, 49]],
  ['generated control 1', [1800, 83, [15, 55, 30]], [133, 205, 50]],
  ['generated control 2', [3000, 60, [20, 50, 25]], 'error: split'],
  ['generated control 3', [2200, 100, [10, 60, 30]], [160, 260, 58]]]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
balanced[150, 244, 47][150, 199, 67]Failed
protein floor binds[192, 129, 24][192, 118, 29]Failed
bad spliterror: spliterror: splitPassed
regression: carb-fat ratio[160, 412, 79][160, 370, 98]Failed
repair check: carb-fat ratio[189, 306, 58][189, 290, 65]Failed
generated control 1[263, 341, 65][263, 262, 100]Failed
generated control 2error: spliterror: splitPassed
generated control 3error: spliterror: splitPassed

SHA-256 / 1c754272c2ec460c40d67affb11d395aee7898ded36135d2b4ac50c48a55e7bf

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(kcal, weight_kg, split):
    p, c, f = split
    if p + c + f != 100:
        return 'error: split'
    def r(x):
        return math.floor(x + Fraction(1, 2))
    protein_g = max(r(Fraction(kcal * p, 400)), math.ceil(Fraction(16, 10) * weight_kg))
    rem = kcal - 4 * protein_g
    fat_g = r(Fraction(rem * f, p + f) / 9)
    carb_g = r(Fraction(rem - 9 * fat_g, 4))
    return [protein_g, carb_g, fat_g]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['balanced', [2000, 70, [30, 40, 30]], [150, 199, 67]],
  ['protein floor binds', [1500, 120, [15, 55, 30]], [192, 118, 29]],
  ['bad split', [2000, 70, [30, 40, 31]], 'error: split'],
  ['regression: carb-fat ratio', [3000, 100, [20, 50, 30]], [160, 370, 98]],
  ['repair check: carb-fat ratio', [2500, 118, [10, 60, 30]], [189, 290, 65]],
  ['generated control 1', [3000, 50, [35, 35, 30]], [263, 262, 100]],
  ['generated control 2', [1800, 83, [30, 40, 31]], 'error: split'],
  ['generated control 3', [1800, 91, [20, 50, 25]], 'error: split']],
 [['protein floor binds', [1500, 120, [15, 55, 30]], [192, 118, 29]],
  ['bad split', [2000, 70, [30, 40, 31]], 'error: split'],
  ['split under 100', [2000, 70, [30, 40, 20]], 'error: split'],
  ['regression: carb-fat ratio', [2500, 120, [30, 40, 30]], [192, 249, 82]],
  ['repair check: carb-fat ratio', [1500, 72, [40, 30, 30]], [150, 113, 50]],
  ['generated control 1', [2200, 83, [30, 40, 29]], 'error: split'],
  ['generated control 2', [2500, 100, [30, 40, 31]], 'error: split'],
  ['generated control 3', [2000, 60, [20, 50, 30]], [100, 249, 67]]],
 [['bad split', [2000, 70, [30, 40, 31]], 'error: split'],
  ['split under 100', [2000, 70, [30, 40, 20]], 'error: split'],
  ['fractional floor', [1200, 83, [20, 50, 30]], [133, 104, 28]],
  ['regression: carb-fat ratio', [2000, 72, [40, 30, 30]], [200, 149, 67]],
  ['repair check: carb-fat ratio', [3000, 72, [20, 50, 30]], [150, 375, 100]],
  ['generated control 1', [3000, 72, [20, 50, 25]], 'error: split'],
  ['generated control 2', [2000, 72, [30, 40, 29]], 'error: split'],
  ['generated control 3', [2500, 72, [30, 40, 30]], [188, 250, 83]]],
 [['split under 100', [2000, 70, [30, 40, 20]], 'error: split'],
  ['fractional floor', [1200, 83, [20, 50, 30]], [133, 104, 28]],
  ['balanced', [2000, 70, [30, 40, 30]], [150, 199, 67]],
  ['regression: carb-fat ratio', [3000, 83, [35, 35, 30]], [263, 262, 100]],
  ['repair check: carb-fat ratio', [1500, 120, [25, 45, 30]], [192, 109, 33]],
  ['generated control 1', [1800, 120, [35, 35, 30]], [192, 139, 53]],
  ['generated control 2', [3000, 91, [40, 30, 30]], [300, 225, 100]],
  ['generated control 3', [3000, 118, [30, 40, 30]], [225, 300, 100]]],
 [['fractional floor', [1200, 83, [20, 50, 30]], [133, 104, 28]],
  ['balanced', [2000, 70, [30, 40, 30]], [150, 199, 67]],
  ['protein floor binds', [1500, 120, [15, 55, 30]], [192, 118, 29]],
  ['regression: carb-fat ratio', [1800, 83, [35, 35, 30]], [158, 157, 60]],
  ['repair check: carb-fat ratio', [1800, 120, [30, 40, 30]], [192, 148, 49]],
  ['generated control 1', [1800, 83, [15, 55, 30]], [133, 205, 50]],
  ['generated control 2', [3000, 60, [20, 50, 25]], 'error: split'],
  ['generated control 3', [2200, 100, [10, 60, 30]], [160, 260, 58]]]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
balanced[150, 175, 78][150, 199, 67]Failed
protein floor binds[192, 62, 54][192, 118, 29]Failed
bad spliterror: spliterror: splitPassed
regression: carb-fat ratio[160, 237, 157][160, 370, 98]Failed
repair check: carb-fat ratio[189, 110, 145][189, 290, 65]Failed
generated control 1[263, 262, 100][263, 262, 100]Passed
generated control 2error: spliterror: splitPassed
generated control 3error: spliterror: splitPassed

SHA-256 / f0c8b9ca43f022b875d431422c468cf4bc6498c255b9e68a19089a8128188be8

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(kcal, weight_kg, split):
    p, c, f = split
    if p + c + f != 100:
        return 'error: split'
    def r(x):
        return math.floor(x + Fraction(1, 2))
    protein_g = max(r(Fraction(kcal * p, 400)), math.ceil(Fraction(16, 10) * weight_kg))
    rem = kcal - 4 * protein_g
    fat_g = r(Fraction(rem * f, c + f) / 9)
    carb_g = r(Fraction(rem - 9 * fat_g, 4))
    return [protein_g, carb_g, fat_g]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['balanced', [2000, 70, [30, 40, 30]], [150, 199, 67]],
  ['protein floor binds', [1500, 120, [15, 55, 30]], [192, 118, 29]],
  ['bad split', [2000, 70, [30, 40, 31]], 'error: split'],
  ['regression: carb-fat ratio', [3000, 100, [20, 50, 30]], [160, 370, 98]],
  ['repair check: carb-fat ratio', [2500, 118, [10, 60, 30]], [189, 290, 65]],
  ['generated control 1', [3000, 50, [35, 35, 30]], [263, 262, 100]],
  ['generated control 2', [1800, 83, [30, 40, 31]], 'error: split'],
  ['generated control 3', [1800, 91, [20, 50, 25]], 'error: split']],
 [['protein floor binds', [1500, 120, [15, 55, 30]], [192, 118, 29]],
  ['bad split', [2000, 70, [30, 40, 31]], 'error: split'],
  ['split under 100', [2000, 70, [30, 40, 20]], 'error: split'],
  ['regression: carb-fat ratio', [2500, 120, [30, 40, 30]], [192, 249, 82]],
  ['repair check: carb-fat ratio', [1500, 72, [40, 30, 30]], [150, 113, 50]],
  ['generated control 1', [2200, 83, [30, 40, 29]], 'error: split'],
  ['generated control 2', [2500, 100, [30, 40, 31]], 'error: split'],
  ['generated control 3', [2000, 60, [20, 50, 30]], [100, 249, 67]]],
 [['bad split', [2000, 70, [30, 40, 31]], 'error: split'],
  ['split under 100', [2000, 70, [30, 40, 20]], 'error: split'],
  ['fractional floor', [1200, 83, [20, 50, 30]], [133, 104, 28]],
  ['regression: carb-fat ratio', [2000, 72, [40, 30, 30]], [200, 149, 67]],
  ['repair check: carb-fat ratio', [3000, 72, [20, 50, 30]], [150, 375, 100]],
  ['generated control 1', [3000, 72, [20, 50, 25]], 'error: split'],
  ['generated control 2', [2000, 72, [30, 40, 29]], 'error: split'],
  ['generated control 3', [2500, 72, [30, 40, 30]], [188, 250, 83]]],
 [['split under 100', [2000, 70, [30, 40, 20]], 'error: split'],
  ['fractional floor', [1200, 83, [20, 50, 30]], [133, 104, 28]],
  ['balanced', [2000, 70, [30, 40, 30]], [150, 199, 67]],
  ['regression: carb-fat ratio', [3000, 83, [35, 35, 30]], [263, 262, 100]],
  ['repair check: carb-fat ratio', [1500, 120, [25, 45, 30]], [192, 109, 33]],
  ['generated control 1', [1800, 120, [35, 35, 30]], [192, 139, 53]],
  ['generated control 2', [3000, 91, [40, 30, 30]], [300, 225, 100]],
  ['generated control 3', [3000, 118, [30, 40, 30]], [225, 300, 100]]],
 [['fractional floor', [1200, 83, [20, 50, 30]], [133, 104, 28]],
  ['balanced', [2000, 70, [30, 40, 30]], [150, 199, 67]],
  ['protein floor binds', [1500, 120, [15, 55, 30]], [192, 118, 29]],
  ['regression: carb-fat ratio', [1800, 83, [35, 35, 30]], [158, 157, 60]],
  ['repair check: carb-fat ratio', [1800, 120, [30, 40, 30]], [192, 148, 49]],
  ['generated control 1', [1800, 83, [15, 55, 30]], [133, 205, 50]],
  ['generated control 2', [3000, 60, [20, 50, 25]], 'error: split'],
  ['generated control 3', [2200, 100, [10, 60, 30]], [160, 260, 58]]]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
balanced[150, 199, 67][150, 199, 67]Passed
protein floor binds[192, 118, 29][192, 118, 29]Passed
bad spliterror: spliterror: splitPassed
regression: carb-fat ratio[160, 370, 98][160, 370, 98]Passed
repair check: carb-fat ratio[189, 290, 65][189, 290, 65]Passed
generated control 1[263, 262, 100][263, 262, 100]Passed
generated control 2error: spliterror: splitPassed
generated control 3error: spliterror: splitPassed

SHA-256 / ee09f41918369ff2958c784890b3dbd875d8a6da15dd1e1051c864e737ac9549

Verification & scope

A deterministic toy contract stated in full here; it is a bounded teaching model, not an authoritative reference or standards implementation. 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.

Observations recorded using Python 3.12.14 at 2026-09-29T14:52:30.684573+00:00.

Case digest / 91dad5c83bf521dbaceb49d79846a571f4965362d13516e07a0d822ce88c9fa6