-
v1.2.0 — Resume & Recovery Stable
released this
2026-05-24 14:26:46 +00:00 | 93 commits to main since this releaseResume & Recovery
Pipeline failures used to be terminal: every botched run had to be re-started from scratch (re-extracting frames, re-running COLMAP) and the user had to remember to swap the matcher by hand. v1.2.0 makes the pipeline self-healing — a partial capture can pick up where it died, the WebUI exposes a Resume button, and a low-camera SfM result auto-retries with the exhaustive matcher even after a process crash.
Added
- Adaptive matcher retry in CLI + WebUI — the watcher daemon's Phase-3 retry mechanism (
QualityGateFailure → retry_hint → swap matcher) was only wired into the long-runningwatchdaemon.autosplat processand the WebUI'sJobRunnernow share it via a new in-processrun_pipeline_with_adaptive_retrywrapper. A 180° drone turn that breaks the sequential matcher with 3/244 cameras self-rescues with exhaustive, frames intact. autosplat resume <capture_dir>CLI command — continues a previous capture from on-disk state.detect_completed_stagesinspectsframes/,colmap/sparse/0/,training/*.ply,output/scene.plyand computes the skip-set;read_source_video_from_logscrapes the original video path frompipeline.log(no new manifest file — works for every existing capture). Newcapture_dir_overrideparameter onrun_pipelineso the resumed run keeps its original date-stamped directory instead of forking<today>_<stem>.- WebUI Resume button — failed captures show a Resume button (replacing the broken-for-real-captures Retry that routed through
/process).POST /captures/{id}/resumecalls a newJobRunner.start_resume_jobthat spins up a worker thread runningresume_capture(...). Shares the existing cancellation/persistence/runs.jsonl path. - New-capture run-start flow (V12-1) — the dashboard's "New capture" button now actually starts a pipeline run from a video path (it previously linked back to the captures list).
GET/POST /captures/newwith path validation (.mp4/.mov/.m4v, file-exists check). - Persistent job history via
runs.jsonl(V12-2) — the JobRunner appends one record per finalized job to<captures_dir>/<id>/runs.jsonl(status, start/finish timestamps, error). On startup,load_history()rehydrates the in-memory history so a WebUI restart no longer wipes the "Recent jobs" view. Append-only, crash-safe. - Responsive WebUI layout + mobile sidebar (V12-3) — three breakpoints (Desktop ≥1024 px / Tablet ≤1023 px / Mobile ≤767 px). Sidebar narrows then slides off-canvas; stat-tiles collapse 4→2 columns; hamburger button toggles
.mobile-sidebar-openon body with tap-to-close backdrop; tables scroll horizontally on mobile. - URL-param developer mode (V12-4) — reactivates the latent aspect subthemes (
?aspect=shugo|gunshi|kantoku|sensei) and the HTMX-annot debug overlay (?dev=1) without adding a settings UI. Both persist in localStorage; URL-params set/clear them.
Fixed
- Quality gate runs on resumed SfM — resuming a capture whose previous SfM stage produced a bad sparse model (e.g. only 3/244 cameras) used to silently skip the quality gate and let Brush train on garbage — the gate lived inside the SfM
elsebranch.run_pipelinenow re-parsessparse/0via_parse_mapper_statswhensfmis inskip_stagesand feeds the synthesizedSfmResultintocheck_sfm_quality. The adaptive-retry wrapper also drops"sfm"fromskip_stageson retry so the matcher swap actually re-runs SfM. - Stale-job liveness reconciliation — jobs whose worker thread died mid-run (e.g. host sleep) used to hang as phantom
runningentries forever.JobRunner._reconcilenow flips them tofailedwithinterrupted — the run ended without producing a resulton the next read. - Version-source consistency —
pyproject.tomlandsrc/autosplat/__init__.pynow agree (both1.2.0).
Design Notes
- Adaptive retry vs. resume — orthogonal mechanisms. Adaptive retry (in-process) catches
QualityGateFailureduring a live pipeline and retries the next stage with the hint set; frames stay in memory. Resume (cross-process) is the answer when the process is fully gone (sleep / crash / Ctrl-C): it reads disk artifacts and the original log to reconstruct the run. - No manifest file for resume. Source video is scraped from the
pipeline.startJSON event inpipeline.log. Works for every existing capture without any migration. - Resume refuses on a complete capture. If
output/scene.plyexists,resume_captureraises immediately instead of silently redoing the whole pipeline.
Tests
246 unit tests (244 passed, 2 opt-in E2E skipped) — +40 over v1.1.2.
For the full changelog see
CHANGELOG.md.Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Adaptive matcher retry in CLI + WebUI — the watcher daemon's Phase-3 retry mechanism (