FAILURE MAP
← Case archive

FA-97301 / Recipe scaling and nutrition / Open access

Backward recipe step scheduler: midnight wraparound · case 01

A marinade starting the previous evening prints "-3:00".

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

ROOT CAUSE

Negative minute offsets are formatted without wrapping into the previous day.

VERIFIED REPAIR

Wrap start minutes modulo 1440.

Unsuccessful approach: abs() mirrors the time instead of wrapping: -180 becomes 03:00 instead of 21:00.

Case contract

Steps [name, minutes, depends_on]; a step must finish before any step depending on it starts. Latest start = min(latest start of dependents, serve time) - minutes. Unknown dependency -> "error: unknown step X"; a cycle -> "error: cycle". Serve "HH:MM"; starts print as "HH:MM" modulo 24h (previous day wraps). Output [[name, time]] sorted by absolute start then name.

Why this case matters

Dinner-party and restaurant prep planners schedule long marinades and roasts backward from service.

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(steps, serve):
    by = {s[0]: s for s in steps}
    for s in steps:
        for d in s[2]:
            if d not in by:
                return 'error: unknown step ' + d
    h, m = serve.split(':')
    T = int(h) * 60 + int(m)
    latest = {}
    visiting = set()
    def ls(n):
        if n in latest:
            return latest[n]
        if n in visiting:
            return None
        visiting.add(n)
        finish = T
        for s in steps:
            if n in s[2]:
                v = ls(s[0])
                if v is None:
                    return None
                finish = min(finish, v)
        visiting.discard(n)
        latest[n] = finish - by[n][1]
        return latest[n]
    rows = []
    for s in steps:
        v = ls(s[0])
        if v is None:
            return 'error: cycle'
        rows.append((v, s[0]))
    rows.sort()
    return [[n, '%02d:%02d' % divmod(v, 60)] for v, n in rows]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
   [['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
  ['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
   [['marinate', '03:40'], ['grill', '11:40']]],
  ['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
  ['regression: midnight wraparound',
   [[['marinate', 90, []], ['roast', 90, ['marinate']], ['prep', 45, []]], '02:00'],
   [['marinate', '23:00'], ['roast', '00:30'], ['prep', '01:15']]],
  ['repair check: midnight wraparound',
   [[['roast', 45, ['prep']], ['prep', 15, []], ['sauce', 10, ['roast']], ['marinate', 10, []]], '00:30'],
   [['prep', '23:20'], ['roast', '23:35'], ['marinate', '00:20'], ['sauce', '00:20']]],
  ['generated control 1',
   [[['roast', 240, []], ['prep', 15, []], ['marinate', 240, ['prep', 'shop']]], '18:30'],
   'error: unknown step shop'],
  ['generated control 2',
   [[['prep', 5, []], ['roast', 15, ['prep']], ['rest', 10, ['marinate']], ['marinate', 5, []],
     ['sauce', 30, []], ['plate', 5, ['marinate', 'roast', 'rest']]],
    '12:00'],
   [['sauce', '11:30'], ['prep', '11:35'], ['marinate', '11:40'], ['roast', '11:40'], ['rest', '11:45'],
    ['plate', '11:55']]],
  ['generated control 3', [[['roast', 45, []], ['prep', 30, []], ['marinate', 90, ['prep']]], '02:00'],
   [['prep', '00:00'], ['marinate', '00:30'], ['roast', '01:15']]]],
 [['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
   [['marinate', '03:40'], ['grill', '11:40']]],
  ['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
  ['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
  ['regression: midnight wraparound',
   [[['prep', 30, []], ['roast', 90, ['prep', 'marinate']], ['marinate', 30, ['prep']],
     ['sauce', 90, ['roast']]],
    '01:15'],
   [['prep', '21:15'], ['marinate', '21:45'], ['roast', '22:15'], ['sauce', '23:45']]],
  ['repair check: midnight wraparound',
   [[['rest', 30, ['prep', 'sauce']], ['sauce', 5, ['prep', 'roast']], ['marinate', 90, []], ['prep', 45, []],
     ['roast', 90, []]],
    '02:00'],
   [['roast', '23:55'], ['marinate', '00:30'], ['prep', '00:40'], ['sauce', '01:25'], ['rest', '01:30']]],
  ['generated control 1',
   [[['sauce', 30, ['marinate', 'shop']], ['marinate', 90, ['prep']], ['prep', 5, []],
     ['rest', 240, ['sauce']], ['roast', 15, ['prep', 'marinate']],
     ['plate', 90, ['prep', 'roast', 'rest']]],
    '01:15'],
   'error: unknown step shop'],
  ['generated control 2',
   [[['roast', 5, ['prep', 'marinate']], ['marinate', 10, ['prep']], ['prep', 30, []]], '12:00'],
   [['prep', '11:15'], ['marinate', '11:45'], ['roast', '11:55']]],
  ['generated control 3',
   [[['marinate', 30, []], ['prep', 90, []], ['rest', 30, ['prep']], ['plate', 45, ['prep', 'rest']],
     ['roast', 10, []], ['sauce', 30, ['prep']]],
    '01:15'],
   [['prep', '22:30'], ['rest', '00:00'], ['plate', '00:30'], ['marinate', '00:45'], ['sauce', '00:45'],
    ['roast', '01:05']]]],
 [['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
  ['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
  ['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
   [['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
  ['regression: midnight wraparound',
   [[['rest', 90, ['sauce']], ['marinate', 90, ['prep']], ['plate', 30, ['rest']], ['roast', 45, ['prep']],
     ['prep', 90, []], ['sauce', 5, ['prep', 'marinate']]],
    '01:15'],
   [['prep', '20:10'], ['marinate', '21:40'], ['sauce', '23:10'], ['rest', '23:15'], ['roast', '00:30'],
    ['plate', '00:45']]],
  ['repair check: midnight wraparound',
   [[['sauce', 30, ['marinate']], ['marinate', 45, ['prep']], ['rest', 30, ['marinate', 'sauce']],
     ['prep', 5, []], ['roast', 15, []]],
    '01:15'],
   [['prep', '23:25'], ['marinate', '23:30'], ['sauce', '00:15'], ['rest', '00:45'], ['roast', '01:00']]],
  ['generated control 1',
   [[['prep', 15, ['sauce']], ['roast', 15, []], ['marinate', 15, []], ['sauce', 30, ['marinate', 'roast']]],
    '19:45'],
   [['marinate', '18:45'], ['roast', '18:45'], ['sauce', '19:00'], ['prep', '19:30']]],
  ['generated control 2',
   [[['prep', 45, []], ['sauce', 30, ['prep']], ['marinate', 90, []], ['roast', 90, ['prep', 'marinate']]],
    '12:00'],
   [['marinate', '09:00'], ['prep', '09:45'], ['roast', '10:30'], ['sauce', '11:30']]],
  ['generated control 3',
   [[['roast', 15, ['marinate']], ['prep', 45, []], ['rest', 30, ['roast']], ['marinate', 45, ['prep']],
     ['sauce', 45, ['roast']]],
    '19:45'],
   [['prep', '17:15'], ['marinate', '18:00'], ['roast', '18:45'], ['sauce', '19:00'], ['rest', '19:15']]]],
 [['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
  ['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
   [['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
  ['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
   [['marinate', '03:40'], ['grill', '11:40']]],
  ['regression: midnight wraparound',
   [[['prep', 15, []], ['roast', 30, ['prep']], ['sauce', 90, []], ['marinate', 45, []]], '00:30'],
   [['sauce', '23:00'], ['marinate', '23:45'], ['prep', '23:45'], ['roast', '00:00']]],
  ['repair check: midnight wraparound',
   [[['roast', 5, ['marinate']], ['prep', 5, []], ['marinate', 240, ['prep']]], '00:30'],
   [['prep', '20:20'], ['marinate', '20:25'], ['roast', '00:25']]],
  ['generated control 1',
   [[['roast', 90, []], ['rest', 90, ['prep', 'shop']], ['marinate', 5, []],
     ['plate', 90, ['roast', 'sauce']], ['prep', 5, []], ['sauce', 10, ['roast']]],
    '19:45'],
   'error: unknown step shop'],
  ['generated control 2', [[['prep', 10, []], ['roast', 45, ['prep']], ['marinate', 240, ['prep']]], '12:00'],
   [['prep', '07:50'], ['marinate', '08:00'], ['roast', '11:15']]],
  ['generated control 3',
   [[['plate', 5, []], ['prep', 10, []], ['rest', 90, ['roast', 'sauce']], ['sauce', 5, ['marinate']],
     ['marinate', 5, ['prep']], ['roast', 15, []]],
    '19:45'],
   [['prep', '17:55'], ['roast', '18:00'], ['marinate', '18:05'], ['sauce', '18:10'], ['rest', '18:15'],
    ['plate', '19:40']]]],
 [['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
   [['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
  ['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
   [['marinate', '03:40'], ['grill', '11:40']]],
  ['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
  ['regression: midnight wraparound',
   [[['roast', 30, []], ['marinate', 30, []], ['sauce', 240, ['marinate']], ['prep', 10, []]], '02:00'],
   [['marinate', '21:30'], ['sauce', '22:00'], ['roast', '01:30'], ['prep', '01:50']]],
  ['repair check: midnight wraparound',
   [[['sauce', 240, ['prep', 'roast']], ['marinate', 240, []], ['prep', 5, []], ['roast', 240, ['marinate']],
     ['rest', 90, ['prep']]],
    '02:00'],
   [['marinate', '14:00'], ['roast', '18:00'], ['prep', '21:55'], ['sauce', '22:00'], ['rest', '00:30']]],
  ['generated control 1',
   [[['prep', 90, []], ['marinate', 15, ['prep']], ['roast', 10, ['shop']], ['rest', 45, ['roast', 'sauce']],
     ['sauce', 90, ['marinate']]],
    '00:30'],
   'error: unknown step shop'],
  ['generated control 2', [[['roast', 30, []], ['marinate', 45, []], ['prep', 15, []]], '01:15'],
   [['marinate', '00:30'], ['roast', '00:45'], ['prep', '01:00']]],
  ['generated control 3',
   [[['marinate', 15, ['prep']], ['prep', 5, ['roast']], ['roast', 240, ['marinate']]], '19:45'],
   'error: cycle']]]
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
chain[['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']][['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]Passed
overnight marinade[['marinate', '03:40'], ['grill', '11:40']][['marinate', '03:40'], ['grill', '11:40']]Passed
cycleerror: cycleerror: cyclePassed
regression: midnight wraparound[['marinate', '-1:00'], ['roast', '00:30'], ['prep', '01:15']][['marinate', '23:00'], ['roast', '00:30'], ['prep', '01:15']]Failed
repair check: midnight wraparound[['prep', '-1:20'], ['roast', '-1:35'], ['marinate', '00:20'], ['sauce', '00:20']][['prep', '23:20'], ['roast', '23:35'], ['marinate', '00:20'], ['sauce', '00:20']]Failed
generated control 1error: unknown step shoperror: unknown step shopPassed
generated control 2[['sauce', '11:30'], ['prep', '11:35'], ['marinate', '11:40'], ['roast', '11:40'], ['rest', '11:45'], ['plate', '11:55']][['sauce', '11:30'], ['prep', '11:35'], ['marinate', '11:40'], ['roast', '11:40'], ['rest', '11:45'], ['plate', '11:55']]Passed
generated control 3[['prep', '00:00'], ['marinate', '00:30'], ['roast', '01:15']][['prep', '00:00'], ['marinate', '00:30'], ['roast', '01:15']]Passed

SHA-256 / b1a1790a97ccba2a8ba39d7d18ef8dee1c5ea45163d30ca9c23d03095f352999

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(steps, serve):
    by = {s[0]: s for s in steps}
    for s in steps:
        for d in s[2]:
            if d not in by:
                return 'error: unknown step ' + d
    h, m = serve.split(':')
    T = int(h) * 60 + int(m)
    latest = {}
    visiting = set()
    def ls(n):
        if n in latest:
            return latest[n]
        if n in visiting:
            return None
        visiting.add(n)
        finish = T
        for s in steps:
            if n in s[2]:
                v = ls(s[0])
                if v is None:
                    return None
                finish = min(finish, v)
        visiting.discard(n)
        latest[n] = finish - by[n][1]
        return latest[n]
    rows = []
    for s in steps:
        v = ls(s[0])
        if v is None:
            return 'error: cycle'
        rows.append((v, s[0]))
    rows.sort()
    return [[n, '%02d:%02d' % divmod(abs(v) % 1440, 60)] for v, n in rows]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
   [['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
  ['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
   [['marinate', '03:40'], ['grill', '11:40']]],
  ['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
  ['regression: midnight wraparound',
   [[['marinate', 90, []], ['roast', 90, ['marinate']], ['prep', 45, []]], '02:00'],
   [['marinate', '23:00'], ['roast', '00:30'], ['prep', '01:15']]],
  ['repair check: midnight wraparound',
   [[['roast', 45, ['prep']], ['prep', 15, []], ['sauce', 10, ['roast']], ['marinate', 10, []]], '00:30'],
   [['prep', '23:20'], ['roast', '23:35'], ['marinate', '00:20'], ['sauce', '00:20']]],
  ['generated control 1',
   [[['roast', 240, []], ['prep', 15, []], ['marinate', 240, ['prep', 'shop']]], '18:30'],
   'error: unknown step shop'],
  ['generated control 2',
   [[['prep', 5, []], ['roast', 15, ['prep']], ['rest', 10, ['marinate']], ['marinate', 5, []],
     ['sauce', 30, []], ['plate', 5, ['marinate', 'roast', 'rest']]],
    '12:00'],
   [['sauce', '11:30'], ['prep', '11:35'], ['marinate', '11:40'], ['roast', '11:40'], ['rest', '11:45'],
    ['plate', '11:55']]],
  ['generated control 3', [[['roast', 45, []], ['prep', 30, []], ['marinate', 90, ['prep']]], '02:00'],
   [['prep', '00:00'], ['marinate', '00:30'], ['roast', '01:15']]]],
 [['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
   [['marinate', '03:40'], ['grill', '11:40']]],
  ['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
  ['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
  ['regression: midnight wraparound',
   [[['prep', 30, []], ['roast', 90, ['prep', 'marinate']], ['marinate', 30, ['prep']],
     ['sauce', 90, ['roast']]],
    '01:15'],
   [['prep', '21:15'], ['marinate', '21:45'], ['roast', '22:15'], ['sauce', '23:45']]],
  ['repair check: midnight wraparound',
   [[['rest', 30, ['prep', 'sauce']], ['sauce', 5, ['prep', 'roast']], ['marinate', 90, []], ['prep', 45, []],
     ['roast', 90, []]],
    '02:00'],
   [['roast', '23:55'], ['marinate', '00:30'], ['prep', '00:40'], ['sauce', '01:25'], ['rest', '01:30']]],
  ['generated control 1',
   [[['sauce', 30, ['marinate', 'shop']], ['marinate', 90, ['prep']], ['prep', 5, []],
     ['rest', 240, ['sauce']], ['roast', 15, ['prep', 'marinate']],
     ['plate', 90, ['prep', 'roast', 'rest']]],
    '01:15'],
   'error: unknown step shop'],
  ['generated control 2',
   [[['roast', 5, ['prep', 'marinate']], ['marinate', 10, ['prep']], ['prep', 30, []]], '12:00'],
   [['prep', '11:15'], ['marinate', '11:45'], ['roast', '11:55']]],
  ['generated control 3',
   [[['marinate', 30, []], ['prep', 90, []], ['rest', 30, ['prep']], ['plate', 45, ['prep', 'rest']],
     ['roast', 10, []], ['sauce', 30, ['prep']]],
    '01:15'],
   [['prep', '22:30'], ['rest', '00:00'], ['plate', '00:30'], ['marinate', '00:45'], ['sauce', '00:45'],
    ['roast', '01:05']]]],
 [['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
  ['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
  ['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
   [['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
  ['regression: midnight wraparound',
   [[['rest', 90, ['sauce']], ['marinate', 90, ['prep']], ['plate', 30, ['rest']], ['roast', 45, ['prep']],
     ['prep', 90, []], ['sauce', 5, ['prep', 'marinate']]],
    '01:15'],
   [['prep', '20:10'], ['marinate', '21:40'], ['sauce', '23:10'], ['rest', '23:15'], ['roast', '00:30'],
    ['plate', '00:45']]],
  ['repair check: midnight wraparound',
   [[['sauce', 30, ['marinate']], ['marinate', 45, ['prep']], ['rest', 30, ['marinate', 'sauce']],
     ['prep', 5, []], ['roast', 15, []]],
    '01:15'],
   [['prep', '23:25'], ['marinate', '23:30'], ['sauce', '00:15'], ['rest', '00:45'], ['roast', '01:00']]],
  ['generated control 1',
   [[['prep', 15, ['sauce']], ['roast', 15, []], ['marinate', 15, []], ['sauce', 30, ['marinate', 'roast']]],
    '19:45'],
   [['marinate', '18:45'], ['roast', '18:45'], ['sauce', '19:00'], ['prep', '19:30']]],
  ['generated control 2',
   [[['prep', 45, []], ['sauce', 30, ['prep']], ['marinate', 90, []], ['roast', 90, ['prep', 'marinate']]],
    '12:00'],
   [['marinate', '09:00'], ['prep', '09:45'], ['roast', '10:30'], ['sauce', '11:30']]],
  ['generated control 3',
   [[['roast', 15, ['marinate']], ['prep', 45, []], ['rest', 30, ['roast']], ['marinate', 45, ['prep']],
     ['sauce', 45, ['roast']]],
    '19:45'],
   [['prep', '17:15'], ['marinate', '18:00'], ['roast', '18:45'], ['sauce', '19:00'], ['rest', '19:15']]]],
 [['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
  ['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
   [['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
  ['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
   [['marinate', '03:40'], ['grill', '11:40']]],
  ['regression: midnight wraparound',
   [[['prep', 15, []], ['roast', 30, ['prep']], ['sauce', 90, []], ['marinate', 45, []]], '00:30'],
   [['sauce', '23:00'], ['marinate', '23:45'], ['prep', '23:45'], ['roast', '00:00']]],
  ['repair check: midnight wraparound',
   [[['roast', 5, ['marinate']], ['prep', 5, []], ['marinate', 240, ['prep']]], '00:30'],
   [['prep', '20:20'], ['marinate', '20:25'], ['roast', '00:25']]],
  ['generated control 1',
   [[['roast', 90, []], ['rest', 90, ['prep', 'shop']], ['marinate', 5, []],
     ['plate', 90, ['roast', 'sauce']], ['prep', 5, []], ['sauce', 10, ['roast']]],
    '19:45'],
   'error: unknown step shop'],
  ['generated control 2', [[['prep', 10, []], ['roast', 45, ['prep']], ['marinate', 240, ['prep']]], '12:00'],
   [['prep', '07:50'], ['marinate', '08:00'], ['roast', '11:15']]],
  ['generated control 3',
   [[['plate', 5, []], ['prep', 10, []], ['rest', 90, ['roast', 'sauce']], ['sauce', 5, ['marinate']],
     ['marinate', 5, ['prep']], ['roast', 15, []]],
    '19:45'],
   [['prep', '17:55'], ['roast', '18:00'], ['marinate', '18:05'], ['sauce', '18:10'], ['rest', '18:15'],
    ['plate', '19:40']]]],
 [['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
   [['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
  ['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
   [['marinate', '03:40'], ['grill', '11:40']]],
  ['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
  ['regression: midnight wraparound',
   [[['roast', 30, []], ['marinate', 30, []], ['sauce', 240, ['marinate']], ['prep', 10, []]], '02:00'],
   [['marinate', '21:30'], ['sauce', '22:00'], ['roast', '01:30'], ['prep', '01:50']]],
  ['repair check: midnight wraparound',
   [[['sauce', 240, ['prep', 'roast']], ['marinate', 240, []], ['prep', 5, []], ['roast', 240, ['marinate']],
     ['rest', 90, ['prep']]],
    '02:00'],
   [['marinate', '14:00'], ['roast', '18:00'], ['prep', '21:55'], ['sauce', '22:00'], ['rest', '00:30']]],
  ['generated control 1',
   [[['prep', 90, []], ['marinate', 15, ['prep']], ['roast', 10, ['shop']], ['rest', 45, ['roast', 'sauce']],
     ['sauce', 90, ['marinate']]],
    '00:30'],
   'error: unknown step shop'],
  ['generated control 2', [[['roast', 30, []], ['marinate', 45, []], ['prep', 15, []]], '01:15'],
   [['marinate', '00:30'], ['roast', '00:45'], ['prep', '01:00']]],
  ['generated control 3',
   [[['marinate', 15, ['prep']], ['prep', 5, ['roast']], ['roast', 240, ['marinate']]], '19:45'],
   'error: cycle']]]
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
chain[['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']][['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]Passed
overnight marinade[['marinate', '03:40'], ['grill', '11:40']][['marinate', '03:40'], ['grill', '11:40']]Passed
cycleerror: cycleerror: cyclePassed
regression: midnight wraparound[['marinate', '01:00'], ['roast', '00:30'], ['prep', '01:15']][['marinate', '23:00'], ['roast', '00:30'], ['prep', '01:15']]Failed
repair check: midnight wraparound[['prep', '00:40'], ['roast', '00:25'], ['marinate', '00:20'], ['sauce', '00:20']][['prep', '23:20'], ['roast', '23:35'], ['marinate', '00:20'], ['sauce', '00:20']]Failed
generated control 1error: unknown step shoperror: unknown step shopPassed
generated control 2[['sauce', '11:30'], ['prep', '11:35'], ['marinate', '11:40'], ['roast', '11:40'], ['rest', '11:45'], ['plate', '11:55']][['sauce', '11:30'], ['prep', '11:35'], ['marinate', '11:40'], ['roast', '11:40'], ['rest', '11:45'], ['plate', '11:55']]Passed
generated control 3[['prep', '00:00'], ['marinate', '00:30'], ['roast', '01:15']][['prep', '00:00'], ['marinate', '00:30'], ['roast', '01:15']]Passed

SHA-256 / 7055420024ccec468bca3be1ee564af43f4ec220cd8521a652924401c970108c

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(steps, serve):
    by = {s[0]: s for s in steps}
    for s in steps:
        for d in s[2]:
            if d not in by:
                return 'error: unknown step ' + d
    h, m = serve.split(':')
    T = int(h) * 60 + int(m)
    latest = {}
    visiting = set()
    def ls(n):
        if n in latest:
            return latest[n]
        if n in visiting:
            return None
        visiting.add(n)
        finish = T
        for s in steps:
            if n in s[2]:
                v = ls(s[0])
                if v is None:
                    return None
                finish = min(finish, v)
        visiting.discard(n)
        latest[n] = finish - by[n][1]
        return latest[n]
    rows = []
    for s in steps:
        v = ls(s[0])
        if v is None:
            return 'error: cycle'
        rows.append((v, s[0]))
    rows.sort()
    return [[n, '%02d:%02d' % divmod(v % 1440, 60)] for v, n in rows]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
   [['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
  ['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
   [['marinate', '03:40'], ['grill', '11:40']]],
  ['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
  ['regression: midnight wraparound',
   [[['marinate', 90, []], ['roast', 90, ['marinate']], ['prep', 45, []]], '02:00'],
   [['marinate', '23:00'], ['roast', '00:30'], ['prep', '01:15']]],
  ['repair check: midnight wraparound',
   [[['roast', 45, ['prep']], ['prep', 15, []], ['sauce', 10, ['roast']], ['marinate', 10, []]], '00:30'],
   [['prep', '23:20'], ['roast', '23:35'], ['marinate', '00:20'], ['sauce', '00:20']]],
  ['generated control 1',
   [[['roast', 240, []], ['prep', 15, []], ['marinate', 240, ['prep', 'shop']]], '18:30'],
   'error: unknown step shop'],
  ['generated control 2',
   [[['prep', 5, []], ['roast', 15, ['prep']], ['rest', 10, ['marinate']], ['marinate', 5, []],
     ['sauce', 30, []], ['plate', 5, ['marinate', 'roast', 'rest']]],
    '12:00'],
   [['sauce', '11:30'], ['prep', '11:35'], ['marinate', '11:40'], ['roast', '11:40'], ['rest', '11:45'],
    ['plate', '11:55']]],
  ['generated control 3', [[['roast', 45, []], ['prep', 30, []], ['marinate', 90, ['prep']]], '02:00'],
   [['prep', '00:00'], ['marinate', '00:30'], ['roast', '01:15']]]],
 [['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
   [['marinate', '03:40'], ['grill', '11:40']]],
  ['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
  ['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
  ['regression: midnight wraparound',
   [[['prep', 30, []], ['roast', 90, ['prep', 'marinate']], ['marinate', 30, ['prep']],
     ['sauce', 90, ['roast']]],
    '01:15'],
   [['prep', '21:15'], ['marinate', '21:45'], ['roast', '22:15'], ['sauce', '23:45']]],
  ['repair check: midnight wraparound',
   [[['rest', 30, ['prep', 'sauce']], ['sauce', 5, ['prep', 'roast']], ['marinate', 90, []], ['prep', 45, []],
     ['roast', 90, []]],
    '02:00'],
   [['roast', '23:55'], ['marinate', '00:30'], ['prep', '00:40'], ['sauce', '01:25'], ['rest', '01:30']]],
  ['generated control 1',
   [[['sauce', 30, ['marinate', 'shop']], ['marinate', 90, ['prep']], ['prep', 5, []],
     ['rest', 240, ['sauce']], ['roast', 15, ['prep', 'marinate']],
     ['plate', 90, ['prep', 'roast', 'rest']]],
    '01:15'],
   'error: unknown step shop'],
  ['generated control 2',
   [[['roast', 5, ['prep', 'marinate']], ['marinate', 10, ['prep']], ['prep', 30, []]], '12:00'],
   [['prep', '11:15'], ['marinate', '11:45'], ['roast', '11:55']]],
  ['generated control 3',
   [[['marinate', 30, []], ['prep', 90, []], ['rest', 30, ['prep']], ['plate', 45, ['prep', 'rest']],
     ['roast', 10, []], ['sauce', 30, ['prep']]],
    '01:15'],
   [['prep', '22:30'], ['rest', '00:00'], ['plate', '00:30'], ['marinate', '00:45'], ['sauce', '00:45'],
    ['roast', '01:05']]]],
 [['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
  ['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
  ['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
   [['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
  ['regression: midnight wraparound',
   [[['rest', 90, ['sauce']], ['marinate', 90, ['prep']], ['plate', 30, ['rest']], ['roast', 45, ['prep']],
     ['prep', 90, []], ['sauce', 5, ['prep', 'marinate']]],
    '01:15'],
   [['prep', '20:10'], ['marinate', '21:40'], ['sauce', '23:10'], ['rest', '23:15'], ['roast', '00:30'],
    ['plate', '00:45']]],
  ['repair check: midnight wraparound',
   [[['sauce', 30, ['marinate']], ['marinate', 45, ['prep']], ['rest', 30, ['marinate', 'sauce']],
     ['prep', 5, []], ['roast', 15, []]],
    '01:15'],
   [['prep', '23:25'], ['marinate', '23:30'], ['sauce', '00:15'], ['rest', '00:45'], ['roast', '01:00']]],
  ['generated control 1',
   [[['prep', 15, ['sauce']], ['roast', 15, []], ['marinate', 15, []], ['sauce', 30, ['marinate', 'roast']]],
    '19:45'],
   [['marinate', '18:45'], ['roast', '18:45'], ['sauce', '19:00'], ['prep', '19:30']]],
  ['generated control 2',
   [[['prep', 45, []], ['sauce', 30, ['prep']], ['marinate', 90, []], ['roast', 90, ['prep', 'marinate']]],
    '12:00'],
   [['marinate', '09:00'], ['prep', '09:45'], ['roast', '10:30'], ['sauce', '11:30']]],
  ['generated control 3',
   [[['roast', 15, ['marinate']], ['prep', 45, []], ['rest', 30, ['roast']], ['marinate', 45, ['prep']],
     ['sauce', 45, ['roast']]],
    '19:45'],
   [['prep', '17:15'], ['marinate', '18:00'], ['roast', '18:45'], ['sauce', '19:00'], ['rest', '19:15']]]],
 [['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
  ['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
   [['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
  ['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
   [['marinate', '03:40'], ['grill', '11:40']]],
  ['regression: midnight wraparound',
   [[['prep', 15, []], ['roast', 30, ['prep']], ['sauce', 90, []], ['marinate', 45, []]], '00:30'],
   [['sauce', '23:00'], ['marinate', '23:45'], ['prep', '23:45'], ['roast', '00:00']]],
  ['repair check: midnight wraparound',
   [[['roast', 5, ['marinate']], ['prep', 5, []], ['marinate', 240, ['prep']]], '00:30'],
   [['prep', '20:20'], ['marinate', '20:25'], ['roast', '00:25']]],
  ['generated control 1',
   [[['roast', 90, []], ['rest', 90, ['prep', 'shop']], ['marinate', 5, []],
     ['plate', 90, ['roast', 'sauce']], ['prep', 5, []], ['sauce', 10, ['roast']]],
    '19:45'],
   'error: unknown step shop'],
  ['generated control 2', [[['prep', 10, []], ['roast', 45, ['prep']], ['marinate', 240, ['prep']]], '12:00'],
   [['prep', '07:50'], ['marinate', '08:00'], ['roast', '11:15']]],
  ['generated control 3',
   [[['plate', 5, []], ['prep', 10, []], ['rest', 90, ['roast', 'sauce']], ['sauce', 5, ['marinate']],
     ['marinate', 5, ['prep']], ['roast', 15, []]],
    '19:45'],
   [['prep', '17:55'], ['roast', '18:00'], ['marinate', '18:05'], ['sauce', '18:10'], ['rest', '18:15'],
    ['plate', '19:40']]]],
 [['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
   [['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
  ['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
   [['marinate', '03:40'], ['grill', '11:40']]],
  ['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
  ['regression: midnight wraparound',
   [[['roast', 30, []], ['marinate', 30, []], ['sauce', 240, ['marinate']], ['prep', 10, []]], '02:00'],
   [['marinate', '21:30'], ['sauce', '22:00'], ['roast', '01:30'], ['prep', '01:50']]],
  ['repair check: midnight wraparound',
   [[['sauce', 240, ['prep', 'roast']], ['marinate', 240, []], ['prep', 5, []], ['roast', 240, ['marinate']],
     ['rest', 90, ['prep']]],
    '02:00'],
   [['marinate', '14:00'], ['roast', '18:00'], ['prep', '21:55'], ['sauce', '22:00'], ['rest', '00:30']]],
  ['generated control 1',
   [[['prep', 90, []], ['marinate', 15, ['prep']], ['roast', 10, ['shop']], ['rest', 45, ['roast', 'sauce']],
     ['sauce', 90, ['marinate']]],
    '00:30'],
   'error: unknown step shop'],
  ['generated control 2', [[['roast', 30, []], ['marinate', 45, []], ['prep', 15, []]], '01:15'],
   [['marinate', '00:30'], ['roast', '00:45'], ['prep', '01:00']]],
  ['generated control 3',
   [[['marinate', 15, ['prep']], ['prep', 5, ['roast']], ['roast', 240, ['marinate']]], '19:45'],
   'error: cycle']]]
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
chain[['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']][['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]Passed
overnight marinade[['marinate', '03:40'], ['grill', '11:40']][['marinate', '03:40'], ['grill', '11:40']]Passed
cycleerror: cycleerror: cyclePassed
regression: midnight wraparound[['marinate', '23:00'], ['roast', '00:30'], ['prep', '01:15']][['marinate', '23:00'], ['roast', '00:30'], ['prep', '01:15']]Passed
repair check: midnight wraparound[['prep', '23:20'], ['roast', '23:35'], ['marinate', '00:20'], ['sauce', '00:20']][['prep', '23:20'], ['roast', '23:35'], ['marinate', '00:20'], ['sauce', '00:20']]Passed
generated control 1error: unknown step shoperror: unknown step shopPassed
generated control 2[['sauce', '11:30'], ['prep', '11:35'], ['marinate', '11:40'], ['roast', '11:40'], ['rest', '11:45'], ['plate', '11:55']][['sauce', '11:30'], ['prep', '11:35'], ['marinate', '11:40'], ['roast', '11:40'], ['rest', '11:45'], ['plate', '11:55']]Passed
generated control 3[['prep', '00:00'], ['marinate', '00:30'], ['roast', '01:15']][['prep', '00:00'], ['marinate', '00:30'], ['roast', '01:15']]Passed

SHA-256 / e4ca9b3ba1a5f6a74f1f584ecb72ce7aa94a529f0993c05fc1f3c76ea4120e2a

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.905410+00:00.

Case digest / 53362d4c548cbad2bf3297cd769aba803405fe8f25e6ca480ef398c643fe7440