CLAUDE.md · git:20260921.3812b08 · 2026-09-21 · sha256 1d2444638597416c
CLAUDE.md git:20260921.3812b08A
Immutable. This exact content is served forever at /api/v1/blob/1d2444638597416c.
# MAST
Method for Agents, Sessions and Tasks — плагин Claude Code, который разворачивает в чужом
проекте наш способ работы: роадмап с пунктами, worktree на пункт, диспетчер, правила с `paths:`,
архив закрытого.
## Куда смотреть
| Документ | Когда читать |
|---|---|
| [ROADMAP.md](ROADMAP.md) | что осталось сделать |
| [docs/roadmap/done/A-1/SPEC.md](docs/roadmap/done/A-1/SPEC.md) | зачем плагин так устроен, ограничения площадки, состав ядра |
| [docs/roadmap/DONE.md](docs/roadmap/DONE.md) | что уже закрыто |
| [TECH_DEBT.md](TECH_DEBT.md) | что оставлено криво и при каком условии чиним |
## Стек
- Markdown — тексты ядра, скиллов и шаблонов, по комплекту на язык в `locales/`.
- Python 3 (только stdlib) — скрипты хуков и сторожа́.
- pytest — сторожа́ в `tests/`.
Из одного репозитория собирается **два плагина**: `plugins/en` → `mast` и `plugins/ru` →
`mast-ru`. Язык — это выбор плагина при установке, а не настройка внутри одного.
## Команды
```bash
git config core.hooksPath .githooks # один раз после клонирования
pytest # весь набор
python3 hooks/roadmap_lint.py ROADMAP.md # проверка формата роадмапа
python3 hooks/roadmap_lint.py --ready ROADMAP.md
```
`.git/hooks/` не версионируется, поэтому pre-commit едет в `.githooks/` и
подключается этой командой. Не подключил — правку без бампа версии поймает
`tests/test_version_bump.py`, но уже после коммита.
## Инварианты проекта
- **Плагин не трогает чужое.** Ни `~/.claude/CLAUDE.md`, ни `settings.json` пользователя, ни файлы его проекта без подтверждения. Любая правка существующего файла — только через дифф и вопрос.
- **Ядро в `SessionStart` ≤ 8200 символов** при лимите площадки 10 000. Не влезает — секция уезжает в скилл, а не сокращается до непонятности. Уехала — в ядре остаётся правило одной строкой **и имя скилла в том месте, где оно применяется**: ссылка одним списком в конце не работает, агент не знает, когда её открыть.
- **Два языка равноправны.** Правка текста на одном языке без правки на другом не вливается: сторож локалей сверяет состав файлов и дерево заголовков.
- **Пути внутри плагина — через `${CLAUDE_PLUGIN_ROOT}`.** Никаких `$HOME/.claude/...`: у пользователя плагина такого пути нет. Путь из текста скилла или команды резолвится относительно `plugins/<язык>/`, а код и тексты лежат в корне — отсюда `../../`; каждый такой путь проверяет сторож в `tests/test_plugin_manifest.py`.
- **Имя плагина в коде — только из `hooks/plugin_names.py`.** Литерал `mast`/`mast-ru` в хуке расходится с манифестом молча, и пользователь получает ссылку на несуществующую команду или скилл.
- **Числа в «Готово когда» получены замером**, а не переписаны из примера.
- **В `plugins/*/` только обёртка** — манифест, разводка хуков, скиллы-указатели, команда и
`.mcp.json`. Код (`hooks/`) и тексты (`locales/`) общие и лежат в корне: продублировать их
по языкам значит завести две истины об одном.
- **Версия растёт вместе с методом и одинакова у обоих плагинов.** Правка `hooks/`,
`locales/` или `plugins/` без бампа — релиз, которого не получит ни один пользователь:
Claude Code обновляет плагин с явной версией только при её росте.
- **Новое правило метода — это пол или потолок?** Пол — инвариант, который проверяет guard
(число в критерии, линт, владение путями). Потолок — «как именно и в каком порядке ходить».
Потолок в ядро и скиллы не вливается: он устареет ровно тогда, когда модель поумнеет,
и его придётся выдирать.