opencode-config/docs/handoff/pr-63-enforce-tool-usage-policy.md
Sergey a2666183f8
fix(agents+skills): enforce tool-usage policy across prompts and skills (#63)
* fix(agents): add tool usage policy to AGENTS.md

* fix(skills): replace raw bash with tools in 6 skills

* feat(skills): restore tunnel skill

* docs(handoff): scaffold handoff and ADR for PR

* docs(handoff): set PR number

* docs(project-map): add tunnel skill + tool usage policy note (PR#63)

---------

Co-authored-by: opencode-agent <agent@opencode.local>
2026-07-25 18:46:16 +03:00

86 lines
No EOL
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
pr: 63
title: fix(agents+skills): enforce tool-usage policy across prompts and skills
---
## Что сделано
- **AGENTS.md** — добавлена секция `## Tool Usage Policy` с таблицей 10 tools
(commit, create_pr, create_issue, merge_pr, post_review, post_docs_review,
pipeline_status, spec_status, memory_setup, tunnel). Колонки: имя tool |
raw-эквивалент (заблокирован deny) | когда использовать | при сбое — STOP,
репорт, НЕ fallback. Правило: "Используй tool вместо raw bash. Raw bash
заблокирован deny (`opencode.json:311-314`). При сбое tool — STOP и репорт
оркестратору, НЕ fallback на raw bash, НЕ импровизируй обход через `gh api`."
Global copy `/root/.config/opencode/AGENTS.md` — bind-mount read-only из
workspace `AGENTS.md`, обновится после merge + хост `git pull` + рестарт
контейнера (см. ADR-026 Решение).
- **6 skills** — raw bash заменён на tool-вызовы:
- `run-pipeline/SKILL.md` Template A: `git commit``commit({ message })`,
`gh pr create``create_pr({ title, body, issue_number })`
- `run-pipeline/SKILL.md` Template B: `git commit``commit({ message })`
(`git add` и `git push` оставлены — не заблокированы)
- `run-pipeline/SKILL.md` Template D: `git commit``commit({ message: "fix(ci): ..." })`
- `issue/SKILL.md`: `gh issue create``create_issue({ title, body, labels })`
(3 места), `gh pr merge``merge_pr({ pr_number })`
- `spec/SKILL.md:311`: `gh issue create``create_issue({ title, body, labels })`
- `release/SKILL.md:44`, `add-skill/SKILL.md:70`, `repo-init/SKILL.md:41`:
`git commit``commit({ message })`
- **Skill `tunnel` восстановлен** — `.opencode/skills/tunnel/SKILL.md` (удалён
в PR#42 как orphan; tool `tunnel` остался без skill-описания, пользователь
вызывал вручную, но агент не "видел" его в контексте). Frontmatter: name:
tunnel, description: "Подними cloudflare туннель когда пользователь просит
'подними тоннель', 'пробрось порт', 'tunnel'". Тело: инструкция вызывать
tool `tunnel()` (1-й вызов — start, 2-й — stop, беспараметровый).
## Почему
Research (subagent explore) выявил 3 gap'а в tool-usage инфраструктуре:
- **Gap A**: 6 skills предписывали raw bash (`git commit`, `gh pr create`,
`gh issue create`, `gh pr merge`), заблокированный deny в
`opencode.json:311-314`. Симптом: subagent грузит skill → получает
инструкцию нарушить permission layer → падает или импровизирует обход через
`gh api` (см. memory `technical/gh-issue-create-blocked-workaround.md`).
- **Gap B**: Tool failure handling ("при сбое tool — STOP, не fallback на raw
bash") был только для 2 из 10 tools — `post_review` (reviewer.md:285) и
`post_docs_review` (docs-reviewer.md:228). Для остальных 8 tools при сбое
agent без инструкции, импровизирует.
- **Gap C**: 4 tool'а не упомянуты нигде как tool — `create_issue`,
`create_pr` (0 упоминаний), `tunnel` (skill удалён в PR#42, tool orphan),
`memory_setup` (1 строка в `memory/SKILL.md:19`).
Дополнительно: `gh pr comment*` остался в allow-list reviewer/docs-reviewer
(ADR-019 отклонил strict-deny "для обратной совместимости"). Решено оставить
как есть — промпт уже запрещает fallback при сбое tool, противоречие minimal.
## Pending
- После merge: на хосте `git pull` + рестарт opencode-контейнера чтобы global
config подхватил обновлённый `AGENTS.md` (bind-mount read-only) и
восстановленный skill `tunnel` (авто-дискаверится при старте).
- Зависимости: supersedes partial PR#42 (orchestration-switch) — Watch out в
handoff pr-42 явно пишет "Третий PR серии: обновить промпты
reviewer.md/memory-syncer.md/skills"; related PR#61 (issue #60) добавил
"Tool failure handling" в reviewer.md/docs-reviewer.md для
post_review/post_docs_review — этот PR расширяет на все 10 tools через
единую policy в AGENTS.md.
## Watch out
- `/root/.config/opencode/AGENTS.md` — bind-mount read-only из
`/dev/vda1[/root/dockers/opencode-config/AGENTS.md]` (compose:
`./AGENTS.md:/root/.config/opencode/AGENTS.md:ro`). В контейнере файл НЕ
редактируется — изменения идут в workspace copy, после merge +
host git pull + container restart подхватятся автоматически. Это
symlink-эквивалент через bind-mount (issue предусматривал оба варианта).
- Skill `tunnel` станет доступен только после рестарта opencode (skills
загружаются при старте, см. add-skill/SKILL.md секция 3).
- `gh pr comment*` в allow-list reviewer/docs-reviewer НЕ трогали — это
intentional (ADR-019), не regression.
- 7 оставшихся упоминаний `gh pr create|git commit -m|gh issue create|gh pr merge`
в skills — это anti-instructions (упоминания в контексте "НЕ raw bash") и
examples в permission-rules docs (`configure-opencode/SKILL.md:89`), не
предписания. Grep на raw patterns нужно фильтровать по контексту.
- Ветка создана от `main` (не `master` — master не существует в этом репо).
Issue говорил "от master" — это соглашение naming, фактически main.