Immutable. This exact content is served forever at /api/v1/blob/413191ebb8b6c17e.
# Точки входа для агента
## Порядок источников истины
Когда меняете Unica, разрешайте противоречия в таком порядке:
1. код и тесты;
2. `plugins/unica/.mcp.json`, `plugins/unica/.codex-plugin/plugin.json`,
`plugins/unica/.claude-plugin/plugin.json` и
`plugins/unica/third-party/tools.lock.json` — это источники контракта пакета,
а не фоновые заметки;
3. `plugins/unica/references/specs/` — источник контракта форматов XML 1С и
JSON-DSL. Когда вопрос в том, как должен выглядеть порождённый `.xml`, `.mxl`
или полезная нагрузка DSL, эти спецификации старше `arch/`, скиллов и прозы.
Они не старше поведения эмиттера, доказанного фикстурой или официальным
дампом платформы; при расхождении с ним правится спецификация;
4. `arch/` — действующий архитектурный слой; при противоречии с источниками из
пунктов 1–3 исправляется `arch/`, а не более высокий источник. Выбором
владеет запись `DEC.*` в `arch/decisions/`, проверяемым правилом — запись
`INV.*` в `arch/invariants/`, наблюдаемой формой — запись `CTR.*` в
`arch/contracts/`. Происхождение адаптированных апстримов нормирует
`docs/provenance/skill-upstreams.json`: полнота
`plugins/unica/ATTRIBUTIONS.md` проверяется против него. `docs/arch-v1/` —
замороженная история и действующим источником не является;
5. `README.md` и проза скиллов.
## Куда смотреть, где менять
Пути в обоих столбцах даны от корня репозитория. Символ `DEC.*`, `INV.*` или
`CTR.*` однозначно разрешается через `arch/index.md`. `<группа>` и `<имя>`
подставляются по имени домена инструмента. Сокращать путь до хвоста нельзя:
`rg` по такому хвосту ничего не находит, и строка перестаёт быть маршрутом.
| Задача | Что читать сначала | Где менять код |
| --- | --- | --- |
| Новый или изменённый публичный инструмент `unica.*` | `CTR.WIRE.TOOL-SURFACE`, `INV.SURFACE.NAMESPACE`, `INV.SURFACE.ACCEPTANCE-UNCHANGED`, `arch/tool-surface.md` | `crates/unica-coder/src/application/mod.rs` (`tools()`), `crates/unica-coder/src/application/tool_contracts.rs`, `crates/unica-coder/src/application/operation_descriptors.rs`, `crates/unica-coder/src/infrastructure/native_operations/<группа>.rs`, `plugins/unica/skills/<имя>/SKILL.md` |
| Изменение формата XML 1С или DSL | `CTR.FORMAT.PLATFORM-XML-8-3-27` и `plugins/unica/references/specs/` | `crates/unica-coder/src/infrastructure/native_operations/` |
| Кеш, состояние рабочего пространства, доменные события | записи `INV.CACHE.*` | `crates/unica-coder/src/domain/events.rs`, `crates/unica-coder/src/domain/cache.rs`, `crates/unica-coder/src/infrastructure/workspace_state.rs`, `crates/unica-coder/src/infrastructure/workspace.rs` |
| Скрытый сервис рабочего пространства или задание runtime | `INV.APP.HIDDEN-SERVICES`, `CTR.WIRE.TOOL-SURFACE` | `crates/unica-coder/src/infrastructure/workspace_services.rs`, `crates/unica-coder/src/infrastructure/runtime_jobs.rs` |
| Упаковка или релиз | записи `INV.PKG.*`, решения о доставке в `arch/decisions/`, `docs/release-runbook.md` | `scripts/ci/package-unica-plugin.py`, `crates/unica-bootstrap/src/`, `.github/workflows/unica-plugin-release.yml` |
| Поведение, зависящее от ОС | `INV.PLATFORM.OS-BEHIND-FACADE` | `crates/unica-coder/src/infrastructure/platform/`, `crates/unica-bootstrap/src/platform/`, страж `scripts/ci/check-rust-platform-boundary.py` |
| Само архитектурное правило | запись в `arch/invariants/` или `arch/contracts/` и её владелец `DEC.*` | проверка, названная в поле `check` этой записи |
**Строки комбинируются.** Одна задача обычно попадает сразу в несколько:
инструмент, который пишет платформенный XML, — это первая строка вместе со
второй; инструмент, который меняет файлы и обязан сообщить о влиянии на кеш, —
первая вместе с третьей; новый инструмент, запускающий долгую работу, — первая
вместе с четвёртой. Читайте объединение подходящих строк, а не одну самую
похожую.
Отдельно про `native_operations`. Реестр инструментов, контракты и дескрипторы в
слое application описывают вызов: имя, схему аргументов, форму результата. Саму
работу делает нативный обработчик в
`crates/unica-coder/src/infrastructure/native_operations/`, где на каждый домен
приходится свой файл — `form.rs`, `meta.rs`, `dcs.rs`, `code.rs`, `cfe.rs`,
`mxl.rs` и остальные. Там же лежит разбор аргументов, чтение и запись
источников. Это самая крупная часть кодовой базы: четыре самых больших файла
рабочего пространства Cargo — из этого каталога, и суммарно он на порядок больше
всего слоя application. Изменение поведения инструмента почти всегда происходит
там, а правка в `application/` только объявляет это поведение наружу.
## Релизы
Публикация версии в публичный маркетплейс выполняется по
`docs/release-runbook.md`. Прочитайте его прежде, чем действовать по любой
просьбе выпустить, отгрузить, продвинуть или доделать релиз: порядок шагов
соответствует действующему workflow и не даёт каталогу указывать на
непроверенный пакет.
## Гигиена поиска
Не сканируйте локальные игнорируемые корпуса при обычном изучении репозитория:
- `target`
- `.build`
- `dist`
- `docs-local` (локальный исследовательский материал; в поставку не входит и
источником справки платформы не является — её отдаёт `unica.documentation.search`)
Датированные деревья планов и проектных записок отслеживаются гитом, но они
описывают, как было сделано прошлое изменение, а не как система ведёт себя
сейчас. Их тоже не сканируйте:
- `docs/design/**`
- `docs/plans/**`
- `docs/provenance/reviews/**`
Открывайте их только чтобы восстановить историю одного конкретного изменения, и
никогда не выводите из их текста действующее архитектурное правило. CI-тест
может закрепить архивный файл по пути как живой тестовый вход:
`tests/ci/test_format_profile_contract.py` читает
`docs/design/2026-07-23-platform-8-3-27-format-2-20-design.md`. Это не делает
прозу файла нормативной, но запрещает считать сам файл неиспользуемым; перед
удалением проверяйте `rg <path> tests/ scripts/`.
Начинайте с `rg` и `git ls-files`. В вопросах об упаковке предпочитайте
отслеживаемые файлы и сгенерированные артефакты пакета обходу файловой системы.
## Проектные документы и решения
Эти правила связывают скиллы мозгового штурма и планирования. Они старше
умолчаний самого скилла.
**Куда кладутся артефакты.** Проектные записки — в
`docs/design/YYYY-MM-DD-<topic>-design.md`, планы реализации — в
`docs/plans/YYYY-MM-DD-<feature-name>.md`. Это переопределяет каталоги по
умолчанию в скиллах `brainstorming` и `writing-plans`. Черновики сессии остаются
в игнорируемом `.superpowers/`; никогда не делайте `git add -f` для пути, который
репозиторий игнорирует.
**`arch/` — единственный слой нормативной архитектурной документации, но не
единственный источник истины репозитория.** Код, тесты, контрактные метаданные
пакета и спецификации форматов остаются выше него согласно порядку в начале
файла. Проектная записка фиксирует путь к выбору и нормативной не становится.
**Прочитайте правила прежде, чем предлагать проект.** Изучая контекст проекта,
начните с `arch/index.md` и откройте выбранные записи из `arch/`.
Подход, который противоречит принятому решению или записи реестра, либо
отбрасывается, либо предлагается вместе с записью, заменяющей прежнюю; скажите
прямо, что именно из двух, а не оставляйте противоречие на откуп ревью.
**Выделите решение, когда сдвинулся контракт.** Написав проектную записку и до
того, как звать пользователя её смотреть, решите, меняет ли работа архитектурный
контракт. Меняет, если затронуто хоть одно из:
- набор публичных инструментов `unica.*`, их аргументы или полезная нагрузка
результата;
- идентичность MCP-сервера или граница «единственный публичный сервер»;
- владение кешем или состоянием рабочего пространства, либо контракт доменных
событий;
- контракт упаковки, хоста или релиза;
- граница слоя или любое правило, которое несёт реестр инвариантов;
- создаётся политика, которой обязан следовать более чем один потребитель —
существующий или будущий (общее ядро, разделяемый writer, единый формат
вывода).
Если меняет — запись решения `DEC.*` пишется в `arch/decisions/` тем же
коммитом, а выведенное проверяемое обязательство — отдельной записью `INV.*`
или `CTR.*`. Запись короткая и нормативная; проектная записка остаётся её
происхождением. Если не меняет — так и напишите в шапке.
**Каждая проектная записка открывается тремя полями:**
```markdown
- Date: `YYYY-MM-DD`
- Status: `draft` | `approved` | `superseded`
- Decision: `DEC.YYYY-MM-DD.NAME` | `none — no architectural contract changed`
```
`Decision: none` — это утверждение, которое ревью может отклонить, а не значение
по умолчанию. Формат проверяет `tests/ci/test_design_documents.py`.
## Именование и жизненный цикл записей
- Решение: `arch/decisions/YYYY-MM-DD-<слаг>.md`, символ
`DEC.YYYY-MM-DD.<СЛАГ>`.
- Инвариант: `arch/invariants/INV.<ОБЛАСТЬ>.<ИМЯ>.md`.
- Контракт: `arch/contracts/CTR.<ОБЛАСТЬ>.<ИМЯ>.md`.
- `active` означает действующее и реализованное обязательство; решение называет
свидетельство в `realized`.
- Принятое, но ещё не построенное направление имеет `status: planned` и
`realized: null`; оно не описывает текущее поведение.
- Продуктовая запись после попадания в целевую ветку не переписывается: решение
получает преемника, а изменение правила приходит с новым решением-основанием.
Процессную запись можно перестраивать вместе с процессом.
- Символ и путь не переиспользуются. `scripts/arch/registry.py` проверяет форму
и порождает `arch/index.md`; `scripts/arch/immutability.py` проверяет историю.
Полная схема полей и правила замещения находятся в `arch/README.md`.
## Обязательные навыки разработки MCP
При любой задаче, которая проектирует, создаёт или развивает MCP-сервер Unica,
до проектирования и реализации обязательно используйте `build-mcp-server`.
После выбора ветки работы применяйте специализированные навыки:
- `build-mcp-app` обязателен для MCP Apps, UI-ресурсов и интерактивных виджетов;
- `build-mcpb` обязателен для MCPB, локальной упаковки и поставки MCP-сервера;
- работа, совмещающая интерактивный интерфейс и MCPB-поставку, использует
навыки в порядке `build-mcp-server` → `build-mcp-app` → `build-mcpb`.
Не применяйте `build-mcp-app` или `build-mcpb` к работе, которая не затрагивает
их контур. Канонический источник комплекта — официальный пакет Anthropic
[`mcp-server-dev`](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/mcp-server-dev).
Если хотя бы один обязательный навык недоступен, не начинайте MCP-работу, пока
не доступен весь комплект. В Codex явно вызовите `$skill-installer` и установите
только отсутствующие навыки из repository
`anthropics/claude-plugins-official`, ref `main`, передав соответствующие пути:
- `plugins/mcp-server-dev/skills/build-mcp-server`;
- `plugins/mcp-server-dev/skills/build-mcp-app`;
- `plugins/mcp-server-dev/skills/build-mcpb`.
Не передавайте установщику путь уже установленного навыка: он не перезаписывает
существующий каталог. Ожидаемое назначение каждого навыка —
`$CODEX_HOME/skills/<имя>/SKILL.md`; если `CODEX_HOME` не задан —
`~/.codex/skills/<имя>/SKILL.md`. После установки завершите текущий ход. На
следующем ходе проверьте, что все три навыка доступны для явного вызова и их
`SKILL.md` читаются. Если навык не появился, перезапустите Codex и повторите
проверку; до успешной проверки MCP-работу не продолжайте.
В Claude Code установите официальный плагин:
```text
/plugin marketplace add anthropics/claude-plugins-official
/plugin install mcp-server-dev
```
Для другого совместимого агента скопируйте каждый каталог навыка целиком —
`SKILL.md` вместе с `references/` — в каталог skills этого агента. Официальное
руководство: [Build with Agent Skills](https://modelcontextprotocol.io/docs/2026-07-28/develop/build-with-agent-skills).
## Правила разработки
- Устраняйте причины, а не симптомы.
- Сначала падающий тест, потом исправление. На любой найденный дефект — кем бы
он ни был найден: вами, ревью, CI или пользователем — пишется тест,
воспроизводящий его на текущем коде; запустите тест, убедитесь, что он падает
и падает именно по причине дефекта, и только после этого правьте код. Тест,
написанный после правки, не падал ни разу: он закрепляет текущее поведение,
но не доказывает ни того, что дефект воспроизводился, ни того, что устранена
именно его причина. Дефект, который тестом не воспроизводится, — утверждение,
которое ревью может отклонить, а не обходной путь: назовите причину и то, чем
проверено исправление вместо теста.
- Выносите наружу противоречия между допущениями, документацией, тестами и
поведением в runtime.
- Держите публичную границу MCP как один сервер с именем `unica` и инструментами
`unica.*`, пока запись решения не изменит этот контракт.
- Видимые модели скиллов остаются MCP-first. Пути прямого запуска упакованных
скриптов не должны возвращаться там, где уже есть нативный инструмент
`unica.*`, кроме описанных утилитарных исключений.
- Один каталог плагина обслуживает Codex и Claude Code. Держите оба манифеста на
одной версии, держите `.mcp.json` независимым от хоста и не добавляйте
необязательные ключи манифеста или каталога, не проверив, что их принимает
самый старый поддерживаемый клиент: там нераспознанный ключ — ошибка загрузки,
а не предупреждение.
- Изменение публичной поверхности — инструментов `unica.*`, идентичности
MCP-сервера, маршрутизации скиллов, упаковки или границ слоёв — правит
владельца `DEC.*` и выведенную запись `INV.*` или `CTR.*` тем же набором
изменений. Отгрузить код и отложить архитектуру значит оставить реестр
утверждать то, что сборка опровергает.
- Ссылайтесь на инвариант или решение по ID, а не копируйте его нормативную
формулировку. Если нужно пояснить применение правила, ставьте ID владельца
рядом и не выдавайте пояснение за независимую норму.
## Топология pull request
- По умолчанию — один самостоятельно проверяемый PR на одно связное изменение, с
базой `main` или явно названной релизной веткой.
- Не открывайте PR, базой которого является head-ветка другого открытого PR. Не
используйте дочерние PR как очередь правок по ревью: коммитьте и пушьте такие
правки в head-ветку существующего PR.
- Перед открытием PR посмотрите предполагаемую базу на GitHub. Если она
принадлежит открытому PR, остановитесь и либо возьмите его head-ветку, либо
спросите пользователя, как поступить; имя ветки само по себе не доказывает
независимость базы.
- Стек из PR допустим, только если пользователь явно попросил именованный стек и
задал порядок слияния и перебазирования. Каждый участник стека объясняет в
описании своего PR, кто его родитель, где проходит граница самостоятельного
ревью и как он будет закрыт.
- Если агент не может пушить в head существующего PR, он обязан предоставить
патч или попросить доступ; создавать дочерний PR в обход нельзя.
- Дефект, найденный во время ревью, разбирается по его происхождению.
- **Привнесённый этим же PR** — правится в нём же, коммитом в его head-ветку.
Отдельный PR на собственную регрессию оставляет в истории заведомо сломанный
коммит и делит ревью одного изменения на два.
- **Существовавший до него** — идёт независимым PR с базой `main` или
заводится задачей. В текущий PR он не втягивается: это расширяет его границу,
смешивает несвязанные изменения в одном ревью и задерживает то, что уже
готово.
- Когда происхождение неочевидно, решает `git log -S` или `git blame` по
строке дефекта, а не ощущение. Если и после этого неясно — дефект считается
существовавшим ранее и выносится наружу.
- Ни в одном из двух случаев дефект не превращается в неявный стек PR.