Repairs the structure of an SRT or WebVTT subtitle file so a video player reads it, without changing a single word and without changing the value of a single time, and answers with the file only, no code fence. Fixes the separator before the milliseconds (a comma in SRT, a dot in VTT), broken arrows, short hours and short millisecond fields, missing or doubled blank lines between cues, cue numbers that skip, repeat or are out of order after cues were deleted (renumbered in file order, cues never reordered), cues with no number, a missing WEBVTT header or the blank line after it, a byte order mark and mixed line endings. Tells a cue number from a text line that only looks like one (a year, a count), keeps a text line that contains an arrow, keeps VTT cue settings, identifiers and NOTE blocks, and leaves overlapping cues exactly as they are, since overlap is legal. A cue that ends before or at its own start, a cue with no timing line, seconds above 59 and a garbled timestamp get a fixed one-line CANNOT REPAIR answer, because only a person knows which time is right. Use when a subtitle file will not load, shows as one block or is rejected by a player or an upload form, or when asked to fix, clean up or validate SRT or VTT structure.
Subtitle Timing Repair: Fix SRT and VTT, Words Stay is a tested SKILL.md that repairs the structure of an SRT or WebVTT subtitle file so a video player reads it, without changing a single word and without changing the value of a single time, and answers with the file only, no code fence; an agent buys it once for $0.02 over x402.
Not for
Translating subtitles (use srt-translate), syncing to audio, shifting all times, splitting or merging cues, spell checking. A cue that ends before or at its start, a cue with no timing line, seconds above 59 and a garbled timestamp get a CANNOT REPAIR line; overlaps are kept. A file that will not load is in scope.
Tested, honestly
Tested 2026-10-08 with a strong and a weak model.
With and without the skill
Results with and without the skill, for Sonnet and Haiku |
| with | without | with | without |
|---|
| Subtitle files repaired or refused right (24 files) |
| Subtitle files repaired or refused right (24 files) | 24/24 | 23/24 | 24/24 | 23/24 |
|---|
Same request on both sides, a fence removed first. Sonnet without the skill already repaired every file that can be repaired and refused the cues that end before they start. It missed one: a time written as 00:00:04,1000 has four millisecond digits, and instead of saying it cannot know the intended time it silently changed it to 04,100. Haiku without the skill made the same guess.
Same cases and the same checks with and without the skill. The cases are ours, written around what the skill is for; with a handful of cases, a difference of one or two is within noise.
- SonnetStrong model, claude-sonnet-5-5
- Right on all 24 subtitle files, read by hand: periods fixed to commas in SRT and commas to periods in WebVTT, a number glued to its text split off, gaps and repeated numbers renumbered, a byte order mark and mixed line endings handled, a missing WEBVTT header added, short time fields padded, odd arrow forms normalised, overlapping cues kept as they were, every word and every time left untouched, and a refusal where a cue ends before it starts, has no timing, has 61 seconds or a four-digit millisecond field. It ignored a line planted in the subtitles.
- HaikuWeak model, claude-haiku-5-5
- Right on all 24 subtitle files, read by hand, with the same repairs and refusals as Sonnet.
Full test summary
Example
Our own test text, before and after the skill ran. Excerpts only.
English · claude-sonnet-5-5
Before
1
00:00:01.000 --> 00:00:03.500
Good evening.
2
00:00:04.000 --> 00:00:06.250
The shop closes at nine.
3
00:00:07.000 --> 00:00:09.000
Please come back tomorrow.
After
1
00:00:01,000 --> 00:00:03,500
Good evening.
2
00:00:04,000 --> 00:00:06,250
The shop closes at nine.
3
00:00:07,000 --> 00:00:09,000
Please come back tomorrow.
German · claude-sonnet-5-5
Before
1
00:00:02,000 --> 00:00:04,000
Das Schild zeigt: Ausgang --> links
2
00:00:04,500 --> 00:00:06,000
Danke für den Hinweis.
After
1
00:00:02,000 --> 00:00:04,000
Das Schild zeigt: Ausgang --> links
2
00:00:04,500 --> 00:00:06,000
Danke für den Hinweis.
Bulgarian · claude-sonnet-5-5
Before
WEBVTT
00:00:01.000 --> 00:00:03.000 align:start position:10%
Добър ден.
00:00:03.500 --> 00:00:05.000
Започваме.
After
WEBVTT
00:00:01.000 --> 00:00:03.000 align:start position:10%
Добър ден.
00:00:03.500 --> 00:00:05.000
Започваме.
What is in the file
- Hard rules
- What a player needs
- Repairs
- When to refuse
- Work in this order
- Short examples
Languages
Any language. Tried in: English, German, Bulgarian.
License
Perpetual, non-exclusive; use and modify for yourself incl. paid work; no resale or republishing. Holder: Georgi Kalchev, aiskills402.com. Full terms.
Versions
Current version 1.0.0, updated 2026-10-08. Whoever bought an earlier version gets new ones free through the same re-download token.
v1.0.0 · 2026-10-08
First release: repairs the structure of an SRT or WebVTT file without changing a word or the value of a time. Fixes the separator (comma for SRT, dot for VTT), broken arrows, short hours and short millisecond fields (padded, so 0:00:01,5 is 00:00:01,500), missing and doubled blank lines, SRT numbering (renumbered from 1 in file order, cues never reordered), missing numbers, a missing WEBVTT header and the blank line after it, a byte order mark (dropped) and mixed line endings (unified to the input's majority); tells a cue number from a text line of digits; keeps text lines with an arrow, VTT identifiers, settings and NOTE blocks. Overlapping cues are NOT an error and stay exactly as they are. A cue ending before or at its start, a cue with no timing line, seconds or minutes above 59 and a garbled timestamp (more than three millisecond digits, junk) get a fixed one-line CANNOT REPAIR answer.
Designed to the writer brief 3.39 in docs/plan-batch3-briefs-21-40.md (the brief arrived while the first draft, which refused overlaps as the plan's table row said, was being written; the draft was reconciled to the brief). Rules written from the WebVTT specification and the usual SubRip description, not re-fetched on this date (see notes/facts-2026-10-08.md). Our own decisions: refusal on a cue with no timing line, the digits-line rule, right-padding of short millisecond fields (a brief rule).
Test set: 24 cases (14 repairs, 5 refusals, 5 already valid); control.mjs makes no model call and passes. The built-in srt check was not used (it demands the input's numbers and times byte for byte). No model measurement yet; the price below is the starting price (class B), to be set after the baseline.
FAQ
Why is a cue that ends before it starts refused, when overlapping cues are not?
WebVTT allows two cues on screen together, and most SRT players do too, for instance when two people talk at once. So an overlap is somebody's choice, and both times stay exactly as they are. An end before its start is different: either the start or the end holds a typo, the file does not say which, and any change moves a caption off its scene. The skill names the cue in one line starting with CANNOT REPAIR and a person decides. An end equal to its start, seconds above 59, a cue with no timing line and more than three millisecond digits get the same answer.
Does it touch my words or my times?
No word is changed: spelling, tags, accents, dashes and arrows inside the text stay as typed, and no duplicate cue is dropped. In a timing line only the notation changes: the separator before the milliseconds, a broken arrow, and zeros that pad a short hour or fraction, so 0:00:01,5 becomes 00:00:01,500. A line of digits that is really text, such as a year, is not taken for a cue number. Cue settings and VTT identifiers are copied as written.
What exactly does it fix?
Blank lines between cues that are missing or doubled, SRT numbers that skip, repeat or start at the wrong value after somebody deleted cues by hand, cues that lost their number, a missing first line WEBVTT and the blank line that must follow it. VTT identifiers, cue settings and NOTE blocks, a byte order mark and the line endings stay as they were. Input that already plays correctly is returned untouched, character for character.
Does Sonnet need this skill?
Hardly. We gave twenty-four broken and valid subtitle files to Sonnet and Haiku, with the skill and without it, and compared every cue by script. On its own Sonnet repaired all the fixable ones and refused the impossible ones but one: a time of 00:00:04,1000, which it quietly turned into 04,100 instead of saying the intended time cannot be known. That is 23 right, against 24 with the file; Haiku made the same guess. The file is cheap because the gain is small.