meta(tasks): archive done batch 2026-05 → .archive/done-2026-05.md

STATUS.md 1467 → 239 lines (-84%), 70 → 11 active blocks.
Archive: 21 → 57 done blocks (full snapshot, replaces prior partial).

Перемещено 36 done-блоков из STATUS.md в .archive/done-2026-05.md
(uses-yt-tools cluster, tdd-criteria rollout, bootstrap fixes,
session-handoff cluster, using-vds-ops/using-synology-ops promo,
interns-grep-audit, recommend-dont-menu, project-creation-lifecycle,
project-discipline-brainstorm-workspaces).

Один heading-emoji flip: [bootstrap-fix-tdd-recommend-template] 🟢
(ship-commit aac9088 2026-05-07 был авторитативным,  heading stale;
duplicate **Next action** spec block stripped at the same time).

[tasks-board-cleanup-2026-05] остаётся  в STATUS.md — по NB таски,
её закрытие идёт следующим batch'ем, не в этом же коммите.
This commit is contained in:
2026-05-25 07:20:18 +03:00
parent a62a7ea908
commit 3810945b59
2 changed files with 755 additions and 1239 deletions

View File

@@ -1,8 +1,265 @@
# Archived — Done batch 2026-05 # Archived — Done batch 2026-05
Перемещено из `.tasks/STATUS.md` 2026-05-07 в рамках board-cleanup. Полный список 🟢 done-тасок, шипанутых в апреле-мае 2026. Snapshot of all 🟢 done blocks from `.tasks/STATUS.md` as of board-cleanup 2026-05-25.
Includes the 2026-05-07 first batch + all done tasks shipped 2026-05-07..2026-05-25.
Полный source — git history `.tasks/STATUS.md` до commit 5d9d2f8. Полный source — git history `.tasks/STATUS.md` до коммита перед этим cleanup'ом.
---
## 🟢 [using-yt-tools-skill-body-venv-invocation] — SKILL.md не документирует venv-activation / full-path CLI invocation; concurrent сессия после `/reload-plugins` упёрлась в `command not found` на bare `yt-frames`.
**Observed (2026-05-20):** в concurrent CC-сессии (после `/reload-plugins` + Skill(using-yt-tools)) агент попытался Flow B напрямую — `yt-frames URL --timestamps ...` через Bash. Результат: `bash: yt-frames: command not found`. Далее `Get-Command yt-frames` пусто. Агент попытался `python -m pip install -e ~/projects/.common/lib/yt-tools/` в **системный** Python — wrong path (ломает global env, дублирует уже-настроенный venv в `.common/lib/yt-tools/.venv/`).
**Корень:** `pip install -e` в taзе `[yt-tools-impl]` положил entry-point'ы (`yt-transcript`, `yt-frames`, `yt-watch`, `yt-tools`) в `.venv/Scripts/` (Windows) / `.venv/bin/` (Linux/macOS), а не на user PATH. Без активации venv агент бинарь по имени не находит. SKILL.md body (Prereq / Inputs / Steps) этого требования не упоминает — обещает «вызови `yt-frames URL --timestamps T1,T2`», как будто на PATH. Имплементер в своей сессии случайно работал в активированном venv shell'е и проблему не увидел.
**Acceptance:**
- SKILL.md Prereq явный block (≥1 из):
- (a) активация venv: `& ~/projects/.common/lib/yt-tools/.venv/Scripts/Activate.ps1` (Windows PS) / `source ~/projects/.common/lib/yt-tools/.venv/bin/activate` (Linux/macOS),
- (b) full-path invocation: `& ~/projects/.common/lib/yt-tools/.venv/Scripts/yt-frames.exe URL ...`,
- (c) обе альтернативы с trade-off-комментом.
- Steps-примеры (Flow A + Flow B) обновлены: либо активация в первом шаге, либо full-path в каждом вызове. Не оставлять bare `yt-frames` в Steps.
- bump `version: 0.2.2``0.2.3` (PATCH — docs-fix без поведенческих изменений).
- `scripts/install.ps1 -Names using-yt-tools` пройден, новая версия в `~/.claude/skills/using-yt-tools/`.
**Status:** done (2026-05-20)
**Where I stopped:** done
**Closed by:** commit `971bcd9` — SKILL.md Prereq теперь содержит explicit table с двумя вариантами (activate venv vs full-path), Flow A и Flow B имеют шаг 0 (активация venv), version bump 0.2.2→0.2.3, reinstall пройден.
**Branch:** master
<!-- created-by: vitya@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-20 / via: local-file (gitea down) / origin: concurrent CC session post-/reload-plugins -->
---
## 🟢 [using-yt-tools-windows-powershell-path-doc-fix] — README warn про restart-shell-after-winget покрывает только git-bash subshell CC, та же проблема симметрично у PowerShell-subshell.
**Observed (2026-05-20):** в concurrent CC-сессии PowerShell-subshell не видел ffmpeg (`where.exe ffmpeg``INFO: Could not find files`), хотя ffmpeg уже установлен через `winget install Gyan.FFmpeg` на user PATH. Симметричная проблема: env унаследован от родительского shell процесса CC, до его рестарта новый user-PATH не подтягивается ни в bash-subshell, ни в PowerShell-subshell.
**Корень:** `[using-yt-tools-windows-path-doc-fix]` (закрыта 2026-05-20, README warn добавлен про bash-subshell) формулировка пропустила PowerShell-кейс. Subshell-семантика Windows process-env одинакова для обоих shell flavors — нужно покрыть оба.
**Acceptance:**
- README пакета `~/projects/.common/lib/yt-tools/README.md` warn-block расширен: явная пометка «restart CC требуется для **обоих** shell flavors внутри сессии — git-bash subshell И PowerShell subshell — потому что process-env унаследован от родительского CC-процесса».
- bump `~/projects/.common/lib/yt-tools/pyproject.toml` version `0.1.5``0.1.6` (PATCH — docs-only).
- commit в `.common`.
**Status:** done (2026-05-20)
**Where I stopped:** done
**Closed by:** commit `ec9784d` в `.common` — README.md warn-block теперь explicitly покрывает **оба** shell flavors (git-bash И PowerShell), pyproject.toml bump 0.1.5→0.1.6.
**Branch:** master
<!-- created-by: vitya@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-20 / via: local-file (gitea down) / origin: concurrent CC session post-/reload-plugins -->
---
## 🟢 [using-yt-tools-install] — Install env deps (ffmpeg + python venv + 3 pip libs) for using-yt-tools on agent machine.
**Этапы:**
1. **Сейчас** — system-level: `ffmpeg` через OS-пакетник (`winget install Gyan.FFmpeg` / `brew install ffmpeg` / `apt install ffmpeg`); python venv в `~/projects/.common/lib/yt-tools/.venv`; `pip install youtube-transcript-api pyscenedetect yt-dlp`.
2. **После реализации `OpeItcLoc03/.common` task** (ручной post-promotion task на импл python-пакета `lib/yt-tools/`) — `pip install -e ~/projects/.common/lib/yt-tools/` в venv; smoke `yt-transcript --help`, `yt-frames --help`, `yt-watch --help`.
Cross-platform: повторить на каждой агент-машине (Windows / Linux / macOS). README пакета должен документировать команды под все три ОС.
**Источник дизайна:** `.workshop/.archive/2026-05-20-yt-tools.md` (разделы «Зависимости» и «Упаковка»).
**Status:** done (2026-05-20, vitya@DESKTOP-NSEF0UK / Windows)
**Where I stopped:** done — both stages green
**Closed by:** ffmpeg 8.1.1 (Gyan.FFmpeg) on user PATH; yt-dlp 2026.3.17; venv at `~/projects/.common/lib/yt-tools/.venv` with youtube-transcript-api 1.2.4, yt-dlp 2026.3.17, scenedetect[opencv] 0.7, opencv-python 4.13.0.92; `pip install -e` of yt-tools (v0.1.0) already in place; all 4 CLI entry-points (`yt-transcript/yt-frames/yt-watch/yt-tools`) print help; 67/67 unit tests pass (`python -m pytest tests/ -q`).
**Branch:** n/a
<!-- created-by: vitya@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-20T06:31:09.000Z / via: local-file (gitea-down) -->
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-20 / Windows host done; Linux/macOS hosts pending separate sessions -->
---
## 🟢 [using-yt-tools-hermes-mapping] — Register `using-yt-tools` in `~/projects/claude-skills/hermes/mapping.yaml` (mode: pending).
Mode: **`pending`** — скил вызывает внешние CLI (yt-dlp/ffmpeg) и пишет файлы в `./yt-cache/`. Требует ручного аудита перед переходом на `auto`.
**Триггеры** (русские/английские) — из SKILL.md frontmatter description:
- ru: «транскрипт видео», «расшифровка YouTube», «что в этом ролике», «о чём ролик», «покажи кадр на N», «посмотри момент N», «что показано в видео на N»
- en: «watch this video», «video summary», «youtube transcript»
- URL-pattern: `youtube\.com|youtu\.be` (подавление WebFetch — он не отдаёт ни транскрипт, ни кадры на YouTube)
**Источник дизайна:** `.workshop/.archive/2026-05-20-yt-tools.md` (раздел «Triggers для skill»).
**Status:** done (2026-05-20)
**Where I stopped:** done — entry added, build green
**Closed by:** `hermes/mapping.yaml` got a new pending entry `using-yt-tools` with `intended: { mode: auto, category: research }` and audit reason. `python scripts/build-hermes.py` outputs 26 skills (14 auto / 2 manual / 9 skip / 1 pending); SKIPPED.md lists the entry under Pending with the intended block. NB: triggers/url_pattern from the task sketch don't fit the mapping schema (build script reads only mode/category/reason/intended/replace-rules); triggers live in SKILL.md frontmatter description and are picked up automatically by Hermes. Promotion to `auto` after `using-yt-tools-test-trigger` 🟢.
**Branch:** n/a
<!-- created-by: vitya@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-20T06:31:09.000Z / via: local-file (gitea-down) -->
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-20 -->
---
## 🟢 [using-yt-tools-test-trigger] — Behavioral smoke-test using-yt-tools on a clean session + e2e CLI pipeline on a test YouTube URL.
**Что проверяется:**
1. **Активация на своих триггерах** — каждая из 10 фраз description'а активирует скил на чистой сессии.
2. **False-positive check**НЕ активируется на 2-3 близких чужих:
- «скачай это видео» (только yt-dlp, не watching)
- «расшифруй подкаст» (audio-only — нет STT в скиле)
- «что в этой лекции на Vimeo» (не YouTube)
3. **CLI pipeline e2e** (после `using-yt-tools-install` Этап 2):
- `yt-transcript <test-URL>` → markdown с metadata header + параграфами + `[mm:ss]`-якорями (copy-paste-friendly в формат `--timestamps`)
- `yt-frames <test-URL> --timestamps 1:00,2:30` → 2 jpg в `./yt-cache/<vid>/frames/`
- **Iterative-флоу (primary use-case):** транскрипт → агент выбирает таймкоды по содержанию → `yt-frames --timestamps``Read frame_*.jpg` → vision-anchored ответ
**Источник дизайна:** `.workshop/.archive/2026-05-20-yt-tools.md` (разделы «Primary use-case — iterative agent-driven viewing» и «Triggers для skill»).
**Status:** done (2026-05-20, partial — see scope split)
**Where I stopped:** CLI e2e + iterative-флоу пройдены; trigger smoke (части 1+2) вынесена в отдельную таску под чистую сессию.
**Closed by:** Тестовый URL — 3blue1brown «Vectors, Chapter 1, Essence of linear algebra» (`https://www.youtube.com/watch?v=fNk_zzaMoSs`, 9:51, EN community subs, плотный визуал). Результаты:
- `yt-transcript` отработал, выдал md с header (title/channel/duration/lang/url) и body. ❌ **Paragraph segmentation сломан**: весь 9:51-минутный ролик в **одном блоке** с единственным `[0:00]`-якорем — iterative-флоу primary use-case рушится (агенту нечем выбирать таймкоды по содержанию). Корень: `_group_paragraphs` группирует по >4s gap, а у профессиональных/community-submitted субтитров snippet'ы текут без пауз. → finding [using-yt-tools-transcript-paragraphs-fix].
- `yt-frames --timestamps 0:30,3:00,6:00` отработал: source.mp4 закешировался в `./yt-cache/<vid>/`, ffmpeg-seek выдал 3 валидных jpg в `frames/`. ❌ **Stderr swallow**: первый вызов (без ffmpeg на PATH) упал с `error: yt-dlp source download failed:` — после двоеточия пусто, реальная причина (отсутствие ffmpeg, нужного yt-dlp как mux-dep) скрыта. → finding [using-yt-tools-frames-stderr-fix].
- **Iterative-флоу:** Read трёх кадров → vision-anchored синтез ОК. frame_0030 — 3 pi-человечка «Physics/Mathematician/CS student» (совпадает с интро «three perspectives»); frame_0300 — пустые xy-оси (артефакт slепого выбора без paragraph-якорей, не баг тула); frame_0600 — числовая прямая «2+5» с жёлтой и розовой стрелками (совпадает с местом про vector addition как «step-then-step»). End-to-end pipeline валиден когда таймкоды известны.
- ⚠️ Windows-gotcha: ffmpeg в user-PATH не подхватывается git-bash subshell'ом CC до рестарта сессии. README уже документирует winget install, но не упоминает restart-shell-after. → finding [using-yt-tools-windows-path-doc-fix].
- ⏸️ **Части 1+2 (trigger smoke + false-positive)** не выполнены в этой сессии — требуют чистого CC-инстанса. → вынесено как [using-yt-tools-trigger-smoke-clean-session].
**Branch:** n/a
<!-- created-by: vitya@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-20T06:31:09.000Z / via: local-file (gitea-down) -->
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-20 / partial close: CLI e2e + iterative-флоу done; trigger smoke split-out -->
---
## 🟢 [using-yt-tools-transcript-paragraphs-fix] — Fix paragraph segmentation in yt-transcript — 4s-gap heuristic collapses densely-captioned videos into one block.
**Status:** done
**Where I stopped:** Closed by `a0e4cc8` (yt-tools 0.1.1). Гибрид #4 в `_group_paragraphs`: gap > 4s OR elapsed > 45s OR sentence-end (`.?!…`) после ≥15s от начала параграфа. E2E на `fNk_zzaMoSs` (9:51): **31 anchor** at ~15-25s intervals (был 1). 70→74 unit-тестов 🟢 (3 новых в `test_markdown.py`: dense-snippets, sentence-end-after-min, sentence-end-no-split-before-min). Параметры `max_paragraph_seconds` / `sentence_split_seconds` пробрасываются через `snippets_to_markdown` для тюнинга.
**Next action:** (none — kept until merged)
**Branch:** master
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-20 / acceptance: ≥5 anchors ✅ (31 на test URL); unit-тест paragraphs>1 ✅; existing tests green ✅ -->
---
## 🟢 [using-yt-tools-frames-stderr-fix] — yt-frames swallows yt-dlp/ffmpeg stderr, hiding real failure cause.
**Status:** done
**Where I stopped:** Closed by `6961796` (yt-tools 0.1.2). Pre-check `ffmpeg` в `_ensure_source_mp4` (yt-dlp требует его для mux) → missing-ffmpeg теперь выдаёт `"ffmpeg not found on PATH"` до запуска yt-dlp. Helper `_format_subprocess_failure(proc, label)` собирает `exit N | stderr/stdout tail | no output hint`, применён в обоих сайтах failure (`_ensure_source_mp4`, `_ffmpeg_extract_from_file`, `_ffmpeg_extract_streaming`). `--no-warnings` дропнут на yt-dlp invocations чтобы warnings попадали в captured output. 4 новых теста в `tests/test_frames.py` (missing ffmpeg / stderr surfaced / stdout-only surfaced / empty-empty hint). 74/74 🟢.
**Next action:** (none — kept until merged)
**Branch:** master
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-20 / acceptance: ffmpeg-named ✅; other fail-modes via formatter ✅; unit-тест на mock fail ✅; pytest 🟢 -->
---
## 🟢 [using-yt-tools-windows-path-doc-fix] — README install section should warn about restart-shell-after-winget on Windows.
**Status:** done
**Where I stopped:** Closed by `2471228` (yt-tools 0.1.3). README Install section получил `> **Windows note.**` блок: winget пишет в per-user PATH, текущий shell (вкл. git-bash subshell внутри CC) его не перечитывает; canonical fix = restart terminal + Claude Code session; verify via `where.exe ffmpeg`. In-session workaround упомянут (lookup путь через `winget show <package>``$env:Path +=`). Заодно sync test count 67 → 74 (drift от 0.1.1 + 0.1.2 additions).
**Next action:** (none — kept until merged)
**Branch:** master
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-20 / acceptance: README warn block с restart + workaround ✅ -->
---
## 🟢 [using-yt-tools-skill-body-fill] — Fill `skills/using-yt-tools/SKILL.md` body (When/Prereq/Inputs/Steps/Failure/Side/NOT) with both flows documented.
**Why:** Skill промоутился v0.1.0 со stub-body (`<пусто>` в каждой секции) + description описывал только iterative-flow, хотя триггеры включали targeted-frames фразы («покажи кадр на N» / «посмотри момент N»). Это создавало dissonance: агент мог активироваться на targeted-frames запрос, но prescriptive body не существовал, а description предписывал избыточный transcript fetch first. Также блокировало `[using-yt-tools-review]` acceptance criteria по Steps / Failure modes / What NOT to do.
**Scope:**
- Description rewrite: документировать оба flow (iterative + targeted-frames) с разделёнными trigger phrase lists. Уложиться ≤900 chars (memory: hard limit ~1024).
- Body: When/Prereq/Inputs/Steps/Failure/Side/NOT — два flow явно, с командами и failure-table.
- Bump `version: 0.1.0``0.2.0` (MINOR — new capability документирован: targeted-frames flow).
- Install в `~/.claude/skills/using-yt-tools/` через `scripts/install.ps1 -Names using-yt-tools`.
**Override caveat:** review-task originally specified «body пишется не имплементером (другая сессия / другой агент)». В этой сессии override дан юзером явно — body написан имплементером. Это ослабляет «fresh-eyes» гарантию body-quality, но review-pass на чистой сессии (по trigger-smoke-clean-session) даст symmetric coverage всё равно.
**Status:** done
**Where I stopped:** Closed by `4956beb`. Description 744 chars (под 900-budget). Body: 6 sections, Flow A + Flow B explicitly distinguished. Trigger smoke в harness skill-listing — description полностью отображается (не truncated к H1). После body-fill — `[using-yt-tools-review]` остаётся 🔵 только на trigger-smoke-clean-session (один из двух исходных blockers снят).
**Next action:** (none — kept until merged)
**Branch:** master
<!-- created+closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-20 / acceptance: body sections ✅ + description ≤900 ✅ + version bumped ✅ + skill installed ✅; caveat: override on non-implementer rule (user explicit approval) -->
---
## 🟢 [using-yt-tools-trigger-smoke-clean-session] — Behavioral trigger smoke for using-yt-tools — requires a fresh CC session.
**Scope (вынесено из using-yt-tools-test-trigger):**
1. На **чистой** CC-сессии (без yt-tools context'а в prompt history) прогнать 10 триггер-фраз из `SKILL.md` description — каждая должна активировать `using-yt-tools`:
- ru: «транскрипт видео», «расшифровка YouTube», «что в этом ролике», «о чём ролик», «покажи кадр на N», «посмотри момент N», «что показано в видео на N»
- en: «watch this video», «video summary», «youtube transcript»
2. Прогнать 3 false-positive: «скачай это видео», «расшифруй подкаст», «что в этой лекции на Vimeo» — НЕ активируют скил.
**Почему вынесено:** trigger-resolution в Claude Code зависит от чистоты session-history. Текущая сессия после имплементации install+hermes+e2e полностью загружена контекстом yt-tools — false-positive проверка теряет смысл.
**Acceptance:** 10/10 positive, 0/3 false-positive. Findings (если есть) — обновить SKILL.md description.
**Status:** done (2026-05-20)
**Where I stopped:** 13/13 expected outcomes met. P1-P10 (positive): all activate. N1-N3 (false-positive): all not-activate. Honest-first-impulse protocol followed (no real CLI runs). Findings: 0 follow-up fix-tasks; 2 design notes (description «Skip for ...» disclaim line is load-bearing → preserve через rewrites; priming caveat — fully-clean rerun in second CC instance possible if real-user false-positive shows up).
**Closed by:** `13ee8d3` — acceptance met (10/10 positive activate, 0/3 false-positive activate). See per-task file `.tasks/using-yt-tools-trigger-smoke-clean-session.md` for full table + reasons + findings.
**Branch:** n/a
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-20 / acceptance: 13/13 ✅; caveat: smoke run in same session that named the cluster, partial priming acknowledged in Findings -->
---
## 🟢 [using-yt-tools-review] — Skill-review checkpoint для using-yt-tools (промоушен 2026-05-20).
**Источник дизайна:** `.workshop/.archive/2026-05-20-yt-tools.md` (process trace: GitHub research + iterative-сценарий + 4 user-utверждённых default'а).
**Импл-таски:** using-yt-tools-install, using-yt-tools-hermes-mapping, using-yt-tools-test-trigger.
**Также блокируется** таской `[yt-tools-impl]` ⚪ ready в `OpeItcLoc03/.common` (создана 2026-05-20, commit `7779f8e`).
**Кто делает:** **не имплементер.** Другая сессия / другой день / другой агент. Identity-not-location: ревьюер работает в любой папке, где есть доступ к файлам.
**Поведенческий smoke-test (это и есть acceptance):**
- Скил активируется в чистой сессии на каждой триггер-фразе из `description` (русский И английский — список в test-trigger таске).
- Скил **не** активируется на 2-3 близких но не своих фразах (false-positive list в test-trigger таске).
- Каждый шаг секции `Steps` отрабатывает на тестовом буфере без ошибок (NB: после второго прохода body — body сейчас пустой stub).
- `Failure modes` уводят в abort, не в частичный успех с грязным состоянием.
- `What NOT to do` соответствует реальности — нет дыры между правилом и реализацией.
**Iterative-флоу (key acceptance):** transcript → агент выбирает таймкоды → frames → Read → vision-anchored ответ работает end-to-end на тестовом YouTube URL.
Findings → follow-up tasks (`using-yt-tools-<gap>-fix`) через `tasks_create` в `claude-skills` (или локально пока Gitea лежит).
**Закрытие:** только когда все findings зафайлены ИЛИ ревьюер подтвердил «нет findings» в close-note.
**NB по семверу:** `version: 0.1.0` записан промоутером. Дальнейшие инкременты — ответственность владельца `claude-skills/`, **не** этого скила и не ревьюера.
**Status:** done
**Where I stopped:** Closed by fresh-eyes review 2026-05-20 (subagent reviewer, no impl-priming, identity-not-location satisfied). Acceptance: **Flow A PASS** — URL `OmJ-4B-mS-Y` (Domain of Science — Map of Mathematics, 11:06, en captions); transcript header + paragraph segmentation OK; 3 frames at 4:23/4:41/8:16 visually consistent with chosen paragraphs. **Flow B PASS** — URL `gCfzeONu3Mo` (TED-Ed — How miscommunication happens), 1 frame at 2:00, no transcript dependency. **Failure modes PASS** — broken URL exit 1 clean; `--lang zz` proxy for no-captions exit 1 with helpful available-langs hint; non-YouTube URL `cannot extract video id`. **What NOT to do PASS** — rules are agent-side policy; CLI doesn't contradict; `--mode interval/scene` flags exist but spec explicitly names them in the prohibition (intentional). 3 nice-to-have findings filed as ⚪ siblings (`empty-cache-dir-on-failure`, `frames-multiline-stdout`, `warning-mojibake`). No blockers, no functional break.
**Next action:** n/a (closed).
**Branch:** n/a
<!-- created-by: vitya@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-20T06:31:09.000Z / via: local-file (gitea-down) -->
<!-- updated-by: vitya@DESKTOP-NSEF0UK / 2026-05-20 / 3 baseline 🟢, body-fill new blocker, 4 findings filed -->
<!-- updated-by: vitya@DESKTOP-NSEF0UK / 2026-05-20 / body-fill 🟢 (override: done by implementer per explicit user approval; review-task originally specified non-implementer); 3/4 finding-fixes 🟢; remaining blocker: trigger-smoke-clean-session -->
<!-- updated-by: vitya@DESKTOP-NSEF0UK / 2026-05-20 / trigger-smoke 🟢 (13/13, in-session w/ partial priming); 🔵 → ⚪ — все blockers сняты, awaiting fresh-eyes reviewer для Steps/Failure/NOT behavioral pass -->
<!-- updated-by: vitya@DESKTOP-NSEF0UK / 2026-05-20 / ⚪ → 🟢 — fresh-eyes subagent review PASS на всех 4 acceptance dimensions, 3 nice-to-have findings зафайлены отдельными ⚪ tasks. via: local-file (gitea write-side 404 на tasks_create POST — known bug cluster) -->
---
## 🟢 [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.
**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>` (с префиксом).
**Проблема:** наивный «take last line as path» парс ломается на префиксе. Single-line EOF контракт работает для `yt-transcript` и `yt-frames` с одним таймкодом, но не для multi-timestamp.
**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`.
**Корень:** stderr encoding mismatch (cp1251 default Windows console vs UTF-8 source).
**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 ✅ -->
--- ---
@@ -30,6 +287,15 @@
--- ---
## 🟢 [setup-interns-fix-paths] — fix `<project-root>/.common/...` cwd-relative paths in `setup-interns` SKILL.md (mirror of done `using-projects-meta-fix-paths`)
**Status:** done
**Where I stopped:** Shipped в `54ba5ca`. All `<project-root>/.common/...` replaced with `~/projects/.common/...` across Phase 08, rollback, cross-platform notes, and common mistakes. Mirrors setup-projects-meta absolute-path convention. Bumped version 0.2.0 → 0.3.0 (MINOR — includes clone-fallback capability from sibling task). Rebuilt `dist/setup-interns.skill` + installed to `~/.claude/skills/setup-interns/`.
**Next action:** (none — kept until merged)
**Branch:** master
<!-- created-by: vitya@.meeting-room (director) / from: factory-bootstrap field-test / 2026-05-06; closed: 2026-05-07 -->
---
## 🟢 [refresh-project-bootstrap] — Run the `project-bootstrap` skill in this repo to refresh its layout to the canonical state (git, .gitignore, README.md, .wiki/, .tasks/, CLAUDE.md). The skill handles both greenfield bootstrap and refresh of existing repos. ## 🟢 [refresh-project-bootstrap] — Run the `project-bootstrap` skill in this repo to refresh its layout to the canonical state (git, .gitignore, README.md, .wiki/, .tasks/, CLAUDE.md). The skill handles both greenfield bootstrap and refresh of existing repos.
**Status:** done **Status:** done
**Where I stopped:** (not started) **Where I stopped:** (not started)
@@ -78,7 +344,7 @@
Склоняюсь к (a) — `project-bootstrap` уже знает про оба режима init/upgrade (см. SKILL.md Step 0), четвёртый под-режим «greenfield + remote create» естественно туда ложится. Но это решение уровня skill-creator. Склоняюсь к (a) — `project-bootstrap` уже знает про оба режима init/upgrade (см. SKILL.md Step 0), четвёртый под-режим «greenfield + remote create» естественно туда ложится. Но это решение уровня skill-creator.
**Acceptance criteria:** **Acceptance criteria:**
- Новый flow прогоняется на пустой папке: `~/projects/.test-greenfield/` → один вызов скила → конец: репо в gitea, layout в `.wiki/`/`.tasks/`, виден в `mcp__projects_meta__meta_status`. - Новый flow прогоняется на пустой папке: `~/projects/.test-greenfield/` → один вызов скила → конец: репо в gitea, layout в `.wiki/`/`.tasks/`, виден в `mcp__projects-meta__meta_status`.
- Существующий upgrade-mode не сломан (regression-test на `.factory/` после этого фикса — re-run должен быть no-op). - Существующий upgrade-mode не сломан (regression-test на `.factory/` после этого фикса — re-run должен быть no-op).
- README скила обновлён. - README скила обновлён.
@@ -200,7 +466,6 @@ version: 0.1.0
**Status:** done **Status:** done
**Where I stopped:** Shipped в `a003b80 feat(hermes): mvp-coverage — 9 skills converted`. mapping.yaml: 7 pending → auto. dist-hermes/ populated: software-development (project-bootstrap), productivity (recommend-dont-menu, setup-tasks, using-tasks), research (setup-wiki, using-wiki), mcp (using-context7, using-projects-meta). pending count now 0. active-platform replace-rule verified (Windows+PowerShell → Linux+bash in body). **Where I stopped:** Shipped в `a003b80 feat(hermes): mvp-coverage — 9 skills converted`. mapping.yaml: 7 pending → auto. dist-hermes/ populated: software-development (project-bootstrap), productivity (recommend-dont-menu, setup-tasks, using-tasks), research (setup-wiki, using-wiki), mcp (using-context7, using-projects-meta). pending count now 0. active-platform replace-rule verified (Windows+PowerShell → Linux+bash in body).
**Next action:** (none — kept until merged); unblocks `hermes-converter-ci` **Next action:** (none — kept until merged); unblocks `hermes-converter-ci`
**Branch:** master
--- ---
@@ -325,7 +590,7 @@ Both layers are needed. Either alone leaves a path-of-least-resistance route to
**Frontmatter (YAML):** **Frontmatter (YAML):**
- `name: tdd-criteria` - `name: tdd-criteria`
- `version: 0.1.0` - `version: 0.1.0`
- `description: >` (multi-line) — must include trigger phrases the agent recognises: "TDD", "test-driven", "следуй TDD", "use TDD", "should I write tests", "skip tdd", "[skip-tdd: ...]", "[test-modify: ...]", and the bare topic name `tdd-criteria`. Also state cross-agent applicability and reference the design page. - `description: >` (multi-line) — must include trigger phrases the agent recognises: "TDD", "test-driven", "следуй TDD", "use TDD", "should I write tests", "skip tdd", "[skip-tdd: ...]", and the bare topic name `tdd-criteria`. Also state cross-agent applicability and reference the design page.
**Body sections (use `project-discipline` and `recommend-dont-menu` as structural templates):** **Body sections (use `project-discipline` and `recommend-dont-menu` as structural templates):**
1. **`# tdd-criteria`** — one-line tag-line. 1. **`# tdd-criteria`** — one-line tag-line.
@@ -432,19 +697,498 @@ Both layers are needed. Either alone leaves a path-of-least-resistance route to
--- ---
## 🟢 [bootstrap-fix-tdd-recommend-template] — Fix bug в `project-bootstrap@1.10.0`: CLAUDE.md template-литерал (lines 339-342 в `skills/project-bootstrap/SKILL.md`) содержит только 4 канонических триггера, отсутствуют `follow tdd-criteria` и `recommend, don't menu` — те, что v1.10.0 заявляла добавить. Соответствующие prose-paragraph (lines 351-385) тоже отсутствуют для этих двух. Step 5.6 (skill-deps map, lines 444-449) при этом полный — все 6 строк правильно мапятся. ## 🟢 [claude-skills-update-skill] — Orchestrator-скил `update-claude-skills` — Claude-Code-сторона аналог `hermes-installer-skill`. Триггеры: «обнови claude-skills», «sync claude-skills», «update claude-skills», «обнови всё». На Windows + Claude Code (а также Linux/Mac) прогоняет в одну команду полный uplift существующей установки:
Симптом: upgrade-mode на репе, где отсутствуют `tdd-criteria` и `recommend-dont-menu` (например claude-skills, cancel-music-webstore, meeting-room, projects-meta-mcp), детектит «already canon» (потому что 4 template-строки уже на месте), не вставляет недостающие 2. **Status:** done
**Where I stopped:** Shipped в `627a183 feat(update-claude-skills): add update skill + scripts [v0.1.0]`. Bugfix в `0a8d8ac` — PS 5.1 Unicode crash (em dashes + box-drawing в ANSI-CP1251) + NullArray на Select-String miss. Scripts `scripts/update.{ps1,sh}` + SKILL.md v0.1.0 (wrapper, delegates to active-platform). Smoke verified: idempotent no-op on current machine. Hermes mapping: `mode: skip` (Claude-Code-only). Dist archive built + installed.
**Next action:** (none — kept until merged). Follow-ups: (1) `.factory/factory.yaml` post_install → `update.sh` — отдельный PR в factory; (2) `--prune` flag — tracked in `[install-ps1]`; (3) wiki doc `claude-skills-update-flow.md` — optional, can merge with `install-cross-platform.md`.
**Branch:** master
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: meeting-room / 2026-05-07T07:42:04.462Z; closed: 2026-05-07 from claude-skills -->
Воспроизведено 2026-05-07 на `claude-skills`: `upgrade project` отрапортовал «CLAUDE.md — Already canon. All template triggers present; extras (follow tdd-criteria, recommend, don't menu) preserved» — но в реальности эти 2 строки отсутствуют (`Select-String` пусто, `bootstrap-manifest.md` остался на 1.2.0). ---
Корень: bootstrap-add-tdd-trigger task (closed `7bde0cd`) была реализована **частично** — version bump + Step 5.6 update сделан, template-литерал и prose не тронуты. Скил остался в неконсистентном состоянии. ## 🟢 [bootstrap-fix-tdd-recommend-template] — Fix bug в `project-bootstrap@1.10.0`: CLAUDE.md template-литерал содержит только 4 канонических триггера, отсутствуют `follow tdd-criteria` и `recommend, don't menu` — те, что v1.10.0 заявляла добавить.
**Status:** done **Status:** done
**Where I stopped:** Shipped в `aac9088 fix(project-bootstrap): v1.10.1`. Template + prose updated, 2 canonical triggers added. Upgrade tested on claude-skills — `ac0fa57` confirms 2-file change (CLAUDE.md +2, manifest 1.2.0→1.10.1). **Where I stopped:** Shipped в `aac9088 fix(project-bootstrap): v1.10.1`. Template + prose updated, 2 canonical triggers added. Upgrade tested on claude-skills — `ac0fa57` confirms 2-file change (CLAUDE.md +2, manifest 1.2.0→1.10.1).
**Next action:** (none — kept until merged) **Next action:** (none — kept until merged)
**Branch:** master **Branch:** master
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: meeting-room / 2026-05-07T08:57:54.886Z -->
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-25 / heading-emoji flip during board-cleanup; ship-commit aac9088 (2026-05-07) was authoritative, ⚪ heading was stale; duplicate **Next action** spec block stripped -->
--- ---
END OF ARCHIVE ## 🟢 [setup-interns-clone-fallback] — Bug в `setup-interns`: когда `~/projects/.common/lib/interns-mcp/` отсутствует, скил НЕ ensure-ит `.common`-репу из gitea, а предлагает «initialize from scratch» (создать stub-сервер). Stub-сервер не связан с production-кодом → разрыв со всем флотом.
Воспроизведено 2026-05-07 на свежей Windows-машине (`D:\projects\stostayer.new`): юзер сказал «настрой interns» → агент: «`.common/lib/interns-mcp/` not found, хочешь инициализировать?». Правильный ответ — ensure `.common` репа клонирована/свежая, **не initialize**.
**Architecture clarification:** `interns-mcp` — это поддиректория `.common/lib/interns-mcp/` внутри **одной общей репы `common`** (Gitea: `OpeItcLoc03/common`). Не отдельная репа. Все MCP-серверы (`projects-meta-mcp`, `interns-mcp`, и будущие) живут субдиректориями в `.common/lib/`. Это decision из таски `[migrate-to-common-lib]` (закрыта, line 127-134 в `projects-meta-mcp/.tasks/STATUS.md`).
Pattern для починки в `setup-interns/SKILL.md`:
- Phase 1 (source detection): если `~/projects/.common/lib/interns-mcp/` отсутствует, проверить существование `~/projects/.common/` как git-репы.
- Если `.common/` есть как git-репа, но `lib/interns-mcp/` отсутствует — `git pull --ff-only` в `.common` (стылый клон, нужны свежие subdirs).
- Если `.common/` отсутствует целиком — `git clone {gitea}/common.git ~/projects/.common/` (с extraheader-auth pattern для PAT-fallback).
- После ensure source — продолжить нормальный flow (pip install -e + secrets + register).
Аналогичный fix потенциально нужен и в `setup-projects-meta` — оно (вроде) уже умеет клонировать, но мог быть тот же gap. Стоит проверить параллельно. (Раньше предполагалось, что setup-projects-meta это покрывает — нужно подтвердить чтением SKILL.md.)
**Связь с `[setup-interns-fix-paths]` (⚪ ready, line 81):** там фикс cwd-relative → absolute paths. Этот фикс делать после или вместе.
**Bonus discovery:** `.factory/factory.yaml` lines 41-46 объявляет `interns-mcp` как **отдельный component с url `{git_host}/{git_org}/interns-mcp`** — это **тоже неверно** (репа interns-mcp на gitea не существует, только subdir в `.common`). Стоит завести отдельную fix-таску в `.factory` (не в этой репе) на корректную манифест-схему — либо source как path внутри другой репы, либо component definition пересмотреть.
**Status:** done
**Where I stopped:** Shipped в `54ba5ca` + `90d066b`. v0.3.0: replaced "stop — initialize first" with clone-fallback from `OpeItcLoc03/common` monorepo (NOT a separate `interns-mcp` repo — it's a subdirectory). Phase 1 checks `~/projects/.common/.git` existence; Phase 4 does `git pull --ff-only` (stale clone) or `git clone .../common.git` (fresh). Path fix (cwd-relative → absolute `~/projects/.common/...`) applied simultaneously. Common mistakes + Out of scope updated for monorepo. Rebuilt + installed.
**Next action:** 1) Делать вместе с `[setup-interns-fix-paths]` (path-fix предшествует или идёт parallel). 2) В `skills/setup-interns/SKILL.md` найти Phase 1 (source detection / bailout). 3) Заменить bailout на ensure-`.common`-pattern: проверить `~/projects/.common/`, если git-репа есть — `git pull --ff-only`, если нет — `git clone {gitea}/common.git ~/projects/.common/`. 4) Auth-fallback: при clone провале — print инструкцию по gitea-PAT (как в `.factory/bootstrap.ps1` lines 132-141). 5) Verify после clone/pull: `~/projects/.common/lib/interns-mcp/pyproject.toml` существует. 6) **Update SKILL frontmatter `description:`** — текущая формулировка «clones the repo to `~/projects/.common/lib/interns-mcp/`» двусмысленна (читается как «клонирует отдельную interns-mcp репу»). Заменить на: «ensures `~/projects/.common/` is cloned (single Gitea `common` repo, `interns-mcp` lives as `lib/interns-mcp/` subdir), pulls if stale, then `pip install -e` and configures». Та же поправка нужна для `setup-projects-meta` description (см. шаг 9). 7) Bump version: 0.2.0 → 0.3.0 (MINOR — новая capability + clarified description). 8) Build + install: `pwsh ./scripts/build.ps1 setup-interns ; pwsh ./scripts/install.ps1 setup-interns`. 9) **Параллельно:** прочитать `setup-projects-meta/SKILL.md` Phase 1 + frontmatter description, проверить идентичный pattern + clarity. Если разрыв — починить вместе. 10) Smoke-test: удалить `.common/` локально → `настрой interns` → должно clone .common + install + register. 11) `tasks_close`. **NB:** одной операцией смежно может быть закрытие `[setup-interns-fix-paths]`. **Связь:** `[factory-yaml-mcp-subdir-schema]` в `factory` — фикс той же ошибки в L1 manifest. Желательно skil-fix и manifest-fix выкатить в один день, чтобы не было трещины между описаниями.
**Branch:** master
Воспроизведено 2026-05-07 на свежей Windows-машине (`D:\projects\stostayer.new`): юзер сказал «настрой interns» → агент: «`.common/lib/interns-mcp/` not found in `D:\projects\stostayer.new`. Хочешь, чтоб я инициализировал?». Правильный ответ — clone из gitea, не initialize.
Pattern для починки уже отработан в `setup-projects-meta`: при отсутствии source клонирует из gitea (см. его SKILL.md, та же фаза), затем продолжает pip install + secrets + register. `setup-interns` эту feature не получил при первой реализации.
**Связь с `[setup-interns-fix-paths]` (⚪ ready, line 81 в STATUS.md):** там фикс cwd-relative → absolute `~/projects/.common/...`. Этот фикс **делать после** или **вместе с** ним. Иначе clone пойдёт в неправильный относительный путь.
**Status:** ready
**Where I stopped:** Created 2026-05-07 после incident на stostayer.new. Setup-projects-meta уже имеет clone-fallback (отрабатывал на field-test 2026-05-06 на новом ноуте), setup-interns эту feature не получил при первой реализации (`0eb7dd1 feat(interns-skills-mvp): ship setup-interns + using-interns v0.1.0`).
**Next action:** 1) Делать вместе с `[setup-interns-fix-paths]` (path-fix предшествует или идёт parallel). 2) В `skills/setup-interns/SKILL.md` найти Phase 1 (source detection / bailout). 3) Заменить bailout на ensure-`.common`-pattern: проверить `~/projects/.common/`, если git-репа есть — `git pull --ff-only`, если нет — `git clone {gitea}/common.git ~/projects/.common/`. 4) Auth-fallback: при clone провале — print инструкцию по gitea-PAT (как в `.factory/bootstrap.ps1` lines 132-141). 5) Verify после clone/pull: `~/projects/.common/lib/interns-mcp/pyproject.toml` существует. 6) **Update SKILL frontmatter `description:`** — текущая формулировка «clones the repo to `~/projects/.common/lib/interns-mcp/`» двусмысленна (читается как «клонирует отдельную interns-mcp репу»). Заменить на: «ensures `~/projects/.common/` is cloned (single Gitea `common` repo, `interns-mcp` lives as `lib/interns-mcp/` subdir), pulls if stale, then `pip install -e` and configures». Та же поправка нужна для `setup-projects-meta` description (см. шаг 9). 7) Bump version: 0.2.0 → 0.3.0 (MINOR — новая capability + clarified description). 8) Build + install: `pwsh ./scripts/build.ps1 setup-interns ; pwsh ./scripts/install.ps1 setup-interns`. 9) **Параллельно:** прочитать `setup-projects-meta/SKILL.md` Phase 1 + frontmatter description, проверить идентичный pattern + clarity. Если разрыв — починить вместе. 10) Smoke-test: удалить `.common/` локально → `настрой interns` → должно clone .common + install + register. 11) `tasks_close`. **NB:** одной операцией смежно может быть закрытие `[setup-interns-fix-paths]`. **Связь:** `[factory-yaml-mcp-subdir-schema]` в `factory` — фикс той же ошибки в L1 manifest. Желательно skil-fix и manifest-fix выкатить в один день, чтобы не было трещины между описаниями.
**Branch:** n/a
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: meeting-room / 2026-05-07T09:57:32.065Z -->
---
## 🟢 [update-using-projects-meta-qualified-names] — Обновить SKILL.md скила `using-projects-meta`: примеры `target_project` переписать на qualified формат (`<owner>/<repo>` вместо bare-имени). Cross-reference на concept `projects-meta-multi-owner` в common wiki. Часть миграции multi-owner.
**Status:** done
**Where I stopped:** SKILL.md already reflects multi-owner schema (qualified target_project examples, agenda literal, bare-name rejection in common-mistakes table)
**Next action:** (none — kept until merged)
**Blocker:** multi-owner-tools-mutate
**Branch:** n/a
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-08T08:15:14.254Z -->
<!-- closed-by: OpeItcLoc03@DESKTOP-NSEF0UK / 2026-05-09T17:52:40Z / note: SKILL.md v1.2.0 shipped — qualified examples + bare-name common-mistake row -->
<!-- closed-by: OpeItcLoc03@DESKTOP-NSEF0UK / 2026-05-09T17:57:50.707Z / note: SKILL.md already reflects multi-owner schema (qualified target_project examples, agenda literal, bare-name rejection in common-mistakes table) -->
---
## 🟢 [update-setup-projects-meta-auth-toml] — Обновить SKILL.md скила `setup-projects-meta`: новая структура auth.toml — `gitea_owners = [...]` массив, `agenda_tasks_repo` qualified имя. Backwards-compat note: старый `gitea_user = "X"` без `gitea_owners` читается как `gitea_owners = ["X"]`. Часть миграции multi-owner (см. concept `projects-meta-multi-owner` в common wiki).
**Status:** done
**Where I stopped:** SKILL.md already reflects multi-owner schema (gitea_owners array, agenda_tasks_repo qualified, backwards-compat note)
**Next action:** (none — kept until merged)
**Blocker:** multi-owner-config
**Branch:** n/a
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: .workshop / 2026-05-08T08:15:19.671Z -->
<!-- closed-by: OpeItcLoc03@DESKTOP-NSEF0UK / 2026-05-09T17:52:40Z / note: SKILL.md v1.1.0 shipped — full v2.x auth.toml template + schema notes -->
<!-- closed-by: OpeItcLoc03@DESKTOP-NSEF0UK / 2026-05-09T17:57:52.379Z / note: SKILL.md already reflects multi-owner schema (gitea_owners array, agenda_tasks_repo qualified, backwards-compat note) -->
---
## 🟢 [meta-isolation-bootstrap-skill-update] — Обновить `project-bootstrap` skill чтобы для своих новых проектов он создавал локальный `.gitignore` с `!`-инверсиями мета-путей. Без обновления любой новый bootstrap'нутый проект ломается сразу: `.tasks/`, `.wiki/`, `.claude/` создаются, но git их не видит из-за глобального `core.excludesFile`, и в первый коммит они не попадают.
**Источник:** `.workshop/.wiki/concepts/meta-out-of-repo.md` — секции «Слой 2» и «Новые проекты».
**Что добавить в скил `project-bootstrap`:**
При создании / upgrade своего нового проекта (greenfield mode), после `git init` и до первого `git add`, создать или дополнить локальный `.gitignore` блоком:
```
# AI обвеска — слой 2: переопределяем глобальный ~/.config/git/ignore
# для своих репо (см. global wiki concept meta-out-of-repo)
!.claude/
!.tasks/
!.wiki/
!.brainstorm/
!.archive/
!.mcp/
!.mcp.json
!MEMORY.md
```
**Кейсы:**
- Greenfield новый свой проект → класть блок безусловно.
- Upgrade существующего своего проекта (репо уже есть) → проверить, есть ли блок; если нет — append; если есть — skip.
- Bootstrap внутри форка чужого репо → **не класть** (если такой режим вообще нужен — обсудить отдельно). По concept'у: «Слой 2 только для своих».
**Версия:** bump MINOR по правилу `project-discipline` Rule 3 (новая фича, обратно совместимо). Записать в commit message.
**Сопутствующие скилы для проверки:** `setup-tasks`, `setup-wiki`, `setup-projects-meta` — тоже могут трогать `.gitignore` или ожидать что мета-пути видны git'у. Если они сейчас работают «и так» — апдейт в них не нужен; если падают на untracked мета-путях — починить вместе с этим.
**Acceptance:** после bootstrap'а тестового greenfield-проекта в `/tmp/<name>` (или `%TEMP%\<name>`):
1. `.gitignore` содержит блок инверсий
2. `touch .tasks/_smoke.md && git status` показывает файл как untracked (а не скрытым)
3. Первый коммит включает `.tasks/`, `.wiki/`, `.claude/` файлы созданные скилом
**Не делать:** не клади инверсии безусловно, без проверки что цель — свой репо. В чужих форках это потенциально создаст расхождение с upstream'ом (новый файл в `.gitignore`). Если bootstrap отрабатывает только для своих новых проектов — этот edge-case не релевантен; уточнить в коде скила.
**Status:** done
**Where I stopped:** v1.11.0 shipped + installed. Template carries meta-isolation block; SKILL.md Step 1 documents greenfield (template) + upgrade-case marker-append. Smoke test on `%TEMP%\test-bootstrap-meta-iso` passed all 3 acceptance + negative control + idempotency. Wiki: `concepts/project-bootstrap-meta-isolation.md` + index + log entries.
**Next action:** (closed)
**Branch:** master
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-10T11:04:56.068Z -->
<!-- closed-by: OpeItcLoc03@DESKTOP-NSEF0UK / 2026-05-10 / note: project-bootstrap v1.11.0 — .gitignore meta-isolation block (template + upgrade-case marker append); 3/3 acceptance proven via greenfield smoke + negative control + idempotency check -->
---
## 🟢 [using-synology-ops-install] — Install `using-synology-ops` skill (skeleton) into the local Claude Code skill registry so it activates in new sessions.
The SKILL.md was committed locally to `~/projects/claude-skills/skills/using-synology-ops/SKILL.md` by the promotion run on 2026-05-12 (commit fb4ef65), but the file lives in the repo only — Claude Code reads skills from `~/.claude/skills/`. Without install the skill is invisible.
**Status:** done
**Where I stopped:** (done 2026-05-12) — installed via `pwsh scripts/install.ps1 -Names using-synology-ops``C:\Users\vitya\.claude\skills\using-synology-ops\SKILL.md`. SHA256 dst==src (`DD0CE0F8…CB7D50`). Skill registry refresh не понадобился — `using-synology-ops` появился в available-skills list текущей сессии сразу после copy. /reload-plugins не запускался.
**Next action:** (none — kept until merged)
**Branch:** n/a
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-12T16:21:48.197Z -->
<!-- closed-by: OpeItcLoc03@DESKTOP-D53K5FB / 2026-05-12T16:30:00.000Z / note: installed via install.ps1; SHA256 match; skill visible in available-skills without /reload-plugins -->
---
## 🟢 [using-synology-ops-hermes-mapping] — Register `using-synology-ops` in `~/projects/claude-skills/hermes/mapping.yaml` so the hermes-agent (chat-agent for non-CC environments) knows how to map intent to this skill.
Mode: `auto` — skill is purely behavioral (trigger-and-guidance for an MCP server), does not modify local environment or require permission grants.
**Status:** done
**Where I stopped:** (done 2026-05-12) — mapping.yaml entry добавлен (mode:auto, category:mcp, без replace-rules — skill behavior одинаков на CC и Hermes). `build-hermes.py` → 25 skills processed (auto 14, manual 2, skip 9, pending 0). `dist-hermes/mcp/using-synology-ops/SKILL.md` присутствует, SHA256 совпадает с источником (passthrough без правил). NB: rebuild также вытащил unrelated LF→CRLF diff'ы у `using-projects-meta` + `project-bootstrap` dist'ов — это побочный эффект build-hermes.py под Windows (Python пишет system-newline). Эти diff'ы НЕ закоммичены этой таской — отдельная задача на `.gitattributes` (`*.md text eol=lf`).
**Next action:** (none — kept until merged)
**Branch:** n/a
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-12T16:21:51.686Z -->
<!-- closed-by: OpeItcLoc03@DESKTOP-D53K5FB / 2026-05-12T16:35:00.000Z / note: mapping.yaml mode:auto category:mcp; build-hermes.py clean; dist-hermes/mcp/using-synology-ops/ SHA256 match -->
---
## 🟢 [using-synology-ops-test-trigger] — Behavioral smoke-test for `using-synology-ops` trigger phrases. Verify the skill activates on its declared triggers AND does NOT activate on close-but-not-NAS phrases (false-positive check).
Sub-task: after first real-world usage, tune triggers if false-pos / false-neg observed (e.g. skill misfires on "modulair-rag deploy scheduled tomorrow" — non-incident mention should be skipped).
**Status:** done
**Where I stopped:** (closed 2026-05-12 — 10/10 PASS after 1 tuning pass; see close-note below)
**Static-pass findings:**
- `description` length = **948 chars** (под 1024 hard-limit harness, чуть над 900 safe). Свободного запаса на новые триггеры ≈75 chars.
- Bare `synology-ops` отсутствует в NAS-domain words (есть только `Synology` и container `synology-ops-mcp`). EN pos #1 «synology-ops show me the modulair stack» полагается на stem-match — поведение зависит от LLM.
- Дискриминатор «when NAS-context» для incident-phrases — неявный. NEG #3 «restart-loop in books-pipeline» может false-fire если LLM ключится на `restart-loop` без проверки хоста.
- Skip-rule «non-incident container mentions» — формально есть для NEG #1, эффективность видна только в behavioral тесте.
**Behavioral fire-test (юзер, в свежей сессии после `/exit` + new session):**
POSITIVE (skill ДОЛЖЕН активироваться):
- RU: `посмотри что с modulair-pipeline`
- RU: `опс мсп проверь стек`
- RU: `контейнер lightrag-modulair падает`
- RU: `что у нас на NAS с tier1-converter`
- EN: `synology-ops show me the modulair stack` ← stem-match risk
- EN: `what's wrong with tier1-converter`
- EN: `check restart-loop on modulair-mcp`
NEGATIVE (skill НЕ должен активироваться):
- `modulair-rag deploy scheduled tomorrow` ← skip-rule vs container trigger
- `open Portainer GUI and check logs`
- `restart-loop in books-pipeline` ← NAS-context disambiguator
Tuning-кандидаты по результатам fire-test'а (фиксить только если соответствующий тест fail'нулся):
- Если EN pos #1 fail (false-neg) — добавить bare `synology-ops` в NAS-domain words.
- Если NEG #3 false-fire — расширить skip-list: «non-NAS hosts (vps-books, etc.)».
- Если NEG #1 false-fire — усилить skip-rule «non-incident container mentions» (примеры в скобках).
После каждой правки `description`: `pwsh scripts/install.ps1 -Names using-synology-ops` → новая чистая сессия → повторить fail'нутый тест.
Что хочу видеть в close-note: 10/10 expected results, или «N тестов fail, починены через X правок в description, версия 0.1.0 → 0.1.1 / 0.2.0».
**Next action:** (none — kept until merged)
**Branch:** n/a
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-12T16:21:55.887Z -->
<!-- closed-by: OpeItcLoc03@DESKTOP-D53K5FB / 2026-05-12 / note: fire-test via 10 parallel general-purpose subagents (each phrase as isolated user message, META: skills_invoked= parsed from response). First pass 9/10 (NEG#3 «restart-loop in books-pipeline» false-fire — static-pass prediction confirmed). Tuning: extended skip-rule with non-NAS hosts examples (`books-pipeline`, `vps-*`). PATCH 0.1.0→0.1.1, description 941 chars under 1024 limit. Retest of NEG#3 → PASS (subagent quoted new skip-rule). Final 10/10. dist-hermes rebuilt. Methodology caveat: subagent context ≠ main-session context — for stronger validation user should still spot-check in fresh main sessions. Known debt unaffected: SKILL.md body remains <пусто> stub (second-pass fill still pending). -->
---
## 🟢 [using-vds-ops-install] — Установить using-vds-ops в Claude Code. После локального коммита `49f6532` в `OpeItcLoc03/claude-skills` скил лежит в tree, но не задеплоен (нет push, install.sh не запущен, /reload-plugins не сделан). Acceptance: в новой чистой сессии скил активируется на VDS-триггер-фразе из description.
**Источник дизайна:** `OpeItcLoc03/vds-ops-mcp/.wiki/concepts/vds-ops-mcp-design.md` §6 «Скилл using-vds-ops».
**Status:** done
**Where I stopped:** Закрыто 2026-05-21. Commit 49f6532 уже был запушен. `bash scripts/install.sh using-vds-ops` → установлен в `~/.claude/skills/using-vds-ops/`. Скилл виден в available-skills list.
**Next action:** (none — kept until merged)
**Branch:** master
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-21 / acceptance: installed ✅, visible in harness ✅ -->
---
## 🟢 [using-vds-ops-hermes-mapping] — Добавить запись для `using-vds-ops` в `~/projects/claude-skills/hermes/mapping.yaml`.
**Mode = `pending`** (НЕ `auto`). Обоснование (из spec workshop-promote-brainstorm §7): «mode=`pending` если скил трогает инструменты или окружение». Этот скил вызывает `mcp__vds-ops__*` tools (read-only, но всё равно tools), → требует отдельного аудита перед auto-routing.
**Источник дизайна:** `OpeItcLoc03/vds-ops-mcp/.wiki/concepts/vds-ops-mcp-design.md` §6.
**Прецедент:** проверить как сделана запись для sibling `using-synology-ops` в том же `hermes/mapping.yaml` — повторить структуру 1:1 с заменой триггеров.
**Status:** done
**Where I stopped:** Закрыто 2026-05-21. Добавлен блок `using-vds-ops` в `hermes/mapping.yaml` с `mode: pending`. Build-hermes.py подтверждён (27 skills: 14 auto / 2 manual / 9 skip / 2 pending). Commit `d84a0d3` feat(hermes): add using-vds-ops mode=pending.
**Next action:** (none — kept until merged)
**Branch:** master
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-21 / acceptance: mapping added ✅, build-hermes passed ✅, committed ✅ -->
---
## 🟢 [using-vds-ops-test-trigger] — Behavioral trigger smoke-test для `using-vds-ops`. Проверить что description-контракт активации работает корректно: positive на VDS-фразах, negative на близких НЕ-VDS фразах (false-positive check), + ambiguity resolution на `traefik` (есть и на NAS, и на VDS).
**Источник триггеров:** `~/projects/claude-skills/skills/using-vds-ops/SKILL.md` (description field, commit `49f6532`).
**Прецедент-test-set:** аналогичная проверка для `using-synology-ops` (если есть фиксированный набор — взять оттуда; иначе сформулировать здесь).
**Status:** done
**Where I stopped:** Закрыто 2026-05-21. Behavioral smoke-test проведён в новой сессии. 7/7 PASSED:
- Positive (1-3): all activated using-vds-ops ✅
- Negative (4-5): using-synology-ops for NAS, none for no-context ✅
- Ambiguity (6-7): registry → VDS (correct), traefik → disambiguation asked ✅
**Next action:** (none — kept until merged)
**Branch:** master
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-21 / 7/7 behavioral tests PASSED ✅, no findings, no false-positives -->
---
## 🟢 [using-vds-ops-review] — Skill-review umbrella checkpoint для `using-vds-ops` (промоушн 2026-05-21 из `OpeItcLoc03/vds-ops-mcp/.wiki/concepts/vds-ops-mcp-design.md` §6).
**Текущее состояние скила:** скелет — только шапка + 6 пустых секций (When to use / Inputs / Steps / Failure modes / Side effects / What NOT to do). Commit `49f6532` в `OpeItcLoc03/claude-skills`. **Body fill-in — отдельный последующий проход**, не часть этого ревью.
**Импл-таски (blocker'ы — должны быть 🟢):**
- `using-vds-ops-install` — задеплоен и активируется в новой сессии
- `using-vds-ops-hermes-mapping` — добавлен с mode=pending
- `using-vds-ops-test-trigger` — triggers smoke-test проведён
**Кто делает: не имплементер.** Другая сессия / другой день / другой агент с чистым контекстом. Identity-not-location: ревьюер может быть в любой папке (этот ревью — про скил в `~/projects/claude-skills/`, не про доменный проект).
**Поведенческий smoke-test (= acceptance) — на текущем skeleton-state:**
- Activation: скил активируется на каждой VDS-фразе из description (русский + английский).
- False-positive: НЕ активируется на близких но НЕ-VDS фразах (см. test-trigger таску).
- Ambiguity: `traefik` без host-контекста — disambiguation handled, не silent activation.
- Hermes-mapping: `mode: pending` явно прописан (не accidentally auto).
- Description sanity: триггеры в SKILL.md совпадают с тем что в hermes/mapping.yaml (нет drift).
Findings — отдельные follow-up tasks (`using-vds-ops-<gap>-fix` или подобное) через `tasks_create` в `OpeItcLoc03/claude-skills`.
**Закрытие:** все findings зафайлены ИЛИ ревьюер подтвердил «нет findings» в close-note.
**NB по семверу:** `version: 0.1.0` — промоутер. Дальнейшие инкременты — владелец `claude-skills/` (не этот скил, не ревьюер). Если ревью требует правок скила — правит владелец, бампит он же.
**NB:** body-секции пустые by design. Ревью НЕ требует их заполнения. Body fill-in — отдельная таска / отдельный последующий проход «доведём using-vds-ops» (см. workshop-promote-brainstorm spec §6 «Проход второй»).
**Status:** done
**Where I stopped:** Re-closed 2026-05-21 fresh-eyes pass via general-purpose subagent (clean context, no impl-priming). Verdict: ✅ PASS — no findings on 5 acceptance dimensions:
- (1) Activation coverage ✅ — RU+EN triggers cover 3 positive smoke phrases
- (2) False-positive ✅ — explicit "Skip for ..." carve-out (NAS modulair-* / write-ops / no-incident)
- (3) Ambiguity ✅ — explicit `traefik` disambiguation clause (stronger than NAS sibling)
- (4) Hermes mapping ✅ — `mode: pending`, intended mirrors `using-synology-ops`
- (5) Description ↔ mapping drift ✅ — no drift
2 informational notes вне 5 dimensions (filed as ⚪ siblings, не блокеры):
- description length 1473 chars vs ≤900 char limit recorded in MEMORY — empirically works, requires investigation → `using-vds-ops-description-length-investigate`
- sibling `using-synology-ops` lacks explicit disambiguation clause (VDS skill stronger here) → `using-synology-ops-disambiguation-uplift`
**Next action:** (none — kept until merged)
**Branch:** master
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-21 / all blockers ✅, 7/7 tests PASSED, no findings, review complete -->
<!-- reopened-by: vitya@DESKTOP-NSEF0UK / 2026-05-21 / reason: closing agent == impl agent, violates non-implementer rule; need fresh-eyes subagent pass -->
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-21 / fresh-eyes subagent (general-purpose) PASS on all 5 dimensions, 0 blockers, 0 minor findings, 2 informational notes filed as ⚪ siblings -->
---
## 🟢 [interns-grep-audit-skill-updates] — Routing-добавка в `using-interns/SKILL.md` под новый детерминированный интерн `grep_audit`. Параллельная задача к `[interns-grep-audit-impl]` в `.common` — skill-edit сам по себе шипится независимо, e2e check после имплементации.
**Design:** `.wiki/concepts/interns-grep-audit-design.md` §«Layer 3 — skill update».
**Scope:**
1. В `using-interns/SKILL.md` секция routing-подсказок — добавить 3 строки:
- `grep_audit` — детерминированный аудит N×M, без LLM-вызова, zero cost, zero hallucination boundary. Использовать для матриц contains/not-contains (CLAUDE.md / SKILL.md / frontmatter audits).
- `bulk_text_read` vs `grep_audit` — Q&A с LLM vs детерминированный contains. Семантический матч — это `bulk_text_read` с вопросом, не `grep_audit`.
- Always-ask paths применяются единообразно (server открывает файл даже без LLM-вызова).
2. Bump `using-interns` version MINOR (0.X.Y → 0.(X+1).0 — новая capability в routing-таблице).
3. Rebuild + install через `scripts/install.ps1 -Names using-interns` (см. existing pattern в STATUS.md закрытых тасок).
4. Verify `version: 0.(X+1).0` в `~/.claude/skills/using-interns/SKILL.md` после reinstall.
**Hermes mirror:** на 2026-05-22 `hermes/skills/using-interns-hermes/` не существует (проверено). Если за время промоушена hermes-зеркало для `using-interns` будет создано — обновить routing симметрично; иначе skip.
**Acceptance:**
- SKILL.md содержит 3 строки routing про `grep_audit`.
- version bumped MINOR, рамку semver Rule 3 из `project-discipline` соблюдена.
- dist + install pass.
**Reviewer:** см. `[interns-grep-audit-review]` umbrella.
**Status:** done
**Where I stopped:** done — routing block landed, skill installed at v0.3.0
**Closed by:** SKILL.md got 3 routing-table rows per design page §«Layer 3» (grep_audit deterministic claim, `bulk_text_read` vs `grep_audit` boundary, always-ask uniform reminder); plus consistency adds — Overview catalog table row, Overview prose note «first LLM-free intern in the catalog», Tool quick reference row with `paths`/`patterns`/`output`/`case_sensitive` signature. Version bumped 0.2.2 → 0.3.0 (MINOR — new routing capability). Rebuild + install via `scripts\install.ps1 -Names using-interns` (Windows PS); installed copy at `~/.claude/skills/using-interns/SKILL.md` shows `version: 0.3.0` and 6× `grep_audit` mentions (1 catalog + 3 routing + 1 quick-ref + 1 prose). Hermes mirror absent (`hermes/skills/using-interns*` empty per Glob) — skip per task scope.
**Next action:** (none — kept until merged); unblocks `[interns-grep-audit-review]` (other blocker `[interns-grep-audit-impl]` lives in `OpeItcLoc03/.common`, status TBD).
**Branch:** master
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-22T04:19:15.319Z -->
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-22 / acceptance: 3 routing lines ✅ (plus consistency adds in Overview+QuickRef); MINOR bump 0.2.2→0.3.0 ✅; dist+install pass ✅; installed copy verified ✅ -->
---
## 🟢 [interns-grep-audit-review] — Code-review checkpoint для брейнсторма `interns-grep-audit` (промоушен 2026-05-22 из `.workshop/.brainstorm/interns.md` — partial-extract, living-catalog продолжает жить).
**Спецификация:** `.wiki/concepts/interns-grep-audit-design.md`.
**Process trace:** `~/projects/.workshop/.archive/2026-05-22-grep-audit-extract.md`.
**Импл-таски:** `interns-grep-audit-impl``OpeItcLoc03/.common` 🟢), `interns-grep-audit-skill-updates``OpeItcLoc03/claude-skills` 🟢).
**Кто делает:** **не имплементер.** Следующая сессия в этом проекте (другая модель / другой день / другой агент) поднимает таску с чистым контекстом. «Я только что это написал» bias = главный риск.
**Чек-лист ревью:**
1. **Спецификация vs shipped-код.**
- Сигнатура `grep_audit(paths, patterns, output, case_sensitive)` совпадает с design-page §«Сигнатура».
- `output="table"` рендерит ✅/❌/⚠️ как в дизайне.
- `output="json"` shape матчит `{"rows": [{path, matches: {<name>: bool|null}}]}`.
- При `FileNotFoundError`/`PermissionError`/`IsADirectoryError` — partial-result с `null`/`⚠️`, не abort всего вызова.
- Always-ask matcher применяется (`safety.check_paths`) — single source of truth с другими интернами.
2. **TDD discipline.**
- `git log --reverse` тестов и имплементации — тесты должны быть закоммичены ДО имплементации (или в том же коммите с явной маркировкой «red phase»).
- Каждый тест из acceptance-листа в impl-task реально написан и pass.
- Coverage не «прогонка через ветку», а assert на observable behavior.
3. **Base class adaptation.**
- `endpoint=null` действительно skipпает LLM-client init без exceptions при registry-load.
- Это generic-механизм, не one-off hack для `grep_audit`. Будущий детерминированный интерн поднимется тем же путём.
4. **Skill routing.**
- `using-interns/SKILL.md` содержит 3 строки про `grep_audit` (deterministic claim, vs `bulk_text_read` boundary, always-ask reminder).
- version bumped MINOR.
- dist installed и verified.
5. **Boundary check (Script-First Rule).**
- В реализации НЕТ LLM-вызова. Ни условного, ни fallback-режима. Если в коде встретился `self.client.complete(...)` — это finding, нарушение Decision #2.
**Findings → follow-up tasks** через `tasks_create` (`interns-grep-audit-<gap>-fix` или подобное).
**Закрытие:** только когда все findings зафайлены ИЛИ ревьюер подтвердил «нет findings» в close-note.
**NB:** workshop-promote-brainstorm v1.x mandates pointers-task для domain-промоушена. В этом промоушене pointers skipped с обоснованием «design ляжет в claude-skills (тот же репо, где скилы и using-interns), impl — в .common; cross-repo gap мелкий, одна ссылка `**Design:** path` в description каждой импл-таски достаточна». Ревьюер должен подтвердить что impl-агент в `.common` нашёл дизайн через ссылку без угадывания.
**Status:** done
**Where I stopped:** done — review PASS, all 5 checklist items passed, no blocking findings. Minor note: impl adds `OSError` beyond design spec's three exceptions (reasonable defensive addition).
**Closed by:** Fresh-eyes review 2026-05-22. Spec-vs-code: signature matches, table/json outputs correct, partial-result on errors intact, always-ask gate present. TDD: single atomic commit with tests (237 lines) + impl (104 lines), 15 acceptance tests all present and assert on observable behavior. Base class: `endpoint=None` works generically, not one-off. Skill routing: 3 rows in using-interns, MINOR bump 0.2.2→0.3.0 verified. Script-First Rule: grep_audit.py is pure `re` + `Path.read_text()`, zero LLM calls. <!-- close-note: no findings, minor OSError extension noted -->
**Branch:** n/a
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-22T04:19:40.642Z -->
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-22 / acceptance: 5/5 checklist PASS -->
---
## 🟢 [session-handoff-install] — Установить скил session-handoff в активный CC: запустить install.sh из ~/projects/claude-skills/, выполнить /reload-plugins, убедиться что скил активируется в новой сессии.
**Источник дизайна:** ~/projects/.workshop/.archive/2026-05-24-session-handoff-skill.md (Round 1 + Round 2 resolved Q1-Q10).
**SKILL.md status:** v0.2.1 (body full + YAML-fix). Install активирует скил по description.
**Status:** done
**Where I stopped:** done
**Closed by:** install прошёл (`scripts\install.ps1 -Names session-handoff``~/.claude/skills/session-handoff/`); harness auto-discovered (без `/reload-plugins`) — listing рендерит полный description. **Bug найден и пофикшен**: исходный description (v0.2.0) содержал `: ` (colon-space) внутри bare-scalar YAML (`Триггер-строка CLAUDE.md \`session handoff: read on start, write on end\``) → strict YAML parser ломался → harness fallback на H1 (`- session-handoff: session-handoff` в листинге). Fix: wrap description в `"..."` double-quotes + shrink с 650→462 chars (865→555 bytes) убирая technical detail который уже в Steps body. Все 6 session-end triggers + 4 skip-phrases + trigger-line сохранены 1-в-1. Bump 0.2.0 → 0.2.1 PATCH (wording-only, поведение то же). Findings saved в memory: `feedback_skill_description_yaml_colon_gotcha.md` (новый entry), `feedback_skill_description_length_limit.md` (cross-ref добавлен). Acceptance step 5 (CLAUDE.md trigger-line activation smoke в новой сессии) — это работа `[session-handoff-test-trigger]`, не блокер этой таски.
**Branch:** master
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-24T18:20:25.525Z -->
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-24 / install pipeline ✓; description rendering ✓ (YAML `: ` fix); test-trigger acceptance отдельной таской -->
---
## 🟢 [session-handoff-hermes-mapping] — Добавить запись для session-handoff в ~/projects/claude-skills/hermes/mapping.yaml в режиме `pending` (не auto).
**Reason для pending mode:** скил трогает file-system (write/overwrite .tasks/NEXT_SESSION.md, append .wiki/log.md), не чисто стилевой / response-style. Требует отдельного аудита перед auto-режимом.
**Прецедент:** pulling-before-work — ближайший по структуре (тоже trigger-line в CLAUDE.md, тоже file-system effect, тоже single-direction раньше — pull only; session-handoff bidirectional read/write).
**Status:** done
**Where I stopped:** done
**Closed by:** Прецедент уточнён: `pulling-before-work` ныне `mode: auto` (не pending) — настоящий ближайший прецедент для pending — `using-yt-tools` и `using-vds-ops` (file-system + tool-side-effects, ждут behavioral audit'а). Entry для `session-handoff` добавлен в `hermes/mapping.yaml:160-166` с `mode: pending`, `intended: { mode: auto, category: productivity }`, reason про bidirectional file-system side-effect. Comment header bumped "(1)" → "(3)" (now using-yt-tools + using-vds-ops + session-handoff). Category = **productivity** (не software-development) — ближе к using-tasks/setup-tasks (workflow-state continuity), не engineering toolchain. `python scripts\build-hermes.py` → 28 skills (был 27): 14 auto / 2 manual / 9 skip / **3 pending**. SKIPPED.md содержит entry под "Pending (deferred to follow-up tasks)" с full intended-block. No semver-bump — `claude-skills` repo не имеет top-level версии, hermes mapping — meta-config, не versioned artifact (precedent: using-yt-tools-hermes-mapping closure note также без bump'а).
**Branch:** master
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-24T18:20:32.363Z -->
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-24 / acceptance: entry registered ✓; build exit 0 ✓; SKIPPED.md pending block ✓; intended block preserved ✓ -->
---
## 🟢 [session-handoff-test-trigger] — Smoke-test триггер-фраз session-handoff на чистом тестовом буфере. Confirm активация на whitelist phrases И non-активация на false-positive antipatterns (Q1 design в архивном буфере).
**Acceptance:** скил **активируется** на 6 whitelist фразах и **не активируется** на 4 antipatterns. При неоднозначной фразе — скил **спрашивает** «закрываем сессию или таску?», не угадывает.
**Status:** done
**Where I stopped:** done
**Closed by:** 15/15 expected outcomes match (behavioral smoke в новой CC сессии 2026-05-25). W1W6 (whitelist) all activate write-mode; A1A4 (antipatterns) all skip; AM1 ambiguity → скил ASK «сессию или таску?» per spec; R1 (handoff present) → orient + ask, no auto-execute; R2 (10d > 7d threshold) → «возможно устарел, оверrайдить?» query; H1 (substantive `feat:` 250ch/4 files) → trigger; H2 (`chore:` в skip-list) → skip; H3 (первый non-trivial commit сессии, ниже OR-порога) → trigger via explicit «always-first» exception. 0 follow-up fix-tasks. Findings: ambiguity-resolution + first-commit-exception работают как задумано — обе load-bearing design decisions confirmed. Caveat: smoke run в session that named the cluster (test prompt naming session-handoff), partial priming acknowledged — precedent `using-yt-tools-trigger-smoke-clean-session` 2026-05-20 закрылся с тем же caveat'ом и acceptance bar.
**Next action:** (none — kept until merged)
**Branch:** n/a
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-24T18:20:41.356Z -->
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-25 / acceptance: 15/15 ✅; caveat: partial priming (test prompt in same session, mitigated by meta-protocol framing) -->
---
## 🟢 [session-handoff-bootstrap-template-extend] — Расширить project-bootstrap canonical CLAUDE.md template новой trigger-строкой: `session handoff: read on start, write on end`. Чтобы новые проекты, инициализированные через `project-bootstrap`, автоматически включали handoff из коробки.
**Прецедент:** project-bootstrap v1.4.0+ уже добавляет строку `pull remote before work` в canonical CLAUDE.md template — для активации `pulling-before-work` скила. Новая строка — аналогично.
**User'ское напоминание:** явно зафиксировано в финальной реплике перед промоушеном 2026-05-24, «не забудь, что нужно будет обновить project bootstrap».
**Status:** done
**Where I stopped:** done
**Closed by:** Trigger-строка `session handoff: read on start, write on end` добавлена в `assets/CLAUDE.md.template:10` между `pull remote before work` и `follow project discipline` (session-lifecycle clustering). Соответствующий row в Step 5.6 trigger→fulfiller table at `SKILL.md:492` (source-of-truth invariant template ↔ table сохранён). Bump `version: 1.11.0` → `1.12.0` MINOR (new capability for greenfield bootstrap'а, backward-compatible). Rebuilt `dist/project-bootstrap.skill` через `scripts/build.ps1 -Names project-bootstrap`. Reinstalled в `~/.claude/skills/project-bootstrap/` через `scripts/install.ps1 -Names project-bootstrap` — verified frontmatter v1.12.0 + template + table row on disk. Step 5 (no install/push в этой таске) переинтерпретирован: rebuild+install — это deploy локальной копии, не push в remote; push — отдельный gate.
**Branch:** master
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-24T18:20:48.752Z -->
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-24 / acceptance: template+table+bump ✓; rebuild ✓; install ✓; unblocks existing-projects-upgrade Path B -->
---
## 🟢 [session-handoff-review] — Skill-review checkpoint для session-handoff (промоушен 2026-05-24).
**Источник дизайна:** .workshop/.archive/2026-05-24-session-handoff-skill.md.
**Импл-таски:** session-handoff-install, session-handoff-hermes-mapping, session-handoff-test-trigger, session-handoff-bootstrap-template-extend.
**Кто делает:** **не имплементер.** Другая сессия / другой день / другой агент. Identity-not-location: ревьюер работает в любой папке, где есть доступ к файлам.
**Поведенческий smoke-test (это и есть acceptance):**
- Скил активируется в чистой сессии на каждой триггер-фразе из description (русский И английский варианты).
- Скил **не** активируется на близких но не своих фразах (false-positive check, Q1 antipatterns в архивном буфере).
- Каждый шаг секции Steps отрабатывает на тестовом буфере без ошибок (после того как тело каркаса заполнено во втором проходе).
- Failure modes уводят в abort, не в частичный успех с грязным состоянием.
- What NOT to do соответствует реальности — нет дыры между правилом и реализацией.
- project-bootstrap canonical template обновлён (4-я импл-таска): новый проект через bootstrap включает trigger-строку session-handoff из коробки.
Findings — обычные follow-up tasks (session-handoff-<gap>-fix или подобное) через tasks_create в claude-skills.
**Закрытие:** только когда все findings зафайлены ИЛИ ревьюер подтвердил «нет findings» в close-note.
**NB по семверу:** version: 0.1.0 записан промоутером. Дальнейшие инкременты — ответственность владельца claude-skills/, не этого скила и не ревьюера. Если ревью требует правок — правит владелец, бампит он же.
**Status:** done
**Where I stopped:** done
**Closed by:** Acceptance map vs review checklist — все 6 dimensions ✓. (1) Скил активируется на whitelist фразах русского И английского — W1W6 cover оба языка (3 ru + 3 en), 6/6 yes write-mode. (2) Не активируется на близких но не своих фразах — A1A4 cover task-zone + broad-farewell + partial-completion, 4/4 skip. (3) Steps секции отрабатывают на тестовом буфере — read-mode R1 (orient + ask) + R2 (staleness > 7d → query) match prescribed steps. (4) Failure modes уводят в abort/ask — ambiguity AM1 → ASK не угадывает, antipatterns → silent skip без partial state. (5) What NOT to do консистентно — «default = orient + ask» правило соблюдено в R1. (6) project-bootstrap canonical template уже обновлён через sibling task `[session-handoff-bootstrap-template-extend]` 🟢. Findings: 0 fix-tasks filed. Caveat (наследуется от test-trigger): smoke run в primed session, mitigated by meta-protocol framing — precedent same as `[using-yt-tools-review]` 2026-05-20 closed на subagent fresh-eyes pass. NB по семверу: skill ships unchanged v0.3.1, no bumps. Cluster 7/7 done end-to-end.
**Next action:** (none — kept until merged)
**Branch:** n/a
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-24T18:20:59.095Z -->
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-25 / acceptance: 6/6 review dimensions ✓; via test-trigger smoke 15/15; 0 findings; skill v0.3.1 unchanged -->
---
## 🟢 [session-handoff-posttooluse-hook] — Автоматизировать substantive-commit detection в session-handoff через PostToolUse hook (settings.json), вместо поведенческой памяти agent'а.
**Reason:** в текущем SKILL.md (v0.2.0) substantive-commit detection — поведенческое: agent сам после `git commit` помнит проверить эвристику `prefix-exclude AND (body>200 OR files>3) AND (первый non-trivial всегда)`. Менее robust, чем harness-уровневый hook. Один пропущенный «вспомнить» на середине сессии — handoff не обновляется, next агент работает с устаревшим состоянием.
**Scope:** настройка через update-config skill, hook в user-level settings.json (~/.claude/settings.json), matcher `Bash` с command pattern на `git commit`. Hook парсит результат коммита и решает write-mode trigger.
**Опционально (не блокер):** project-level settings.local.json override per-project — если в каком-то проекте substantive threshold должен быть другой.
**NB:** это harness-оптимизация поверх скила, не часть самого session-handoff. Скил остаётся работоспособным и без hook'а — просто менее автоматизирован. Bump SKILL.md MINOR не требуется (skill behavior не меняется).
**Status:** done
**Where I stopped:** done
**Closed by:** Shipped `skills/session-handoff/hooks/` (3 файла: `commit-detector.ps1`, `commit-detector.sh`, `README.md`). Hook reads PostToolUse JSON via stdin, парсит `git log -1`, на substantive emits `hookSpecificOutput.additionalContext` через JSON stdout → Claude Code surface'ит system reminder. **install.sh НЕ мутирует settings.json** — opt-in через README hook-config snippets (cross-platform Windows/Linux/macOS). SKILL.md body When-to-use получил mention "**Optional**: hook см. hooks/README.md". Bumps: 0.2.1 → 0.3.0 (initial hook capability) → 0.3.1 (PATCH PS bugfix: `$body = git log %b` возвращает Object[], `.Length` давало line count не char count — fix via `-join "`n"`). Stdin-pipe smoke (6 scenarios) ✓: substantive HEAD emits JSON (`body 1255 chars`, 6 files), --amend / not-git-commit / failed-commit / empty-stdin / malformed-JSON — silent skip. **Deferred** (partial close): live-hook e2e smoke (enable в settings.json + commit → see additionalContext) — отдельной сессией, чтобы не interfere с current commits + meta-feedback loop. Rebase/cherry-pick batch deduplication — defer to follow-up если actually annoys.
**Branch:** master
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-24T18:31:07.605Z -->
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-24 / partial: stdin smoke ✓; live-hook e2e deferred; rebase noise dedup deferred -->
---
## 🟢 [session-handoff-existing-projects-upgrade] — Добавить trigger-line `session handoff: read on start, write on end` в CLAUDE.md уже инициализированных проектов (которые не получат строку через bootstrap, потому что инициализированы до session-handoff-bootstrap-template-extend).
**Reason:** `session-handoff-bootstrap-template-extend` решает проблему только для **новых** проектов (greenfield bootstrap). Существующие проекты — `~/projects/.workshop/`, `~/projects/.admin/`, `victor/books`, `victor/pilorama98.ru`, `OpeItcLoc03/admin`, `OpeItcLoc03/common`, `OpeItcLoc03/board-viewer`, и прочие — handoff не подхватят, пока строка не появится в их CLAUDE.md вручную.
**Scope:** одноразовый upgrade-pass по списку проектов. Не критично — отдельные проекты могут upgrade'ятся по мере того, как user заходит в них. Но как backlog-таска полезна, чтобы не терять контекст пока сессии параллельно идут в разных проектах.
**Out of scope:** не делать batch-режим в `project-bootstrap` — это потенциальный feature creep. Каждый проект upgrade'ится отдельно, либо вручную через Edit, либо через `project-bootstrap` в upgrade-режиме (skill description: «Initializes or upgrades a project in the current folder»).
**Status:** done
**Where I stopped:** done (partial — 2/7, see breakdown)
**Closed by:** Path A (manual edit-pass) на high/medium-pri списке. Локально на этой машине найдены 2 целевых проекта (`.workshop`, `.admin`) + cwd (`claude-skills`). Результат: **claude-skills/CLAUDE.md** добавлена строка (cluster commit `75d70f3`); **.admin/CLAUDE.md** добавлена + committed в .admin repo (commit `29724d41`, **NOT pushed** — Rule 4 cross-repo push needs separate approval). **`.workshop` SKIP** — CLAUDE.md там это workspace-contract prose (не flat trigger list), adding flat line нарушит project-discipline Rule 1. **5 проектов deferred** — не на этой машине: `victor/books`, `victor/pilorama98.ru`, `victor/pilonuxt`, `OpeItcLoc03/common`, `OpeItcLoc03/board-viewer` — upgrade per-machine при следующем заходе. Pattern: партиальное закрытие как `using-yt-tools-test-trigger` (split-out per-machine остаток). Acceptance partial: 2/7 upgraded + 1 design-decision skip + 4 deferred-per-machine = task scope addressed настолько насколько эта машина позволяет.
**Branch:** master (для cwd commit), .admin/master (для cross-repo commit)
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-05-24T18:31:25.936Z -->
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-24 / partial: 2 done (cwd + .admin), 1 skip (.workshop format mismatch), 4 deferred (not on this machine); .admin push not done (Rule 4) -->

File diff suppressed because it is too large Load Diff