FA-78201 / Subtitle cue timing / Open access
Timed-text time expression evaluation: clock fraction digits · case 01
A clock time of 00:00:01.5 evaluates to 1005 ms.
ROOT CAUSE
Fraction digits are assumed to be milliseconds regardless of their count.
VERIFIED REPAIR
Interpret the digits as a decimal fraction of a second.
Unsuccessful approach: Truncating to three digits still misreads short fractions and drops sub-millisecond rounding.
Case contract
Evaluate a timed-text time expression to integer ms, rounded half up. Offset form <number><metric> with metric h, m, s, ms, f (frames at frame_rate) or t (ticks at tick_rate). Clock form HH:MM:SS with optional .fraction (any digits) or :FF frames (FF < frame_rate). Minutes/seconds above 59 or malformed text give None.
Why this case matters
Subtitle timing defects shift, hide or overlap captions that viewers depend on for comprehension and accessibility.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
import re
from fractions import Fraction
N = 1
observations = []
def solve(expr, frame_rate, tick_rate):
m=re.fullmatch(r'(\d+(?:\.\d+)?)(h|ms|m|s|f|t)',expr)
if m:
v=Fraction(m.group(1))
unit=m.group(2)
scale={'h':3600000,'m':60000,'s':1000,'ms':1}
if unit in scale:
x=v*scale[unit]
elif unit=='f':
x=v*1000/frame_rate
else:
x=v*1000/tick_rate
return math.floor(x+Fraction(1,2))
m=re.fullmatch(r'(\d{2,}):(\d{2}):(\d{2})(?:\.(\d+)|:(\d{2,}))?',expr)
if not m:
return None
h,mi,se,frac,fr=m.groups()
if int(mi)>59 or int(se)>59:
return None
x=Fraction(int(h)*3600+int(mi)*60+int(se))*1000
if frac:
x+=Fraction(int(frac),1000)*1000
if fr:
if int(fr)>=frame_rate:
return None
x+=Fraction(int(fr)*1000,frame_rate)
return (x*2+1)//2
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: clock fraction digits', ['00:00:01.0005', 25, 1000], 1001), ('regression variant: clock fraction digits', ['00:00:05.25', 30, 1000], 5250), ('partial repair probe: clock fraction digits', ['10:00:00.25', 16, 3], 36000250), ('partial repair variant: clock fraction digits', ['10:59:59.0005', 50, 90000], 39599001), ('boundary control', ['10t', 25, 1000], 10), ('boundary control', ['00:00:00:25', 25, 1000], None), ('normal control', ['3f', 16, 1000], 188), ('normal control', ['10:59:59:15', 40, 1000], 39599375), ('normal control', ['01:60:59:30', 50, 10000000], None)], [('regression: clock fraction digits', ['10:59:59.25', 25, 10000000], 39599250), ('regression variant: clock fraction digits', ['100:00:00.5', 25, 90000], 360000500), ('partial repair probe: clock fraction digits', ['10:30:59.5', 24, 1000], 37859500), ('partial repair variant: clock fraction digits', ['01:30:59.25', 40, 3], 5459250), ('boundary control', ['3f', 16, 1000], 188), ('boundary control', ['10t', 25, 1000], 10), ('normal control', ['0ms', 16, 90000], 0), ('normal control', ['10:59:00:15', 40, 90000], 39540375), ('normal control', ['00:00:59:12', 30, 10000000], 59400)], [('regression: clock fraction digits', ['10:00:00.25', 16, 3], 36000250), ('regression variant: clock fraction digits', ['100:59:59.1234', 40, 10000000], 363599123), ('partial repair probe: clock fraction digits', ['01:00:00.5', 50, 1000], 3600500), ('partial repair variant: clock fraction digits', ['00:30:00.5', 25, 10000000], 1800500), ('boundary control', ['00:00:01:15', 16, 1000], 1938), ('boundary control', ['3f', 16, 1000], 188), ('normal control', ['100:30:59:30', 25, 10000000], None), ('normal control', ['00:30:00:15', 16, 10000000], 1800938), ('normal control', ['2s', 50, 3], 2000)], [('regression: clock fraction digits', ['10:30:59.5', 24, 1000], 37859500), ('regression variant: clock fraction digits', ['10:00:05.5', 30, 90000], 36005500), ('partial repair probe: clock fraction digits', ['00:00:05.25', 30, 1000], 5250), ('partial repair variant: clock fraction digits', ['00:30:00.5', 40, 1000], 1800500), ('boundary control', ['00:00:00:25', 25, 1000], None), ('boundary control', ['00:00:01:15', 16, 1000], 1938), ('normal control', ['100:59:59:12', 24, 1000], 363599500), ('normal control', ['7t', 25, 10000000], 0), ('normal control', ['17s', 25, 1000], 17000)], [('regression: clock fraction digits', ['01:00:00.5', 50, 1000], 3600500), ('regression variant: clock fraction digits', ['100:00:05.25', 50, 90000], 360005250), ('partial repair probe: clock fraction digits', ['100:00:00.5', 25, 90000], 360000500), ('partial repair variant: clock fraction digits', ['100:59:00.0005', 16, 3], 363540001), ('boundary control', ['10t', 25, 1000], 10), ('boundary control', ['00:00:00:25', 25, 1000], None), ('normal control', ['2ms', 40, 90000], 2), ('normal control', ['0.001ms', 30, 90000], 0), ('normal control', ['10:00:00:30', 25, 1000], None)]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: clock fraction digits | 1005 | 1001 | Failed |
| regression variant: clock fraction digits | 5025 | 5250 | Failed |
| partial repair probe: clock fraction digits | 36000025 | 36000250 | Failed |
| partial repair variant: clock fraction digits | 39599005 | 39599001 | Failed |
| boundary control | 10 | 10 | Passed |
| boundary control | None | None | Passed |
| normal control | 188 | 188 | Passed |
| normal control | 39599375 | 39599375 | Passed |
| normal control | None | None | Passed |
SHA-256 / 712b637ac2c377c900323fb412be0e0e161dd1cf4c8ad63c0ed0f23c2920533a
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
import re
from fractions import Fraction
N = 1
observations = []
def solve(expr, frame_rate, tick_rate):
m=re.fullmatch(r'(\d+(?:\.\d+)?)(h|ms|m|s|f|t)',expr)
if m:
v=Fraction(m.group(1))
unit=m.group(2)
scale={'h':3600000,'m':60000,'s':1000,'ms':1}
if unit in scale:
x=v*scale[unit]
elif unit=='f':
x=v*1000/frame_rate
else:
x=v*1000/tick_rate
return math.floor(x+Fraction(1,2))
m=re.fullmatch(r'(\d{2,}):(\d{2}):(\d{2})(?:\.(\d+)|:(\d{2,}))?',expr)
if not m:
return None
h,mi,se,frac,fr=m.groups()
if int(mi)>59 or int(se)>59:
return None
x=Fraction(int(h)*3600+int(mi)*60+int(se))*1000
if frac:
x+=Fraction(int(frac[:3]),1000)*1000
if fr:
if int(fr)>=frame_rate:
return None
x+=Fraction(int(fr)*1000,frame_rate)
return (x*2+1)//2
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: clock fraction digits', ['00:00:01.0005', 25, 1000], 1001), ('regression variant: clock fraction digits', ['00:00:05.25', 30, 1000], 5250), ('partial repair probe: clock fraction digits', ['10:00:00.25', 16, 3], 36000250), ('partial repair variant: clock fraction digits', ['10:59:59.0005', 50, 90000], 39599001), ('boundary control', ['10t', 25, 1000], 10), ('boundary control', ['00:00:00:25', 25, 1000], None), ('normal control', ['3f', 16, 1000], 188), ('normal control', ['10:59:59:15', 40, 1000], 39599375), ('normal control', ['01:60:59:30', 50, 10000000], None)], [('regression: clock fraction digits', ['10:59:59.25', 25, 10000000], 39599250), ('regression variant: clock fraction digits', ['100:00:00.5', 25, 90000], 360000500), ('partial repair probe: clock fraction digits', ['10:30:59.5', 24, 1000], 37859500), ('partial repair variant: clock fraction digits', ['01:30:59.25', 40, 3], 5459250), ('boundary control', ['3f', 16, 1000], 188), ('boundary control', ['10t', 25, 1000], 10), ('normal control', ['0ms', 16, 90000], 0), ('normal control', ['10:59:00:15', 40, 90000], 39540375), ('normal control', ['00:00:59:12', 30, 10000000], 59400)], [('regression: clock fraction digits', ['10:00:00.25', 16, 3], 36000250), ('regression variant: clock fraction digits', ['100:59:59.1234', 40, 10000000], 363599123), ('partial repair probe: clock fraction digits', ['01:00:00.5', 50, 1000], 3600500), ('partial repair variant: clock fraction digits', ['00:30:00.5', 25, 10000000], 1800500), ('boundary control', ['00:00:01:15', 16, 1000], 1938), ('boundary control', ['3f', 16, 1000], 188), ('normal control', ['100:30:59:30', 25, 10000000], None), ('normal control', ['00:30:00:15', 16, 10000000], 1800938), ('normal control', ['2s', 50, 3], 2000)], [('regression: clock fraction digits', ['10:30:59.5', 24, 1000], 37859500), ('regression variant: clock fraction digits', ['10:00:05.5', 30, 90000], 36005500), ('partial repair probe: clock fraction digits', ['00:00:05.25', 30, 1000], 5250), ('partial repair variant: clock fraction digits', ['00:30:00.5', 40, 1000], 1800500), ('boundary control', ['00:00:00:25', 25, 1000], None), ('boundary control', ['00:00:01:15', 16, 1000], 1938), ('normal control', ['100:59:59:12', 24, 1000], 363599500), ('normal control', ['7t', 25, 10000000], 0), ('normal control', ['17s', 25, 1000], 17000)], [('regression: clock fraction digits', ['01:00:00.5', 50, 1000], 3600500), ('regression variant: clock fraction digits', ['100:00:05.25', 50, 90000], 360005250), ('partial repair probe: clock fraction digits', ['100:00:00.5', 25, 90000], 360000500), ('partial repair variant: clock fraction digits', ['100:59:00.0005', 16, 3], 363540001), ('boundary control', ['10t', 25, 1000], 10), ('boundary control', ['00:00:00:25', 25, 1000], None), ('normal control', ['2ms', 40, 90000], 2), ('normal control', ['0.001ms', 30, 90000], 0), ('normal control', ['10:00:00:30', 25, 1000], None)]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: clock fraction digits | 1000 | 1001 | Failed |
| regression variant: clock fraction digits | 5025 | 5250 | Failed |
| partial repair probe: clock fraction digits | 36000025 | 36000250 | Failed |
| partial repair variant: clock fraction digits | 39599000 | 39599001 | Failed |
| boundary control | 10 | 10 | Passed |
| boundary control | None | None | Passed |
| normal control | 188 | 188 | Passed |
| normal control | 39599375 | 39599375 | Passed |
| normal control | None | None | Passed |
SHA-256 / 19a3326a8cdebb0e501120c530a198ec2082d95329dbe15c85b676b23ef81e59
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
import re
from fractions import Fraction
N = 1
observations = []
def solve(expr, frame_rate, tick_rate):
m=re.fullmatch(r'(\d+(?:\.\d+)?)(h|ms|m|s|f|t)',expr)
if m:
v=Fraction(m.group(1))
unit=m.group(2)
scale={'h':3600000,'m':60000,'s':1000,'ms':1}
if unit in scale:
x=v*scale[unit]
elif unit=='f':
x=v*1000/frame_rate
else:
x=v*1000/tick_rate
return math.floor(x+Fraction(1,2))
m=re.fullmatch(r'(\d{2,}):(\d{2}):(\d{2})(?:\.(\d+)|:(\d{2,}))?',expr)
if not m:
return None
h,mi,se,frac,fr=m.groups()
if int(mi)>59 or int(se)>59:
return None
x=Fraction(int(h)*3600+int(mi)*60+int(se))*1000
if frac:
x+=Fraction('0.'+frac)*1000
if fr:
if int(fr)>=frame_rate:
return None
x+=Fraction(int(fr)*1000,frame_rate)
return (x*2+1)//2
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: clock fraction digits', ['00:00:01.0005', 25, 1000], 1001), ('regression variant: clock fraction digits', ['00:00:05.25', 30, 1000], 5250), ('partial repair probe: clock fraction digits', ['10:00:00.25', 16, 3], 36000250), ('partial repair variant: clock fraction digits', ['10:59:59.0005', 50, 90000], 39599001), ('boundary control', ['10t', 25, 1000], 10), ('boundary control', ['00:00:00:25', 25, 1000], None), ('normal control', ['3f', 16, 1000], 188), ('normal control', ['10:59:59:15', 40, 1000], 39599375), ('normal control', ['01:60:59:30', 50, 10000000], None)], [('regression: clock fraction digits', ['10:59:59.25', 25, 10000000], 39599250), ('regression variant: clock fraction digits', ['100:00:00.5', 25, 90000], 360000500), ('partial repair probe: clock fraction digits', ['10:30:59.5', 24, 1000], 37859500), ('partial repair variant: clock fraction digits', ['01:30:59.25', 40, 3], 5459250), ('boundary control', ['3f', 16, 1000], 188), ('boundary control', ['10t', 25, 1000], 10), ('normal control', ['0ms', 16, 90000], 0), ('normal control', ['10:59:00:15', 40, 90000], 39540375), ('normal control', ['00:00:59:12', 30, 10000000], 59400)], [('regression: clock fraction digits', ['10:00:00.25', 16, 3], 36000250), ('regression variant: clock fraction digits', ['100:59:59.1234', 40, 10000000], 363599123), ('partial repair probe: clock fraction digits', ['01:00:00.5', 50, 1000], 3600500), ('partial repair variant: clock fraction digits', ['00:30:00.5', 25, 10000000], 1800500), ('boundary control', ['00:00:01:15', 16, 1000], 1938), ('boundary control', ['3f', 16, 1000], 188), ('normal control', ['100:30:59:30', 25, 10000000], None), ('normal control', ['00:30:00:15', 16, 10000000], 1800938), ('normal control', ['2s', 50, 3], 2000)], [('regression: clock fraction digits', ['10:30:59.5', 24, 1000], 37859500), ('regression variant: clock fraction digits', ['10:00:05.5', 30, 90000], 36005500), ('partial repair probe: clock fraction digits', ['00:00:05.25', 30, 1000], 5250), ('partial repair variant: clock fraction digits', ['00:30:00.5', 40, 1000], 1800500), ('boundary control', ['00:00:00:25', 25, 1000], None), ('boundary control', ['00:00:01:15', 16, 1000], 1938), ('normal control', ['100:59:59:12', 24, 1000], 363599500), ('normal control', ['7t', 25, 10000000], 0), ('normal control', ['17s', 25, 1000], 17000)], [('regression: clock fraction digits', ['01:00:00.5', 50, 1000], 3600500), ('regression variant: clock fraction digits', ['100:00:05.25', 50, 90000], 360005250), ('partial repair probe: clock fraction digits', ['100:00:00.5', 25, 90000], 360000500), ('partial repair variant: clock fraction digits', ['100:59:00.0005', 16, 3], 363540001), ('boundary control', ['10t', 25, 1000], 10), ('boundary control', ['00:00:00:25', 25, 1000], None), ('normal control', ['2ms', 40, 90000], 2), ('normal control', ['0.001ms', 30, 90000], 0), ('normal control', ['10:00:00:30', 25, 1000], None)]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: clock fraction digits | 1001 | 1001 | Passed |
| regression variant: clock fraction digits | 5250 | 5250 | Passed |
| partial repair probe: clock fraction digits | 36000250 | 36000250 | Passed |
| partial repair variant: clock fraction digits | 39599001 | 39599001 | Passed |
| boundary control | 10 | 10 | Passed |
| boundary control | None | None | Passed |
| normal control | 188 | 188 | Passed |
| normal control | 39599375 | 39599375 | Passed |
| normal control | None | None | Passed |
SHA-256 / a8589be37673e3b64475c8c28a4837578713fd9a41efbabb6891bb8764519549
Verification & scope
A deterministic bounded teaching model with a stipulated toy contract; it does not claim conformance to any subtitle 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.
Observations recorded using Python 3.12.14 at 2026-09-29T14:49:33.108797+00:00.
Case digest / 42666a9fc90c74466892d81ba9b6ff47627d66d93af3e95e4e7c6dc87f6a18bd