* feat(pipeline): add check_project_map to DOCS phase * test(pipeline): add check_project_map unit tests + update check_docs tests * docs(adr): add ADR-028 project map contract * docs(project-map): mention check_project_map guard in Update Protocol * docs(handoff): add PR handoff for check_project_map * docs(handoff): set PR number 67 * docs(review): fix PR#66 to PR#67 typo in project map and handoff * fix(ci): ruff lint errors in pipeline-status and project map test --------- Co-authored-by: opencode-agent <agent@opencode.local>
73 lines
No EOL
5.1 KiB
Markdown
73 lines
No EOL
5.1 KiB
Markdown
# ADR-028: Project map contract (mandatory README.md, aspirational modules)
|
||
|
||
## Статус
|
||
|
||
Accepted (2026-07-25)
|
||
|
||
## Контекст
|
||
|
||
Контракт `docs/project-map/` в репо `slaid098/opencode-config` размазан по 3
|
||
файлам с внутренними несоответствиями:
|
||
|
||
- `.opencode/agents/docs-reviewer.md:158-159,191` — обязывает
|
||
docs-reviewer обновлять карту при структурных изменениях и предлагает
|
||
один commit message.
|
||
- `.opencode/skills/get-project-map/SKILL.md:25-27` — описывает структуру
|
||
карты (README.md + модульные файлы per module) и frontmatter
|
||
`last_updated`.
|
||
- `.opencode/agents/reviewer.md:199-205` — требует от code-reviewer проверять
|
||
актуальность карты и предлагает *другой* commit message для той же
|
||
операции (несоответствие с docs-reviewer.md).
|
||
|
||
Фактическое состояние карты: только `README.md` (~140 строк, ASCII-дерево
|
||
структуры репо) без frontmatter и без модульных файлов. Полный контракт
|
||
(модульные файлы per module) никогда не соблюдался — aspirational документ,
|
||
не enforcement.
|
||
|
||
`pipeline-status.py:check_docs` (DOCS phase) валидировал handoff (4 секции),
|
||
ADR (filename pattern) и docs-reviewer comment (heading `## Docs Review
|
||
Summary`), но **не валидировал `docs/project-map/`**. Это позволяло PR проходить
|
||
DOCS-фазу даже при «тихом провале» docs-reviewer (забыл обновить карту при
|
||
структурных изменениях) — детерминированный guard отсутствовал. Зафиксировано
|
||
в memory `technical/pipeline-status-no-project-map-check.md`.
|
||
|
||
## Решение
|
||
|
||
Минимальный guard в `pipeline-status.py` — новая функция `check_project_map()`
|
||
проверяет существование `docs/project-map/README.md` (через
|
||
`PROJECT_MAP_DIR.exists()` + `README.md.exists()`). Встроена в `check_docs`
|
||
между `check_adr` и `_check_docs_reviewer_comment` (short-circuit на
|
||
NOT_DONE). Mandatory для pipeline-driven репо: docs-reviewer автосоздаёт
|
||
initial README.md при отсутствии каталога (`docs-reviewer.md:82-84`), поэтому
|
||
guard не блокирует первый PR и не требует ручной bootstrap-операции.
|
||
|
||
Контракт ослаблен под фактическое состояние:
|
||
|
||
- **README.md обязателен** — единственное, что проверяется детерминированно.
|
||
Возвращает DONE с размером файла в detail, либо NOT_DONE с указанием что
|
||
docs-reviewer должен создать (с ссылками на строки docs-reviewer.md).
|
||
- **Модульные файлы per module и frontmatter `last_updated`** — aspirational,
|
||
НЕ enforced. Полный контракт остаётся в `get-project-map/SKILL.md` как
|
||
рекомендация для docs-reviewer, но не блокирует пайплайн.
|
||
|
||
Возвращает только DONE/NOT_DONE (без AMBIGUOUS) — проверка файловой системы
|
||
детерминирована, нет внешних API вызовов.
|
||
|
||
## Альтернативы
|
||
|
||
- **Полный контракт (модульные файлы per module)** — отклонено: потребовало
|
||
бы создания ~12 новых файлов (по одному на модуль) для существующего репо,
|
||
блокируя пайплайн до их создания. Фактическое состояние никогда не
|
||
соответствовало этому контракту — enforcement сломал бы все открытые PR.
|
||
|
||
- **Опциональность через env-flag `OPENCODE_REQUIRE_PROJECT_MAP`** —
|
||
отклонено: docs-reviewer уже автосоздаёт initial README.md при отсутствии
|
||
каталога (`docs-reviewer.md:82-84`), feature-flag избыточен — guard
|
||
никогда не блокирует корректно настроенный pipeline-driven репо. Env-flag
|
||
добавил бы конфигурационную поверхность без выгоды.
|
||
|
||
- **Diff-based проверка (карта обновлена в PR через `gh pr view --json
|
||
files`)** — отклонено: сложнее в реализации (парсинг diff, фильтр по путям),
|
||
не гарантирует валидность содержимого (файл может быть изменён, но остаться
|
||
пустым/устаревшим). Существование README.md — более сильный guard (файл
|
||
присутствует), diff-based — слабее (файл изменён, но может быть невалиден). |