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

6.2 KiB
Raw Permalink Blame History


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 commitcommit({ message }), gh pr createcreate_pr({ title, body, issue_number })
    • run-pipeline/SKILL.md Template B: git commitcommit({ message }) (git add и git push оставлены — не заблокированы)
    • run-pipeline/SKILL.md Template D: git commitcommit({ message: "fix(ci): ..." })
    • issue/SKILL.md: gh issue createcreate_issue({ title, body, labels }) (3 места), gh pr mergemerge_pr({ pr_number })
    • spec/SKILL.md:311: gh issue createcreate_issue({ title, body, labels })
    • release/SKILL.md:44, add-skill/SKILL.md:70, repo-init/SKILL.md:41: git commitcommit({ 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.