FA-78221 / Subtitle cue timing / Open access
Karaoke syllable timing: centisecond unit · case 01
Karaoke highlighting races through the line ten times too fast.
ROOT CAUSE
Tag durations are read as milliseconds instead of centiseconds.
VERIFIED REPAIR
Multiply centiseconds by 10.
Unsuccessful approach: Multiplying by 100 treats the durations as deciseconds.
Case contract
Karaoke text is a sequence of {\k|\K|\kf|\ko<cs>}syllable with durations in centiseconds. Syllable i starts at cue start plus the sum of all previous durations (empty syllables still consume time). Syllables starting at or after the cue end are dropped; others are clipped to the cue end. Output [syllable,start_ms,end_ms].
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(cue, text):
cs,ce=cue
out=[]
t=cs
for m in re.finditer(r'\{\\(kf|ko|k|K)(\d+)\}([^{]*)',text):
d=int(m.group(2))
syl=m.group(3)
if syl and t<ce:
out.append([syl,t,min(t+d,ce)])
t+=d
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: centisecond unit', [[0, 1000], '{\\k50}Hel{\\k50}lo'], [['Hel', 0, 500], ['lo', 500, 1000]]), ('regression variant: centisecond unit', [[0, 2000], '{\\K25}la{\\ko25}Hel{\\K0}Hel{\\ko25}'], [['la', 0, 250], ['Hel', 250, 500], ['Hel', 500, 500]]), ('partial repair probe: centisecond unit', [[1000, 1500], '{\\kf10} {\\k10}la'], [[' ', 1000, 1100], ['la', 1100, 1200]]), ('partial repair variant: centisecond unit', [[0, 800], '{\\k0}lo{\\ko50}la{\\kf30}lo'], [['lo', 0, 0], ['la', 0, 500], ['lo', 500, 800]]), ('normal control', [[0, 300], '{\\k10}'], []), ('normal control', [[1000, 1100], '{\\K0}lo'], [['lo', 1000, 1000]]), ('normal control', [[1000, 1500], '{\\kf0}'], [])], [('regression: centisecond unit', [[0, 300], '{\\k20}a{\\kf20}b'], [['a', 0, 200], ['b', 200, 300]]), ('regression variant: centisecond unit', [[1000, 1800], '{\\ko50}{\\kf25}{\\k50} '], [[' ', 1750, 1800]]), ('partial repair probe: centisecond unit', [[0, 2000], '{\\K25}la{\\ko25}Hel{\\K0}Hel{\\ko25}'], [['la', 0, 250], ['Hel', 250, 500], ['Hel', 500, 500]]), ('partial repair variant: centisecond unit', [[1000, 1100], '{\\k5}Hel{\\k5}la'], [['Hel', 1000, 1050], ['la', 1050, 1100]]), ('normal control', [[1000, 1100], '{\\ko30}'], []), ('normal control', [[1000, 3000], '{\\ko5}'], []), ('normal control', [[0, 500], '{\\kf5}'], [])], [('regression: centisecond unit', [[0, 200], '{\\k20}a{\\k10}{\\k5}b'], [['a', 0, 200]]), ('regression variant: centisecond unit', [[1000, 3000], '{\\kf50}{\\k25}Hel'], [['Hel', 1500, 1750]]), ('partial repair probe: centisecond unit', [[1000, 1800], '{\\ko50}{\\kf25}{\\k50} '], [[' ', 1750, 1800]]), ('partial repair variant: centisecond unit', [[0, 800], '{\\kf25}o '], [['o ', 0, 250]]), ('normal control', [[0, 100], '{\\k5}'], []), ('normal control', [[1000, 1100], '{\\K5}'], []), ('normal control', [[0, 100], '{\\k5}{\\K25}'], [])], [('regression: centisecond unit', [[0, 100], '{\\ko10}x{\\k1}y'], [['x', 0, 100]]), ('regression variant: centisecond unit', [[0, 300], '{\\k10}la{\\k5}la{\\k50}lo{\\ko25}lo'], [['la', 0, 100], ['la', 100, 150], ['lo', 150, 300]]), ('partial repair probe: centisecond unit', [[1000, 3000], '{\\kf50}{\\k25}Hel'], [['Hel', 1500, 1750]]), ('partial repair variant: centisecond unit', [[1000, 1500], '{\\k30}lo{\\k5} {\\k0}'], [['lo', 1000, 1300], [' ', 1300, 1350]]), ('normal control', [[1000, 1300], '{\\K0}o '], [['o ', 1000, 1000]]), ('normal control', [[0, 2000], '{\\kf0}la{\\k5}'], [['la', 0, 0]]), ('normal control', [[1000, 1100], '{\\ko5}'], [])], [('regression: centisecond unit', [[1000, 1500], '{\\kf10} {\\k10}la'], [[' ', 1000, 1100], ['la', 1100, 1200]]), ('regression variant: centisecond unit', [[1000, 1500], '{\\ko5} {\\ko25}{\\k5}o {\\k0} '], [[' ', 1000, 1050], ['o ', 1300, 1350], [' ', 1350, 1350]]), ('partial repair probe: centisecond unit', [[0, 300], '{\\k10}la{\\k5}la{\\k50}lo{\\ko25}lo'], [['la', 0, 100], ['la', 100, 150], ['lo', 150, 300]]), ('partial repair variant: centisecond unit', [[0, 500], '{\\ko30}Hel{\\K5}Hel{\\k50}lo{\\K30}{\\k30}lo'], [['Hel', 0, 300], ['Hel', 300, 350], ['lo', 350, 500]]), ('normal control', [[1000, 1800], '{\\k50}'], []), ('normal control', [[1000, 1100], '{\\k0}lo'], [['lo', 1000, 1000]]), ('normal control', [[0, 300], '{\\ko30}'], [])]]
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: centisecond unit | [['Hel', 0, 50], ['lo', 50, 100]] | [['Hel', 0, 500], ['lo', 500, 1000]] | Failed |
| regression variant: centisecond unit | [['la', 0, 25], ['Hel', 25, 50], ['Hel', 50, 50]] | [['la', 0, 250], ['Hel', 250, 500], ['Hel', 500, 500]] | Failed |
| partial repair probe: centisecond unit | [[' ', 1000, 1010], ['la', 1010, 1020]] | [[' ', 1000, 1100], ['la', 1100, 1200]] | Failed |
| partial repair variant: centisecond unit | [['lo', 0, 0], ['la', 0, 50], ['lo', 50, 80]] | [['lo', 0, 0], ['la', 0, 500], ['lo', 500, 800]] | Failed |
| normal control | [] | [] | Passed |
| normal control | [['lo', 1000, 1000]] | [['lo', 1000, 1000]] | Passed |
| normal control | [] | [] | Passed |
SHA-256 / 7f1b58c186e5473f86fc8377379e8bd0a7450577644598334115d362a98cc157
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import re
N = 1
observations = []
def solve(cue, text):
cs,ce=cue
out=[]
t=cs
for m in re.finditer(r'\{\\(kf|ko|k|K)(\d+)\}([^{]*)',text):
d=int(m.group(2))*100
syl=m.group(3)
if syl and t<ce:
out.append([syl,t,min(t+d,ce)])
t+=d
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: centisecond unit', [[0, 1000], '{\\k50}Hel{\\k50}lo'], [['Hel', 0, 500], ['lo', 500, 1000]]), ('regression variant: centisecond unit', [[0, 2000], '{\\K25}la{\\ko25}Hel{\\K0}Hel{\\ko25}'], [['la', 0, 250], ['Hel', 250, 500], ['Hel', 500, 500]]), ('partial repair probe: centisecond unit', [[1000, 1500], '{\\kf10} {\\k10}la'], [[' ', 1000, 1100], ['la', 1100, 1200]]), ('partial repair variant: centisecond unit', [[0, 800], '{\\k0}lo{\\ko50}la{\\kf30}lo'], [['lo', 0, 0], ['la', 0, 500], ['lo', 500, 800]]), ('normal control', [[0, 300], '{\\k10}'], []), ('normal control', [[1000, 1100], '{\\K0}lo'], [['lo', 1000, 1000]]), ('normal control', [[1000, 1500], '{\\kf0}'], [])], [('regression: centisecond unit', [[0, 300], '{\\k20}a{\\kf20}b'], [['a', 0, 200], ['b', 200, 300]]), ('regression variant: centisecond unit', [[1000, 1800], '{\\ko50}{\\kf25}{\\k50} '], [[' ', 1750, 1800]]), ('partial repair probe: centisecond unit', [[0, 2000], '{\\K25}la{\\ko25}Hel{\\K0}Hel{\\ko25}'], [['la', 0, 250], ['Hel', 250, 500], ['Hel', 500, 500]]), ('partial repair variant: centisecond unit', [[1000, 1100], '{\\k5}Hel{\\k5}la'], [['Hel', 1000, 1050], ['la', 1050, 1100]]), ('normal control', [[1000, 1100], '{\\ko30}'], []), ('normal control', [[1000, 3000], '{\\ko5}'], []), ('normal control', [[0, 500], '{\\kf5}'], [])], [('regression: centisecond unit', [[0, 200], '{\\k20}a{\\k10}{\\k5}b'], [['a', 0, 200]]), ('regression variant: centisecond unit', [[1000, 3000], '{\\kf50}{\\k25}Hel'], [['Hel', 1500, 1750]]), ('partial repair probe: centisecond unit', [[1000, 1800], '{\\ko50}{\\kf25}{\\k50} '], [[' ', 1750, 1800]]), ('partial repair variant: centisecond unit', [[0, 800], '{\\kf25}o '], [['o ', 0, 250]]), ('normal control', [[0, 100], '{\\k5}'], []), ('normal control', [[1000, 1100], '{\\K5}'], []), ('normal control', [[0, 100], '{\\k5}{\\K25}'], [])], [('regression: centisecond unit', [[0, 100], '{\\ko10}x{\\k1}y'], [['x', 0, 100]]), ('regression variant: centisecond unit', [[0, 300], '{\\k10}la{\\k5}la{\\k50}lo{\\ko25}lo'], [['la', 0, 100], ['la', 100, 150], ['lo', 150, 300]]), ('partial repair probe: centisecond unit', [[1000, 3000], '{\\kf50}{\\k25}Hel'], [['Hel', 1500, 1750]]), ('partial repair variant: centisecond unit', [[1000, 1500], '{\\k30}lo{\\k5} {\\k0}'], [['lo', 1000, 1300], [' ', 1300, 1350]]), ('normal control', [[1000, 1300], '{\\K0}o '], [['o ', 1000, 1000]]), ('normal control', [[0, 2000], '{\\kf0}la{\\k5}'], [['la', 0, 0]]), ('normal control', [[1000, 1100], '{\\ko5}'], [])], [('regression: centisecond unit', [[1000, 1500], '{\\kf10} {\\k10}la'], [[' ', 1000, 1100], ['la', 1100, 1200]]), ('regression variant: centisecond unit', [[1000, 1500], '{\\ko5} {\\ko25}{\\k5}o {\\k0} '], [[' ', 1000, 1050], ['o ', 1300, 1350], [' ', 1350, 1350]]), ('partial repair probe: centisecond unit', [[0, 300], '{\\k10}la{\\k5}la{\\k50}lo{\\ko25}lo'], [['la', 0, 100], ['la', 100, 150], ['lo', 150, 300]]), ('partial repair variant: centisecond unit', [[0, 500], '{\\ko30}Hel{\\K5}Hel{\\k50}lo{\\K30}{\\k30}lo'], [['Hel', 0, 300], ['Hel', 300, 350], ['lo', 350, 500]]), ('normal control', [[1000, 1800], '{\\k50}'], []), ('normal control', [[1000, 1100], '{\\k0}lo'], [['lo', 1000, 1000]]), ('normal control', [[0, 300], '{\\ko30}'], [])]]
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: centisecond unit | [['Hel', 0, 1000]] | [['Hel', 0, 500], ['lo', 500, 1000]] | Failed |
| regression variant: centisecond unit | [['la', 0, 2000]] | [['la', 0, 250], ['Hel', 250, 500], ['Hel', 500, 500]] | Failed |
| partial repair probe: centisecond unit | [[' ', 1000, 1500]] | [[' ', 1000, 1100], ['la', 1100, 1200]] | Failed |
| partial repair variant: centisecond unit | [['lo', 0, 0], ['la', 0, 800]] | [['lo', 0, 0], ['la', 0, 500], ['lo', 500, 800]] | Failed |
| normal control | [] | [] | Passed |
| normal control | [['lo', 1000, 1000]] | [['lo', 1000, 1000]] | Passed |
| normal control | [] | [] | Passed |
SHA-256 / f7c2234e4d59a4864d3df8283c2b8b5964d394f5f72c40b30315610bbf664145
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import re
N = 1
observations = []
def solve(cue, text):
cs,ce=cue
out=[]
t=cs
for m in re.finditer(r'\{\\(kf|ko|k|K)(\d+)\}([^{]*)',text):
d=int(m.group(2))*10
syl=m.group(3)
if syl and t<ce:
out.append([syl,t,min(t+d,ce)])
t+=d
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: centisecond unit', [[0, 1000], '{\\k50}Hel{\\k50}lo'], [['Hel', 0, 500], ['lo', 500, 1000]]), ('regression variant: centisecond unit', [[0, 2000], '{\\K25}la{\\ko25}Hel{\\K0}Hel{\\ko25}'], [['la', 0, 250], ['Hel', 250, 500], ['Hel', 500, 500]]), ('partial repair probe: centisecond unit', [[1000, 1500], '{\\kf10} {\\k10}la'], [[' ', 1000, 1100], ['la', 1100, 1200]]), ('partial repair variant: centisecond unit', [[0, 800], '{\\k0}lo{\\ko50}la{\\kf30}lo'], [['lo', 0, 0], ['la', 0, 500], ['lo', 500, 800]]), ('normal control', [[0, 300], '{\\k10}'], []), ('normal control', [[1000, 1100], '{\\K0}lo'], [['lo', 1000, 1000]]), ('normal control', [[1000, 1500], '{\\kf0}'], [])], [('regression: centisecond unit', [[0, 300], '{\\k20}a{\\kf20}b'], [['a', 0, 200], ['b', 200, 300]]), ('regression variant: centisecond unit', [[1000, 1800], '{\\ko50}{\\kf25}{\\k50} '], [[' ', 1750, 1800]]), ('partial repair probe: centisecond unit', [[0, 2000], '{\\K25}la{\\ko25}Hel{\\K0}Hel{\\ko25}'], [['la', 0, 250], ['Hel', 250, 500], ['Hel', 500, 500]]), ('partial repair variant: centisecond unit', [[1000, 1100], '{\\k5}Hel{\\k5}la'], [['Hel', 1000, 1050], ['la', 1050, 1100]]), ('normal control', [[1000, 1100], '{\\ko30}'], []), ('normal control', [[1000, 3000], '{\\ko5}'], []), ('normal control', [[0, 500], '{\\kf5}'], [])], [('regression: centisecond unit', [[0, 200], '{\\k20}a{\\k10}{\\k5}b'], [['a', 0, 200]]), ('regression variant: centisecond unit', [[1000, 3000], '{\\kf50}{\\k25}Hel'], [['Hel', 1500, 1750]]), ('partial repair probe: centisecond unit', [[1000, 1800], '{\\ko50}{\\kf25}{\\k50} '], [[' ', 1750, 1800]]), ('partial repair variant: centisecond unit', [[0, 800], '{\\kf25}o '], [['o ', 0, 250]]), ('normal control', [[0, 100], '{\\k5}'], []), ('normal control', [[1000, 1100], '{\\K5}'], []), ('normal control', [[0, 100], '{\\k5}{\\K25}'], [])], [('regression: centisecond unit', [[0, 100], '{\\ko10}x{\\k1}y'], [['x', 0, 100]]), ('regression variant: centisecond unit', [[0, 300], '{\\k10}la{\\k5}la{\\k50}lo{\\ko25}lo'], [['la', 0, 100], ['la', 100, 150], ['lo', 150, 300]]), ('partial repair probe: centisecond unit', [[1000, 3000], '{\\kf50}{\\k25}Hel'], [['Hel', 1500, 1750]]), ('partial repair variant: centisecond unit', [[1000, 1500], '{\\k30}lo{\\k5} {\\k0}'], [['lo', 1000, 1300], [' ', 1300, 1350]]), ('normal control', [[1000, 1300], '{\\K0}o '], [['o ', 1000, 1000]]), ('normal control', [[0, 2000], '{\\kf0}la{\\k5}'], [['la', 0, 0]]), ('normal control', [[1000, 1100], '{\\ko5}'], [])], [('regression: centisecond unit', [[1000, 1500], '{\\kf10} {\\k10}la'], [[' ', 1000, 1100], ['la', 1100, 1200]]), ('regression variant: centisecond unit', [[1000, 1500], '{\\ko5} {\\ko25}{\\k5}o {\\k0} '], [[' ', 1000, 1050], ['o ', 1300, 1350], [' ', 1350, 1350]]), ('partial repair probe: centisecond unit', [[0, 300], '{\\k10}la{\\k5}la{\\k50}lo{\\ko25}lo'], [['la', 0, 100], ['la', 100, 150], ['lo', 150, 300]]), ('partial repair variant: centisecond unit', [[0, 500], '{\\ko30}Hel{\\K5}Hel{\\k50}lo{\\K30}{\\k30}lo'], [['Hel', 0, 300], ['Hel', 300, 350], ['lo', 350, 500]]), ('normal control', [[1000, 1800], '{\\k50}'], []), ('normal control', [[1000, 1100], '{\\k0}lo'], [['lo', 1000, 1000]]), ('normal control', [[0, 300], '{\\ko30}'], [])]]
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: centisecond unit | [['Hel', 0, 500], ['lo', 500, 1000]] | [['Hel', 0, 500], ['lo', 500, 1000]] | Passed |
| regression variant: centisecond unit | [['la', 0, 250], ['Hel', 250, 500], ['Hel', 500, 500]] | [['la', 0, 250], ['Hel', 250, 500], ['Hel', 500, 500]] | Passed |
| partial repair probe: centisecond unit | [[' ', 1000, 1100], ['la', 1100, 1200]] | [[' ', 1000, 1100], ['la', 1100, 1200]] | Passed |
| partial repair variant: centisecond unit | [['lo', 0, 0], ['la', 0, 500], ['lo', 500, 800]] | [['lo', 0, 0], ['la', 0, 500], ['lo', 500, 800]] | Passed |
| normal control | [] | [] | Passed |
| normal control | [['lo', 1000, 1000]] | [['lo', 1000, 1000]] | Passed |
| normal control | [] | [] | Passed |
SHA-256 / 87440833a9d1bbe60b6219a9c44913ed8fb33c4b034ce42c95440838039a9747
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.334380+00:00.
Case digest / 8130dfebb166a9416d3111ab9a7f56694dbbf91fdd8e66ed4dee36a5048c1201