Files
claude-skills/.wiki/concepts/project-discipline-design.md
vitya df8f1cb72b docs(project-discipline): design spec + implementation plan + STATUS active block
Spec: .wiki/concepts/project-discipline-design.md — four cross-project
rules (conventions-over-defaults, master-only, semver-bumping with
first-edit-unversioned clause, session-scoped ask-before-push with
grant/revoke and force/delete/non-ff exceptions); architecture: single
policy skill activated by 'follow project discipline' line in CLAUDE.md
template (added by project-bootstrap v1.5.0); 12-task implementation
plan tracked in .tasks/project-discipline-skill.md.
2026-05-01 11:30:38 +03:00

24 KiB
Raw Permalink Blame History

title, type, updated
title type updated
project-discipline — четыре правила работы в проекте concept 2026-05-01

project-discipline — четыре правила работы в проекте

2026-05-01.

Problem

Дисциплина в работе агента в проекте сейчас держится на двух источниках, которые друг с другом не согласованы:

  1. Defaults внешних скиллов (superpowers и пр.) — например, superpowers:brainstorming пишет spec в docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md. Этот путь зашит в скилл и применяется по умолчанию во всех проектах.
  2. Конвенции конкретного проекта — например, в claude-skills spec'и живут в .wiki/concepts/<topic>-design.md, а не в docs/superpowers/. Эта конвенция нигде явно не объявлена; держится только на том, что текущий агент случайно читает .wiki/CLAUDE.md до того, как применить дефолт скилла.

В claude-skills это работает потому что репо плотно дисциплинирован. В других проектах того же пользователя такое не работает: агент по умолчанию пишет в docs/superpowers/, ветвится на feature-branches, забывает bump'ить версии скиллов, и push'ит без подтверждения.

Пользователь хочет четыре правила, действующие во всех его проектах:

  1. Project conventions > skill defaults — то, что в CLAUDE.md / .wiki/CLAUDE.md / .tasks/, перекрывает defaults любого скилла.
  2. Master-only — вся работа на главной ветке, никаких feature-branches без явного запроса.
  3. Versioning discipline — bump version'у на каждом edit'е версионированного артефакта, по semver, в commit-message.
  4. Commit yes, push no — каждый сеанс стартует с "ask before push"; разрешение на автопуш выдаётся устно в рамках сессии и обнуляется при её завершении.

Текущий механизм передачи кросс-проектных правил — строки-триггеры в CLAUDE.md, активирующие соответствующие скиллы (use superpowers, use project wiki, pull remote before work, и т.д.). project-bootstrap v1.4.0 уже умеет идемпотентный merge новых строк в существующий CLAUDE.md (см. bootstrap-claude-md-merge.md). Эта схема естественно расширяется на новый policy-скилл.

Decision

Два артефакта:

  1. Новый policy-скилл project-discipline (skills/project-discipline/SKILL.md, v0.1.0) — кодифицирует все четыре правила, активируется триггером follow project discipline в CLAUDE.md.
  2. project-bootstrap v1.4.0 → v1.5.0 (MINOR, добавляет capability) — новая строка в assets/CLAUDE.md.template сразу после pull remote before work. Идемпотентный merge в Step 5 переносит её в существующие проекты без ручного edit'а. bootstrap-manifest.md получает новую строку для project-discipline.

Этот репо (claude-skills) получает trigger'ную строку в свой CLAUDE.md как dogfood.

Почему один скилл, а не четыре

Все четыре правила — про дисциплину работы в проекте, единая тема. Разделение на четыре скилла + четыре строки в CLAUDE.md (use master-only, confirm before push, и т.д.) раздуло бы template и плодит файлы. Если позже какое-то правило отделится в самостоятельный универсальный механизм — выделим его тогда. Сейчас YAGNI.

Почему скилл, а не просто прямые строки в CLAUDE.md template

