* 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>
86 lines
No EOL
6.2 KiB
Markdown
86 lines
No EOL
6.2 KiB
Markdown
---
|
||
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. |