{"abstract":"Half-frame offsets are always rounded as if they were whole frames.","category":"Broadcast timecode arithmetic","checks":9,"contract":"Convert a decimal seconds string exactly (no binary floating point) at rate [N,D] to the nearest frame, halves rounding up, and a non-drop label using the nominal rate ceil(N/D). Negative input returns None.","evaluation_group":"w2-broadcast-timecode-arithmetic-decimal-seconds-to-frame","failed_approach":"Truncating the rate to 29 or 23 fps drifts NTSC positions.","family":"w2-broadcast-timecode-arithmetic-decimal-seconds-to-frame-rate-scaling","id":"FA-78746","implementations":{"attempt":{"sha256":"55a52291870619ed47c8681b5f6548d254057f838b7d3dc34e614a47f93c9816","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nfrom fractions import Fraction\nN = 1\nobservations = []\ndef solve(sec, fps):\n    num,den=fps\n    x=Fraction(sec)\n    if x<0:\n        return None\n    n=x*(num//den)\n    fr=math.floor(n+Fraction(1,2))\n    nominal=-(-num//den)\n    return [fr,'%02d:%02d:%02d:%02d'%(fr//(3600*nominal)%24,fr//(60*nominal)%60,fr//nominal%60,fr%nominal)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression: rate scaling', ['0.06', [25, 1]], [2, '00:00:00:02']), ('regression variant: rate scaling', ['0.1', [25, 1]], [3, '00:00:00:03']), ('partial repair probe: rate scaling', ['3600', [30000, 1001]], [107892, '00:59:56:12']), ('partial repair variant: rate scaling', ['3600', [24000, 1001]], [86314, '00:59:56:10']), ('boundary control', ['-1', [25, 1]], None), ('boundary control', ['0', [24, 1]], [0, '00:00:00:00']), ('normal control', ['-1', [24000, 1001]], None), ('normal control', ['-1', [24, 1]], None), ('normal control', ['0.14', [24000, 1001]], [3, '00:00:00:03'])], [('regression: rate scaling', ['0.02', [25, 1]], [1, '00:00:00:01']), ('regression variant: rate scaling', ['0.02', [30000, 1001]], [1, '00:00:00:01']), ('partial repair probe: rate scaling', ['7.3', [30000, 1001]], [219, '00:00:07:09']), ('partial repair variant: rate scaling', ['1.5', [24000, 1001]], [36, '00:00:01:12']), ('boundary control', ['0', [24, 1]], [0, '00:00:00:00']), ('boundary control', ['-1', [25, 1]], None), ('normal control', ['-0.5', [25, 1]], None), ('normal control', ['0.18', [50, 1]], [9, '00:00:00:09']), ('normal control', ['0.02', [24000, 1001]], [0, '00:00:00:00'])], [('regression: rate scaling', ['12.345', [24000, 1001]], [296, '00:00:12:08']), ('regression variant: rate scaling', ['0.04', [24000, 1001]], [1, '00:00:00:01']), ('partial repair probe: rate scaling', ['1.001', [24000, 1001]], [24, '00:00:01:00']), ('partial repair variant: rate scaling', ['1.001', [30000, 1001]], [30, '00:00:01:00']), ('boundary control', ['-1', [25, 1]], None), ('boundary control', ['0', [24, 1]], [0, '00:00:00:00']), ('normal control', ['-0.5', [50, 1]], None), ('normal control', ['1.5', [24, 1]], [36, '00:00:01:12']), ('normal control', ['3600', [24, 1]], [86400, '01:00:00:00'])], [('regression: rate scaling', ['1.5', [25, 1]], [38, '00:00:01:13']), ('regression variant: rate scaling', ['0.14', [25, 1]], [4, '00:00:00:04']), ('partial repair probe: rate scaling', ['12.345', [30000, 1001]], [370, '00:00:12:10']), ('partial repair variant: rate scaling', ['12.345', [24000, 1001]], [296, '00:00:12:08']), ('boundary control', ['0', [24, 1]], [0, '00:00:00:00']), ('boundary control', ['-1', [25, 1]], None), ('normal control', ['0.22', [50, 1]], [11, '00:00:00:11']), ('normal control', ['0.0166', [24000, 1001]], [0, '00:00:00:00']), ('normal control', ['0.06', [50, 1]], [3, '00:00:00:03'])], [('regression: rate scaling', ['0.04', [24, 1]], [1, '00:00:00:01']), ('regression variant: rate scaling', ['0.0166', [50, 1]], [1, '00:00:00:01']), ('partial repair probe: rate scaling', ['0.22', [30000, 1001]], [7, '00:00:00:07']), ('partial repair variant: rate scaling', ['3600', [30000, 1001]], [107892, '00:59:56:12']), ('boundary control', ['-1', [25, 1]], None), ('boundary control', ['0', [24, 1]], [0, '00:00:00:00']), ('normal control', ['12.345', [50, 1]], [617, '00:00:12:17']), ('normal control', ['0', [50, 1]], [0, '00:00:00:00']), ('normal control', ['0.0166', [25, 1]], [0, '00:00:00:00'])]]\nfor label, args, expected in fixtures[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":"c57f4b47064f72cee725a2beb1bd30f36d9fa4aa32d83957242632732833654e","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nfrom fractions import Fraction\nN = 1\nobservations = []\ndef solve(sec, fps):\n    num,den=fps\n    x=Fraction(sec)\n    if x<0:\n        return None\n    n=x*num//den\n    fr=math.floor(n+Fraction(1,2))\n    nominal=-(-num//den)\n    return [fr,'%02d:%02d:%02d:%02d'%(fr//(3600*nominal)%24,fr//(60*nominal)%60,fr//nominal%60,fr%nominal)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression: rate scaling', ['0.06', [25, 1]], [2, '00:00:00:02']), ('regression variant: rate scaling', ['0.1', [25, 1]], [3, '00:00:00:03']), ('partial repair probe: rate scaling', ['3600', [30000, 1001]], [107892, '00:59:56:12']), ('partial repair variant: rate scaling', ['3600', [24000, 1001]], [86314, '00:59:56:10']), ('boundary control', ['-1', [25, 1]], None), ('boundary control', ['0', [24, 1]], [0, '00:00:00:00']), ('normal control', ['-1', [24000, 1001]], None), ('normal control', ['-1', [24, 1]], None), ('normal control', ['0.14', [24000, 1001]], [3, '00:00:00:03'])], [('regression: rate scaling', ['0.02', [25, 1]], [1, '00:00:00:01']), ('regression variant: rate scaling', ['0.02', [30000, 1001]], [1, '00:00:00:01']), ('partial repair probe: rate scaling', ['7.3', [30000, 1001]], [219, '00:00:07:09']), ('partial repair variant: rate scaling', ['1.5', [24000, 1001]], [36, '00:00:01:12']), ('boundary control', ['0', [24, 1]], [0, '00:00:00:00']), ('boundary control', ['-1', [25, 1]], None), ('normal control', ['-0.5', [25, 1]], None), ('normal control', ['0.18', [50, 1]], [9, '00:00:00:09']), ('normal control', ['0.02', [24000, 1001]], [0, '00:00:00:00'])], [('regression: rate scaling', ['12.345', [24000, 1001]], [296, '00:00:12:08']), ('regression variant: rate scaling', ['0.04', [24000, 1001]], [1, '00:00:00:01']), ('partial repair probe: rate scaling', ['1.001', [24000, 1001]], [24, '00:00:01:00']), ('partial repair variant: rate scaling', ['1.001', [30000, 1001]], [30, '00:00:01:00']), ('boundary control', ['-1', [25, 1]], None), ('boundary control', ['0', [24, 1]], [0, '00:00:00:00']), ('normal control', ['-0.5', [50, 1]], None), ('normal control', ['1.5', [24, 1]], [36, '00:00:01:12']), ('normal control', ['3600', [24, 1]], [86400, '01:00:00:00'])], [('regression: rate scaling', ['1.5', [25, 1]], [38, '00:00:01:13']), ('regression variant: rate scaling', ['0.14', [25, 1]], [4, '00:00:00:04']), ('partial repair probe: rate scaling', ['12.345', [30000, 1001]], [370, '00:00:12:10']), ('partial repair variant: rate scaling', ['12.345', [24000, 1001]], [296, '00:00:12:08']), ('boundary control', ['0', [24, 1]], [0, '00:00:00:00']), ('boundary control', ['-1', [25, 1]], None), ('normal control', ['0.22', [50, 1]], [11, '00:00:00:11']), ('normal control', ['0.0166', [24000, 1001]], [0, '00:00:00:00']), ('normal control', ['0.06', [50, 1]], [3, '00:00:00:03'])], [('regression: rate scaling', ['0.04', [24, 1]], [1, '00:00:00:01']), ('regression variant: rate scaling', ['0.0166', [50, 1]], [1, '00:00:00:01']), ('partial repair probe: rate scaling', ['0.22', [30000, 1001]], [7, '00:00:00:07']), ('partial repair variant: rate scaling', ['3600', [30000, 1001]], [107892, '00:59:56:12']), ('boundary control', ['-1', [25, 1]], None), ('boundary control', ['0', [24, 1]], [0, '00:00:00:00']), ('normal control', ['12.345', [50, 1]], [617, '00:00:12:17']), ('normal control', ['0', [50, 1]], [0, '00:00:00:00']), ('normal control', ['0.0166', [25, 1]], [0, '00:00:00:00'])]]\nfor label, args, expected in fixtures[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":"87e1c6a05ca2f410a388c722b9dd243633c467c808abcfc94fa21dc0efe6917b","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nfrom fractions import Fraction\nN = 1\nobservations = []\ndef solve(sec, fps):\n    num,den=fps\n    x=Fraction(sec)\n    if x<0:\n        return None\n    n=x*num/den\n    fr=math.floor(n+Fraction(1,2))\n    nominal=-(-num//den)\n    return [fr,'%02d:%02d:%02d:%02d'%(fr//(3600*nominal)%24,fr//(60*nominal)%60,fr//nominal%60,fr%nominal)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('regression: rate scaling', ['0.06', [25, 1]], [2, '00:00:00:02']), ('regression variant: rate scaling', ['0.1', [25, 1]], [3, '00:00:00:03']), ('partial repair probe: rate scaling', ['3600', [30000, 1001]], [107892, '00:59:56:12']), ('partial repair variant: rate scaling', ['3600', [24000, 1001]], [86314, '00:59:56:10']), ('boundary control', ['-1', [25, 1]], None), ('boundary control', ['0', [24, 1]], [0, '00:00:00:00']), ('normal control', ['-1', [24000, 1001]], None), ('normal control', ['-1', [24, 1]], None), ('normal control', ['0.14', [24000, 1001]], [3, '00:00:00:03'])], [('regression: rate scaling', ['0.02', [25, 1]], [1, '00:00:00:01']), ('regression variant: rate scaling', ['0.02', [30000, 1001]], [1, '00:00:00:01']), ('partial repair probe: rate scaling', ['7.3', [30000, 1001]], [219, '00:00:07:09']), ('partial repair variant: rate scaling', ['1.5', [24000, 1001]], [36, '00:00:01:12']), ('boundary control', ['0', [24, 1]], [0, '00:00:00:00']), ('boundary control', ['-1', [25, 1]], None), ('normal control', ['-0.5', [25, 1]], None), ('normal control', ['0.18', [50, 1]], [9, '00:00:00:09']), ('normal control', ['0.02', [24000, 1001]], [0, '00:00:00:00'])], [('regression: rate scaling', ['12.345', [24000, 1001]], [296, '00:00:12:08']), ('regression variant: rate scaling', ['0.04', [24000, 1001]], [1, '00:00:00:01']), ('partial repair probe: rate scaling', ['1.001', [24000, 1001]], [24, '00:00:01:00']), ('partial repair variant: rate scaling', ['1.001', [30000, 1001]], [30, '00:00:01:00']), ('boundary control', ['-1', [25, 1]], None), ('boundary control', ['0', [24, 1]], [0, '00:00:00:00']), ('normal control', ['-0.5', [50, 1]], None), ('normal control', ['1.5', [24, 1]], [36, '00:00:01:12']), ('normal control', ['3600', [24, 1]], [86400, '01:00:00:00'])], [('regression: rate scaling', ['1.5', [25, 1]], [38, '00:00:01:13']), ('regression variant: rate scaling', ['0.14', [25, 1]], [4, '00:00:00:04']), ('partial repair probe: rate scaling', ['12.345', [30000, 1001]], [370, '00:00:12:10']), ('partial repair variant: rate scaling', ['12.345', [24000, 1001]], [296, '00:00:12:08']), ('boundary control', ['0', [24, 1]], [0, '00:00:00:00']), ('boundary control', ['-1', [25, 1]], None), ('normal control', ['0.22', [50, 1]], [11, '00:00:00:11']), ('normal control', ['0.0166', [24000, 1001]], [0, '00:00:00:00']), ('normal control', ['0.06', [50, 1]], [3, '00:00:00:03'])], [('regression: rate scaling', ['0.04', [24, 1]], [1, '00:00:00:01']), ('regression variant: rate scaling', ['0.0166', [50, 1]], [1, '00:00:00:01']), ('partial repair probe: rate scaling', ['0.22', [30000, 1001]], [7, '00:00:00:07']), ('partial repair variant: rate scaling', ['3600', [30000, 1001]], [107892, '00:59:56:12']), ('boundary control', ['-1', [25, 1]], None), ('boundary control', ['0', [24, 1]], [0, '00:00:00:00']), ('normal control', ['12.345', [50, 1]], [617, '00:00:12:17']), ('normal control', ['0', [50, 1]], [0, '00:00:00:00']), ('normal control', ['0.0166', [25, 1]], [0, '00:00:00:00'])]]\nfor label, args, expected in fixtures[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 with a stipulated toy contract; it does not claim conformance to SMPTE or any broadcast standard. 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-broadcast-timecode-arithmetic-decimal-seconds-to-frame-rate-scaling","generated_at":"2026-09-29T14:49:38.021514+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Timecode arithmetic errors misplace edits, commercial breaks and captions against the broadcast clock.","repair":"Keep the exact frame position until the final rounding.","root_cause":"The frame position is floored before the half-up rounding step.","sha256":"ca94d1527ab2fa796020678f4bd34d6aa3440d4004d3eb5c7ed3f03ca3ee706c","title":"Decimal seconds to frame label: rate scaling · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":42.711,"exit_code":1,"observations":[{"actual":[2,"00:00:00:02"],"check":"regression: rate scaling","expected":[2,"00:00:00:02"],"passed":true},{"actual":[3,"00:00:00:03"],"check":"regression variant: rate scaling","expected":[3,"00:00:00:03"],"passed":true},{"actual":[104400,"00:58:00:00"],"check":"partial repair probe: rate scaling","expected":[107892,"00:59:56:12"],"passed":false},{"actual":[82800,"00:57:30:00"],"check":"partial repair variant: rate scaling","expected":[86314,"00:59:56:10"],"passed":false},{"actual":null,"check":"boundary control","expected":null,"passed":true},{"actual":[0,"00:00:00:00"],"check":"boundary control","expected":[0,"00:00:00:00"],"passed":true},{"actual":null,"check":"normal control","expected":null,"passed":true},{"actual":null,"check":"normal control","expected":null,"passed":true},{"actual":[3,"00:00:00:03"],"check":"normal control","expected":[3,"00:00:00:03"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: rate scaling\", \"actual\": [2, \"00:00:00:02\"], \"expected\": [2, \"00:00:00:02\"], \"passed\": true}, {\"check\": \"regression variant: rate scaling\", \"actual\": [3, \"00:00:00:03\"], \"expected\": [3, \"00:00:00:03\"], \"passed\": true}, {\"check\": \"partial repair probe: rate scaling\", \"actual\": [104400, \"00:58:00:00\"], \"expected\": [107892, \"00:59:56:12\"], \"passed\": false}, {\"check\": \"partial repair variant: rate scaling\", \"actual\": [82800, \"00:57:30:00\"], \"expected\": [86314, \"00:59:56:10\"], \"passed\": false}, {\"check\": \"boundary control\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"boundary control\", \"actual\": [0, \"00:00:00:00\"], \"expected\": [0, \"00:00:00:00\"], \"passed\": true}, {\"check\": \"normal control\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"normal control\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"normal control\", \"actual\": [3, \"00:00:00:03\"], \"expected\": [3, \"00:00:00:03\"], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.754,"exit_code":1,"observations":[{"actual":[1,"00:00:00:01"],"check":"regression: rate scaling","expected":[2,"00:00:00:02"],"passed":false},{"actual":[2,"00:00:00:02"],"check":"regression variant: rate scaling","expected":[3,"00:00:00:03"],"passed":false},{"actual":[107892,"00:59:56:12"],"check":"partial repair probe: rate scaling","expected":[107892,"00:59:56:12"],"passed":true},{"actual":[86313,"00:59:56:09"],"check":"partial repair variant: rate scaling","expected":[86314,"00:59:56:10"],"passed":false},{"actual":null,"check":"boundary control","expected":null,"passed":true},{"actual":[0,"00:00:00:00"],"check":"boundary control","expected":[0,"00:00:00:00"],"passed":true},{"actual":null,"check":"normal control","expected":null,"passed":true},{"actual":null,"check":"normal control","expected":null,"passed":true},{"actual":[3,"00:00:00:03"],"check":"normal control","expected":[3,"00:00:00:03"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: rate scaling\", \"actual\": [1, \"00:00:00:01\"], \"expected\": [2, \"00:00:00:02\"], \"passed\": false}, {\"check\": \"regression variant: rate scaling\", \"actual\": [2, \"00:00:00:02\"], \"expected\": [3, \"00:00:00:03\"], \"passed\": false}, {\"check\": \"partial repair probe: rate scaling\", \"actual\": [107892, \"00:59:56:12\"], \"expected\": [107892, \"00:59:56:12\"], \"passed\": true}, {\"check\": \"partial repair variant: rate scaling\", \"actual\": [86313, \"00:59:56:09\"], \"expected\": [86314, \"00:59:56:10\"], \"passed\": false}, {\"check\": \"boundary control\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"boundary control\", \"actual\": [0, \"00:00:00:00\"], \"expected\": [0, \"00:00:00:00\"], \"passed\": true}, {\"check\": \"normal control\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"normal control\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"normal control\", \"actual\": [3, \"00:00:00:03\"], \"expected\": [3, \"00:00:00:03\"], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":40.833,"exit_code":0,"observations":[{"actual":[2,"00:00:00:02"],"check":"regression: rate scaling","expected":[2,"00:00:00:02"],"passed":true},{"actual":[3,"00:00:00:03"],"check":"regression variant: rate scaling","expected":[3,"00:00:00:03"],"passed":true},{"actual":[107892,"00:59:56:12"],"check":"partial repair probe: rate scaling","expected":[107892,"00:59:56:12"],"passed":true},{"actual":[86314,"00:59:56:10"],"check":"partial repair variant: rate scaling","expected":[86314,"00:59:56:10"],"passed":true},{"actual":null,"check":"boundary control","expected":null,"passed":true},{"actual":[0,"00:00:00:00"],"check":"boundary control","expected":[0,"00:00:00:00"],"passed":true},{"actual":null,"check":"normal control","expected":null,"passed":true},{"actual":null,"check":"normal control","expected":null,"passed":true},{"actual":[3,"00:00:00:03"],"check":"normal control","expected":[3,"00:00:00:03"],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: rate scaling\", \"actual\": [2, \"00:00:00:02\"], \"expected\": [2, \"00:00:00:02\"], \"passed\": true}, {\"check\": \"regression variant: rate scaling\", \"actual\": [3, \"00:00:00:03\"], \"expected\": [3, \"00:00:00:03\"], \"passed\": true}, {\"check\": \"partial repair probe: rate scaling\", \"actual\": [107892, \"00:59:56:12\"], \"expected\": [107892, \"00:59:56:12\"], \"passed\": true}, {\"check\": \"partial repair variant: rate scaling\", \"actual\": [86314, \"00:59:56:10\"], \"expected\": [86314, \"00:59:56:10\"], \"passed\": true}, {\"check\": \"boundary control\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"boundary control\", \"actual\": [0, \"00:00:00:00\"], \"expected\": [0, \"00:00:00:00\"], \"passed\": true}, {\"check\": \"normal control\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"normal control\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"normal control\", \"actual\": [3, \"00:00:00:03\"], \"expected\": [3, \"00:00:00:03\"], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}