Resume from checkpoint on long runs #16
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Mark/whisper-transcribe#16
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Lex 3.4h took 60s. But what about a 10h file? If the run crashes at hour 7, we don't want to re-transcribe hours 0-7.
What needs building:
transcribe.state.json) listing which chunks are done--resumeflag (default ON if state file exists)--freshto ignore and restart)Tied to: issue #8 (long-file streaming). Both should land together.
Schema spec for
transcribe.state.jsonlanded indocs/state-file.mdon branchdocs/state-file-schema(commit217cb08). Branch is local-only; push + PR are the review checkpoint.The spec covers:
statusstate machine (pending→in_progress→done/failed),started_at/completed_at,output_json_path, andsegment_count/word_countdiagnostics.os.fsyncandos.replace, same-filesystem temp viatempfile.mkstemp(dir=target.parent), plus per-chunk JSON dump order (chunk JSON first, state rewrite second) so a crash mid-run never leaves a half-written state file.--stale-hours, default 24;in_progresschunk older than 2h is reset topendingand retried).--resume/--no-resume(auto-default by state-file presence),--fresh,--stale-hours,--workdir.Field list is stable enough to build against without further design changes; changes after acceptance require bumping
schema_versionwith a migration note.Additive scope filed as #19 (Stale-state cleanup + 7-day threshold + smoke tests) — please absorb into this PR if the Plan phase has not yet finalized, or land as a follow-up if it has.
Additions over the current spec at docs/state-file.md (commit
217cb08):--stale-hoursdefault changes from 24h -> 168h (7 days). Update §5.4 + §6 in the spec doc, and the CLI default.--freshgate, NOT a hardStaleStateErrorreject. Refactorvalidate_state()to either return a result object or raise a distinctSourceMtimeChangedWarning. Spec §5.1/§5.2 needs to match.--clean-staleflag with--dry-run/--yes/--workdirsemantics (full spec in #19 §3).tests/test_resume.pycovering 4 scenarios (interrupted run, resume, modified source, --fresh) — full spec in #19 §4.The four scenarios in (4) line up exactly with the kanban task t_e5ac8155 acceptance criteria, so the test file doubles as the verification artifact for the parent decomposer (t_d5c5d159).
If this lands in the same PR as #16, the PR description should reference both #16 and #19. If it lands as a follow-up PR, base off the #16 PR branch, not main.
Integration summary: #16 resume x #8 long-file streaming
Post-merge composition audit of the two features, requested by kanban card
t_02afa75b(fixit board). Both landed onmain: #8 ase2d1647/d43a782/418c100, #16 as217cb08(spec) +b95dfe3(impl), plus #19 as8b2f2afe5d(stale-state cleanup). Audited atorigin/main4a0b976with a clean tree andruff check src testsclean.Where the two features join
The composition point is
cli._run_transcription:The join key is the chunk index:
ChunkRange.indexfrom #8's planner againstChunkRecord["index"]in #16's state file, guarded by thechunk_secondsequality check instate.validate_state(state.py:396).Chunk-index stability: verified
chunking.plan_chunks(duration_sec, chunk_minutes)is a pure function of its two arguments — no wall clock, norandom, no ordering dependence. Empirically:plan_chunks(10h, 30min)-> 20 chunks, identical across repeated calls.start_sec=25200.0,end_sec=27000.0).ffprobeduration jitter (a real cross-version risk) shifts only the final chunk'send_sec; every non-final(index, start_sec)pair stays byte-identical, so a resume after a duration re-probe still joins correctly on index.--chunk-minutesbetween runs — is already hard-rejected aschunk_seconds mismatchrather than silently mis-joined. Correct behaviour.No change needed for index stability.
Three gaps -> #21
--state-file PATHoverride. Only--workdir DIRexists; the filename is the fixedSTATE_FILENAMEconstant. Not a one-line addition, sincestate.pyderives every path from a workdir today (state_path,chunk_json_path,cleanup_state,find_stale_state_workspaces).cli._resolve_workdir), which §1 ofdocs/state-file.mdmandates on purpose so--outcan move without invalidating resume. Recommendation on #21: keep the shipped default (resume correctness is the whole point of #16) and let--state-filecover the read-only-source-dir case. Flipping it is a behaviour change for existing state files, so it wants an explicit decision.tests/test_resume.py:614 test_resume_picks_up_after_interrupthas the right shape at the wrong scale (2h / 4 chunks / crash on chunk 3), asserts uniqueness but not contiguity, and never exercisesaudio_stream.decode_chunkjointly with the resume loop.All three are tracked on #21 with per-item acceptance criteria. Cross-linked from #8.