FAILURE MAP
← Case archive

FA-78221 / Subtitle cue timing / Open access

Karaoke syllable timing: centisecond unit · case 01

Karaoke highlighting races through the line ten times too fast.

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

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 fixtureActualExpectedOutcome
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 fixtureActualExpectedOutcome
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 fixtureActualExpectedOutcome
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