- Зачем:
- шаг 5 плана: нужен рабочий CLI-happy path, связывающий utils / transcriber / formatter.
- ревью этапов 4–5 выявило два medium-бага в formatter и отсутствие тестов для CLI.
- Что:
- cli.py: все опции по PRD 3.2 (--model, --language, --output, --device, --compute-type, --verbose),
rich Status + stderr-консоль, предупреждение на пустую речь, статистика времени.
- transcriber.py: добавлена ensure_model_available() с проверкой кэша HF и валидацией
локальной директории; on_status callback для передачи прогресса в CLI; обработка
ImportError при отсутствии socksio через SOCKS proxy.
- formatter.py: исправлен overflow в format_timestamp (0.995 → 00:01.00 вместо 00:00.100);
сегменты теперь пишутся с явным пробелом и strip() независимо от whisper-формата текста.
- deps: добавлен socksio>=1.0.0 для поддержки SOCKS proxy при загрузке модели.
- tests: test_cli.py (8 тестов на CLI-контракт), расширены test_formatter.py и test_transcriber.py.
- Проверка:
- uv run pytest — 42 passed.
- uv run transcribe --help показывает все опции.
4.4 KiB
Review: Stages 4-5
Executive Summary
| Severity | Count |
|---|---|
| CRITICAL | 0 |
| HIGH | 0 |
| MEDIUM | 2 |
| LOW | 1 |
Overall Risk: MEDIUM Recommendation: CONDITIONAL
Key Metrics:
- Files analyzed: 4
- Verified commands:
pytest, CLI help, mocked CLI happy path - Test coverage gaps: 1 user-facing module (
cli.py) - High blast radius changes: 0
- Security regressions detected: 0
What Changed
Commit Range: dfc5f46..WORKTREE
Commits: 0d1a734, plus uncommitted step 5 changes
| File | Risk | Notes |
|---|---|---|
src/local_transcriber/formatter.py |
MEDIUM | Output contract and markdown formatting |
tests/test_formatter.py |
LOW | Unit coverage for formatter |
src/local_transcriber/cli.py |
MEDIUM | Main user-facing flow and file writing |
docs/plan.md |
LOW | Checkbox updates for step 5 |
Findings
MEDIUM: format_timestamp() can emit invalid centiseconds like .100
File: src/local_transcriber/formatter.py:7
Test Coverage: NO
The implementation rounds centiseconds independently from the integral seconds:
total_seconds = int(seconds)
centiseconds = int(round((seconds - total_seconds) * 100))
For values such as 0.995, this produces 00:00.100 instead of carrying into the next second.
Reproduction:
format_timestamp(0.995)returns00:00.100
Impact:
- Breaks the PRD timestamp format contract (
SS.ssmust always have exactly two fractional digits) - Can produce malformed transcript timestamps on real segment boundaries
Recommendation:
- Round the full timestamp first and then split into components, or normalize
centiseconds == 100by incrementing seconds - Add a regression test for
0.995
MEDIUM: Transcript formatting depends on segment text already containing a leading space
File: src/local_transcriber/formatter.py:62
Test Coverage: PARTIAL
Segment lines are written as:
f"[{start} - {end}]{seg.text}"
This only matches the PRD format if seg.text already starts with a space. The current tests mask that dependency by building fixtures with leading spaces.
Reproduction:
- A mocked CLI run with a segment text of
"Hello"writes:[00:00.00 - 00:01.00]Hello
- Expected:
[00:00.00 - 00:01.00] Hello
Impact:
- Output format becomes model-dependent instead of being guaranteed by the formatter
- Any future normalization in
transcriber.pywill immediately break transcript formatting
Recommendation:
- Normalize segment text inside the formatter, e.g.
seg.text.strip()plus an explicit single space after] - Add a test case where segment text has no leading whitespace
LOW: Step 5 has no automated tests for the public CLI contract
File: src/local_transcriber/cli.py:16
Test Coverage: NO
The user-facing entrypoint is now wired end to end, but there is still no test_cli.py coverage for:
- option parsing
- warning path for empty speech
- default output-path generation
- exit-code behavior on failure
This already matters because the mocked CLI happy path is what exposed the missing-space formatting bug above.
Test Coverage Analysis
Executed checks:
uv run pytest-> 22 tests passed.venv/bin/transcribe --help-> works- mocked
CliRunnerhappy path -> exit code 0 and output file written
Coverage gaps:
| Area | Gap | Risk |
|---|---|---|
formatter.py |
No edge-case test for centisecond carry | MEDIUM |
formatter.py |
No test for segment text without leading whitespace | MEDIUM |
cli.py |
No automated tests at all | LOW |
Blast Radius Analysis
The blast radius is still low because this is a small CLI project, but cli.py is now the single public entrypoint. Any formatting or wiring defect directly affects all users.
| Function | Exposure | Risk | Priority |
|---|---|---|---|
main() |
All CLI invocations | MEDIUM | P1 |
format_transcript() |
All saved transcript files | MEDIUM | P1 |
format_timestamp() |
Every segment line | MEDIUM | P1 |
Recommendations
Immediate
- Fix centisecond carry handling in
format_timestamp() - Stop relying on leading whitespace in
seg.text - Add formatter regression tests for both cases
Before Step 6
- Add
tests/test_cli.pywith a mocked happy path and one error path - Assert output file contents through the CLI layer, not only through direct formatter calls