tasks(using-yt-tools): close 3 nice-to-have findings 🟢
* empty-cache-dir-on-failure — fixed via `common@fc400b7` (defer mkdir in transcript.py + watch.py; 2 regression tests + 1 happy-path). * warning-mojibake — fixed in same `common@fc400b7` (force_utf8_streams helper called from trio CLI entries; capsys-safe). * frames-multiline-stdout — fixed via `claude-skills@b2c1a21` (spec describes per-CLI stdout shape; existing piping contract preserved rather than rewritten). Cluster fully closed. Header _Updated_ note rewritten to reflect closure. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# Task Board
|
||||
_Updated: 2026-05-20 (using-yt-tools: 3 baseline 🟢; 3 finding fixes 🟢; skill-body-fill 🟢 [SKILL.md 0.2.0]; trigger-smoke-clean-session 🟢 [13/13]; review 🟢 by fresh-eyes subagent — Flow A/B/Failure-modes/NOT all PASS; 3 nice-to-have findings filed as ⚪ [empty-cache-dir-on-failure, frames-multiline-stdout, warning-mojibake])_
|
||||
_Updated: 2026-05-20 (using-yt-tools cluster fully closed: 3 baseline 🟢; 3 finding fixes 🟢; skill-body-fill 🟢 [SKILL.md 0.2.0]; trigger-smoke-clean-session 🟢 [13/13]; review 🟢 by fresh-eyes subagent — Flow A/B/Failure-modes/NOT all PASS; all 3 nice-to-have findings 🟢 — empty-cache-dir-on-failure & warning-mojibake fixed in `common@fc400b7` [yt-tools 0.1.5]; frames-multiline-stdout spec-fixed in `claude-skills@b2c1a21` [SKILL.md 0.2.2])_
|
||||
|
||||
<!--
|
||||
Canonical layout. One block per task. Per-task deep context lives in
|
||||
@@ -189,66 +189,42 @@ Findings → follow-up tasks (`using-yt-tools-<gap>-fix`) через `tasks_crea
|
||||
|
||||
---
|
||||
|
||||
## ⚪ [using-yt-tools-empty-cache-dir-on-failure] — `yt-transcript` создаёт `yt-cache/<vid>/` ДО фетча captions; при abort оставляет пустую папку, что противоречит Failure-modes интенту SKILL.md «никогда не оставляй полусостояние».
|
||||
## 🟢 [using-yt-tools-empty-cache-dir-on-failure] — `yt-transcript` создаёт `yt-cache/<vid>/` ДО фетча captions; при abort оставляет пустую папку, что противоречит Failure-modes интенту SKILL.md «никогда не оставляй полусостояние».
|
||||
|
||||
**Reviewer observed** на broken-URL тесте (URL=`https://www.youtube.com/watch?v=AAAAAAAAAAAA`): exit 1 + stderr clean, но пустая `yt-cache/AAAAAAAAAAAA/` остаётся на FS.
|
||||
|
||||
**Fix-направления:**
|
||||
- (a) defer mkdir до первого успешного write — проще логически, но требует review всех путей записи в `yt_tools/cache.py` + `transcript.py`;
|
||||
- (b) cleanup-on-abort через atexit / try-finally в CLI entry — точечный диф, дешевле.
|
||||
|
||||
Затем — тест на «no empty dir после abort» в `tests/test_cache.py` (или новом `test_failure_modes.py`).
|
||||
|
||||
**Severity:** nice-to-have (cosmetic, не ломает workflow).
|
||||
|
||||
**Status:** ready
|
||||
**Where I stopped:** (not started)
|
||||
**Next action:** Решить fix-стратегию (a) vs (b). Имплементировать. Добавить regression-тест.
|
||||
**Status:** done
|
||||
**Closed by:** `OpeItcLoc03/common@fc400b7` — option (a) chosen: `out_dir.mkdir(parents=True, exist_ok=True)` deferred в `transcript.py` к месту прямо перед `out.write_text`; в `watch.py` — снято upfront, dir создаётся через `_ensure_source_mp4(...)`'s downstream mkdir после успешного `_fetch_snippets`. Regression: `tests/test_failure_modes.py::test_yt_transcript_no_empty_cache_dir_on_fetch_failure` + `::test_yt_watch_no_empty_cache_dir_on_snippets_failure` (mock `_fetch_snippets` raise → assert `yt-cache/<vid>/` не существует). Plus happy-path sanity `::test_yt_transcript_succeeds_creates_dir`. pytest 77/77 🟢. yt-tools bump 0.1.4→0.1.5 PATCH.
|
||||
**Next action:** (none — kept until merged)
|
||||
**Branch:** n/a
|
||||
<!-- created-by: vitya@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-20 / via: local-file (gitea write-side 404 на tasks_create POST) / origin: [using-yt-tools-review] fresh-eyes subagent finding -->
|
||||
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-20 / acceptance: no-empty-dir on abort ✅ (2 mock-fetch-fail tests); happy-path dir created ✅; yt-tools 0.1.5 ✅; pytest 77/77 ✅ -->
|
||||
|
||||
---
|
||||
|
||||
## ⚪ [using-yt-tools-frames-multiline-stdout] — Spec/реальность mismatch в SKILL.md: «Last line каждого CLI's stdout — absolute path артефакта (CLI designed для single-line EOF output)» обещает чистый bare-path, а `yt-frames --timestamps T1,T2,T3` фактически выдаёт N строк формата `Wrote: <abspath>` (с префиксом).
|
||||
## 🟢 [using-yt-tools-frames-multiline-stdout] — Spec/реальность mismatch в SKILL.md: «Last line каждого CLI's stdout — absolute path артефакта (CLI designed для single-line EOF output)» обещает чистый bare-path, а `yt-frames --timestamps T1,T2,T3` фактически выдаёт N строк формата `Wrote: <abspath>` (с префиксом).
|
||||
|
||||
**Проблема:** наивный «take last line as path» парс ломается на префиксе. Single-line EOF контракт работает для `yt-transcript` и `yt-frames` с одним таймкодом, но не для multi-timestamp.
|
||||
|
||||
**Решений два:**
|
||||
- (a) **fix CLI** — emit bare paths matching contract (для multi-timestamp выводить N строк без `Wrote: ` префикса);
|
||||
- (b) **fix spec** — описать multi-line case + `Wrote: ` префикс явно в SKILL.md.
|
||||
|
||||
Рекомендация ревьюера implicit: (a) чище — единый контракт «last line = path» через все три CLI, парсинг агента остаётся тривиальным. (b) дешевле — только edit SKILL.md, но размывает контракт.
|
||||
|
||||
Решение влияет на yt-tools 0.x semver (CLI change = MINOR bump; spec change = PATCH в claude-skills).
|
||||
|
||||
**Severity:** nice-to-have (работает на практике потому что агент знает имена кадров из таймкодов и Read'ит их напрямую, но spec wording misleading; будущий tooling «парсь stdout, бери EOF» сломается).
|
||||
|
||||
**Status:** ready
|
||||
**Where I stopped:** (not started)
|
||||
**Next action:** Выбрать (a) vs (b). Если (a) — fix `yt_tools/frames.py` printf, bump yt-tools версию, регрессионный тест. Если (b) — edit `skills/using-yt-tools/SKILL.md` Inputs/Outputs или Steps секцию, bump skill PATCH.
|
||||
**Status:** done
|
||||
**Closed by:** `claude-skills@b2c1a21` — option (b) chosen: fix spec, не код. Причина: `yt_tools/frames.py:12-13` docstring явно декларирует per-line `Wrote: <path>` дизайн «so callers can pipe/scrape without parsing summary», `tests/test_cli_smoke.py:81` уже enforce'ит `assert all(line.startswith("Wrote: "))`. Code-side change ломал бы намеренный piping-friendly контракт. SKILL.md Steps секция (L61) теперь разделяет stdout-контракт на per-CLI: `yt-transcript`/`yt-watch` — bare single-line path; `yt-frames` — N строк `Wrote: <abs path>`, strip префикс «Wrote: » чтобы получить путь. Skill PATCH 0.2.1→0.2.2 (wording, без behavior change).
|
||||
**Next action:** (none — kept until merged)
|
||||
**Branch:** n/a
|
||||
<!-- created-by: vitya@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-20 / via: local-file (gitea write-side 404 на tasks_create POST) / origin: [using-yt-tools-review] fresh-eyes subagent finding -->
|
||||
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-20 / acceptance: spec per-CLI stdout shape documented ✅; existing piping contract preserved ✅; skill 0.2.2 ✅; install.ps1 picked up new version ✅ -->
|
||||
|
||||
---
|
||||
|
||||
## ⚪ [using-yt-tools-warning-mojibake] — yt-dlp warnings на Windows console рендерятся с mojibake: `Video unavailable “ using minimal metadata` → `Video unavailable <20> using minimal metadata`.
|
||||
## 🟢 [using-yt-tools-warning-mojibake] — yt-dlp warnings на Windows console рендерятся с mojibake: `Video unavailable “ using minimal metadata` → `Video unavailable <20> using minimal metadata`.
|
||||
|
||||
**Корень:** stderr encoding mismatch (cp1251 default Windows console vs UTF-8 source).
|
||||
|
||||
**Fix-направления:**
|
||||
- `sys.stderr.reconfigure(encoding='utf-8', errors='replace')` в trio CLI-entry (`yt-transcript`, `yt-frames`, `yt-watch`) — программная починка;
|
||||
- PYTHONIOENCODING=utf-8 hint в README Windows-блоке — пользовательская;
|
||||
- filter warning sym↔ascii — workaround в `_warning_filter`.
|
||||
|
||||
Рекомендация: первый вариант (программная) — единый fix, не требует от user'а лишних шагов.
|
||||
|
||||
**Severity:** nice-to-have (cosmetic, сообщение остаётся читаемым).
|
||||
|
||||
**Status:** ready
|
||||
**Where I stopped:** (not started)
|
||||
**Next action:** Проверить, помогает ли `sys.stderr.reconfigure(encoding='utf-8', errors='replace')` в trio CLI-entry на проблемном кейсе. Если нет — добавить PYTHONIOENCODING=utf-8 в README Windows-note.
|
||||
**Status:** done
|
||||
**Closed by:** `OpeItcLoc03/common@fc400b7` — программная починка (первый вариант). Helper `force_utf8_streams()` в `yt_tools/core.py` делает `sys.stdout.reconfigure(encoding='utf-8', errors='replace')` + same for stderr; AttributeError/OSError swallowed для wrapped streams (pytest capsys, file redirects). Вызывается в `main()` всех трёх CLI: `yt-transcript`, `yt-frames`, `yt-watch`. pytest 77/77 🟢 (helper не ломает capsys). yt-tools bump 0.1.4→0.1.5 PATCH (одним коммитом с empty-cache-dir-on-failure).
|
||||
**Next action:** (none — kept until merged)
|
||||
**Branch:** n/a
|
||||
<!-- created-by: vitya@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-20 / via: local-file (gitea write-side 404 на tasks_create POST) / origin: [using-yt-tools-review] fresh-eyes subagent finding -->
|
||||
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-20 / acceptance: utf-8 reconfigure in trio CLI entries ✅; capsys-safe via AttributeError swallow ✅; pytest 77/77 ✅; yt-tools 0.1.5 ✅ -->
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user