fix(docs): align tool names to kebab-case in active documentation (#78)

Co-authored-by: opencode-agent <agent@opencode.local>
This commit is contained in:
Sergey 2026-07-26 17:48:55 +03:00 committed by GitHub
parent 7c1fa4985e
commit d641f7a65b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 156 additions and 82 deletions

View file

@ -1,5 +1,5 @@
--- ---
description: Reviews and updates project map documentation before code review. Auto-commits updates to PR branch. Posts verdict via post_docs_review tool (deterministic heading for pipeline-status.py). description: Reviews and updates project map documentation before code review. Auto-commits updates to PR branch. Posts verdict via post-docs-review tool (deterministic heading for pipeline-status.py).
mode: subagent mode: subagent
temperature: 0.1 temperature: 0.1
steps: 150 steps: 150
@ -197,7 +197,7 @@ last_updated: <YYYY-MM-DD>
## PR Comment (mandatory) ## PR Comment (mandatory)
After validation (regardless of whether structural changes occurred), **ALWAYS** leave a PR comment using the `post_docs_review` tool. The tool auto-generates the `## Docs Review Summary` heading and the `### Verdict: <verdict>` line — you only pass the body content (between heading and verdict). Do NOT manually format the heading or verdict. This is the deterministic marker that `check_docs` in pipeline-status.py uses to prove docs-reviewer ran. Without this comment, the pipeline is blocked at DOCS phase. After validation (regardless of whether structural changes occurred), **ALWAYS** leave a PR comment using the `post-docs-review` tool. The tool auto-generates the `## Docs Review Summary` heading and the `### Verdict: <verdict>` line — you only pass the body content (between heading and verdict). Do NOT manually format the heading or verdict. This is the deterministic marker that `check_docs` in pipeline-status.py uses to prove docs-reviewer ran. Without this comment, the pipeline is blocked at DOCS phase.
Body format (without heading — tool adds `## Docs Review Summary` and `### Verdict: <verdict>`): Body format (without heading — tool adds `## Docs Review Summary` and `### Verdict: <verdict>`):
``` ```
@ -211,7 +211,7 @@ Body format (without heading — tool adds `## Docs Review Summary` and `### Ver
Call: Call:
``` ```
post_docs_review({ pr_number: <PR_NUMBER>, verdict: "<APPROVE|FIXED|NO_CHANGES>", body: `<body text above>` }) post-docs-review({ pr_number: <PR_NUMBER>, verdict: "<APPROVE|FIXED|NO_CHANGES>", body: `<body text above>` })
``` ```
Verdict semantics: Verdict semantics:
@ -222,15 +222,15 @@ Verdict semantics:
Rules: Rules:
1. Comment is left AFTER commit+push (if any) — so reviewer can see final state. 1. Comment is left AFTER commit+push (if any) — so reviewer can see final state.
2. If no structural changes AND handoff+ADR valid → no commit, but comment IS still left with `Verdict: NO_CHANGES`. 2. If no structural changes AND handoff+ADR valid → no commit, but comment IS still left with `Verdict: NO_CHANGES`.
3. The comment heading `## Docs Review Summary` is guaranteed by the `post_docs_review` tool — `check_docs` matches regex `Docs Review` (case-insensitive). 3. The comment heading `## Docs Review Summary` is guaranteed by the `post-docs-review` tool — `check_docs` matches regex `Docs Review` (case-insensitive).
4. Never skip the comment, even on edge cases — use `Verdict: NO_CHANGES` instead of silence. 4. Never skip the comment, even on edge cases — use `Verdict: NO_CHANGES` instead of silence.
## Tool failure handling ## Tool failure handling
If `post_docs_review` returns a string starting with `⚠️ ...failed` (e.g. `⚠️ post-docs-review failed for PR #N (exit 1): ...`): If `post-docs-review` returns a string starting with `⚠️ ...failed` (e.g. `⚠️ post-docs-review failed for PR #N (exit 1): ...`):
- **СООБЩИ оркестратору о сбое tool и STOP.** Не продолжай молча, не пытайся fallback на raw `gh pr comment` через bash. - **СООБЩИ оркестратору о сбое tool и STOP.** Не продолжай молча, не пытайся fallback на raw `gh pr comment` через bash.
- Причина сбоя обычно: gh не аутентифицирован, PR не найден в текущем репо (cwd не git-репо или нет origin remote), или network error. - Причина сбоя обычно: gh не аутентифицирован, PR не найден в текущем репо (cwd не git-репо или нет origin remote), или network error.
- Возвращай текст вида: `⚠️ post_docs_review tool failed: <сообщение от tool>. Pipeline заблокирован на DOCS phase — требуется вмешательство.` - Возвращай текст вида: `⚠️ post-docs-review tool failed: <сообщение от tool>. Pipeline заблокирован на DOCS phase — требуется вмешательство.`
- Любой дальнейший tool call после сбоя = protocol violation. - Любой дальнейший tool call после сбоя = protocol violation.
## Rules ## Rules

View file

@ -92,6 +92,6 @@ If a fact is already recorded — update the entry (bump `updated` in frontmatte
5. Receipt is mandatory even if no durable records found. 5. Receipt is mandatory even if no durable records found.
6. If memory file doesn't exist — create it with proper frontmatter (title, tags, summary, created, updated, importance). 6. If memory file doesn't exist — create it with proper frontmatter (title, tags, summary, created, updated, importance).
7. Для debug-вывода используй `pwd`/`ls`/`cat`/`printenv`НЕ `echo` (не в allow-list). 7. Для debug-вывода используй `pwd`/`ls`/`cat`/`printenv`НЕ `echo` (не в allow-list).
8. Для статуса PR используй нативный tool `pipeline_status` (НЕ bash `python3 .../pipeline-status.py` — детерминированный deny-rule, см. ADR-019). 8. Для статуса PR используй нативный tool `pipeline-status` (НЕ bash `python3 .../pipeline-status.py` — детерминированный deny-rule, см. ADR-019).
9. НЕ используй `git -C <path>` — работай в текущем cwd (memory-syncer читает уже смерженный default branch). 9. НЕ используй `git -C <path>` — работай в текущем cwd (memory-syncer читает уже смерженный default branch).
10. НЕ делай `git checkout`/`git pull` — работаешь на уже смерженном default branch, переключаться не нужно. 10. НЕ делай `git checkout`/`git pull` — работаешь на уже смерженном default branch, переключаться не нужно.

View file

@ -1,5 +1,5 @@
--- ---
description: Global code reviewer. Reviews PRs against project skills and universal code standards. Invoke via @reviewer. Uses post_review tool to approve or request changes (deterministic heading format for pipeline-status.py). Does NOT merge — merge is done by main agent via run-pipeline. description: Global code reviewer. Reviews PRs against project skills and universal code standards. Invoke via @reviewer. Uses post-review tool to approve or request changes (deterministic heading format for pipeline-status.py). Does NOT merge — merge is done by main agent via run-pipeline.
mode: subagent mode: subagent
temperature: 0.1 temperature: 0.1
steps: 150 steps: 150
@ -95,7 +95,7 @@ You are a global code reviewer. Your job: review PRs against project skills and
4. Check if the repo has project-specific skills: 4. Check if the repo has project-specific skills:
- Run `find skills/ -name "SKILL.md" -o -name "skill.md" 2>/dev/null` - Run `find skills/ -name "SKILL.md" -o -name "skill.md" 2>/dev/null`
- If skills exist, load each via `skill("<name>")` to get project-specific rules. - If skills exist, load each via `skill("<name>")` to get project-specific rules.
5. Check CI status: use `pipeline_status({pr_number: <PR_NUMBER>})` tool. 5. Check CI status: use `pipeline-status({pr_number: <PR_NUMBER>})` tool.
If unavailable, use `gh run list --branch <headRefName> --limit 3`. If unavailable, use `gh run list --branch <headRefName> --limit 3`.
Do NOT use `gh pr checks` (403) or bash `python3 .../pipeline-status.py` (denied). Do NOT use `gh pr checks` (403) or bash `python3 .../pipeline-status.py` (denied).
6. Also check for `.opencode/agents/` project-level agents that may define conventions. 6. Also check for `.opencode/agents/` project-level agents that may define conventions.
@ -103,7 +103,7 @@ You are a global code reviewer. Your job: review PRs against project skills and
## Investigation Budget ## Investigation Budget
You have a maximum of ~15 steps for investigation (Setup + checklist). You have a maximum of ~15 steps for investigation (Setup + checklist).
After that, you MUST call post_review — even if you haven't checked everything. After that, you MUST call post-review — even if you haven't checked everything.
An incomplete review with verdict NEEDS_DISCUSSION is better than an infinite investigation. An incomplete review with verdict NEEDS_DISCUSSION is better than an infinite investigation.
Do NOT repeatedly verify references in agent .md files — read once, assess, move on. Do NOT repeatedly verify references in agent .md files — read once, assess, move on.
@ -215,13 +215,13 @@ Examples of project-specific rules:
## Output Format ## Output Format
After reviewing, leave a GitHub PR comment using the `post_review` tool. The tool auto-generates the `## Code Review Summary` heading and the `### Verdict: <verdict>` line — you only pass the body content (between heading and verdict). Do NOT manually format the heading or verdict. After reviewing, leave a GitHub PR comment using the `post-review` tool. The tool auto-generates the `## Code Review Summary` heading and the `### Verdict: <verdict>` line — you only pass the body content (between heading and verdict). Do NOT manually format the heading or verdict.
### If approving (no critical or blocking warnings): ### If approving (no critical or blocking warnings):
Run: Run:
``` ```
post_review({ pr_number: <PR_NUMBER>, verdict: "APPROVE", body: `<review body>` }) post-review({ pr_number: <PR_NUMBER>, verdict: "APPROVE", body: `<review body>` })
``` ```
Body format (without heading — tool adds `## Code Review Summary` and `### Verdict: APPROVE`): Body format (without heading — tool adds `## Code Review Summary` and `### Verdict: APPROVE`):
@ -242,7 +242,7 @@ After this call, you MUST respond with your review text only. Do NOT call any mo
Run: Run:
``` ```
post_review({ pr_number: <PR_NUMBER>, verdict: "REQUEST_CHANGES", body: `<review body>` }) post-review({ pr_number: <PR_NUMBER>, verdict: "REQUEST_CHANGES", body: `<review body>` })
``` ```
Body format (without heading — tool adds `## Code Review Summary` and `### Verdict: REQUEST_CHANGES`): Body format (without heading — tool adds `## Code Review Summary` and `### Verdict: REQUEST_CHANGES`):
@ -269,7 +269,7 @@ After this call, you MUST respond with your review text only. Do NOT call any mo
Run: Run:
``` ```
post_review({ pr_number: <PR_NUMBER>, verdict: "NEEDS_DISCUSSION", body: `<review body>` }) post-review({ pr_number: <PR_NUMBER>, verdict: "NEEDS_DISCUSSION", body: `<review body>` })
``` ```
Body format (without heading — tool adds `## Code Review Summary` and `### Verdict: NEEDS_DISCUSSION`): Body format (without heading — tool adds `## Code Review Summary` and `### Verdict: NEEDS_DISCUSSION`):
@ -284,11 +284,11 @@ After this call, you MUST respond with your review text only. Do NOT call any mo
## Tool failure handling ## Tool failure handling
If `post_review` returns a string starting with `⚠️ ...failed` (e.g. `⚠️ post-review failed for PR #N (exit 1): ...`): If `post-review` returns a string starting with `⚠️ ...failed` (e.g. `⚠️ post-review failed for PR #N (exit 1): ...`):
- **СООБЩИ оркестратору о сбое tool и STOP.** Не продолжай молча, не пытайся fallback на raw `gh pr comment` через bash. - **СООБЩИ оркестратору о сбое tool и STOP.** Не продолжай молча, не пытайся fallback на raw `gh pr comment` через bash.
- Причина сбоя обычно: gh не аутентифицирован, PR не найден в текущем репо (cwd не git-репо или нет origin remote), или network error. - Причина сбоя обычно: gh не аутентифицирован, PR не найден в текущем репо (cwd не git-репо или нет origin remote), или network error.
- Возвращай текст вида: `⚠️ post_review tool failed: <сообщение от tool>. Pipeline заблокирован на REVIEW phase — требуется вмешательство.` - Возвращай текст вида: `⚠️ post-review tool failed: <сообщение от tool>. Pipeline заблокирован на REVIEW phase — требуется вмешательство.`
- Любой дальнейший tool call после сбоя = protocol violation (как и после успешного `post_review`). - Любой дальнейший tool call после сбоя = protocol violation (как и после успешного `post-review`).
## Severity Levels ## Severity Levels
@ -306,9 +306,9 @@ If `post_review` returns a string starting with `⚠️ ...failed` (e.g. `⚠️
4. ALWAYS provide file:line references in issues. 4. ALWAYS provide file:line references in issues.
5. ALWAYS suggest a fix, not just describe the problem. 5. ALWAYS suggest a fix, not just describe the problem.
6. If unsure about something → NEEDS_DISCUSSION, don't guess. 6. If unsure about something → NEEDS_DISCUSSION, don't guess.
7. After `post_review` (APPROVE, REQUEST_CHANGES, or NEEDS_DISCUSSION), STOP. 7. After `post-review` (APPROVE, REQUEST_CHANGES, or NEEDS_DISCUSSION), STOP.
Respond with final text only. ANY further tool call is a protocol violation. Respond with final text only. ANY further tool call is a protocol violation.
Main agent merges via run-pipeline. Main agent merges via run-pipeline.
8. After `post_review` with REQUEST_CHANGES, STOP. Do not merge. 8. After `post-review` with REQUEST_CHANGES, STOP. Do not merge.
9. Для получения login автора PR используй `gh pr view --json author` (НЕ `gh api user` — broad API call, не в allow-list, вызывает doom-loop). 9. Для получения login автора PR используй `gh pr view --json author` (НЕ `gh api user` — broad API call, не в allow-list, вызывает doom-loop).
10. Для debug-вывода используй `pwd`/`ls`/`cat`НЕ `echo` (не в allow-list). 10. Для debug-вывода используй `pwd`/`ls`/`cat`НЕ `echo` (не в allow-list).

View file

@ -2,4 +2,4 @@
description: Run pipeline — autonomous 7-phase PR pipeline description: Run pipeline — autonomous 7-phase PR pipeline
agent: build agent: build
--- ---
Load the `run-pipeline` skill via `skill({name: "run-pipeline"})` and follow its ПРОТОКОЛ strictly. Each iteration: call `pipeline_status` tool, execute the `NEXT:` action it returns, repeat until COMPLETE or STOP. Полностью автономно — 1 строка прогресса после каждой фазы, STOP на AMBIGUOUS/error. Load the `run-pipeline` skill via `skill({name: "run-pipeline"})` and follow its ПРОТОКОЛ strictly. Each iteration: call `pipeline-status` tool, execute the `NEXT:` action it returns, repeat until COMPLETE or STOP. Полностью автономно — 1 строка прогресса после каждой фазы, STOP на AMBIGUOUS/error.

View file

@ -2,4 +2,4 @@
description: Run spec — interactive spec generation for new project description: Run spec — interactive spec generation for new project
agent: build agent: build
--- ---
Load the `spec` skill via `skill({name: "spec"})` and follow its ПРОТОКОЛ strictly. Главный агент — оркестратор: `spec_status` tool (read-only) + вопрос юзеру + task(general) делегирование. Не делает edit/memory_search/gh сам. Каждая фаза = 1 subagent. Стоп на issues — дальше юзер сам /run-pipeline. Load the `spec` skill via `skill({name: "spec"})` and follow its ПРОТОКОЛ strictly. Главный агент — оркестратор: `spec-status` tool (read-only) + вопрос юзеру + task(general) делегирование. Не делает edit/memory_search/gh сам. Каждая фаза = 1 subagent. Стоп на issues — дальше юзер сам /run-pipeline.

View file

@ -47,11 +47,13 @@ description: <когда загружать. Триггеры на русско
├── get-project-map/SKILL.md ├── get-project-map/SKILL.md
├── issue/SKILL.md ├── issue/SKILL.md
├── memory/SKILL.md ├── memory/SKILL.md
├── run-pipeline/SKILL.md
├── python-development/SKILL.md ├── python-development/SKILL.md
├── release/SKILL.md
├── repo-init/SKILL.md ├── repo-init/SKILL.md
├── run-pipeline/SKILL.md
├── run-tests/SKILL.md ├── run-tests/SKILL.md
└── spec/SKILL.md ├── spec/SKILL.md
└── tunnel/SKILL.md
``` ```
## 3. Скиллы авто-дискаверятся ## 3. Скиллы авто-дискаверятся

View file

@ -80,10 +80,10 @@ Issue создаёт **subagent** (general type), а не основной аг
1. Загрузи навык `issue` 1. Загрузи навык `issue`
2. Собери контекст — прочитай файлы из intent summary, пойми задачу, оцени объём (правило дробления ниже) 2. Собери контекст — прочитай файлы из intent summary, пойми задачу, оцени объём (правило дробления ниже)
3. Составь self-contained body по шаблону (Контекст → Что сделать → Проверка → Acceptance criteria → Dependencies → Связанные ресурсы) 3. Составь self-contained body по шаблону (Контекст → Что сделать → Проверка → Acceptance criteria → Dependencies → Связанные ресурсы)
4. Запусти `create_issue({ title: "...", body: "...", labels: ["..."] })` tool (НЕ raw `gh issue create` — заблокирован deny; tool валидирует conventional title format и headings `## Контекст`/`## Задача`/`## Критерии приемки`) 4. Запусти `create-issue({ title: "...", body: "...", labels: ["..."] })` tool (НЕ raw `gh issue create` — заблокирован deny; tool валидирует conventional title format и headings `## Контекст`/`## Задача`/`## Критерии приемки`)
5. Верни URL созданного issue основному агенту 5. Верни URL созданного issue основному агенту
Main agent НЕ пишет body и НЕ запускает `create_issue` — всё через subagent. Это согласовано с `run-pipeline` skill (Phase 0: "через subagent с `issue` skill") и `AGENTS.md` (Dev Workflow, step 2: "delegate to `task` subagent"). Main agent НЕ пишет body и НЕ запускает `create-issue` — всё через subagent. Это согласовано с `run-pipeline` skill (Phase 0: "через subagent с `issue` skill") и `AGENTS.md` (Dev Workflow, step 2: "delegate to `task` subagent").
## Пример хорошего issue ## Пример хорошего issue
@ -126,7 +126,7 @@ Zoom breathing падает при включённом geometry crop — crop
Через tool (НЕ raw bash — `gh issue create *` заблокирован deny): Через tool (НЕ raw bash — `gh issue create *` заблокирован deny):
``` ```
create_issue({ title: "type(scope): description", body: "...", labels: ["<label>"] }) create-issue({ title: "type(scope): description", body: "...", labels: ["<label>"] })
``` ```
Tool валидирует: title соответствует conventional format (type(scope): desc, Tool валидирует: title соответствует conventional format (type(scope): desc,
@ -157,7 +157,7 @@ Label выбирай по типу задачи (совпадает с commit `t
1. **Subagent**`task(general)` читает issue, реализует, коммитит, push, создаёт PR. Оркестрация — через `run-pipeline` skill. 1. **Subagent**`task(general)` читает issue, реализует, коммитит, push, создаёт PR. Оркестрация — через `run-pipeline` skill.
2. **Docs review**`@docs-reviewer` subagent валидирует handoff + ADR, обновляет project map (pre-merge). 2. **Docs review**`@docs-reviewer` subagent валидирует handoff + ADR, обновляет project map (pre-merge).
3. **Code review**`@reviewer` subagent ревьюит PR (diff, skills, standards), постит `## Code Review Summary` комментарий. 3. **Code review**`@reviewer` subagent ревьюит PR (diff, skills, standards), постит `## Code Review Summary` комментарий.
4. **Merge or Repeat** — APPROVE → `merge_pr({ pr_number: N })` tool (squash + 4. **Merge or Repeat** — APPROVE → `merge-pr({ pr_number: N })` tool (squash +
delete branch, без `--admin`; НЕ raw `gh pr merge` — заблокирован deny), delete branch, без `--admin`; НЕ raw `gh pr merge` — заблокирован deny),
после CI ✅; замечания → fix subagent → re-review → merge. после CI ✅; замечания → fix subagent → re-review → merge.
5. **Memory-sync**`@memory-syncer` дистиллирует handoff + ADR в `app_data/opencode-memory/repos/{host}/{org}/{repo}.md`. 5. **Memory-sync**`@memory-syncer` дистиллирует handoff + ADR в `app_data/opencode-memory/repos/{host}/{org}/{repo}.md`.

View file

@ -16,7 +16,7 @@ description: Инструкция по работе с файловой памя
| `memory_list(category?)` | Список категорий / файлов | | `memory_list(category?)` | Список категорий / файлов |
| `memory_save()` | Commit + re-index после записи/редактирования | | `memory_save()` | Commit + re-index после записи/редактирования |
| `memory_access(path)` | Отметить файл как прочитанный | | `memory_access(path)` | Отметить файл как прочитанный |
| `memory_setup()` | Проверить статус бэкендов | | `memory-setup()` | Проверить статус бэкендов |
## Категории ## Категории

View file

@ -6,14 +6,14 @@ description: Автономный исполнитель PR-пайплайна.
# Run Pipeline # Run Pipeline
Автономная процедура-loop для проведения PR через 7 фаз. Source of truth для Автономная процедура-loop для проведения PR через 7 фаз. Source of truth для
порядка и действий — `pipeline_status` tool. NEXT action из tool явно порядка и действий — `pipeline-status` tool. NEXT action из tool явно
указывает `subagent_type` + `template` (кроме MERGE — `merge_pr` tool). указывает `subagent_type` + `template` (кроме MERGE — `merge-pr` tool).
## ПРОТОКОЛ (ЖЁСТКО) ## ПРОТОКОЛ (ЖЁСТКО)
Каждая итерация (БЕЗ ИСКЛЮЧЕНИЙ): Каждая итерация (БЕЗ ИСКЛЮЧЕНИЙ):
1. Вызови tool `pipeline_status({pr_number: M})` — вернёт статус всех фаз + строку `NEXT: <action>`. 1. Вызови tool `pipeline-status({pr_number: M})` — вернёт статус всех фаз + строку `NEXT: <action>`.
2. Если вывод содержит `Status: COMPLETE` → финальный репорт пользователю, exit. 2. Если вывод содержит `Status: COMPLETE` → финальный репорт пользователю, exit.
3. Если вывод содержит `AMBIGUOUS` → репорт пользователю с причиной, STOP. 3. Если вывод содержит `AMBIGUOUS` → репорт пользователю с причиной, STOP.
4. Иначе — исполни action из строки `NEXT:` (используй prompt templates A-E ниже). 4. Иначе — исполни action из строки `NEXT:` (используй prompt templates A-E ниже).
@ -22,18 +22,18 @@ description: Автономный исполнитель PR-пайплайна.
### ЗАПРЕЩЕНО ### ЗАПРЕЩЕНО
- ЛЮБОЙ action БЕЗ предшествующего вызова `pipeline_status` = protocol violation. - ЛЮБОЙ action БЕЗ предшествующего вызова `pipeline-status` = protocol violation.
- Импровизировать порядок. Решать сам какой subagent запускать — читай `NEXT:`. - Импровизировать порядок. Решать сам какой subagent запускать — читай `NEXT:`.
- Пропускать вызов `pipeline_status`, даже если «кажется, что фаза уже ✅» — скрипт решает. - Пропускать вызов `pipeline-status`, даже если «кажется, что фаза уже ✅» — скрипт решает.
- Делать bash `sleep` для ожидания CI — `pipeline_status` сам блокирует до 5 мин (polling Actions API внутри `check_ci`). Один вызов → финальный статус. - Делать bash `sleep` для ожидания CI — `pipeline-status` сам блокирует до 5 мин (polling Actions API внутри `check_ci`). Один вызов → финальный статус.
- Merge при CI ❌ (transitive guard в скрипте). - Merge при CI ❌ (transitive guard в скрипте).
- Передавать `--admin` flag в `merge_pr` (или raw `gh pr merge`) — никогда. - Передавать `--admin` flag в `merge-pr` (или raw `gh pr merge`) — никогда.
- Параллелить subagents (последовательно: action → `pipeline_status` → next action). - Параллелить subagents (последовательно: action → `pipeline-status` → next action).
### Остановы ### Остановы
- Subagent error → 1 retry, потом STOP + report пользователю. - Subagent error → 1 retry, потом STOP + report пользователю.
- `AMBIGUOUS` в выводе `pipeline_status` → STOP + report. - `AMBIGUOUS` в выводе `pipeline-status` → STOP + report.
- 5 итераций подряд без прогресса (та же фаза ❌) → STOP + report. - 5 итераций подряд без прогресса (та же фаза ❌) → STOP + report.
## Prompt templates ## Prompt templates
@ -47,12 +47,12 @@ description: Автономный исполнитель PR-пайплайна.
зафикь и продолжай — не додумывай. зафикь и продолжай — не додумывай.
3. Создай handoff + ADR: `bash .opencode/scripts/scaffold-handoff.sh M <slug>` 3. Создай handoff + ADR: `bash .opencode/scripts/scaffold-handoff.sh M <slug>`
(M — будет PR номер, используй placeholder `<PR-NUMBER>` в handoff (M — будет PR номер, используй placeholder `<PR-NUMBER>` в handoff
frontmatter, потом исправишь после create_pr). frontmatter, потом исправишь после create-pr).
4. Коммиты через `commit({ message: "type(scope): description" })` tool (НЕ 4. Коммиты через `commit({ message: "type(scope): description" })` tool (НЕ
raw `git commit` — заблокирован deny). Формат: ≤72 chars, English, no raw `git commit` — заблокирован deny). Формат: ≤72 chars, English, no
period, no body unless necessary. Минимум 3-4 логических коммита. period, no body unless necessary. Минимум 3-4 логических коммита.
5. Push ветку (`git push -u origin HEAD`), затем создай PR через tool: 5. Push ветку (`git push -u origin HEAD`), затем создай PR через tool:
`create_pr({ title: "type(scope): description", body: "## Что сделано\n...\n\n## Почему\n...\n\nCloses #N", issue_number: N })`. `create-pr({ title: "type(scope): description", body: "## Что сделано\n...\n\n## Почему\n...\n\nCloses #N", issue_number: N })`.
6. После получения PR номера — исправь placeholder `<PR-NUMBER>` в handoff 6. После получения PR номера — исправь placeholder `<PR-NUMBER>` в handoff
frontmatter, отдельный коммит `docs(handoff): set PR number` через frontmatter, отдельный коммит `docs(handoff): set PR number` через
`commit` tool, push. `commit` tool, push.
@ -76,10 +76,10 @@ Review PR#M в текущем репо (pre-merge, режим docs).
tool, и `git push`. tool, и `git push`.
8. **ВСЕГДА** оставь PR comment (даже если structural changes нет) — это 8. **ВСЕГДА** оставь PR comment (даже если structural changes нет) — это
детерминированный marker для `check_docs` в pipeline-status.py. Без comment детерминированный marker для `check_docs` в pipeline-status.py. Без comment
pipeline блокируется на DOCS phase. Используй tool `post_docs_review` (НЕ pipeline блокируется на DOCS phase. Используй tool `post-docs-review` (НЕ
raw bash-вызов `gh`) — tool гарантирует heading `## Docs Review Summary` и raw bash-вызов `gh`) — tool гарантирует heading `## Docs Review Summary` и
verdict-enum (zod), формат который парсит `check_docs`. verdict-enum (zod), формат который парсит `check_docs`.
`post_docs_review({ pr_number: M, verdict: "APPROVE|FIXED|NO_CHANGES", body: "- Project map: ...\n- Handoff: ...\n- ADR: ..." })`. `post-docs-review({ pr_number: M, verdict: "APPROVE|FIXED|NO_CHANGES", body: "- Project map: ...\n- Handoff: ...\n- ADR: ..." })`.
Heading `## Docs Review Summary` — обязательно (regex `Docs Review`), Heading `## Docs Review Summary` — обязательно (regex `Docs Review`),
tool добавляет его автоматически — НЕ форматируй heading/verdict вручную. tool добавляет его автоматически — НЕ форматируй heading/verdict вручную.
Если tool вернул строку начинающуюся с `⚠️ ...failed` — СООБЩИ оркестратору Если tool вернул строку начинающуюся с `⚠️ ...failed` — СООБЩИ оркестратору
@ -96,11 +96,11 @@ Review PR#M в текущем репо.
через `skill("<name>")`. через `skill("<name>")`.
4. Проверь: code quality, architecture, error handling, security, testing, 4. Проверь: code quality, architecture, error handling, security, testing,
duplication, project-specific rules, PR hygiene, handoff/ADR (quick check). duplication, project-specific rules, PR hygiene, handoff/ADR (quick check).
5. Оставь review через tool `post_review` (НЕ `gh pr review --approve` 5. Оставь review через tool `post-review` (НЕ `gh pr review --approve`
GitHub блокирует self-approve; НЕ raw bash-вызов `gh`) — tool гарантирует GitHub блокирует self-approve; НЕ raw bash-вызов `gh`) — tool гарантирует
heading `## Code Review Summary` + verdict-enum которые парсит heading `## Code Review Summary` + verdict-enum которые парсит
`pipeline-status.py`: `pipeline-status.py`:
`post_review({ pr_number: M, verdict: "APPROVE|REQUEST_CHANGES|NEEDS_DISCUSSION", body: "..." })`. `post-review({ pr_number: M, verdict: "APPROVE|REQUEST_CHANGES|NEEDS_DISCUSSION", body: "..." })`.
Tool добавляет heading + verdict line автоматически — НЕ форматируй их Tool добавляет heading + verdict line автоматически — НЕ форматируй их
вручную. Если tool вернул строку начинающуюся с `⚠️ ...failed` — СООБЩИ вручную. Если tool вернул строку начинающуюся с `⚠️ ...failed` — СООБЩИ
оркестратору о сбое и STOP (не fallback на raw bash). оркестратору о сбое и STOP (не fallback на raw bash).
@ -143,28 +143,28 @@ Log: `gh run view <run-id> --log-failed` output:
### Template F (merge) ### Template F (merge)
MERGE phase — main agent вызывает tool напрямую (НЕ subagent, НЕ raw bash). MERGE phase — main agent вызывает tool напрямую (НЕ subagent, НЕ raw bash).
`pipeline_status` сам решает, можно ли мержить (CI gate внутри скрипта — `pipeline-status` сам решает, можно ли мержить (CI gate внутри скрипта —
transitive guard). После `NEXT: ...merge_pr...` → один вызов: transitive guard). После `NEXT: ...merge-pr...` → один вызов:
``` ```
merge_pr({ pr_number: M }) merge-pr({ pr_number: M })
``` ```
Если вернулась `⚠️ merge_pr failed ...` → репорт пользователю, STOP (НЕ retry Если вернулась `⚠️ merge-pr failed ...` → репорт пользователю, STOP (НЕ retry
через raw bash — это нарушит orchestrator-контракт). Если `PR #M merged через raw bash — это нарушит orchestrator-контракт). Если `PR #M merged
successfully ...` → 1 строка прогресса и re-loop (`pipeline_status` покажет successfully ...` → 1 строка прогресса и re-loop (`pipeline-status` покажет
`Status: COMPLETE` или перейдёт на MEMORY phase). `Status: COMPLETE` или перейдёт на MEMORY phase).
## API Restrictions ## API Restrictions
Использовать только Actions API (`pipeline_status`, `gh run list`, `gh run view`, `gh api repos/.../actions/runs`). **Запрещено** `gh pr checks` и `gh pr view --json statusCheckRollup` — 403 на fine-grained PAT (scope `Checks: read` не существует). Использовать только Actions API (`pipeline-status`, `gh run list`, `gh run view`, `gh api repos/.../actions/runs`). **Запрещено** `gh pr checks` и `gh pr view --json statusCheckRollup` — 403 на fine-grained PAT (scope `Checks: read` не существует).
## Rules ## Rules
- `pipeline_status` — единственный source of truth для порядка шагов и действий. - `pipeline-status` — единственный source of truth для порядка шагов и действий.
- Скрипт read-only (только `gh api`/`gh pr view`, без мутаций). - Скрипт read-only (только `gh api`/`gh pr view`, без мутаций).
- После каждой фазы → 1 строка прогресса юзеру. - После каждой фазы → 1 строка прогресса юзеру.
- Если subagent error → 1 retry, потом STOP + report пользователю. - Если subagent error → 1 retry, потом STOP + report пользователю.
- `merge_pr({ pr_number: M })` tool — единственный способ мержить PR (без - `merge-pr({ pr_number: M })` tool — единственный способ мержить PR (без
`--admin`, без raw bash). См. Template F. `--admin`, без raw bash). См. Template F.
- Если reviewer вердикт `REQUEST_CHANGES` → dispatch subagent (general) с prompt "fix reviewer comments: <list>", commit, push → re-loop (`pipeline_status` проверит CI автоматически). - Если reviewer вердикт `REQUEST_CHANGES` → dispatch subagent (general) с prompt "fix reviewer comments: <list>", commit, push → re-loop (`pipeline-status` проверит CI автоматически).

View file

@ -1,19 +1,19 @@
--- ---
name: spec name: spec
description: Автономный исполнитель spec-генерации для нового проекта. Детерминированно ведёт агента по 9 фазам через spec_status tool. Главный агент — оркестратор, делегирует ВСЮ работу subagent'ам. Also when user says "создай спеку", "новый проект", "спецификация проекта", "spec", "project spec". description: Автономный исполнитель spec-генерации для нового проекта. Детерминированно ведёт агента по 9 фазам через spec-status tool. Главный агент — оркестратор, делегирует ВСЮ работу subagent'ам. Also when user says "создай спеку", "новый проект", "спецификация проекта", "spec", "project spec".
--- ---
# Spec # Spec
Автономная процедура-loop для генерации спецификации нового проекта. Source of Автономная процедура-loop для генерации спецификации нового проекта. Source of
truth для порядка и действий — `spec_status` tool. На выходе — `docs/spec/` truth для порядка и действий — `spec-status` tool. На выходе — `docs/spec/`
(директория с файлами по фазам) + N GitHub issues, готовых для `/run-pipeline`. (директория с файлами по фазам) + N GitHub issues, готовых для `/run-pipeline`.
## ПРОТОКОЛ (ЖЁСТКО) ## ПРОТОКОЛ (ЖЁСТКО)
Каждая итерация (БЕЗ ИСКЛЮЧЕНИЙ): Каждая итерация (БЕЗ ИСКЛЮЧЕНИЙ):
1. Вызови tool `spec_status({})` — вернёт текущую фазу + строку `NEXT: <action>`. 1. Вызови tool `spec-status({})` — вернёт текущую фазу + строку `NEXT: <action>`.
2. Если вывод содержит `Status: COMPLETE` → финальный репорт пользователю, exit. 2. Если вывод содержит `Status: COMPLETE` → финальный репорт пользователю, exit.
3. Если вывод содержит `AMBIGUOUS` → репорт пользователю с причиной, STOP. 3. Если вывод содержит `AMBIGUOUS` → репорт пользователю с причиной, STOP.
4. Иначе — выполни action из строки `NEXT:` (используй prompt templates A-I ниже). 4. Иначе — выполни action из строки `NEXT:` (используй prompt templates A-I ниже).
@ -22,10 +22,10 @@ truth для порядка и действий — `spec_status` tool. На в
### ЗАПРЕЩЕНО ### ЗАПРЕЩЕНО
- ЛЮБОЙ action БЕЗ предшествующего вызова `spec_status` = protocol violation. - ЛЮБОЙ action БЕЗ предшествующего вызова `spec-status` = protocol violation.
- Импровизировать порядок. Решать сам какую фазу выполнять — читай `NEXT:`. - Импровизировать порядок. Решать сам какую фазу выполнять — читай `NEXT:`.
- Пропускать вызов `spec_status`, даже если «кажется, что фаза уже ✅» — скрипт решает. - Пропускать вызов `spec-status`, даже если «кажется, что фаза уже ✅» — скрипт решает.
- bash-запуск `python3 config/scripts/spec-status.py` — детерминированный deny-rule (см. ADR-026, аналог ADR-019). Только нативный tool `spec_status`. - bash-запуск `python3 .opencode/scripts/spec-status.py` — детерминированный deny-rule (см. ADR-019). Только нативный tool `spec-status`.
- Главному агенту: edit/write/read файлов (всё через subagent), memory_search (через subagent), gh issue create (через subagent). - Главному агенту: edit/write/read файлов (всё через subagent), memory_search (через subagent), gh issue create (через subagent).
- Формулировать вопросы не из question templates ниже. - Формулировать вопросы не из question templates ниже.
- Предлагать стек вне hardcoded default stack по типу проекта. - Предлагать стек вне hardcoded default stack по типу проекта.
@ -34,7 +34,7 @@ truth для порядка и действий — `spec_status` tool. На в
### Остановы ### Остановы
- Subagent error → 1 retry, потом STOP + report пользователю. - Subagent error → 1 retry, потом STOP + report пользователю.
- `AMBIGUOUS` в выводе `spec_status` → STOP + report. - `AMBIGUOUS` в выводе `spec-status` → STOP + report.
- 3 итераций подряд без прогресса (та же фаза ❌) → STOP + report. - 3 итераций подряд без прогресса (та же фаза ❌) → STOP + report.
## Default stack по типам проекта (хардкод) ## Default stack по типам проекта (хардкод)
@ -239,7 +239,7 @@ Default stack для типа (хардкод, добавить всегда):
- worker: Prefect flows + tasks, prefect.yaml, docker-compose worker profile - worker: Prefect flows + tasks, prefect.yaml, docker-compose worker profile
1. Создай docs/spec/stack.md с полным списком (default + choices). 1. Создай docs/spec/stack.md с полным списком (default + choices).
2. edit docs/spec/meta.md frontmatter: phase=2. 2. edit docs/spec/meta.md frontmatter: phase=2.
3. spec_status валидирует mandatory items через содержимое stack.md — если FAIL, верни что не хватает. 3. spec-status валидирует mandatory items через содержимое stack.md — если FAIL, верни что не хватает.
4. Верни: "done: stack.md created, <N>/<M> mandatory items". 4. Верни: "done: stack.md created, <N>/<M> mandatory items".
``` ```
@ -308,7 +308,7 @@ Default stack для типа (хардкод, добавить всегда):
## Связанные ресурсы (Part of spec, ref к docs/spec/roadmap.md) ## Связанные ресурсы (Part of spec, ref к docs/spec/roadmap.md)
- Issue #1 (scaffolding) body ДОЛЖЕН включать: - Issue #1 (scaffolding) body ДОЛЖЕН включать:
"Используй repo-init skill для: pyproject.toml, CI, .gitignore, LICENSE, dependabot, pre-commit. Структура — из ## Структура в docs/spec/modules.md." "Используй repo-init skill для: pyproject.toml, CI, .gitignore, LICENSE, dependabot, pre-commit. Структура — из ## Структура в docs/spec/modules.md."
- `create_issue({ title: "type(scope): description", body: "<body>", labels: ["enhancement", "from-spec"] })` tool (НЕ raw `gh issue create` — заблокирован deny) - `create-issue({ title: "type(scope): description", body: "<body>", labels: ["enhancement", "from-spec"] })` tool (НЕ raw `gh issue create` — заблокирован deny)
4. Собери реальные номера issues из вывода tool. 4. Собери реальные номера issues из вывода tool.
5. Update docs/spec/roadmap.md: добавь реальные #N номера. Update docs/spec/meta.md: executed=true, phase=8. 5. Update docs/spec/roadmap.md: добавь реальные #N номера. Update docs/spec/meta.md: executed=true, phase=8.
6. Верни: [{number, url, title}, ...] для всех issues. 6. Верни: [{number, url, title}, ...] для всех issues.
@ -316,9 +316,9 @@ Default stack для типа (хардкод, добавить всегда):
## Rules ## Rules
- `spec_status` — единственный source of truth для порядка шагов и действий. - `spec-status` — единственный source of truth для порядка шагов и действий.
- Скрипт read-only (только presence check в `docs/spec/*.md`, без мутаций). - Скрипт read-only (только presence check в `docs/spec/*.md`, без мутаций).
- После каждой фазы → 1 строка прогресса юзеру. - После каждой фазы → 1 строка прогресса юзеру.
- Если subagent error → 1 retry, потом STOP + report пользователю. - Если subagent error → 1 retry, потом STOP + report пользователю.
- Главный агент = оркестратор: `spec_status` tool + вопрос юзеру + task(general) делегирование. Не делает edit/memory_search/gh сам. - Главный агент = оркестратор: `spec-status` tool + вопрос юзеру + task(general) делегирование. Не делает edit/memory_search/gh сам.
- Стоп на issues — дальше юзер сам /run-pipeline. - Стоп на issues — дальше юзер сам /run-pipeline.

View file

@ -10,11 +10,11 @@
## Development Workflow ## Development Workflow
All PR work runs through `/run-pipeline`. Pipeline phases orchestrated by `pipeline_status` tool (NEXT action per phase). Load `run-pipeline` skill. All PR work runs through `/run-pipeline`. Pipeline phases orchestrated by `pipeline-status` tool (NEXT action per phase). Load `run-pipeline` skill.
## Pipeline ## Pipeline
`pipeline_status` = read-only oracle (returns NEXT action). `merge_pr` = orchestrator-safe merge wrapper. Execution via `/run-pipeline` skill. `pipeline-status` = read-only oracle (returns NEXT action). `merge-pr` = orchestrator-safe merge wrapper. Execution via `/run-pipeline` skill.
## Read Path ## Read Path
@ -36,14 +36,14 @@ fallback на raw bash, НЕ импровизируй обход через `gh
| Tool | Raw bash (заблокирован deny) | Когда использовать | При сбое — STOP, репорт, НЕ fallback | | Tool | Raw bash (заблокирован deny) | Когда использовать | При сбое — STOP, репорт, НЕ fallback |
|---|---|---|---| |---|---|---|---|
| `commit({ message })` | `git commit *` | Коммит staged файлов (conventional format валидируется tool'ом) | Сообщи оркестратору, не `git commit` | | `commit({ message })` | `git commit *` | Коммит staged файлов (conventional format валидируется tool'ом) | Сообщи оркестратору, не `git commit` |
| `create_pr({ title, body, issue_number })` | `gh pr create *` | Создание PR после push ветки | Сообщи оркестратору, не `gh pr create`, не `gh api repos/*/pulls` | | `create-pr({ title, body, issue_number })` | `gh pr create *` | Создание PR после push ветки | Сообщи оркестратору, не `gh pr create`, не `gh api repos/*/pulls` |
| `create_issue({ title, body, labels })` | `gh issue create *` | Создание GitHub issue (валидация формата) | Сообщи оркестратору, не `gh issue create`, не `gh api repos/*/issues` | | `create-issue({ title, body, labels })` | `gh issue create *` | Создание GitHub issue (валидация формата) | Сообщи оркестратору, не `gh issue create`, не `gh api repos/*/issues` |
| `merge_pr({ pr_number })` | `gh pr merge *` | Merge PR (squash + delete branch, без `--admin`) | Сообщи оркестратору, не `gh pr merge` | | `merge-pr({ pr_number })` | `gh pr merge *` | Merge PR (squash + delete branch, без `--admin`) | Сообщи оркестратору, не `gh pr merge` |
| `post_review({ pr_number, verdict, body })` | `gh pr comment` для verdict | Code review verdict (heading `## Code Review Summary` + verdict) | Сообщи оркестратору, не `gh pr comment` | | `post-review({ pr_number, verdict, body })` | `gh pr comment` для verdict | Code review verdict (heading `## Code Review Summary` + verdict) | Сообщи оркестратору, не `gh pr comment` |
| `post_docs_review({ pr_number, verdict, body })` | `gh pr comment` для verdict | Docs review verdict (heading `## Docs Review Summary` + verdict) | Сообщи оркестратору, не `gh pr comment` | | `post-docs-review({ pr_number, verdict, body })` | `gh pr comment` для verdict | Docs review verdict (heading `## Docs Review Summary` + verdict) | Сообщи оркестратору, не `gh pr comment` |
| `pipeline_status({ pr_number })` | `python3 .opencode/scripts/pipeline-status.py` | Read-only oracle: статус фаз PR + NEXT action | Сообщи оркестратору, не bash-запуск скрипта | | `pipeline-status({ pr_number })` | `python3 .opencode/scripts/pipeline-status.py` | Read-only oracle: статус фаз PR + NEXT action | Сообщи оркестратору, не bash-запуск скрипта |
| `spec_status({})` | `python3 .opencode/scripts/spec-status.py` | Read-only oracle: текущая фаза spec + NEXT action | Сообщи оркестратору, не bash-запуск скрипта | | `spec-status({})` | `python3 .opencode/scripts/spec-status.py` | Read-only oracle: текущая фаза spec + NEXT action | Сообщи оркестратору, не bash-запуск скрипта |
| `memory_setup()` | `bash .opencode/scripts/setup-memory.sh` | Инициализация/синхронизация opencode-memory (clone + hook + reindex) | Сообщи оркестратору, не bash-запуск скрипта | | `memory-setup()` | `bash .opencode/scripts/setup-memory.sh` | Инициализация/синхронизация opencode-memory (clone + hook + reindex) | Сообщи оркестратору, не bash-запуск скрипта |
| `tunnel()` | `bash .opencode/scripts/tunnel.sh` | Cloudflare tunnel toggle (1-й вызов — start, 2-й — stop) | Сообщи оркестратору, не bash-запуск скрипта | | `tunnel()` | `bash .opencode/scripts/tunnel.sh` | Cloudflare tunnel toggle (1-й вызов — start, 2-й — stop) | Сообщи оркестратору, не bash-запуск скрипта |
`gh pr comment*` остаётся в allow-list reviewer/docs-reviewer для обратной `gh pr comment*` остаётся в allow-list reviewer/docs-reviewer для обратной

View file

@ -0,0 +1,35 @@
# ADR-034: Align local tool names to kebab-case in documentation
## Статус
Accepted (2026-07-26)
## Контекст
Реальные имена opencode tools в runtime registry — kebab-case (подтверждено анализом opencode.db: 397 runtime вызовов локальных .opencode/tools/*.ts tools в kebab-case, 0 в snake_case). SDK `@opencode-ai/plugin@1.18.5` `tool()` функция не имеет поля `name` — имя tool'а резолвится из filename (`create-pr.ts` → registry name "create-pr").
В AGENTS.md / SKILL.md / agents промптах tool'ы были написаны в snake_case (create_pr, merge_pr, pipeline_status и т.д.) — документационная конвенция эпохи написания (ADR-009, 2026-07-23). Runtime резолвит snake→kebab автоматически через utility `Re=(X)=>X.replace(/_/g,"-")` в opencode.exe — система работала, НО агент спотыкался: читал "вызови pipeline_status", искал такой tool в tool-списке сессии, находил только pipeline-status, не совпадало → вызывал не тот tool или fallback на raw bash (который deny → блок).
PR#71 GOTCHA memory (2026-07-26) зафиксировала расхождение: "Фактические tool names (как их вызывает opencode runtime) = дефис. Underscore в AGENTS.md — документационная конвенция, не runtime."
## Решение
1. Заменить snake_case имена ЛОКАЛЬНЫХ opencode tools на kebab-case в активной документации: AGENTS.md, 6 SKILL.md, 3 agents/*.md, 2 commands/*.md, docs/project-map/README.md. 12 файлов, 84 insertions / 82 deletions.
2. Локальные tools (правки): create-issue, create-pr, merge-pr, post-review, post-docs-review, pipeline-status, spec-status, memory-setup. Однословные commit/tunnel — без изменений.
3. MCP plugin tools (memory_search, memory_list, memory_save, memory_access) — НЕ трогать. Это другой namespace: имена задаёт плагин в export-коде (snake_case), не filename. opencode.db подтверждает: memory_search (65 calls), memory_save (13), memory_access (22) — все snake_case.
4. Исторические docs/handoff/* и docs/decisions/* НЕ трогать — сохраняют оригинальное написание эпохи написания (включая snake_case в ADR-009, handoff pr-29). Правка исторических ADR/handoff исказит историю.
5. opencode.json `agent.tools` map keys — НЕ трогать (snake_case keys работают через runtime Re-utility, смена требует проверки JSON-схемы + test_permissions.py — отдельный PR).
6. Аргументы tool'ов (pr_number, issue_number, verdict, body) остаются snake_case — это имена параметров в JSON schema, не tool names.
Доп. правки: broken ADR-026 ref в spec/SKILL.md:28 → ADR-019; путь скрипта config/scripts/ → .opencode/scripts/; список скиллов в add-skill/SKILL.md 12 → 14.
## Альтернативы
1. Сменить `agent.tools` map keys в opencode.json на kebab — отклонено (требует проверки JSON-схемы + test_permissions.py, отдельный PR, snake keys работают через Re-utility).
2. Править исторические ADR/handoff на kebab — отклонено (исказит историю, ADR-009 фиксирует intent "tools не переименовывались" — написание snake_case там документационная конвенция, не runtime assertion).
3. Добавить поле `name` в .ts tools с явным kebab — отклонено (SDK `tool()` не имеет этого поля в signature, имя уже корректно резолвится из filename).
4. Оставить snake_case в документации + rely on Re-utility — отклонено (агент спотыкается, читает "pipeline_status" и не находит такого tool в tool-списке сессии; документация должна совпадать с runtime).

View file

@ -0,0 +1,37 @@
---
pr: 78
title: fix(docs): align tool names to kebab-case (local .opencode/tools)
---
## Что сделано
Заменил snake_case имена ЛОКАЛЬНЫХ opencode tools на kebab-case в активной документации (AGENTS.md, 6 SKILL.md, 3 agents/*.md, 2 commands/*.md, docs/project-map/README.md). 12 файлов, 84 insertions / 82 deletions.
Локальные tools (правки, kebab-case): create-issue, create-pr, merge-pr, post-review, post-docs-review, pipeline-status, spec-status, memory-setup. Однословные commit/tunnel — без изменений.
MCP plugin tools (memory_search, memory_list, memory_save, memory_access) — НЕ тронуты, остались snake_case (это другой namespace, имена задаёт плагин).
Доп. правки:
- spec/SKILL.md:28 — broken ADR-026 ref → ADR-019 (ADR-026 создан в PR#63 про другой topic — enforce-tool-usage-policy; ADR-019 уже описывает аналогичный deny-rule паттерн для post-review/post-docs-review).
- spec/SKILL.md:28 — путь скрипта `config/scripts/spec-status.py``.opencode/scripts/spec-status.py` (расхождение с AGENTS.md).
- add-skill/SKILL.md — список существующих скиллов 12 → 14 (добавлены release, tunnel; восстановлен алфавитный порядок).
Исторические docs/handoff/* и docs/decisions/* НЕ тронуты — сохраняют оригинальное написание эпохи написания (включая snake_case в ADR-009, handoff pr-29 — там документационная конвенция, не runtime).
Верификация: grep по активным файлам на snake_case локальных tools → 0 совпадений.
## Почему
Реальные имена opencode tools в runtime registry — kebab-case (подтверждено анализом opencode.db: 397 runtime вызовов локальных tools в kebab-case, 0 в snake_case). Имя tool'а резолвится из filename (.opencode/tools/create-pr.ts → registry name "create-pr") — SDK `tool()` не имеет поля `name` (@opencode-ai/plugin@1.18.5 `tool.js`: `tool(input){ return input }`).
В AGENTS.md / SKILL.md / agents промптах tool'ы были написаны в snake_case (create_pr, merge_pr, pipeline_status и т.д.) — документационная конвенция эпохи написания (ADR-009/handoff pr-29, 2026-07-23). Runtime резолвит snake→kebab автоматически через utility `Re=(X)=>X.replace(/_/g,"-")` в opencode.exe — поэтому система работала, НО агент спотыкался: читал "вызови pipeline_status", искал такой tool в tool-списке, находил только pipeline-status, не совпадало → fallback на raw bash (deny → блок) или вызов не того tool.
MCP plugin tools (memory_*) остаются snake_case — их имена задаёт плагин в export-коде, не filename. opencode.db подтверждает: memory_search (65 calls), memory_save (13), memory_access (22) — все snake_case.
См. ADR-034 (этот PR) + memory `technical/tool-name-casing-kebab-vs-mcp-snake.md`.
## Pending
## Watch out
- ADR-009 (PR#29) текст остался со snake_case (pipeline_status, spec_status) — НЕ правлен, исторический документ. Intent ADR верен: "commands переименованы, tool'ы не тронуты" — registry names действительно не менялись, просто написаны были в snake в документации.
- opencode.json `agent.tools` map keys остались snake_case (create_pr, merge_pr и т.д.) — НЕ правлен. Runtime конвертирует _ → - через Re-utility, система работает. Смена keys на kebab требует проверки JSON-схемы + test_permissions.py (assert'ит snake keys) — отдельный PR если нужно.
- PR#2 (commit tool doc fix + restore --staged allow + ADR) — отдельный PR, не в этом scope.

View file

@ -2,7 +2,7 @@
opencode-config — Docker-based AI coding assistant with persistent memory (opencode configuration). Runs in Docker via `docker-compose.yml` (dind + opencode services). opencode-config — Docker-based AI coding assistant with persistent memory (opencode configuration). Runs in Docker via `docker-compose.yml` (dind + opencode services).
Root `AGENTS.md` — orchestrator directive (chat = plan only, all via subagents) + global rules (pipeline, code style, language RU) + `## Tool Usage Policy` (таблица 10 tools: commit/create_pr/create_issue/merge_pr/post_review/post_docs_review/pipeline_status/spec_status/memory_setup/tunnel; raw bash заблокирован deny, при сбое tool — STOP, НЕ fallback). Auto-loaded for project + bind-mounted globally in container — PR#31, PR#63. Root `AGENTS.md` — orchestrator directive (chat = plan only, all via subagents) + global rules (pipeline, code style, language RU) + `## Tool Usage Policy` (таблица 10 tools: commit/create-pr/create-issue/merge-pr/post-review/post-docs-review/pipeline-status/spec-status/memory-setup/tunnel; raw bash заблокирован deny, при сбое tool — STOP, НЕ fallback). Auto-loaded for project + bind-mounted globally in container — PR#31, PR#63.
## Structure ## Structure
@ -16,9 +16,9 @@ opencode-config/
│ └── dependabot.yml # pip + github-actions ecosystem updates │ └── dependabot.yml # pip + github-actions ecosystem updates
├── .opencode/ # Project-local opencode config (auto-discovery, zero env var) — PR#23 ├── .opencode/ # Project-local opencode config (auto-discovery, zero env var) — PR#23
│ ├── agents/ │ ├── agents/
│ │ ├── docs-reviewer.md # Docs validation subagent (project map + handoff + ADR, uses `commit`+`post_docs_review` tools) — PR#40, PR#46, PR#69 │ │ ├── docs-reviewer.md # Docs validation subagent (project map + handoff + ADR, uses `commit`+`post-docs-review` tools) — PR#40, PR#46, PR#69
│ │ ├── memory-syncer.md # Distills gotchas from handoffs into opencode-memory — PR#69 │ │ ├── memory-syncer.md # Distills gotchas from handoffs into opencode-memory — PR#69
│ │ └── reviewer.md # Code review subagent (verdict via `post_review` tool: APPROVE|REQUEST_CHANGES|NEEDS_DISCUSSION) — PR#46, PR#69 │ │ └── reviewer.md # Code review subagent (verdict via `post-review` tool: APPROVE|REQUEST_CHANGES|NEEDS_DISCUSSION) — PR#46, PR#69
│ ├── commands/ │ ├── commands/
│ │ ├── configure-opencode.md # /configure-opencode — edit opencode.json │ │ ├── configure-opencode.md # /configure-opencode — edit opencode.json
│ │ ├── run-pipeline.md # /run-pipeline — 7-phase PR pipeline │ │ ├── run-pipeline.md # /run-pipeline — 7-phase PR pipeline
@ -43,12 +43,12 @@ opencode-config/
│ │ ├── commit.ts # commit tool wrapper (1 arg message, validates format+staged) — PR#38 │ │ ├── commit.ts # commit tool wrapper (1 arg message, validates format+staged) — PR#38
│ │ ├── create-issue.ts # create-issue tool wrapper (3 args, validates format+labels; optional repo?: string) — PR#38, PR#65 │ │ ├── create-issue.ts # create-issue tool wrapper (3 args, validates format+labels; optional repo?: string) — PR#38, PR#65
│ │ ├── create-pr.ts # create-pr tool wrapper (3 args, validates format+Closes #N; optional repo?: string) — PR#38, PR#65 │ │ ├── create-pr.ts # create-pr tool wrapper (3 args, validates format+Closes #N; optional repo?: string) — PR#38, PR#65
│ │ ├── merge-pr.ts # merge_pr tool wrapper (orchestrator-safe gh pr merge; optional repo?: string) — PR#30, PR#65 │ │ ├── merge-pr.ts # merge-pr tool wrapper (orchestrator-safe gh pr merge; optional repo?: string) — PR#30, PR#65
│ │ ├── memory-setup.ts # memory_setup tool wrapper (0 args, calls setup-memory.sh) — PR#36 │ │ ├── memory-setup.ts # memory-setup tool wrapper (0 args, calls setup-memory.sh) — PR#36
│ │ ├── pipeline-status.ts # pipeline_status tool wrapper │ │ ├── pipeline-status.ts # pipeline-status tool wrapper
│ │ ├── post-docs-review.ts # post_docs_review tool wrapper (3 args: pr_number, verdict enum, body; deterministic ## Docs Review Summary heading; optional repo?: string) — PR#46, PR#65 │ │ ├── post-docs-review.ts # post-docs-review tool wrapper (3 args: pr_number, verdict enum, body; deterministic ## Docs Review Summary heading; optional repo?: string) — PR#46, PR#65
│ │ ├── post-review.ts # post_review tool wrapper (3 args: pr_number, verdict enum, body; deterministic ## Code Review Summary heading; optional repo?: string) — PR#46, PR#65 │ │ ├── post-review.ts # post-review tool wrapper (3 args: pr_number, verdict enum, body; deterministic ## Code Review Summary heading; optional repo?: string) — PR#46, PR#65
│ │ ├── spec-status.ts # spec_status tool wrapper │ │ ├── spec-status.ts # spec-status tool wrapper
│ │ └── tunnel.ts # Cloudflare tunnel toggle tool (start/stop без args) — PR#34 │ │ └── tunnel.ts # Cloudflare tunnel toggle tool (start/stop без args) — PR#34
│ ├── scripts/ │ ├── scripts/
│ │ ├── check-adr-refs.py # ADR cross-reference validator (adr-check.yml) │ │ ├── check-adr-refs.py # ADR cross-reference validator (adr-check.yml)