The four sequence stages (detecting face landmarks, cropping and
aligning faces, restoring faces with KEEP, pasting faces and finalizing
frames) logged only their start line and went silent until the next
stage. StageBar (src/keep_stage_progress.py, stdlib-only) is a second,
console-only progress channel beside the V3 execution-API reporter:
- the line "{label} {done}/{total} ({pct}%) {rate} fps ETA {mm:ss}
elapsed {mm:ss}" - overall-average rate, floored percent (never 100
early), ETA from the average rate;
- carriage-return rendering on a real console (no ANSI escapes, the
[KEEP] pack tag, writes to sys.__stdout__ so the D4 console capture
is never corrupted); one complete logger line per render otherwise;
- the cadence is a 2 s time gate - O(1) per tick, no per-frame spam;
- one bar per stage per run: constructed before the chunk loop, ticks
accumulate across chunks, one finish() on the normal path (an OOM or
a cancel leaves without a final line - the exception is the report).
Hooked at nine sites across both sequence paths: detection ticks per
frame (face-less frames too), the single-face crop per affine, the
multi-face crop once per face batch (unit=faces - the per-face LMEDS
loop is opaque), restore per chunk, paste per frame iteration. The
early returns (all-NaN, zero faces) carry their stage's final line.
Gate: 552 passed, 6 skipped, 7 deselected, 0 failed (baseline 535; the
new pins live in tests/test_keep_stage_progress.py).