# Task Board _Updated: 2026-05-20 (using-yt-tools: 3 baseline 🟢; 3 finding fixes 🟢 [paragraphs/frames-stderr/windows-path-doc] → yt-tools 0.1.0→0.1.3, 74/74 tests; skill-body-fill 🟢 [SKILL.md 0.1.0→0.2.0, two flows documented]; trigger-smoke-clean-session ⚪ (needs fresh CC session); review 🔵 still — body blocker removed, now blocked on trigger-smoke only)_ ## 🟢 [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 --- ## 🟢 [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 --- ## 🟢 [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 ` → markdown с metadata header + параграфами + `[mm:ss]`-якорями (copy-paste-friendly в формат `--timestamps`) - `yt-frames --timestamps 1:00,2:30` → 2 jpg в `./yt-cache//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//`, 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 --- ## 🟢 [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 --- ## 🟢 [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 --- ## 🟢 [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 ` → `$env:Path +=`). Заодно sync test count 67 → 74 (drift от 0.1.1 + 0.1.2 additions). **Next action:** (none — kept until merged) **Branch:** master --- ## 🟢 [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 `` (this commit). 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 --- ## ⚪ [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:** ready **Where I stopped:** (not started — split-out from using-yt-tools-test-trigger 2026-05-20) **Next action:** В новой CC-сессии (в любой папке с установленным using-yt-tools) ввести каждую из 13 фраз и зафиксировать, активировался ли скил. Документ-чеклист подойдёт. **Branch:** n/a --- ## 🔵 [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--fix`) через `tasks_create` в `claude-skills` (или локально пока Gitea лежит). **Закрытие:** только когда все findings зафайлены ИЛИ ревьюер подтвердил «нет findings» в close-note. **NB по семверу:** `version: 0.1.0` записан промоутером. Дальнейшие инкременты — ответственность владельца `claude-skills/`, **не** этого скила и не ревьюера. **Status:** blocked (на trigger-smoke-clean-session — единственный остаток после body-fill 🟢) **Where I stopped:** 3 baseline impl-таски 🟢 (install, hermes-mapping, test-trigger partial). `.common/lib/yt-tools/` python-пакет 🟢 (74/74 тестов после 0.1.0→0.1.3). `SKILL.md` body 🟢 (0.1.0→0.2.0 — Flow A iterative + Flow B targeted-frames документированы, см. [using-yt-tools-skill-body-fill]). 3 finding-fix таски 🟢. Остаётся только: trigger-smoke на чистой CC-сессии (см. [using-yt-tools-trigger-smoke-clean-session]). **Next action:** В чистой CC-сессии прогнать smoke из [using-yt-tools-trigger-smoke-clean-session] (10 positive + 3 false-positive trigger phrases) + поведенческий smoke-test для каждого шага Flow A и Flow B на тестовом URL. Если 0 findings — закрыть 🟢 с close-note. Findings — новые ⚪ fix-tasks. **Branch:** n/a --- ## 🟡 [skill-readmes] — write English README.md for every skill + translate root README **Status:** paused **Where I stopped:** infra-skill cluster done — READMEs for `project-bootstrap`, `setup-wiki`, `setup-tasks`, `using-wiki`, `using-tasks`; root README translated; cross-links between all five skills wired up **Next action:** continue with the next batch — suggest the caveman cluster (`caveman`, `caveman-commit`, `caveman-review`, `caveman-help`, `caveman-compress`, `compress`) since they form a coherent group; or jump to `active-platform`, `find-skills`, `setup-context7`, `using-context7`, `using-markitdown` if the caveman cluster needs deduplication first (see `compress-dedup` task) **Branch:** master --- ## 🟢 [bootstrap-skill-deps-check] — refactor project-bootstrap Step 5.6 into a generic skill-dependencies check (replaces per-skill `Step 5.X` mirror shape) **Status:** done **Where I stopped:** `skills/project-bootstrap/SKILL.md` Step 5.6 переписан с single-skill `superpowers`-only detector на generic `trigger → fulfiller` table walker (9-row inline map: 8 skills + 1 plugin; `kind` flag drives install-command emission); README Workflow Step 5.6 description обновлён под новую форму; `version:` 1.6.0 → 1.7.0 (MINOR — adds capability, absorbs prior detector cleanly); `dist/project-bootstrap.skill` rebuilt + installed; `~/.claude/skills/project-bootstrap/SKILL.md` shows `version: 1.7.0`; design page `.wiki/concepts/bootstrap-skill-deps-check.md` written (rationale: why generic over per-skill mirrors, skill/plugin kind distinction, MCP-server caveat, source-of-truth invariant between SKILL map ↔ `assets/CLAUDE.md.template`); `.wiki/index.md` + `.wiki/log.md` updated. Subsumes `[bootstrap-recommend-projects-meta]` by absorption. **Next action:** (none — kept until merged) **Branch:** master --- ## 🟢 [bootstrap-recommend-projects-meta] — Step 5.7 in project-bootstrap: recommend `setup-projects-meta` if MCP tools missing **Status:** done **Where I stopped:** closed by absorption 2026-05-05 — `[bootstrap-skill-deps-check]` shipped a generic Step 5.6 that walks the whole canonical trigger list (`using-projects-meta` is one of 9 rows in the inline `trigger → fulfiller` map). The per-skill mirror this task envisioned was rejected as a copy-paste explosion shape; the generic walker handles the same case + the analogous gap for every other canonical trigger. **Next action:** (none — kept until merged) **Branch:** master --- ## 🟢 [compress-dedup] — resolve compress vs caveman-compress duplication **Status:** done **Where I stopped:** `skills/compress/` deleted as a byte-identical dupe of `skills/caveman-compress/` (SHA256 match across all 7 scripts/ files; SKILL.md diff was `name:` + Process step 2 only; README + SECURITY only in caveman-compress). Ported the better Process-step wording from compress (`cd ` instead of brittle `cd caveman-compress`) into `skills/caveman-compress/SKILL.md`. Added `version: 1.0.0` to caveman-compress frontmatter (first versioned release; aligns with skill-versioning concept). Removed: `skills/compress/`, `dist/compress.skill`, `~/.claude/skills/compress/` (manual prune — install.sh has no prune step). Rebuilt `dist/caveman-compress.skill` + reinstalled to `~/.claude/skills/caveman-compress/` (verified `version: 1.0.0` + new Process step on disk). Harness skill listing confirms `compress` is gone, only `caveman-compress` remains. `.wiki/concepts/compress-dedup.md` written (rationale + rejected alternatives: alias-stub has no harness mechanism, "keep both" wastes listing budget, "delete caveman-compress" loses README + SECURITY); `.wiki/index.md` + `.wiki/log.md` updated. **Next action:** (none — kept until merged) **Branch:** master --- ## ⚪ [install-ps1] — paired install.sh + install.ps1 (cross-platform parity, with --prune) **Status:** ready **Where I stopped:** Verify 2026-05-07 (factory-context audit): (a) ✅ `scripts/install.ps1` существует — кросс-платформа есть; (b) ❌ `--prune` flag отсутствует в обоих скриптах; (c) ❌ doc `.wiki/concepts/install-cross-platform.md` не написан. 1/3 acceptance — не закрывать. Пересечение с `[claude-skills-update-skill]`: оба про install/build/prune trinity. Имеет смысл сделать вместе — `--prune` логику добавить в существующие `install.{ps1,sh}` параллельно с новыми `update.{ps1,sh}` (которые будут жить в том же `scripts/`). Doc `install-cross-platform.md` тогда покрывает всю четвёрку. **Next action:** (a) уже есть. Остаётся: (b) добавить `--prune` flag в `scripts/install.ps1` и `scripts/install.sh` — для каждого имени в `~/.claude/skills//`, отсутствующего в `skills//`, удалить (lesson из `[compress-dedup]`). (c) написать `.wiki/concepts/install-cross-platform.md` — документировать parity-инвариант (PS+bash сpan, identical behavior, paired flags, error semantics). Опционально: совместить с `[claude-skills-update-skill]` (см. её next_action). **Branch:** (not started) --- ## ⚪ [archive-roundtrip-test] — smoke-test for .skill archive shape **Status:** ready **Where I stopped:** (not started) — caught the PowerShell-Compress-Archive backslash bug manually; a smoke-test would catch the next regression automatically **Next action:** add a script that builds `dist/.skill`, unzips into a temp dir, and `diff -r` against `skills//`. Fail on any difference. Run from CI or pre-commit if we add one **Branch:** (not started) --- ## 🟡 [active-platform-eval] — eval-driven tuning of active-platform (description + body), absorbs `[active-platform-tuning]` **Status:** paused **Where I stopped:** design doc complete (`.wiki/concepts/active-platform-eval-design.md`, ~150 lines); per-task file complete (`.tasks/active-platform-eval.md`); STATUS.md collapsed the two original ⚪ tasks into this one block. Pre-flight verified: `claude` CLI on PATH at `C:\nvm4w\nodejs\claude.ps1` (Claude Code 2.1.128); `run_loop.py` present at `~/.claude/plugins/cache/claude-plugins-official/skill-creator/unknown/skills/skill-creator/scripts/run_loop.py`. Stopped right before eval-set authoring at user request — paused for asynchronous follow-up. No code touched, no tooling launched, no `.tasks/active-platform-eval/` workspace dir created yet. **Next action:** resume by answering Q2 from the chat ("eval set — write 20 queries solo from current SKILL.md + concept-page open questions, or run skill-creator's HTML review template first for user-driven edits before kickoff?"), then (a) build `.tasks/active-platform-eval/eval-set.json`, (b) snapshot skill to `.tasks/active-platform-eval/skill-snapshot/`, (c) launch run_loop.py in background, (d) parallel manual body sweep, (e) apply changes + bump to 1.1.0 + rebuild + reinstall + final report + commit. **Branch:** master --- ## ⚪ [skills-grouping-revisit] — revisit flat vs grouped skills/ layout if count grows past ~30 **Status:** ready **Where I stopped:** (not started) — current 14 skills fit fine in flat `skills/`; threshold for revisiting is ~30 **Next action:** when triggered (skill count crosses threshold), evaluate variant B (grouped by family) vs variant C (flat + manifest) from the original brainstorm in `.wiki/concepts/repo-layout.md` **Branch:** (not started) --- ## 🟢 [setup-interns-fix-paths] — fix `/.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 `/.common/...` replaced with `~/projects/.common/...` across Phase 0–8, 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 --- ## 🟢 [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 **Where I stopped:** (not started) **Next action:** Invoke the `project-bootstrap` skill at the repo root, confirm each file write, push to main. **Branch:** n/a --- ## 🟢 [using-projects-meta-fix-paths] — fix stale `~/.local/projects-meta-mcp/` paths in `setup-projects-meta` SKILL.md **Status:** done **Where I stopped:** `setup-projects-meta/SKILL.md` lines 152–154 (Phase 5 platform-path table) переписаны с `~/.local/projects-meta-mcp` на `~/projects/.common/lib/projects-meta-mcp` (Windows/Linux/macOS варианты); `version:` bump 1.0.0 → 1.0.1 (PATCH, doc consistency); rebuild `dist/setup-projects-meta.skill` + install в `~/.claude/skills/setup-projects-meta/` подтверждены (frontmatter `version: 1.0.1` в установленной копии); `using-projects-meta/{SKILL,README}.md` уже были чистые из прошлых коммитов; line 224 (`Path forms (~/.local/..., ~/.config/..., ~/projects/...) are identical on all three.`) намеренно оставлена как generic POSIX-path syntax aside, не projects-meta install reference **Next action:** (none — kept until merged) **Branch:** master --- ## 🟢 [interns-repo-read-skill-updates] — Skill-side updates for the `repo_read` intern (design at claude-skills/.wiki/concepts/interns-repo-read-design.md). Two coordinated edits: (1) `using-interns/SKILL.md` routing section — add hints on when to use `repo_read` vs `bulk_text_read`, MINOR bump; (2) `setup-interns/SKILL.md` — add Node-in-PATH check + optional `npx repomix@latest --version` pre-warm step, MINOR bump. Blocked by `common#interns-repo-read-impl` only for end-to-end test; skill edits themselves can ship in parallel. **Status:** done **Where I stopped:** both skills edited (0.1.0→0.2.0), rebuilt + installed, versions verified on disk **Next action:** (none — kept until merged) **Branch:** n/a --- ## 🟢 [project-creation-lifecycle-skill] — Extend `project-bootstrap` (or add a new `create-project` skill) to cover the **full new-project lifecycle**, not just upgrading an existing folder. **Gap surfaced 2026-05-06** при промоушене брейнсторма `factory-bootstrap`: репо `git.kzntsv.site/OpeItcLoc03/factory` был создан ad-hoc (git init + gitea repo create + push), без бутстрапа `.tasks/STATUS.md` и `.wiki/index.md`. Из-за этого `projects-meta-mcp:sync-runner.ts:69` отбрасывал репо как «не проект», и `knowledge_ingest target=factory` / `tasks_create target=factory` валились с «project not in cache». Промоушн встал, пришлось вручную сидить layout через прямые `Write` + push. Это чинится один раз в скиле, а не каждый раз руками. **Что должен делать новый flow** (один обход): 1. Создать локальную папку `~/projects//` (валидация: latin, kebab-case, не существует). 2. `git init` + первоначальный `.gitignore` + минимальный `README.md`. 3. Создать гитеа-репо в org/user через Gitea API (auth из `~/.config/projects-mcp/auth.toml`), set remote, push initial commit. 4. Делегировать в `setup-wiki` + `setup-tasks` для канонического layout (или inline-fallback с записью в bootstrap-manifest). 5. `node ~/projects/.common/lib/projects-meta-mcp/dist/sync.js` — re-sync кэша, чтобы новый репо стал виден projects-meta. 6. Опционально: `tasks_create target=_meta slug=-onboarded` — чтобы новый проект засветился на кросс-проектном борде с момента создания. **Два варианта дизайна — выбрать в скил-creator:** - **(a) Extend `project-bootstrap`** — добавить flag `--create` (или авто-detection «папки нет / git remote нет»), который запускает шаги 1–3 и 5–6. Существующий path для «уже существующая папка → upgrade» сохраняется. Плюс: один скил для всего lifecycle. Минус: SKILL.md распухает. - **(b) Новый скил `create-project`** — отдельный entry-point, в конце дёргает `project-bootstrap` для шагов 4 (layout). Плюс: single-responsibility. Минус: ещё один скил в реестре, юзеру выбирать какой звать. Склоняюсь к (a) — `project-bootstrap` уже знает про оба режима init/upgrade (см. SKILL.md Step 0), четвёртый под-режим «greenfield + remote create» естественно туда ложится. Но это решение уровня skill-creator. **Acceptance criteria:** - Новый flow прогоняется на пустой папке: `~/projects/.test-greenfield/` → один вызов скила → конец: репо в gitea, layout в `.wiki/`/`.tasks/`, виден в `mcp__projects-meta__meta_status`. - Существующий upgrade-mode не сломан (regression-test на `.factory/` после этого фикса — re-run должен быть no-op). - README скила обновлён. **Status:** done **Where I stopped:** Shipped в `23431c5 feat(project-bootstrap): add greenfield-full mode with remote create`. Variant (a) — extend `project-bootstrap`. SKILL.md v1.8.0 → 1.9.0 (mode `greenfield-full` + `add-remote` + `upgrade`); Step 1.5 (remote create через Gitea API + auth.toml + push initial); Step 8 (projects-meta sync через `dist/sync.js`). README обновлён под три режима. ⚠️ Acceptance criteria smoke-test «один вызов на `.test-greenfield/`» **не прогонялся** — surfaced в `using-tasks-close-coverage-gate`. Закрыто по shipped-code-баребоне; regression-test трек отдельно. **Next action:** (none — kept until merged); regression-smoke-test на пустой папке трекать через `using-tasks-close-coverage-gate` **Branch:** n/a --- ## 🟢 [extend-project-discipline-brainstorm-workspaces] — Расширить `project-discipline` (`C:\Users\vitya\.claude\skills\project-discipline\SKILL.md`) явным обращением к **transit-zone / brainstorm-workspaces** типа `~/projects/.meeting-room/`. **Gap surfaced 2026-05-05:** Rule 1 скила («project conventions override skill defaults») написан для проектов с `.wiki/` / `.tasks/`. Не покрывает кейс, когда workspace **сам по себе** — discussion-zone, и его README/CLAUDE.md явно говорит «здесь no `.tasks/`, transit zone, всё уезжает в глобал». В той сессии я неправильно применил «transit-zone autopilot» — потащил artifact из брейнсторма в `~/projects/.wiki/concepts/` без явной директивы пользователя. Корректировка: artifacts уезжают в `.brainstorm/.md` (in-progress) ИЛИ в глобал-вики (mature, user-directed) — никогда автопилотом по аналогии с Rule 1. **Предлагаемая поправка к SKILL.md:** 1. Default destination для in-progress brainstorm artifacts: `.brainstorm/.md` (или чем README workspace'а это объявил). 2. Default destination для mature, cross-cutting outputs: `~/projects/.wiki/concepts/-design.md` через `mcp__projects-meta__knowledge_ingest` — **только** когда user явно это направил. 3. Агент **не должен** auto-promote brainstorm-артефакты в глобал-вики по аналогии с Rule 1; convergence-moment решение принадлежит user'у. **Reference:** `.meeting-room/CLAUDE.md` уже описывает «hard rules» этого workspace'а (правила §1–§4) — это конкретный пример того, что project-discipline должен явно поддерживать. **Acceptance criteria:** - В SKILL.md `project-discipline` появилась секция «Transit-zone / brainstorm workspaces» с тремя пунктами выше. - Регрессия: на тестовом meeting-room сессии (как 2026-05-05) агент не вытаскивает brainstorm в `.wiki/concepts/` без user-команды. **Status:** done **Where I stopped:** Shipped в `215afdd feat(project-discipline): add Rule 5 — transit-zone workspaces`. SKILL.md v0.1.0 → 0.1.1 (PATCH; описано в commit как добавление, де-факто новая секция — но user-decision на PATCH). Rule 5 содержит три обязательных пункта (`.brainstorm/.md` для in-progress, global wiki только по user-команде, no auto-promote по аналогии с Rule 1). `.meeting-room/CLAUDE.md` служит каноничным примером (упомянут в Example блоке Rule 5). **Next action:** (none — kept until merged) **Branch:** n/a --- ## 🟢 [recommend-dont-menu-skill] — Создать новый скил `recommend-dont-menu` (имя обсуждаемо в skill-creator) — codifies user-style override: в design-conversations, брейнстормах, code review агент даёт **одну аргументированную рекомендацию**, а не меню вариантов A/B/C/D. **Why skill, not CLAUDE.md:** правило сейчас живёт в `~/.claude/CLAUDE.md` на одной машине (создан 2026-05-06). Per-machine, per-agent — на новом ноуте его не будет, Gemini/Copilot его не прочитают. Скил в claude-skills клонится на все машины как L1 component factory-manifest'а; trigger-line в CLAUDE.md template наследуется всеми проектами через project-bootstrap. **Содержимое скила (SKILL.md body — готово, копируется из удалённого memory entry):** > Default mode для design-questions: «Я рекомендую X, потому что Y₁, Y₂. Trade-off: Z. Возражения?» > > Альтернативы упоминать **только если они реально близки** или несут важный trade-off, который user должен взвесить — тогда коротко: «Если важно W — лучше X', но добавляет сложность; иначе X». > > Не перечислять варианты ради видимости вариативности. Меню тормозит когда один вариант очевидно лучше — вынуждает читать заведомо проигрышные опции и задвигает позицию агента за обтекаемое перечисление вместо ответственной рекомендации. > > Это override стандарта `superpowers:brainstorming`, где multiple-choice указан как preferred. User instructions > skill defaults. **Frontmatter (черновик):** ```yaml --- name: recommend-dont-menu description: Use during design discussions, brainstorming, architecture reviews, or any "what should we do" question — give one argued recommendation with explicit trade-offs, not a multiple-choice menu. Override of superpowers:brainstorming default. version: 0.1.0 --- ``` **Triggers (когда скил активируется):** - Любые design / architecture / "что выбрать" вопросы. - Активные брейнстормы (где `superpowers:brainstorming` тоже бы подцепилось — этот скил **переопределяет** его стиль). - Code review с альтернативами. - В `.meeting-room/` — постоянно (в её workspace contract это default для совещаний). **Cross-agent applicability:** скил — про стиль ответа, не про tool calls, поэтому работает на любом агенте без mappings (в отличие от `using-superpowers`, которому нужны `references/copilot-tools.md` и т.д.). В description явно отметить «works on any agent — pure response-style rule». **Integration tasks:** 1. **Trigger-line в `project-bootstrap` CLAUDE.md template.** Добавить строку в canonical set (`assets/CLAUDE.md.template`, см. `project-bootstrap/SKILL.md` Step 5). Кандидаты: `prefer single recommendations`, `recommend, don't menu`, `argued recommendations`. Решает skill-creator. После — в Step 5.6 (skill dependencies check) добавить новую строку в trigger→fulfiller table. 2. **Свернуть `~/.claude/CLAUDE.md`** на машинах, где скил установлен, до одной trigger-строки. Текущее содержимое (1 параграф правила) переносится в SKILL.md body, в global CLAUDE.md остаётся только триггер. 3. **Cross-agent prop:** trigger-line должен попасть в `~/.gemini/GEMINI.md` и `~/.copilot/AGENTS.md` — следствие, отдельная подзадача (либо часть `setup-*` для соответствующих агентов, либо часть будущего factory L1 manifest'а). **Acceptance criteria:** - `~/.claude/skills/recommend-dont-menu/SKILL.md` существует, проходит skill-validation. - Trigger-line в `project-bootstrap/assets/CLAUDE.md.template` + соответствующий ряд в Step 5.6 trigger→fulfiller table. - Регрессионный smoke-test: в test-сессии после установки скила я (агент) на «как лучше — X или Y?» отвечаю «рекомендую X, потому что Z. Возражения?» вместо меню. - В `using-superpowers/SKILL.md` или `superpowers:brainstorming` упомянут override (либо через priority-секцию, которая уже есть: «User instructions > Superpowers skills > Default»). **Reference:** правило выкристаллизовалось в брейнсторме interns 2026-05-05, проверено многократно в `.meeting-room/` сессиях. Source content до удаления memory лежал в `feedback_brainstorm_recommend_dont_menu.md` (memory была удалена 2026-05-06 после переноса в `~/.claude/CLAUDE.md`, который сам теперь временный). **Status:** done **Where I stopped:** Shipped в `011a8b4 feat(recommend-dont-menu): add skill + integrate into project-bootstrap [v0.1.0 / v1.9.0]`. Skill at `skills/recommend-dont-menu/SKILL.md` v0.1.0; trigger-line `recommend, don't menu` в `project-bootstrap/assets/CLAUDE.md.template:12`; row в Step 5.6 trigger→fulfiller table at `project-bootstrap/SKILL.md:447`; override упомянут в SKILL.md секция "## Override". `project-bootstrap` bumped 1.8.0 → 1.9.0 (MINOR; одновременно с greenfield-full mode из `[project-creation-lifecycle-skill]` — single bump cover both features). Heading emoji приведён к `done`-канону 2026-05-06 (был ⚪ при `Status: 🟢 Done` — рассинхрон, surfaced `using-tasks-close-coverage-gate`). **Next action:** (none — kept until merged) **Branch:** n/a --- ## 🟢 [hermes-converter-mvp] — Build conversion infrastructure для Hermes-rollout: создать `hermes/mapping.yaml` (схема: per-skill `mode: auto|manual|skip`, `category`, `replace-rules`, `skip-list` + `reason`), написать `scripts/build-hermes.{sh,py}` (читает `skills//SKILL.md` или `hermes/skills//` для manual, применяет mapping, пишет `dist-hermes///`, генерит `dist-hermes/SKIPPED.md` с per-skip reason'ами). Прогнать через 4 universal: `pulling-before-work`, `active-platform`, `project-discipline`, `using-markitdown`. Закоммитить `dist-hermes/` для этих 4 в репу. Дизайн: `.wiki/concepts/hermes-skills-rollout-design.md`. Pre-encode security уроки (extraheader-pattern, POSIX-absolute paths, version-bump per Rule 3) на этапе шаблонов конвертера. **Status:** done **Where I stopped:** Shipped в `6b36b31 feat(hermes): MVP converter + 4 universal skills converted`. (1) `hermes/mapping.yaml` — 4-mode schema (`auto`/`manual`/`skip`/`pending`); 22 skills mapped explicitly; build fails on unmapped (verified on synthetic `fake-skill` → exit 1). (2) `scripts/build-hermes.py` — Python (PyYAML 6.0.3); replace-rules ordered string-substitution on SKILL.md only; manual mode copies `hermes/skills//` verbatim; SKIPPED.md auto-generated с pending intended-mode preserved. (3) 4 universal через converter в `dist-hermes/`: `pulling-before-work` + `project-discipline` (with READMEs) → `software-development/`; `active-platform` (replace-rules `**Windows + PowerShell.**` → `**Linux + bash.**` + reasoning sentence) → `software-development/`; `using-markitdown` → `productivity/`. (4) `dist-hermes/` committed (8 файлов: 4 SKILL.md + 2 README.md + SKIPPED.md). (5) Security infra: replace-rules + manual mode ready; concrete extraheader / POSIX / version-bump templates land в `hermes-flavour-mcp-setups` (per design separation `.wiki/concepts/hermes-skills-rollout-design.md` § Связанные таски). README.md updated (новая секция `### Build for Hermes` + Layout). Per-task file `.tasks/hermes-converter-mvp.md`. **Smoke:** idempotent re-run no diff; replace-rules verified via grep on `dist-hermes/.../active-platform/SKILL.md`; strict-mapping fail-fast verified. **Next action:** (none — kept until merged); unblocks `[hermes-flavour-mcp-setups]`, `[hermes-installer-skill]`, `[hermes-mvp-coverage]` **Branch:** master --- ## 🟢 [hermes-flavour-mcp-setups] — Переписать `setup-projects-meta` и `setup-context7` в Hermes-flavour: вместо клона/билда — yaml-edit `~/.hermes/config.yaml > mcp_servers.` (stdio command pointing к `~/projects/.common/lib/projects-meta-mcp/dist/server.js`, env-vars из `~/.config/projects-mcp/auth.toml`), затем `/reload-mcp`. Обе версии лежат как `mode: manual` в `hermes/skills/setup-projects-meta-hermes/SKILL.md` и `hermes/skills/setup-context7-hermes/SKILL.md` (конвертер копирует as-is, без преобразований). Pre-check: бинарь existing в `~/projects/.common/lib/projects-meta-mcp/`, `auth.toml` existing в `~/.config/projects-mcp/`. Применить extraheader-pattern сразу на git-clone fallbacks (если pre-check провалится). Дизайн: `.wiki/concepts/hermes-skills-rollout-design.md`. Зависит от `hermes-converter-mvp` (нужен mapping.yaml schema понимающий `mode: manual`). **Status:** done **Where I stopped:** Shipped в `5990b06 feat(hermes): flavour-mcp-setups + installer-skill`. `hermes/skills/setup-projects-meta/SKILL.md` + `hermes/skills/setup-context7/SKILL.md` написаны (mode: manual, yaml-edit паттерн); mapping.yaml: оба pending → manual; `dist-hermes/mcp/setup-projects-meta/` + `dist-hermes/mcp/setup-context7/` populated; extraheader-pattern на git-clone fallback включён. **Next action:** (none — kept until merged) **Branch:** master --- ## 🟢 [hermes-installer-skill] — Написать `dist-hermes/meta/claude-skills-installer/SKILL.md` — recursive bootstrap installer для Hermes-стороны. SKILL'у на триггер «установи скилы из claude-skills» / «обнови claude-skills»: итерирует по `dist-hermes///` (всем кроме `meta/`), для каждого вызывает `skill_manage(action='create', category=, name=, content=, assets=)`. Учитывать `dist-hermes/SKIPPED.md` — не пытаться установить пропущенные. Документировать **bootstrap-процедуру** в `claude-skills/README.md` (Linux/Hermes раздел): один раз вручную `skill_manage(action='create', from=)`, далее команда «обнови claude-skills» работает сама. Recursive: installer обновляется вместе со всем остальным через `git pull && trigger update`. Дизайн: `.wiki/concepts/hermes-skills-rollout-design.md`. **Status:** done **Where I stopped:** Shipped в `5990b06 feat(hermes): flavour-mcp-setups + installer-skill`. `dist-hermes/meta/claude-skills-installer/SKILL.md` написан (recursive bootstrap, iterates dist-hermes/ excluding meta/, calls skill_manage); README.md Hermes quick-start секция добавлена. **Next action:** (none — kept until merged); smoke-test на фабричной Linux box ещё не прогонялся **Branch:** master --- ## 🟢 [hermes-mvp-coverage] — Расширить `hermes/mapping.yaml` и пропустить через converter оставшиеся 9 MVP-скилов: `setup-tasks`, `using-tasks`, `setup-wiki`, `using-wiki`, `using-projects-meta`, `using-context7`, `project-bootstrap` (адаптируется последним — orchestrator). Замечания: (a) `using-wiki`/`setup-wiki` поверх Hermes built-in `research/llm-wiki` — наша schema (`.wiki/CLAUDE.md`, `entities/persons/`, `packages/`, `raw/research,transcripts`) сохраняется через override-precedence; (b) `project-bootstrap` Hermes-flavour убирает CLAUDE.md trigger-lines (Hermes auto-discover), оставляет git/gitignore/README/setup-wiki/setup-tasks orchestration. End-to-end smoke-test на фабричной Linux-машине: `git clone claude-skills` на чистую box → `skill_manage` installer → trigger «установи всё» → `hermes skills list` показывает все 13 в правильных категориях → `mcp__projects_meta__*` тулы доступны после `/reload-mcp`. Дизайн: `.wiki/concepts/hermes-skills-rollout-design.md`. **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). **Next action:** (none — kept until merged); unblocks `hermes-converter-ci` --- ## ⚪ [hermes-converter-ci] — [deferred — после ручной валидации MVP] CI hook (Gitea-pipeline или GitHub-Action если зеркалим): на push to master запустить `scripts/build-hermes.py`, сравнить diff `dist-hermes/`, авто-коммит если изменения (или PR-шаблон). Цель — чтобы `dist-hermes/` всегда матчил `skills/`+`hermes/mapping.yaml`+`hermes/skills/` без ручного запуска build. Не блокирует MVP — первая итерация делается ручным запуском конвертера. Дизайн: `.wiki/concepts/hermes-skills-rollout-design.md`. **Status:** ready **Where I stopped:** unblocked 2026-05-07 — `hermes-mvp-coverage` shipped в `a003b80`; MVP живой на фабрике. **Next action:** Выбрать платформу CI (Gitea Actions vs внешняя), написать workflow, прогнать тестовый push. **Branch:** master --- ## 🟢 [using-tasks-close-coverage-gate] — Расширяет `using-tasks` SKILL **двумя коррелированными правилами для decision-points** (изначально таска была только про close-coverage; scope-priority добавлен 2026-05-06 после session-start ревью отчёта claude-skills агента). **Часть A — Pre-close coverage gate** (исходный scope). `using-tasks` должен явно требовать coverage-проверку acceptance-criteria тестами **перед** вызовом `tasks_close`. Surfaced 2026-05-06 в код-ревью factory-bootstrap fallout: 3 из 4 common-фиксов закрыты по «150/150 / 151/151 tests pass» (existing suite), но новые behaviour не покрыты — нет теста на `cached = null` invalidation, нет теста на `AggregateStatusEnum` validation error, partial test на archived-filter. Acceptance criteria требовали regression-тестов — пропущены. Также: после `feat:`/`fix:` коммита skill должен подсказывать «эта работа закрывает таску ``?» — иначе код shipped (`215afdd`, `23431c5` в claude-skills) при stale ⚪ ready статусе (`extend-project-discipline-brainstorm-workspaces`, `project-creation-lifecycle-skill`). **Часть B — Scope priority at recommendation time** (added 2026-05-06). При session-start (или любой триггер «что делать дальше / куда копаем»), рекомендации должны идти **в порядке**: сначала ranked-список из cwd-проекта (🔴 active → 🟡 paused → ⚪ ready), потом — **одна footnote-строка** «есть 🔴 в других проектах: , см. `tasks_aggregate`», если релевантно. Cross-project — информация, не driver рекомендации. Surfaced когда другой агент в claude-skills cwd рапортовал «Срочные — 3 🔴 в других проектах (stostayer.new, modules-db, crsc.web)» — выводя cross-project в первую строку, хотя у юзера cwd был claude-skills и интересовали локальные таски. `using-projects-meta` уже декларирует local-first для **чтений** — нужно распространить на **recommendation phase**. Парный фикс к `common#tasks-close-normalize-body` (там tooling, тут policy/skill). После закрытия: новые hermes-таски попадут в починенный close-flow + рекомендации фокусируются в cwd-проекте. **Status:** done **Where I stopped:** Shipped в `b0d2d51 feat(using-tasks): pre-close coverage gate + local-first recommendations [v1.1.0]`. Часть A: `### Task completion` step 1 — pre-close coverage check со списком acceptance criteria и грозой gap'а; новая секция `### Post-commit task closure prompt` — на `feat:`/`fix:` коммитах prompt про closure (skips `chore:`/`meta:`). Часть B: новая секция `### Recommendations / "what's next" trigger` — local cwd-board first, cross-project как одна footnote-строка; explicit cross-project trigger flips order. README.md mirrored. Version bump 1.0.0 → 1.1.0 (MINOR, **не PATCH** как было в next_action — Rule 3 grades adding 2 new operation types as capability addition). Build+install подтверждены, `~/.claude/skills/using-tasks/SKILL.md` shows `version: 1.1.0`. **Smoke-tests:** (1) coverage-check триггернулся на самой этой close-операции (acceptance criteria verified inline above); (2) local-first рекомендации сработали раньше в этой сессии — на «discipline pre-reqs первыми» отчёт фокусировался на claude-skills, не на cross-project 🔴. **Next action:** (none — kept until merged) **Branch:** master --- ## 🟢 [tdd-criteria-skill-write] — runtime artefact for the TDD-criteria policy. Design rationale (the «why» behind every rule + the anti-vandalism leading argument + the test-immutability second-order defence) lives in `.wiki/concepts/tdd-criteria-design.md` (already promoted via `meeting-room-promote-brainstorm` 2026-05-07; NOTE: design doc was promoted at 2026-05-07T04:00 with 3 anti-loophole rules; **rule 4 (test-immutability) was added in this task description below at 2026-05-07T05:00 after user surfaced the symmetric vandalism risk; the impl session must mirror rule 4 into the design doc as well — see «Design doc amendment» section below**). This task writes the **runtime SKILL.md** + amends the design doc to include rule 4. **Frontmatter (YAML):** - `name: tdd-criteria` - `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. **Body sections (use `project-discipline` and `recommend-dont-menu` as structural templates):** 1. **`# tdd-criteria`** — one-line tag-line. 2. **`## When this runs`** — trigger phrases (session-start trigger via `follow tdd-criteria` line in CLAUDE.md, plus on-demand triggers); explicit «applies before any code touches a *.ts/*.js/*.py file the agent didn't author this session». 3. **`## Default mode`** — one sentence: «TDD by default. Skip only if one of four bright-line carve-outs matches and is marked in commit subject.» 4. **`## Decision algorithm (8 questions, top-down)`** — copy the algorithm block verbatim from design doc. 5. **`## Ironclad rules (TDD obligatory)`** — 4 rules, each ≤3 lines: trigger property + what test type. No rationale (rationale = design doc). 6. **`## Permissive carve-outs (skip + marker required)`** — 4 categories, each ≤2 lines: trigger + marker. 7. **`## Anti-loophole`** — **4 rules** (was 3 before the 2026-05-07 amendment): - Rule 1: skip-without-category invalid - Rule 2: spike-survivor (backfill-tests task on merge) - Rule 3: friction is the point (don't relax before ≥2 weeks) - **Rule 4 (NEW): tests are append-only by default.** Modifying assertion / deleting test / disabling (`it.skip`/`xit`/`@skip`/`@Disabled`) requires: - **Marker in commit subject:** `[test-modify: : was ; is ; reason: ]` where `` and `` are the **literal assertion expressions** (not paraphrased). - **Separate commit from impl changes:** a commit must not modify both `*.test.*` and `src/*` files (or project-equivalents). `git log --grep '\[test-modify'` must give a clean test-only audit trail. - **Why literal `was/is`:** an agent forced to write the literal assertion publishes exactly what they're rewriting. Reasons like «updated to match new behaviour» hide vandalism — agents will use them whenever allowed. - **Bright-line check** for an optional pre-commit hook (see follow-up task `tdd-criteria-precommit-hook`): diff includes removed `expect(...)` / changed assertion args / added `.skip`/`xit`/`@skip` / deleted test definition AND commit subject has no matching `[test-modify: ...]` → block. AND files include both test-pattern and impl-pattern → block (require split). - Composite-task pattern (decompose by artefact) is example, not rule. 8. **`## Cross-agent applicability`** — pure policy, no Claude tool refs, Hermes-mappable as `mode: auto`. 9. **`## Out of scope`** — does not enforce via git hooks (separate optional task `tdd-criteria-precommit-hook`); does not modify project CLAUDE.md (that's `project-bootstrap`'s job); does not run tests. 10. **`## Why this exists`** — one paragraph: «Tests make behaviour an invariant; without them code is an artefact silent-deletable by agents. AND: the test itself must be defended too (rule 4) — otherwise the contract collapses back into an artefact when the agent rewrites the failing test. Full rationale at `.wiki/concepts/tdd-criteria-design.md`.» **Constraints:** - No `Read/Edit/Glob/Bash` references in body — keep it agent-agnostic. - No code blocks with shell commands — pure policy doc. - Length target: ≤220 lines (project-discipline ~140, this is denser due to rule 4). - Frontmatter version starts at `0.1.0` (per Rule 3 of `project-discipline`: first edit of new versioned artefact = add 0.1.0, not bump). **Design doc amendment (do in same impl session):** After SKILL.md is written, also amend `~/projects/claude-skills/.wiki/concepts/tdd-criteria-design.md` to add rule 4 to the «Anti-loophole» section AND extend «The argument behind TDD-default» with a sub-section «The contract is only as strong as the contract itself». Full text below — paste verbatim, no rewriting: --- **ADD to «The argument behind TDD-default» section, after the existing paragraphs:** ```markdown ### The contract is only as strong as the contract itself But there's a **second-order vandalism mode** that the bare contract argument doesn't cover: the agent doesn't delete the code, it rewrites the **test**. Test fails → agent changes the expected value, adds `.skip`, or deletes the test → test now passes → success reported. If the contract artefact (the test) is rewritable by the same agent that's failing to satisfy it, the invariant collapses back into an artefact. The defence requires **two layers**: 1. **Code is defended by tests.** Ironclad rules 1-4 below. 2. **Tests are defended by process discipline.** Anti-loophole rule 4 below — append-only by default, modifications require literal-`was/is` marker in commit subject, test changes are separate commits from impl changes. Both layers are needed. Either alone leaves a path-of-least-resistance route to «success». ``` **ADD to «Anti-loophole» section (after rule 3):** ```markdown 4. **Tests are append-only by default** (added 2026-05-07). New tests: free. **Modifying** an existing assertion, **deleting** a test, or **disabling** it (`it.skip`, `xit`, `@pytest.mark.skip`, `@Disabled`, etc.) requires both: **a)** A marker in commit subject: `​`` [test-modify: : was ; is ; reason: ] `​`` Where `` and `` are the **literal assertion expressions** before and after, not paraphrased. Example: `​`` [test-modify: validates email format: was expect(isValid("a@b")).toBe(true); is expect(isValid("a@b.com")).toBe(true); reason: tightened spec to require TLD] `​`` **b)** Test changes go in a **separate commit** from any impl changes. A single commit must not modify both `*.test.*` and `src/*` files (or their project-equivalents). This forces an audit-able split — `git log --grep '\[test-modify'` shows every test rewrite cleanly. **Why literal `was/is`, not free-form reason:** an agent forced to write the literal assertion publishes exactly what they're rewriting. If `42` was the correct expectation and they changed it to `43` to make a buggy fix pass, the literal `was 42; is 43` line in `git log` identifies the culprit. A reason like «updated to match new behaviour» hides everything — agents will use it whenever it is allowed. **Bright-line check** (for an optional pre-commit hook, see follow-up task `tdd-criteria-precommit-hook`): - `git diff --cached` includes a removed `expect(...)` / `assert(...)` / `assertThat(...)` line, OR - changes the arguments of an existing assertion call, OR - adds `.skip`, `xit`, `@skip`, `@Disabled`, etc. annotation, OR - deletes a test file or `it(...)` / `test(...)` / `def test_*` definition AND the commit subject does not contain `[test-modify: ...]` matching the format above → block. AND `git diff --cached --name-only` includes both test-pattern and impl-pattern files → block (require split). 5. **Don't apply rule 4 retroactively** to tests written before the rule was adopted. The rule applies to test changes made after the project's CLAUDE.md picks up `follow tdd-criteria`. Existing test bodies aren't grandfathered into requiring `was/is` for a one-time rewrite. ``` **ADD to «What's excluded as not bright-line»:** - ~~«Tests should not be modified casually»~~ — paraphrasable, agents will modify casually and call it «refactor». Replaced by Anti-loophole rule 4 with literal-evidence requirement. **ADD to «Trade-offs» section:** - **The literal-`was/is` requirement is verbose** for a renamed test or trivial typo fix. The verbosity is the point — an agent that genuinely fixed a typo writes the same assertion twice with one character changed; an agent that rewrote a failing test writes obviously different assertions. Reading `git log --grep '\[test-modify'` shows the difference at a glance. **UPDATE frontmatter** to add `amended: "2026-05-07: added test-immutability defence (Anti-loophole rule 4) after user noted symmetric vandalism risk on tests"`. --- **Commit pattern for impl session:** - Commit 1: `skills/tdd-criteria/SKILL.md` (new file). Subject: `feat(skills): tdd-criteria skill v0.1.0 [TDD-default + 4 carve-outs + 4 anti-loophole rules incl. test-immutability]`. - Commit 2: `.wiki/concepts/tdd-criteria-design.md` (amend). Subject: `docs(tdd-criteria): rule 4 — test-immutability defence (was X; is Y marker)`. Note: this is wiki, not test code, so `[test-modify]` rule doesn't apply to this commit — rule 4 governs *test* file changes, not wiki rationale changes. **Frontmatter (YAML):** - `name: tdd-criteria` - `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: ...]", 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):** 1. **`# tdd-criteria`** — one-line tag-line. 2. **`## When this runs`** — trigger phrases (session-start trigger via `follow tdd-criteria` line in CLAUDE.md, plus on-demand triggers); explicit «applies before any code touches a *.ts/*.js/*.py file the agent didn't author this session». 3. **`## Default mode`** — one sentence: «TDD by default. Skip only if one of four bright-line carve-outs matches and is marked in commit subject.» 4. **`## Decision algorithm (8 questions, top-down)`** — copy the algorithm block verbatim from design doc. 5. **`## Ironclad rules (TDD obligatory)`** — 4 rules, each ≤3 lines: trigger property + what test type. No rationale (rationale = design doc). 6. **`## Permissive carve-outs (skip + marker required)`** — 4 categories, each ≤2 lines: trigger + marker. 7. **`## Anti-loophole`** — 3 bullets: skip-without-category invalid; spike-survivor rule; composite-task = decompose by artefact. 8. **`## Cross-agent applicability`** — pure policy, no Claude tool refs, Hermes-mappable as `mode: auto`. 9. **`## Out of scope`** — does not enforce via git hooks (separate optional task `tdd-criteria-precommit-hook`); does not modify project CLAUDE.md (that's `project-bootstrap`'s job); does not run tests. 10. **`## Why this exists`** — one paragraph: «Tests make behaviour an invariant; without them code is an artefact silent-deletable by agents. Full rationale at `.wiki/concepts/tdd-criteria-design.md`.» **Constraints:** - No `Read/Edit/Glob/Bash` references in body — keep it agent-agnostic. - No code blocks with shell commands — pure policy doc. - Length target: ≤200 lines (project-discipline is ~140 — similar density). - Frontmatter version starts at `0.1.0` (per Rule 3 of `project-discipline`: first edit of new versioned artefact = add 0.1.0, not bump). **Status:** done **Where I stopped:** Shipped в `954f8ba feat(skills): tdd-criteria skill v0.1.0`. SKILL.md 86 lines, 4 ironclad + 4 permissive + 4 anti-loophole (incl. rule 4 test-immutability), 0 Claude-tool refs. Design doc amended в `2ba6981` — rule 4 + subsection + trade-off + excluded formulation added. **Next action:** (none — kept until merged) **Branch:** master --- ## 🟢 [tdd-criteria-hermes-mapping] — Add entry for `tdd-criteria` skill to `~/projects/claude-skills/hermes/mapping.yaml`. Required step — `build-hermes.py` fails on unmapped skills. **Entry (place alphabetically among `auto`-mode skills, after `project-discipline`):** ```yaml tdd-criteria: mode: auto category: software-development ``` **No `replace-rules`** — the skill is pure policy (no Claude-tool refs like `Read`/`Edit`/`Bash`/`Glob` in SKILL.md body). Verified by `tdd-criteria-skill-write` task constraints. **Verification step:** run `python ~/projects/claude-skills/scripts/build-hermes.py` after edit — output must include `tdd-criteria` in the converted list under `dist-hermes/software-development/tdd-criteria/`. If build fails on `Unmapped skill: tdd-criteria` the entry didn't take; if it fails with replace-rule errors, the SKILL.md inadvertently has Claude-tool refs (loop back to `tdd-criteria-skill-write` to clean). **Out of scope:** no Hermes-side install / activation (Hermes side handled by `hermes-mvp-coverage` task family separately). This task only ensures the converter knows about the skill. **Status:** done **Where I stopped:** Shipped в `7d308ff feat(hermes): add tdd-criteria mapping (auto, software-development) + rebuild dist-hermes`. Build verified: `dist-hermes/software-development/tdd-criteria/SKILL.md` created. No replace-rules needed (pure policy skill). **Next action:** (none — kept until merged) **Branch:** master --- ## 🟢 [tdd-criteria-build-install] — Build `dist/tdd-criteria.skill` archive, install to `~/.claude/skills/tdd-criteria/`, commit both `dist/` and `dist-hermes/` artefacts. Closes the rollout loop — after this task the skill is live for both Claude (next session) and Hermes (next factory deploy). **Steps:** 1. `bash ~/projects/claude-skills/scripts/install.sh tdd-criteria` — copies `skills/tdd-criteria/` → `~/.claude/skills/tdd-criteria/` (replaces if exists). Verifies skill is loadable in next Claude session. 2. `bash ~/projects/claude-skills/scripts/build.sh tdd-criteria` — zips `skills/tdd-criteria/` → `dist/tdd-criteria.skill`. Cross-platform: bash on Linux/macOS, delegates to PowerShell on Windows without `zip`. 3. `python ~/projects/claude-skills/scripts/build-hermes.py` — regenerates `dist-hermes/` (already done in `tdd-criteria-hermes-mapping`'s verification step, but re-run for clean state before commit). 4. Commit: `dist/tdd-criteria.skill` + `dist-hermes/software-development/tdd-criteria/` (whole tree). 5. Push (subject to project-discipline Rule 4 — ask user if no auto-push grant). **Verification:** - `ls ~/.claude/skills/tdd-criteria/SKILL.md` exists. - `ls ~/projects/claude-skills/dist/tdd-criteria.skill` exists, size > 0. - `ls ~/projects/claude-skills/dist-hermes/software-development/tdd-criteria/SKILL.md` exists. - Optional: in a fresh Claude session, ask «what skills do you have for TDD?» — `tdd-criteria` should surface. **Out of scope:** activation in specific projects (separate task `tdd-criteria-rollout-projects` if user wants to add `follow tdd-criteria` trigger to selected `CLAUDE.md`s). Skill is reachable via description-based pull regardless. **Status:** done **Where I stopped:** Shipped в `62a54c9 build(tdd-criteria): add dist archive`. `install.sh` → `~/.claude/skills/tdd-criteria/`; `build.sh` → `dist/tdd-criteria.skill` (2862 bytes); `build-hermes.py` → `dist-hermes/software-development/tdd-criteria/SKILL.md`. All three artefacts verified on disk. **Next action:** (none — kept until merged) **Branch:** master --- ## 🟢 [tdd-criteria-review] — Code-review checkpoint для брейнсторма `tdd-criteria` (промоушен 2026-05-07). **Status:** done **Where I stopped:** Review complete. 7-point checklist passed. 4 findings applied directly as v0.2.0 (trigger-loophole fix, composite-tasks + refactoring sections, file-extension expansion, wrapper line-count clarification, spike-survivor .tasks/ fallback, foreign-schema fix). 3 minor items deferred as wontfix (retroactivity marker — negligible risk; spike-survivor already has fallback; refactoring is now documented). SKILL.md 0.1.0→0.2.0, design doc amended, rebuilt + reinstalled + hermes rebuilt. **Next action:** (none — kept until merged) **Branch:** master --- ## ⚪ [tdd-criteria-precommit-hook] — Optional pre-commit hook script that automates the bright-line checks from `tdd-criteria` Anti-loophole rules 1 and 4. Project owner opts in per-repo by symlinking / copying to `.git/hooks/pre-commit` (or via `husky` / `lefthook` integration if the project uses them). **Two checks** (both bright-line, both fail-closed): **Check 1 — `[skip-tdd: ]` validation.** If `git diff --cached --name-only` includes a `*.ts` / `*.js` / `*.py` / similar code file (excluding tests and Permissive-zoned paths like `*.css` / `*.env*` / `*.md` / `*.yaml`), require either: - A `*.test.*` / `*.spec.*` / `test_*.py` / similar file present in the same diff, OR - The commit subject (read from `$1` arg, line 1 of `$1` = msg path) matches `\[skip-tdd: (visual|spike|oneshot|wrapper)\]`. If neither holds → block with message: ``` TDD policy violation: code change without test or skip marker. Add a test, or include [skip-tdd: ] in commit subject. See claude-skills/.wiki/concepts/tdd-criteria-design.md for which category applies. ``` **Check 2 — Test-modification audit (`[test-modify]` rule 4).** Detect test-modifying changes in `git diff --cached`: - Removed line matching `^-\s*(expect|assert|assertThat|chai\.)\(` (assertion deletion) - Added/removed lines that change argument values inside `expect(...)` / `assert(...)` calls - Added `.skip` / `\.xit\b` / `@pytest\.mark\.skip` / `@Disabled` / `@Ignore` annotations - Deleted `it(...)` / `test(...)` / `def test_*` definitions (matches `^-\s*(it|test|describe)\(` or `^-def test_`) If any matched → require commit subject matches `\[test-modify: [^:]+: was .+; is .+; reason: .+\]`. Block otherwise with message: ``` Test-modification without [test-modify: ...] marker. Required format: [test-modify: : was ; is ; reason: ] The was/is must be the LITERAL assertion expressions, not paraphrased. See tdd-criteria Anti-loophole rule 4. ``` ALSO: if `git diff --cached --name-only` includes both a test-pattern file AND an impl-pattern file → block: ``` Test changes must be in a separate commit from impl changes (tdd-criteria rule 4b). Run: git reset HEAD && git commit (test-only) && git add && git commit (impl-only). ``` **Implementation:** - Bash script (single file). Cross-platform: works on Linux/macOS and on Windows under git-bash (which Claude/Hermes both already run on). - Path: `~/projects/claude-skills/scripts/tdd-criteria-precommit-hook.sh`. Plus a Windows wrapper `.ps1` that delegates if needed. - Tested on a real repo before commit (`books` is a good candidate — it has Jest tests + `*.test.js` convention). - Documented in `claude-skills/.wiki/concepts/tdd-criteria-design.md` «See also» section (already linked). **Activation pattern (per-repo):** ```bash # Symlink or copy the hook ln -sf ~/projects/claude-skills/scripts/tdd-criteria-precommit-hook.sh \ .git/hooks/pre-commit chmod +x .git/hooks/pre-commit ``` Or via `lefthook.yml` / `.husky/pre-commit` if the project already uses one of those. **Out of scope:** - Mutation testing (Stryker, mutmut) — separate heavyweight infra, not this hook. - Coverage gates — different mechanism, different cost/benefit. - Visual regression infra (Percy, Chromatic) — Permissive-5 acknowledges this is heavyweight; not bundled. - Auto-fixing the violation — hook only blocks; fix is human's job. **Why this is optional, not required by the SKILL.md:** The skill is **policy** that lives in claude-skills and gets pulled into agent context per project. The hook is **enforcement** that needs per-project setup. Some projects opt out of pre-commit hooks entirely (e.g. `karu` if it's pure CSS — no code surface to enforce). Forcing the hook into the skill would couple policy to tooling. **Bypass:** Pre-commit hooks have `--no-verify`. Per `project-discipline` Rule 4 («never skip hooks unless user explicitly asks») agents must not use `--no-verify` — but humans can in emergencies. Each `--no-verify` use should be self-flagged in the commit body («bypassed pre-commit because: ...»). Not enforceable by the hook itself; this is a higher-level audit. **Status:** ready **Where I stopped:** (not started) **Next action:** Решить, нужен ли hook (он опционален) — если да, написать `~/projects/claude-skills/scripts/tdd-criteria-precommit-hook.sh` по спеке в description, протестировать на `books` (Jest-конвенция `*.test.js`), задокументировать activation pattern. Если нет — закрыть как `wontfix` с пометкой что fence чисто социальная (commit subject visible в `git log`). **Branch:** master --- ## 🟢 [bootstrap-add-tdd-trigger] — Добавить `tdd-criteria` в раскатку `project-bootstrap`: канонический триггер в шаблоне `CLAUDE.md` + запись в Step 5.6 (skill-deps check). Сейчас у `tdd-criteria` v0.1.0 есть Hermes-mapping (commit 7d308ff — авто-классификатор по домену software-development), но текстового триггера в раскатываемом `CLAUDE.md` нет — старые/новые проекты явного крючка для агента не получают, срабатывание только через классификацию. Паттерн повторяет коммиты d0a450c (`follow project discipline`, v1.5.0) и dcad950 (`pull remote before work`, v1.4.0). Версия `project-bootstrap` 1.9.0 → 1.10.0 (MINOR — новый канонический триггер). **Status:** done **Where I stopped:** Shipped в `e566df4 feat(project-bootstrap): add tdd-criteria to canonical triggers [v1.10.0]`. Trigger-line `follow TDD criteria` добавлен в `assets/CLAUDE.md.template` + Step 5.6 trigger→fulfiller table. Version 1.9.0 → 1.10.0. **Next action:** (none — kept until merged) **Branch:** n/a --- ## 🟢 [bootstrap-upgrade-canonical-triggers] — Прогнать `project-bootstrap` v1.10.0 в upgrade-режиме на этом проекте. Цель — дописать в `CLAUDE.md` 2 недостающих канонических триггера: `follow tdd-criteria`, `recommend, don't menu`. Уже присутствуют: `pull remote before work`, `follow project discipline`, `delegate to interns when allowed`, `we're on Windows`. Аудит 2026-05-07 через `bulk_text_read`. Контекст — координатор `[bootstrap-rollout-canonical-triggers]` в `_meta` (commit dd933fd). Пилот на `books` подтвердил идемпотентность (158fc95). **Status:** done **Where I stopped:** Shipped в `ac0fa57 chore(bootstrap): upgrade CLAUDE.md — add tdd-criteria, recommend-dont-menu triggers`. 2 файла изменены: CLAUDE.md (+2 triggers), manifest 1.2.0→1.10.1. Verify подтверждён — `git diff --stat` показывал 2 файла. Unblock готов — можно продолжить mass-unblock 5-string группы. **Next action:** (none — kept until merged) **Branch:** master --- ## 🟢 [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 существующей установки: **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 --- ## ⚪ [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 строк правильно мапятся. Симптом: upgrade-mode на репе, где отсутствуют `tdd-criteria` и `recommend-dont-menu` (например claude-skills, cancel-music-webstore, meeting-room, projects-meta-mcp), детектит «already canon» (потому что 4 template-строки уже на месте), не вставляет недостающие 2. Воспроизведено 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 не тронуты. Скил остался в неконсистентном состоянии. **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). **Next action:** (none — kept until merged) **Branch:** master **Next action:** 1) В `skills/project-bootstrap/SKILL.md`, lines 339-342 — добавить две строки в template-литерал в правильном порядке (соответствует канон-порядку из `books@5ca16d9`): ``` pull remote before work follow project discipline follow tdd-criteria ← NEW, после discipline delegate to interns when allowed recommend, don't menu ← NEW, после interns we're on Windows ``` 2) Добавить две prose-paragraph после существующих: - **`follow tdd-criteria`** — после `follow project discipline` paragraph (~line 366). Текст по образцу соседних: что активирует, что делает, install hint, ссылка на `.wiki/concepts/tdd-criteria-design.md`. - **`recommend, don't menu`** — после `delegate to interns when allowed` paragraph (~line 379). Текст: override `superpowers:brainstorming`, одна рекомендация вместо меню, install hint. 3) Bump version frontmatter: `version: 1.10.0` → `1.10.1` (PATCH — bug fix, completing what 1.10.0 заявляла, но не доставила). 4) Build + install: ```powershell pwsh ./scripts/build.ps1 project-bootstrap pwsh ./scripts/install.ps1 project-bootstrap ``` 5) Verify: `head -5 ~/.claude/skills/project-bootstrap/SKILL.md` показывает `version: 1.10.1`. 6) Commit: `fix(project-bootstrap): v1.10.1 — add missing tdd-criteria + recommend-dont-menu to CLAUDE.md template + prose` с body, объясняющим что 1.10.0 был частичным. 7) **Test:** в этой же сессии (после reload-skill через rebuild) — `upgrade project` в `~/projects/claude-skills/`. Должен теперь увидеть 2 missing строки и предложить вставку. Прогнать. Получить 2-файловый коммит (CLAUDE.md +2 + bootstrap-manifest.md 1.2.0 → 1.10.1). Закрыть `[bootstrap-upgrade-canonical-triggers]` в этой же репе. 8) `tasks_close` этой fix-таски + параллельно — после успешного теста — подтвердить в `.meeting-room` сессии, чтобы я мог продолжить mass-unblock 5-string группы и step 3 cleanup. **Branch:** n/a --- ## ⚪ [tasks-board-cleanup-2026-05] — Архивная чистка `.tasks/STATUS.md`: переместить все 🟢 done-блоки в `.tasks/.archive/done-2026-05.md`, оставить в STATUS.md только header + status legend + 🔴/🟡/⚪/🔵 блоки. Цель — разгрузить файл от исторического шума без потери data (git history + явный архивный файл для текстового поиска). Предпосылка: на 2026-05-07 в `claude-skills/.tasks/STATUS.md` накопилось ~18+ 🟢 done-блоков (rolled out за 2026-04-25 — 2026-05-07: tdd-criteria-rollout, hermes-rollout, bootstrap-related, project-creation-lifecycle, recommend-dont-menu и т.д.). Convention в шапке файла говорит «🟢 Done — kept until merged», но проект работает на master-only (нет ветвления для merge), поэтому convention превратилась в «kept forever». Файл рос до ~600 строк / 26K токенов — Read-инструменты упираются в лимит. После чистки STATUS.md остаётся только активный board (🔴/🟡/⚪/🔵 + closed `[bootstrap-upgrade-canonical-triggers]` если уже отработал). Архивный файл `.tasks/.archive/done-2026-05.md` сохраняет полный текст всех перемещённых блоков для grep-поиска и historical context. **Status:** ready **Where I stopped:** Создана 2026-05-07. После rollout v1.10.0/1.10.1 на STATUS.md накопилось много свежих 🟢 (bootstrap-add-tdd-trigger, refresh-project-bootstrap closed-as-superseded, bootstrap-fix-tdd-recommend-template, bootstrap-upgrade-canonical-triggers если уже отработал). Хороший момент для batch-archive. **Next action:** 1) Прочитать `.tasks/STATUS.md` целиком (Read in chunks if needed). 2) Идентифицировать все блоки `## 🟢 [...]` — разделители `---`. 3) Создать `.tasks/.archive/` директорию (если нет). 4) Записать `.tasks/.archive/done-2026-05.md` с шапкой: ```markdown # Archived — Done batch 2026-05 Перемещено из `.tasks/STATUS.md` 2026-05-07 в рамках board-cleanup. Полный список 🟢 done-тасок, шипанутых в апреле-мае 2026. Полный source — git history `.tasks/STATUS.md` до commit X. --- ``` И подряд все 🟢-блоки в исходном виде. 5) Edit `.tasks/STATUS.md`: убрать все 🟢-блоки + соседние `---` разделители. Header + status legend + 🔴/🟡/⚪/🔵 блоки оставить. 6) Verify: `grep '^## ' .tasks/STATUS.md | wc -l` — было ~28+, должно остаться число активных (🔴+🟡+⚪+🔵, ожидание ~10-12). 7) Commit `meta(tasks): archive done batch 2026-05 → .tasks/.archive/done-2026-05.md` с body, описывающим какие группы перемещены (tdd-criteria, hermes, bootstrap, etc.) и итоговый count. 8) `tasks_close`. NB: эта таска сама уйдёт в следующий cleanup batch (2026-06 или подобный), так что не пытаться её закрыть+архивировать в одном коммите. **Branch:** n/a --- ## 🟢 [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 --- ## 🟢 [update-using-projects-meta-qualified-names] — Обновить SKILL.md скила `using-projects-meta`: примеры `target_project` переписать на qualified формат (`/` вместо 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 --- ## 🟢 [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 --- ## 🟢 [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/` (или `%TEMP%\`): 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 --- ## 🟢 [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 --- ## 🟢 [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 --- ## 🟢 [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 --- ## ⚪ [using-synology-ops-review] — Skill-review checkpoint для using-synology-ops (промоушен 2026-05-12). **Источник дизайна:** .workshop/.archive/2026-05-12-using-synology-ops-skill.md (process trace дискуссии Q1–Q6) + .wiki/concepts/synology-ops-mcp-design.md в shared projects-wiki (canonical design самого MCP-сервера). **Импл-таски:** using-synology-ops-install, using-synology-ops-hermes-mapping, using-synology-ops-test-trigger. **Кто делает:** **не имплементер.** Другая сессия / другой день / другой агент. Identity-not-location: ревьюер работает в любой папке, где есть доступ к файлам (см. .workshop/.wiki/concepts/workshop-architecture.md §5.1 если есть). **Поведенческий smoke-test (это и есть acceptance):** - Скил активируется в чистой сессии на каждой триггер-фразе из `description` (русский И английский варианты — список в test-trigger таске). - Скил **не** активируется на 2-3 близких но не своих фразах из соседних доменов (false-positive check; список в test-trigger таске). - Каждый шаг секции `Steps` отрабатывает на тестовом буфере без ошибок (NB: после второго прохода body, см. ниже). - `Failure modes` уводят в abort, не в частичный успех с грязным состоянием. - `What NOT to do` соответствует реальности — нет дыры между правилом и реализацией. Findings — обычные follow-up tasks (`using-synology-ops--fix` или подобное) через `tasks_create` в `claude-skills`. **Закрытие:** только когда все findings зафайлены ИЛИ ревьюер подтвердил «нет findings» в close-note. **NB по семверу:** `version: 0.1.0` записан промоутером. Дальнейшие инкременты — ответственность владельца `claude-skills/`, **не** этого скила и не ревьюера. Если ревью требует правок — правит владелец, бампит он же. **NB по body:** на момент создания таски body SKILL.md — пустой каркас (When to use / Inputs / Steps / Failure modes / Side effects / What NOT to do все пустые). Второй проход «доведём using-synology-ops» дописывает их глазами из archive + concepts/synology-ops-mcp-design.md. Если этот проход не сделан до review — close-note: "skill каркас, body пустой, перенесите review", это не findings. **Status:** ready **Where I stopped:** (not started — baseline-таски все 🟢 на 2026-05-12, version теперь 0.1.1, body всё ещё <пусто> stub) **Next action:** Ревьюер: прогнать поведенческий smoke-test в чистой main-сессии (subagent fire-test уже сделан имплементером — см. close-note test-trigger; нужен gold-standard прогон). Body пустой → по NB-правилу: "skill каркас, body пустой, перенесите review" или закрыть с findings про body-gap. Findings → follow-up tasks через `tasks_create`. **Branch:** n/a ---