# Task Board _Updated: 2026-05-07 (tdd-criteria-review done → v0.2.0)_ ## 🟡 [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:** (not started) — `install.sh` exists, `install.ps1` missing; both must coexist (PS users on Windows shouldn't be forced into git-bash, Linux/Mac users shouldn't be forced into pwsh). Cross-platform = bash + PS *paired*, behaviorally identical. **Next action:** (a) write `scripts/install.ps1` mirroring `install.sh` logic (copy `skills//` → `~/.claude/skills//`, support `$env:CLAUDE_SKILLS_DIR` override); (b) add `--prune` flag to **both** scripts that drops `~/.claude/skills//` for any name not in `skills//` (lesson from `[compress-dedup]` — manual prune was needed because install.sh can't); (c) confirm `build.ps1`/`build.sh` are already paired (they are) and document the parity invariant in `.wiki/concepts/install-cross-platform.md`. README's install quick-start should show both variants side-by-side per `active-platform` cross-platform-docs convention. **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:** ready **Where I stopped:** (not started) — surfaced 2026-05-06 during factory-bootstrap field-test on fresh Win11 laptop. `/setup-interns` Phase 1 stopped with "`.common/lib/interns-mcp/` not found" because claude was launched from `C:\Windows\System32` (cwd inherited). The skill resolves all `.common/` paths relative to cwd. Sister skill `setup-projects-meta` uses absolute `~/projects/.common/...` (fixed in [using-projects-meta-fix-paths]) — `setup-interns` is the next inconsistency. Field-test workaround: `cd $PROJECTS_DIR` before launching claude. **Next action:** in `setup-interns/SKILL.md` Phase 0/1/2/3/4/5/6/7 — replace every `/.common/...` with `~/projects/.common/...` (POSIX-absolute, matches `setup-projects-meta` after the [using-projects-meta-fix-paths] fix). Audit Bash blocks too. Bump `setup-interns` version (PATCH — doc consistency, no behavior change). Rebuild `dist/setup-interns.skill`, install to `~/.claude/skills/setup-interns/`, verify `version` on disk. Long-term: factor `~/projects` out into `$FACTORY_PROJECTS_DIR` (read from `~/.config/factory/home.toml`) once `factory` CLI lands — track separately. Field-test artefact: `.factory/L0/install-log.md` шаг 11c-2 в gitea `OpeItcLoc03/factory`. **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:** ready **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:** blocked **Where I stopped:** Создана 2026-05-07. Blocked — ждёт разблокировки от координатора `bootstrap-rollout-canonical-triggers` (mass-unblock после первого успешного прогона в группе). **Next action:** 1) Открыть свежую сессию в `~/projects/claude-skills/`. 2) `upgrade project` — триггер `project-bootstrap` v1.10.0. 3) Подтвердить план — добавиться должны ровно 2 строки (`follow tdd-criteria`, `recommend, don't menu`). 4) Прогнать. 5) `git diff CLAUDE.md` — 2 вставки, остальное нетронуто. 6) Повторный прогон — no-op. 7) Закрыть таску при успехе; при криво записанном — фикс-таска в `claude-skills`, координатор остаётся открытым. **Blocker:** bootstrap-rollout-canonical-triggers **Branch:** n/a ---