feat(agents): enable create_issue and behavioral rules (#113)

* feat(agents): enable create_issue for subagents

* docs(agents): add bug discovery protocol and linear execution rule

* docs(handoff): add handoff and ADR

* docs(handoff): set PR number

* docs(project-map): update after structural changes

* fix(agents): revert create_issue for read-only subagents

* fix(agents): re-enable create_issue and update tests

---------

Co-authored-by: opencode-agent <agent@opencode.local>
This commit is contained in:
Sergey 2026-07-29 01:25:30 +03:00 committed by GitHub
parent 7ea12b982d
commit f1b8ff94bf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 69 additions and 11 deletions

View file

@ -35,6 +35,7 @@ permission:
"gh pr comment*": allow "gh pr comment*": allow
"gh pr comment *": allow "gh pr comment *": allow
"gh issue view*": allow "gh issue view*": allow
"gh issue list*": allow
"git rm docs/handoff*": allow "git rm docs/handoff*": allow
"git rm docs/decisions*": allow "git rm docs/decisions*": allow
"git rm -r docs/spec*": allow "git rm -r docs/spec*": allow

View file

@ -30,6 +30,7 @@ permission:
"echo *": allow "echo *": allow
"gh pr view*": allow "gh pr view*": allow
"gh issue view*": allow "gh issue view*": allow
"gh issue list*": allow
--- ---
You are a memory-syncer agent. Your job: distill durable knowledge from a merged PR handoff into the global memory file at `<memory_dir>/repos/{host}/{org}/{repo}.md` (default `~/.local/share/opencode/opencode-memory`, override via `OPENCODE_MEMORY_DIR`). You are a memory-syncer agent. Your job: distill durable knowledge from a merged PR handoff into the global memory file at `<memory_dir>/repos/{host}/{org}/{repo}.md` (default `~/.local/share/opencode/opencode-memory`, override via `OPENCODE_MEMORY_DIR`).

View file

@ -295,7 +295,7 @@
"tools": { "tools": {
"commit": false, "commit": false,
"create_pr": false, "create_pr": false,
"create_issue": false, "create_issue": true,
"merge_pr": false, "merge_pr": false,
"post_review": true, "post_review": true,
"post_docs_review": false "post_docs_review": false
@ -305,7 +305,7 @@
"tools": { "tools": {
"commit": true, "commit": true,
"create_pr": false, "create_pr": false,
"create_issue": false, "create_issue": true,
"merge_pr": false, "merge_pr": false,
"post_review": false, "post_review": false,
"post_docs_review": true "post_docs_review": true
@ -315,7 +315,7 @@
"tools": { "tools": {
"commit": false, "commit": false,
"create_pr": false, "create_pr": false,
"create_issue": false, "create_issue": true,
"merge_pr": false, "merge_pr": false,
"post_review": false, "post_review": false,
"post_docs_review": false "post_docs_review": false

View file

@ -13,6 +13,25 @@
Pipeline: ISSUE → IMPLEMENT → DOCS → CI → REVIEW → MERGE → MEMORY. Pipeline: ISSUE → IMPLEMENT → DOCS → CI → REVIEW → MERGE → MEMORY.
`pipeline-status` = read-only oracle (NEXT action). `merge-pr` = orchestrator-safe merge wrapper. Execution via `/run-pipeline` skill. `pipeline-status` = read-only oracle (NEXT action). `merge-pr` = orchestrator-safe merge wrapper. Execution via `/run-pipeline` skill.
## Bug Discovery Protocol
Если в процессе работы найден баг вне scope текущей задачи:
1. Проверь `gh issue list` на дубликаты.
2. Создай GitHub issue через `create-issue` tool (НЕ raw `gh issue create`).
3. Title: `fix(scope): краткое описание` на английском.
4. Body: `## Контекст` / `## Задача` / `## Критерии приемки` (на русском).
5. Продолжай текущую задачу. НЕ исправляй баг сам.
6. В отчёте orchestrator'у укажи: "Создан issue #N: ...".
## Linear Execution
- В рамках одного репозитория — строго линейное выполнение pipeline.
- Нельзя запускать второй pipeline, пока не завершён первый (merge или close).
- Issues создаёт ОДИН агент за раз (batch creation), не параллельные агенты.
- Параллельные исследования (explore agents, 3-4 concurrently) — можно.
- Параллельное исполнение (implementation/review/docs) — ЗАПРЕЩЕНО.
- Причина: агенты прыгают между ветками → конфликты, потеря работы, хаос.
## Read Path ## Read Path
Перед началом задачи в репо: просмотри имена файлов в `docs/handoff/` (если есть) — открой релевантные по теме. Перед началом задачи в репо: просмотри имена файлов в `docs/handoff/` (если есть) — открой релевантные по теме.

View file

@ -0,0 +1,17 @@
# ADR-050: Enable create_issue for subagents and add behavioral rules
## Статус
Accepted (2026-07-28)
## Контекст
Саб-агенты (reviewer, docs-reviewer, memory-syncer) не имели tool `create_issue` — найденные баги вне scope текущей задачи терялись без фиксации. Также отсутствовало правило о линейном исполнении pipeline, что при параллельном запуске приводило к конфликтам веток и потере работы.
## Решение
1. Включить `create_issue: true` для reviewer, docs-reviewer, memory-syncer в `opencode.json` (general уже имел).
2. Добавить `gh issue list*` в bash allow-list для docs-reviewer и memory-syncer (reviewer уже имел `gh issue*`).
3. Добавить Bug Discovery Protocol в AGENTS.md — инструкция для агентов по созданию issues через `create-issue` tool.
4. Добавить Linear Execution Rule в AGENTS.md — строго линейный pipeline, параллельные research OK.
## Альтернативы
- Делегировать создание issues только general-агенту: отвергнуто — требует context switching, теряется контекст бага.
- Запретить параллельное исполнение на уровне tool permissions: отвергнуто — слишком жёстко, research-агенты могут работать параллельно без конфликтов.

View file

@ -0,0 +1,20 @@
---
pr: 113
title: feat(agents): enable create_issue and behavioral rules
---
## Что сделано
- `create_issue: true` для reviewer, docs-reviewer, memory-syncer в `.opencode/opencode.json`
- `gh issue list*` добавлен в bash allow-list для `.opencode/agents/docs-reviewer.md` и `.opencode/agents/memory-syncer.md`
- Bug Discovery Protocol добавлен в `AGENTS.md` после раздела Pipeline
- Linear Execution Rule добавлен в `AGENTS.md` после Bug Discovery Protocol
- `check-permissions.py` проходит без ошибок
## Почему
Саб-агенты не могли создавать issues — найденные баги терялись. Linear execution предотвращает конфликты веток при параллельном выполнении pipeline. Closes #110.
## Pending
## Watch out

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` (таблица tools: commit/create-pr/create-issue/merge-pr/post-review/post-docs-review/pipeline-status/spec-status/memory-doctor/memory-save/memory-search/memory-list/memory-access/tunnel; raw bash заблокирован deny, при сбое tool — STOP, НЕ fallback; `memory-setup` REMOVED PR#103). 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` (таблица tools: commit/create-pr/create-issue/merge-pr/post-review/post-docs-review/pipeline-status/spec-status/memory-doctor/memory-save/memory-search/memory-list/memory-access/tunnel; raw bash заблокирован deny, при сбое tool — STOP, НЕ fallback; `memory-setup` REMOVED PR#103) + `## Bug Discovery Protocol` (агенты создают issues через `create-issue` tool для найденных багов вне scope) + `## Linear Execution` (строго линейный pipeline, параллельные research OK, параллельное исполнение ЗАПРЕЩЕНО) — PR#113. Auto-loaded for project + bind-mounted globally in container — PR#31, PR#63.
## Structure ## Structure
@ -16,8 +16,8 @@ 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`+`create_issue` tools; `gh issue list*` allow) — PR#40, PR#46, PR#69, PR#113
│ │ ├── memory-syncer.md # Distills gotchas from handoffs into opencode-memory — PR#69 │ │ ├── memory-syncer.md # Distills gotchas from handoffs into opencode-memory (`create_issue` tool; `gh issue list*` allow) — PR#69, PR#113
│ │ └── 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
@ -64,7 +64,7 @@ opencode-config/
│ │ ├── scaffold-handoff.sh # Scaffold handoff + ADR stubs │ │ ├── scaffold-handoff.sh # Scaffold handoff + ADR stubs
│ │ ├── spec-status.py # 9-phase spec oracle │ │ ├── spec-status.py # 9-phase spec oracle
│ │ └── tunnel.sh # Cloudflare tunnel toggle bash (named mode via CLOUDFLARE_TUNNEL_TOKEN) — PR#34 │ │ └── tunnel.sh # Cloudflare tunnel toggle bash (named mode via CLOUDFLARE_TUNNEL_TOKEN) — PR#34
│ ├── opencode.json # MCP servers, providers, permissions, agents (role-based tools) — PR#40, PR#69 (plugin block REMOVED PR#103, deprecated `new_api` provider REMOVED PR#106) │ ├── opencode.json # MCP servers, providers, permissions, agents (role-based tools; `create_issue` enabled for reviewer/docs-reviewer/memory-syncer) — PR#40, PR#69, PR#113 (plugin block REMOVED PR#103, deprecated `new_api` provider REMOVED PR#106)
│ ├── package.json # npm deps for tools/*.ts (deps: @vscode/ripgrep; devDeps: @types/node, typescript) — PR#101 │ ├── package.json # npm deps for tools/*.ts (deps: @vscode/ripgrep; devDeps: @types/node, typescript) — PR#101
│ └── .gitignore # Ignores node_modules, etc. │ └── .gitignore # Ignores node_modules, etc.
├── docs/ ├── docs/
@ -132,7 +132,7 @@ opencode-config/
├── .editorconfig ├── .editorconfig
├── .gitignore ├── .gitignore
├── .python-version ├── .python-version
├── AGENTS.md # Orchestrator directive + global rules (bind-mounted globally) — PR#31 ├── AGENTS.md # Orchestrator directive + global rules + Bug Discovery Protocol + Linear Execution (bind-mounted globally) — PR#31, PR#113
├── LICENSE ├── LICENSE
└── README.md └── README.md
``` ```

View file

@ -127,7 +127,7 @@ def test_reviewer_tools_all_false():
tools = _load_config()["agent"]["reviewer"]["tools"] tools = _load_config()["agent"]["reviewer"]["tools"]
assert tools["commit"] is False assert tools["commit"] is False
assert tools["create_pr"] is False assert tools["create_pr"] is False
assert tools["create_issue"] is False assert tools["create_issue"] is True
assert tools["merge_pr"] is False assert tools["merge_pr"] is False
@ -139,7 +139,7 @@ def test_docs_reviewer_tools():
tools = _load_config()["agent"]["docs-reviewer"]["tools"] tools = _load_config()["agent"]["docs-reviewer"]["tools"]
assert tools["commit"] is True assert tools["commit"] is True
assert tools["create_pr"] is False assert tools["create_pr"] is False
assert tools["create_issue"] is False assert tools["create_issue"] is True
assert tools["merge_pr"] is False assert tools["merge_pr"] is False
@ -151,7 +151,7 @@ def test_memory_syncer_tools_all_false():
tools = _load_config()["agent"]["memory-syncer"]["tools"] tools = _load_config()["agent"]["memory-syncer"]["tools"]
assert tools["commit"] is False assert tools["commit"] is False
assert tools["create_pr"] is False assert tools["create_pr"] is False
assert tools["create_issue"] is False assert tools["create_issue"] is True
assert tools["merge_pr"] is False assert tools["merge_pr"] is False