FA-78181 / Subtitle cue timing / Open access
WebVTT cue timing line parsing: cue ordering check · case 01
Zero-duration cues where END equals START are accepted.
ROOT CAUSE
The order check only rejects ends strictly before the start.
VERIFIED REPAIR
Reject cues whose end is not after the start.
Unsuccessful approach: Special-casing an end of zero still accepts equal non-zero start and end.
Case contract
Parse "START --> END [settings...]" (whitespace separated). Timestamps are [hh:]mm:ss.ttt with hours of two or more digits, minutes and seconds exactly two digits below 60, and exactly three fraction digits after a period. END must be after START. Return [start_ms,end_ms,settings joined by single spaces] or 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 re
N = 1
observations = []
def solve(line):
parts=line.split()
if len(parts)<3 or parts[1]!='-->':
return None
def ts(x):
m=re.fullmatch(r'(?:(\d{2,}):)?(\d{2}):(\d{2})\.(\d{3})',x)
if not m:
return None
h,mi,se,f=m.groups()
if int(mi)>59 or int(se)>59:
return None
return int(h or 0)*3600000+int(mi)*60000+int(se)*1000+int(f)
a=ts(parts[0]); b=ts(parts[2])
if a is None or b is None or b<a:
return None
return [a,b,' '.join(parts[3:])]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: cue ordering check', ['00:01.000 --> 00:01.000'], None), ('regression variant: cue ordering check', ['01:00.500 --> 01:00.500'], None), ('partial repair probe: cue ordering check', ['01:09.500 --> 01:09.500'], None), ('partial repair variant: cue ordering check', ['100:59:59.999 --> 100:59:59.999 align:start'], None), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('normal control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('normal control', ['59:09.5 --> 00:02.000 align:start'], None), ('normal control', ['100:01:60,500 --> 00:00:60.5 align:start'], None)], [('regression: cue ordering check', ['100:59:09.000 --> 100:59:09.000'], None), ('regression variant: cue ordering check', ['100:59:09.500 --> 100:59:09.500 align:start'], None), ('partial repair probe: cue ordering check', ['00:00:09.000 --> 00:00:09.000'], None), ('partial repair variant: cue ordering check', ['00:59.000 --> 00:59.000 line:0 position:10%'], None), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('normal control', ['00:5:00.000 -> 00:5:00.000'], None), ('normal control', ['01:01:09.5 --> 60:09.5 size:50% align:end'], None), ('normal control', ['01:60:59.999 --> 00:00.001 line:0 position:10%'], None)], [('regression: cue ordering check', ['01:09.500 --> 01:09.500'], None), ('regression variant: cue ordering check', ['01:59:00.500 --> 01:59:00.500 size:50% align:end'], None), ('partial repair probe: cue ordering check', ['01:59:59.500 --> 01:59:59.500 size:50% align:end'], None), ('partial repair variant: cue ordering check', ['00:01:00.000 --> 00:01:00.000'], None), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('normal control', ['01:60:00.500 --> 5:60,500 line:0 position:10%'], None), ('normal control', ['100:01:00,500 --> 01:00:00.000 align:start'], None), ('normal control', ['60:59.500 --> 100:00:00.000'], None)], [('regression: cue ordering check', ['00:00:09.000 --> 00:00:09.000'], None), ('regression variant: cue ordering check', ['100:59:00.000 --> 100:59:00.000 size:50% align:end'], None), ('partial repair probe: cue ordering check', ['01:00.500 --> 01:00.500'], None), ('partial repair variant: cue ordering check', ['00:59:00.999 --> 00:59:00.999 size:50% align:end'], None), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('normal control', ['60:60.999 --> 00:00.001'], None), ('normal control', ['01:59:59,500 --> 01:59:59,500 size:50% align:end'], None), ('normal control', ['59:60.5 --> 100:00:00.000 line:0 position:10%'], None)], [('regression: cue ordering check', ['01:59:59.500 --> 01:59:59.500 size:50% align:end'], None), ('regression variant: cue ordering check', ['100:59:59.999 --> 100:59:59.999 align:start'], None), ('partial repair probe: cue ordering check', ['100:59:09.500 --> 100:59:09.500 align:start'], None), ('partial repair variant: cue ordering check', ['01:59:59.999 --> 01:59:59.999'], None), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('normal control', ['01:5:60.500 --> 00:00.001 size:50% align:end'], None), ('normal control', ['100:00:59.000 --> 00:02.000 size:50% align:end'], None), ('normal control', ['59:59.5 -> 00:5:59.999'], 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: cue ordering check | [1000, 1000, ''] | None | Failed |
| regression variant: cue ordering check | [60500, 60500, ''] | None | Failed |
| partial repair probe: cue ordering check | [69500, 69500, ''] | None | Failed |
| partial repair variant: cue ordering check | [363599999, 363599999, 'align:start'] | None | Failed |
| boundary control | [1000, 2000, ''] | [1000, 2000, ''] | Passed |
| boundary control | [360000000, 360001000, 'align:start'] | [360000000, 360001000, 'align:start'] | Passed |
| normal control | [59999, 60000, 'line:0 size:50%'] | [59999, 60000, 'line:0 size:50%'] | Passed |
| normal control | None | None | Passed |
| normal control | None | None | Passed |
SHA-256 / d75a2bb861a088ac682e5b1bf9f82df1199ae189c73d88e28d4eb5d660453122
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import re
N = 1
observations = []
def solve(line):
parts=line.split()
if len(parts)<3 or parts[1]!='-->':
return None
def ts(x):
m=re.fullmatch(r'(?:(\d{2,}):)?(\d{2}):(\d{2})\.(\d{3})',x)
if not m:
return None
h,mi,se,f=m.groups()
if int(mi)>59 or int(se)>59:
return None
return int(h or 0)*3600000+int(mi)*60000+int(se)*1000+int(f)
a=ts(parts[0]); b=ts(parts[2])
if a is None or b is None or b<a or b==0:
return None
return [a,b,' '.join(parts[3:])]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: cue ordering check', ['00:01.000 --> 00:01.000'], None), ('regression variant: cue ordering check', ['01:00.500 --> 01:00.500'], None), ('partial repair probe: cue ordering check', ['01:09.500 --> 01:09.500'], None), ('partial repair variant: cue ordering check', ['100:59:59.999 --> 100:59:59.999 align:start'], None), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('normal control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('normal control', ['59:09.5 --> 00:02.000 align:start'], None), ('normal control', ['100:01:60,500 --> 00:00:60.5 align:start'], None)], [('regression: cue ordering check', ['100:59:09.000 --> 100:59:09.000'], None), ('regression variant: cue ordering check', ['100:59:09.500 --> 100:59:09.500 align:start'], None), ('partial repair probe: cue ordering check', ['00:00:09.000 --> 00:00:09.000'], None), ('partial repair variant: cue ordering check', ['00:59.000 --> 00:59.000 line:0 position:10%'], None), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('normal control', ['00:5:00.000 -> 00:5:00.000'], None), ('normal control', ['01:01:09.5 --> 60:09.5 size:50% align:end'], None), ('normal control', ['01:60:59.999 --> 00:00.001 line:0 position:10%'], None)], [('regression: cue ordering check', ['01:09.500 --> 01:09.500'], None), ('regression variant: cue ordering check', ['01:59:00.500 --> 01:59:00.500 size:50% align:end'], None), ('partial repair probe: cue ordering check', ['01:59:59.500 --> 01:59:59.500 size:50% align:end'], None), ('partial repair variant: cue ordering check', ['00:01:00.000 --> 00:01:00.000'], None), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('normal control', ['01:60:00.500 --> 5:60,500 line:0 position:10%'], None), ('normal control', ['100:01:00,500 --> 01:00:00.000 align:start'], None), ('normal control', ['60:59.500 --> 100:00:00.000'], None)], [('regression: cue ordering check', ['00:00:09.000 --> 00:00:09.000'], None), ('regression variant: cue ordering check', ['100:59:00.000 --> 100:59:00.000 size:50% align:end'], None), ('partial repair probe: cue ordering check', ['01:00.500 --> 01:00.500'], None), ('partial repair variant: cue ordering check', ['00:59:00.999 --> 00:59:00.999 size:50% align:end'], None), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('normal control', ['60:60.999 --> 00:00.001'], None), ('normal control', ['01:59:59,500 --> 01:59:59,500 size:50% align:end'], None), ('normal control', ['59:60.5 --> 100:00:00.000 line:0 position:10%'], None)], [('regression: cue ordering check', ['01:59:59.500 --> 01:59:59.500 size:50% align:end'], None), ('regression variant: cue ordering check', ['100:59:59.999 --> 100:59:59.999 align:start'], None), ('partial repair probe: cue ordering check', ['100:59:09.500 --> 100:59:09.500 align:start'], None), ('partial repair variant: cue ordering check', ['01:59:59.999 --> 01:59:59.999'], None), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('normal control', ['01:5:60.500 --> 00:00.001 size:50% align:end'], None), ('normal control', ['100:00:59.000 --> 00:02.000 size:50% align:end'], None), ('normal control', ['59:59.5 -> 00:5:59.999'], 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: cue ordering check | [1000, 1000, ''] | None | Failed |
| regression variant: cue ordering check | [60500, 60500, ''] | None | Failed |
| partial repair probe: cue ordering check | [69500, 69500, ''] | None | Failed |
| partial repair variant: cue ordering check | [363599999, 363599999, 'align:start'] | None | Failed |
| boundary control | [1000, 2000, ''] | [1000, 2000, ''] | Passed |
| boundary control | [360000000, 360001000, 'align:start'] | [360000000, 360001000, 'align:start'] | Passed |
| normal control | [59999, 60000, 'line:0 size:50%'] | [59999, 60000, 'line:0 size:50%'] | Passed |
| normal control | None | None | Passed |
| normal control | None | None | Passed |
SHA-256 / a4ec6581f9e35b30941c982abcbb8ad49208dafbb875b99c2b2ef7e0f61b8716
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import re
N = 1
observations = []
def solve(line):
parts=line.split()
if len(parts)<3 or parts[1]!='-->':
return None
def ts(x):
m=re.fullmatch(r'(?:(\d{2,}):)?(\d{2}):(\d{2})\.(\d{3})',x)
if not m:
return None
h,mi,se,f=m.groups()
if int(mi)>59 or int(se)>59:
return None
return int(h or 0)*3600000+int(mi)*60000+int(se)*1000+int(f)
a=ts(parts[0]); b=ts(parts[2])
if a is None or b is None or b<=a:
return None
return [a,b,' '.join(parts[3:])]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: cue ordering check', ['00:01.000 --> 00:01.000'], None), ('regression variant: cue ordering check', ['01:00.500 --> 01:00.500'], None), ('partial repair probe: cue ordering check', ['01:09.500 --> 01:09.500'], None), ('partial repair variant: cue ordering check', ['100:59:59.999 --> 100:59:59.999 align:start'], None), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('normal control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('normal control', ['59:09.5 --> 00:02.000 align:start'], None), ('normal control', ['100:01:60,500 --> 00:00:60.5 align:start'], None)], [('regression: cue ordering check', ['100:59:09.000 --> 100:59:09.000'], None), ('regression variant: cue ordering check', ['100:59:09.500 --> 100:59:09.500 align:start'], None), ('partial repair probe: cue ordering check', ['00:00:09.000 --> 00:00:09.000'], None), ('partial repair variant: cue ordering check', ['00:59.000 --> 00:59.000 line:0 position:10%'], None), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('normal control', ['00:5:00.000 -> 00:5:00.000'], None), ('normal control', ['01:01:09.5 --> 60:09.5 size:50% align:end'], None), ('normal control', ['01:60:59.999 --> 00:00.001 line:0 position:10%'], None)], [('regression: cue ordering check', ['01:09.500 --> 01:09.500'], None), ('regression variant: cue ordering check', ['01:59:00.500 --> 01:59:00.500 size:50% align:end'], None), ('partial repair probe: cue ordering check', ['01:59:59.500 --> 01:59:59.500 size:50% align:end'], None), ('partial repair variant: cue ordering check', ['00:01:00.000 --> 00:01:00.000'], None), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('normal control', ['01:60:00.500 --> 5:60,500 line:0 position:10%'], None), ('normal control', ['100:01:00,500 --> 01:00:00.000 align:start'], None), ('normal control', ['60:59.500 --> 100:00:00.000'], None)], [('regression: cue ordering check', ['00:00:09.000 --> 00:00:09.000'], None), ('regression variant: cue ordering check', ['100:59:00.000 --> 100:59:00.000 size:50% align:end'], None), ('partial repair probe: cue ordering check', ['01:00.500 --> 01:00.500'], None), ('partial repair variant: cue ordering check', ['00:59:00.999 --> 00:59:00.999 size:50% align:end'], None), ('boundary control', ['00:01.000 --> 00:02.000'], [1000, 2000, '']), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('normal control', ['60:60.999 --> 00:00.001'], None), ('normal control', ['01:59:59,500 --> 01:59:59,500 size:50% align:end'], None), ('normal control', ['59:60.5 --> 100:00:00.000 line:0 position:10%'], None)], [('regression: cue ordering check', ['01:59:59.500 --> 01:59:59.500 size:50% align:end'], None), ('regression variant: cue ordering check', ['100:59:59.999 --> 100:59:59.999 align:start'], None), ('partial repair probe: cue ordering check', ['100:59:09.500 --> 100:59:09.500 align:start'], None), ('partial repair variant: cue ordering check', ['01:59:59.999 --> 01:59:59.999'], None), ('boundary control', ['100:00:00.000 --> 100:00:01.000 align:start'], [360000000, 360001000, 'align:start']), ('boundary control', ['00:59.999 --> 01:00.000 line:0 size:50%'], [59999, 60000, 'line:0 size:50%']), ('normal control', ['01:5:60.500 --> 00:00.001 size:50% align:end'], None), ('normal control', ['100:00:59.000 --> 00:02.000 size:50% align:end'], None), ('normal control', ['59:59.5 -> 00:5:59.999'], 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: cue ordering check | None | None | Passed |
| regression variant: cue ordering check | None | None | Passed |
| partial repair probe: cue ordering check | None | None | Passed |
| partial repair variant: cue ordering check | None | None | Passed |
| boundary control | [1000, 2000, ''] | [1000, 2000, ''] | Passed |
| boundary control | [360000000, 360001000, 'align:start'] | [360000000, 360001000, 'align:start'] | Passed |
| normal control | [59999, 60000, 'line:0 size:50%'] | [59999, 60000, 'line:0 size:50%'] | Passed |
| normal control | None | None | Passed |
| normal control | None | None | Passed |
SHA-256 / 38cf253039aaff0cc9f8066ad812dc02d5d2477d16a8568e1e8c71cf319758f1
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:32.746351+00:00.
Case digest / 6954345eb7421ce66492a8ae6eb535d1a7bb2f63d9539f816ae622196a325777