* feat(tools): add merge_pr TS tool wrapper * refactor(run-pipeline): replace raw gh pr merge with merge_pr tool * fix(scripts): update pipeline-status MERGE NEXT action * docs(handoff): add pr-16 handoff + ADR-010 * fix(handoff): remove dangling ADR-012/ADR-016 references * docs(handoff): set PR number 30 * docs(project-map): add merge-pr.ts tool (PR#30) --------- Co-authored-by: opencode-agent <agent@slaid098.dev>
29 lines
No EOL
3.5 KiB
Markdown
29 lines
No EOL
3.5 KiB
Markdown
# ADR-010: merge_pr tool wrapper for orchestrator model
|
||
|
||
## Статус
|
||
Accepted
|
||
|
||
## Контекст
|
||
MERGE phase выполнялась main agent'ом через raw `gh pr merge` (см. `run-pipeline/SKILL.md` Rules + `pipeline-status.py` `NEXT_ACTIONS["MERGE"]`). Это конфликтует с pure-orchestrator моделью: main agent = plan/delegate/verify, НЕ исполняет mutations напрямую. Tool-led philosophy (обёртка side-effects в tools, imported из приватного репо как принцип без локального ADR) предписывает: (1) сохранить orchestrator-контракт, (2) дать uniform API surface, (3) централизовать guard logic.
|
||
|
||
Дополнительно: `config/` paths в `run-pipeline/SKILL.md` (`config/scripts/scaffold-handoff.sh`) stale после PR#23 (миграция config/ → .opencode/). Phase 0 "load issue skill" ambiguity — противоречит PR#28 issue-skill rewrite (full subagent delegation).
|
||
|
||
## Решение
|
||
- Created `merge_pr` TS tool (`.opencode/tools/merge-pr.ts`) — wrapper для `gh pr merge N --squash --delete-branch` через `spawnSync`. Built with `@opencode-ai/plugin` `tool({...})` pattern (matching `pipeline-status.ts`, `spec-status.ts`), auto-discovered из `.opencode/tools/` — без регистрации в `opencode.json`.
|
||
- `run-pipeline/SKILL.md`: replaced raw `gh pr merge` в Rules → `merge_pr({ pr_number: M })` tool call; added explicit `Template F (merge)` MERGE phase section (tool call, error handling, re-loop).
|
||
- `run-pipeline/SKILL.md` Phase 0: "load issue skill" → "dispatch subagent (general) with instruction to load `issue` skill" (pure orchestrator).
|
||
- `run-pipeline/SKILL.md` Template A: `config/scripts/scaffold-handoff.sh` → `.opencode/scripts/scaffold-handoff.sh`.
|
||
- `pipeline-status.py` `NEXT_ACTIONS["MERGE"]`: "смержить PR (gh pr merge N...)" → "вызвать merge_pr tool ({pr_number: N})...". Placeholder `N` для `get_next_action` replace.
|
||
- Тест `test_get_next_action` MERGE assertion обновлён.
|
||
|
||
## Альтернативы
|
||
- **Dedicated merger subagent** — отклонено. Subagent = task executor с own context, ослабляет security guard (merge by main agent, НЕ subagent — established guard). `merge_pr` tool вызывается main agent'ом напрямую — preserves guard + orchestrator-контракт.
|
||
- **Explicit exception в AGENTS.md** ("main agent may run gh pr merge") — отклонено. Violates pure-orchestrator model, создаёт precedent для других raw-bash exceptions.
|
||
- **Keep raw bash + документировать** — отклонено. Orchestrator conflict не resolved, tool-led philosophy не honoured.
|
||
- **`check-permissions.py` runtime merge guard в tool** — рассмотрено, отложено. `check-permissions.py` сейчас только linting (CI-time), не runtime guard. Реализация runtime guard — follow-up (potential ADR).
|
||
|
||
## Связанные
|
||
- Tool-led philosophy — referenced из приватного репо как принцип (без локального ADR-номера).
|
||
- PR#28 (issue-skill full subagent delegation) — Phase 0 ambiguity resolved в том же направлении.
|
||
- PR#29 (commands rename: `/pipeline-driver` → `/run-pipeline`) — tool names (`pipeline_status`, `merge_pr`) independent от command names.
|
||
- Issue #10 (AGENTS.md orchestrator rewrite) — pending, references `/run-pipeline`. |