Прямые строки (work on master only, commit but don't push) тоже сработали бы как триггеры — каждая инструкция в CLAUDE.md имеет высший приоритет. Но:

  • Версионирование — правила со временем меняются (например, добавится исключение для force-push). Если они зашиты в template и разосланы по N проектам, обновление = ручной edit в каждом. Скилл со своей версией обновляется централизованно.
  • Полнота описания — четыре правила требуют ~150 строк подробной формулировки (что считается push'ем, какие исключения, как выдаётся grant). В CLAUDE.md это не помещается; в скилле — нормальный объём.
  • ОбнаруживаемостьSkill tool listing показывает скилл с описанием. Прямые строки в CLAUDE.md агент видит, но не воспринимает как один связанный набор.

Skill behaviour

Activation (description field)

Trigger conditions:

  • CLAUDE.md содержит строку follow project discipline — скилл активируется при старте сессии и применяет все четыре правила к остальной работе.
  • Пользователь явно ссылается на дисциплину: "use project discipline", "соблюди дисциплину", "проектные правила", "что у меня по правилам?".

Скилл сам по себе не выполняет действий и не имеет внешних эффектов; он — policy-документ, читаемый агентом.

Rule 1 — Project conventions override skill defaults

Текст правила в SKILL.md:

До применения defaults любого другого скилла (superpowers, frontend-design, mcp-builder, и т.д.), агент читает в этом порядке:

  1. CLAUDE.md в корне проекта;
  2. .wiki/CLAUDE.md (если существует);
  3. .tasks/STATUS.md (если существует).

Любой путь, формат, или workflow, явно указанный в этих файлах, перекрывает дефолт скилла.

Конкретные следствия:

  • Spec'и / design-документы идут в .wiki/concepts/<topic>-design.md, не в docs/superpowers/specs/.
  • Task tracking — в .tasks/<slug>.md + STATUS.md (формат using-tasks), не в docs/superpowers/plans/ или ином inline-формате.
  • Frontmatter, naming-conventions, log-формат — как описано в .wiki/CLAUDE.md проекта.

Если конвенция не указана явно — применяется дефолт скилла.

Почему: в claude-skills это уже работает (поэтому pulling-before-work-design.md лежит в .wiki/concepts/, а не в docs/superpowers/specs/). Цель правила — перенести эту дисциплину в другие проекты пользователя, где она сейчас держится только на удаче.

Rule 2 — Master-only

Текст правила в SKILL.md:

Вся работа идёт на главной ветке репозитория — обычно master, но если проект использует main, скилл считает main эквивалентом.

  • Никаких git checkout -b feature/foo для соло-работы.
  • Sync с remote — git pull --ff-only или git pull --rebase. Никаких merge-коммитов для соло-работы.
  • Если задача реально требует изоляции (большой эксперимент, рискованный refactor с возможностью отката, multi-day работа с промежуточными WIP-коммитами) — агент спрашивает пользователя: "это требует отдельной ветки, ок?" — и ждёт явного разрешения. Без разрешения — на master.

При detached HEAD или нахождении на не-главной ветке (например, после git checkout) — агент сообщает об этом и спрашивает, нужно ли вернуться на master перед работой.

Почему: соло-разработка с CI/CD не получает выгоды от feature-branches; PR-workflow это overhead для одного человека. Master-only сводит к нулю vocabulary "merge conflict / rebase onto / rebase interactive" в обычном дне.

Rule 3 — Versioning discipline

Текст правила в SKILL.md:

При редактировании любого артефакта с semver-полем агент bump'ит версию перед коммитом по правилам:

  • MAJOR (X+1.0.0) — ломает контракт. Переименование скилла, удаление триггеров, изменение layout, удаление публичных функций, breaking change в API.
  • MINOR (X.Y+1.0) — добавляет capability без ломки. Новый триггер, новый опциональный шаг, новая публичная функция.
  • PATCH (X.Y.Z+1) — wording, clarity, исправление опечаток без изменения поведения.

Bump указывается в commit-message: feat(<artifact>): … [v<X.Y.Z>] или эквивалент. Точный формат подгоняется под convention'ы проекта (см. Rule 1).

Применяется к: skills/<name>/SKILL.md (frontmatter version:), package.json ("version":), pyproject.toml (version = ), Cargo.toml (version = ), и любым другим semver-полям.

Если артефакт пакуется в dist/<name>.skill, dist/*.tgz и т.п. — rebuild пакета в том же или следующем коммите. Забытые dist'ы — частая причина деплоя устаревшего бинаря.

Первый edit unversioned артефакта, у которого ВОЗМОЖНО semver-поле (новый скилл без version:, новый package.json без "version":) — агент добавляет version: 0.1.0 (или эквивалент) перед коммитом, не bump'ит существующее.

Не применяется к: артефактам без semver-поля и без потенциала его иметь (concept-страницы wiki, README.md, скрипты shell без публичного интерфейса).

Почему: в .wiki/concepts/skill-versioning.md уже описана semver-схема, но (а) она была scoped только на infra-набор скиллов; (б) дисциплина держалась только на текущем агенте. Правило 3 расширяет её на все скиллы в этом репо и на все версионируемые артефакты в любом проекте.

Расширение scope. Концепт-страница skill-versioning.md будет обновлена с пометкой, что после v0.1.0 project-discipline требование версионирования действует на все скиллы, не только infra-subset. Communication-mode скиллы (caveman, ...) и discovery-скиллы (find-skills, active-platform) тоже получают version: поле в frontmatter — это разовый migration, отдельная задача после shipping project-discipline.

Rule 4 — Commit yes, push no (session-scoped)

Текст правила в SKILL.md:

Старт каждой сессии: агент находится в режиме ask-before-push. На каждый git push он спрашивает:

Готов push'нуть в <remote>/<branch> (N коммитов: ). Ок?

и ждёт явного yes / да / push / эквивалента. Без подтверждения — не push'ит.

Выдача grant'а в сессии. Пользователь говорит:

  • "разреши автопуш" / "allow auto-push" / "автопуш ок" / эквивалент

— после этого агент push'ит без вопросов до конца сессии или до отзыва.

Отзыв grant'а в сессии. Пользователь говорит:

  • "отзови автопуш" / "revoke auto-push" / "снова спрашивай" / эквивалент

— агент возвращается в ask-mode.

Конец сессии — состояние не сохраняется. Следующая сессия снова стартует в ask-mode. Это намеренно: grant выдаётся под конкретный текущий контекст (пользователь рядом, осознанно решил что push'ить безопасно), и не должен переживать смену контекста.

Исключения — всегда ask, даже с активным grant'ом:

  • git push --force / --force-with-lease (перезапись истории);
  • git push origin --delete <branch> (удаление ветки);
  • push не в текущий tracked upstream (git push other-remote ..., git push origin other-branch);
  • push в главную ветку, требующий не-fast-forward (т.е. потребовался бы force).

Логика: grant выдан под обычный fast-forward push в апстрим; всё остальное — отдельный класс операций, требует отдельного решения.

Что считается "push": только команды семейства git push. Локальные коммиты, git stash push, и т.п. — не push, grant на них не нужен.

Почему: пользователь хочет чтобы каждая сессия начиналась с явного "коммить, но не пуш!" — даже если в прошлой сессии всё было разрешено. Это страховка от "вчера агент думал что все ок, сегодня он же думает что всё ок, и заpush'ил то что не должен был". Persistent grant (файл-флаг в проекте) был бы удобнее но менее безопасен — поэтому намеренно отвергнут.

Out of scope

Скилл не делает:

  • Не модифицирует CLAUDE.md — это работа project-bootstrap. Скилл — текстовая policy, не tooling.
  • Не enforce'ит правила через hooks / git hooks / pre-commit — дисциплина агента, не CI. Если пользователь хочет твёрдый enforcement (например, pre-push hook, который ломается без явной env-переменной) — это отдельный setup-скилл, не часть project-discipline.
  • Не управляет settings.json permissions — это update-config. Можно представить вариант, в котором git push запрещён по умолчанию через permissions.deny: ["Bash(git push:*)"], и Rule 4 его временно ослабляет. Этот вариант отвергнут на v0.1.0: пользователь хочет policy-уровень, не tool-уровень. Если правило Rule 4 окажется недостаточным — вернёмся к идее.
  • Не проверяет наличие .wiki//.tasks/ — это работа setup-wiki/setup-tasks/project-bootstrap. Скилл предполагает что layout уже на месте; если .wiki/CLAUDE.md отсутствует — Rule 1 просто не находит конвенций для override'а и работает как пустой fallback.

Bootstrap integration

assets/CLAUDE.md.template

Текущий вид:

talk like a caveman
use superpowers
use project wiki
use task management system
check across all projects
pull remote before work
we're on Windows

После v1.5.0:

talk like a caveman
use superpowers
use project wiki
use task management system
check across all projects
pull remote before work
follow project discipline
we're on Windows

follow project discipline ставится после pull remote before work и до платформенной строки — потому что:

  • Pull остаётся первым в logical order'е (сначала подтягиваем код, потом думаем о правилах).
  • follow project discipline логически суммирует все остальные триггеры, должна стоять близко к их концу.
  • Платформенная строка — мета-конфиг, всегда последняя.

project-bootstrap SKILL.md изменения

  • Frontmatter: version: 1.4.0version: 1.5.0.

  • Step 5 — добавить параграф commentary о новой строке (по образцу commentary для pull remote before work):

    The follow project discipline line activates the project-discipline skill, which codifies four cross-project rules: (1) project CLAUDE.md / .wiki/CLAUDE.md / .tasks/ override skill defaults; (2) all work on master/main, no feature branches; (3) version bump on every edit per semver; (4) commit freely, push only after explicit per-session approval. Install the skill on the host if project-discipline is not in ~/.claude/skills/; otherwise the trigger is silently dead like any other absent skill.

  • Step 5.5 (manifest) — добавить project-discipline в таблицу:

    | Skill | Version | Role |
    |---|---|---|
    | `project-bootstrap` | <version> | orchestrator |
    | `setup-wiki` | <version> | wiki canonical layout |
    | `setup-tasks` | <version> | tasks canonical layout |
    | `project-discipline` | <version> | cross-project policy |
    

    Манифест читает version: из frontmatter project-discipline/SKILL.md как для остальных. Если скилл не установлен — unknown, как уже принято.

Idempotent merge — что произойдёт в существующих проектах

Step 5 upgrade-mode (см. bootstrap-claude-md-merge.md) на следующем bootstrap:

  1. Прочитает существующий CLAUDE.md.
  2. Не найдёт substring follow project discipline в нём.
  3. Покажет user'у diff: "Append 1 missing canonical trigger: follow project discipline?"
  4. По подтверждению — допишет строку в конец.

Существующий порядок (например, если we're on Windows уже не в конце, а в середине) не пересортировывается — это сделанное решение upgrade-merge'а, чтобы не ломать пользовательские edit'ы.

Cross-impact

Файл Изменение
skills/project-discipline/SKILL.md новый, v0.1.0
skills/project-discipline/README.md новый
skills/project-bootstrap/SKILL.md bump 1.4.0→1.5.0; commentary + manifest row
skills/project-bootstrap/assets/CLAUDE.md.template +1 строка
skills/project-bootstrap/README.md sync (упомянуть новый триггер)
dist/project-bootstrap.skill rebuild
dist/project-discipline.skill новый archive
~/.claude/skills/project-discipline/ install (через install.sh или install.ps1)
CLAUDE.md (этого репо) +1 строка follow project discipline (dogfood)
.wiki/concepts/skill-versioning.md заметка о расширении scope (Rule 3 теперь требует version: на ВСЕХ скиллах)
.wiki/concepts/project-discipline-design.md этот файл
.wiki/concepts/bootstrap-manifest.md regenerate с новой строкой
.wiki/index.md +1 концепт-page link
.wiki/log.md +1 entry decision | project-discipline — четыре правила работы в проекте
.tasks/project-discipline-skill.md новый task-file
.tasks/STATUS.md новый 🔴 active block

Open questions

  • Нужен ли отдельный setup-скилл? По образцу setup-context7 / using-context7. Сейчас — нет: project-discipline ничего не устанавливает, просто policy. Если в будущем добавится tooling-enforcement (git hooks, settings.json overrides) — выделим setup-project-discipline.
  • Wide vs narrow Rule 3 scope. Сейчас правило применяется ко всем артефактам с semver-полем. Если окажется что в каких-то проектах семвер реально неуместен (например, исследовательский notebook) — добавим explicit opt-out через .wiki/CLAUDE.md (# project-discipline: skip versioning).
  • Migration communication-mode скиллов на version:. Это побочная работа после shipping project-discipline. Открывается отдельной задачей в .tasks/.
  • Отслеживание session-state Rule 4. В текущей имплементации — чисто conversational ("я помню что разрешил"). Если auto-compaction обрезает раннюю часть сессии где был выдан grant — fallback на ask-mode (безопаснее). Это намеренно: лучше переспросить чем накосячить.

References

  • bootstrap-claude-md-merge.md — механизм идемпотентного merge, который перенесёт триггер в существующие проекты.
  • pulling-before-work-design.md — образец policy-скилла + bootstrap-integration, который этот проект мимикрирует.
  • skill-versioning.md — текущая semver-схема, которую Rule 3 расширяет на все скиллы.
  • bootstrap-manifest.md — формат манифеста, в который добавляется новая строка.