opencode-config/docs/handoff/pr-49-doom-loop-frontmatter.md
Sergey 2473360530
fix(agents): remove invalid doom_loop frontmatter field + simplify reviewer setup (#49)
* fix(agents): remove invalid top-level doom_loop field from frontmatter

* fix(reviewer): simplify setup step 5 and add investigation budget

* test(agents): add frontmatter validation tests

* docs(handoff): add handoff and ADR-020 for doom_loop frontmatter fix

* docs(handoff): set PR number

* docs: update project map

---------

Co-authored-by: opencode-agent <agent@slaid098.dev>
2026-07-24 19:24:36 +03:00

36 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: 49
title: remove invalid doom_loop frontmatter field + simplify reviewer setup
---
# PR #49: remove invalid doom_loop frontmatter field + simplify reviewer setup
## Что сделано
- `.opencode/agents/reviewer.md:6` — удалён top-level `doom_loop: deny` (ВНЕ блока `permission:`). Невалидное поле — не в схеме `AgentV2.Info` opencode, форвардилось провайдеру как model param → `AI_APICallError: Extra inputs are not permitted` на строгих провайдерах (umans-ai-coding-plan).
- `.opencode/agents/docs-reviewer.md:6` — удалён top-level `doom_loop: deny` (тот же fix).
- `.opencode/agents/memory-syncer.md:6` — удалён top-level `doom_loop: deny` (тот же fix).
- `permission.doom_loop: deny` ВНУТРИ блока `permission:` — сохранён во всех 3 файлах (валидный permission guard, не тронут).
- `steps: 100` — не изменён во всех 3 файлах.
- `reviewer.md` Setup шаг 5 — упрощён: убрана inline-ссылка на ADR-019 и детальное объяснение запрета `gh pr checks` / `python3 pipeline-status.py`. Заменено на лаконичную инструкцию с `pipeline_status` tool + `gh run list` fallback + явным "Do NOT". Это устраняет self-referential trigger (модель зацикливалась на верификации ADR-019 ссылки — 75 повторений `git show f06c9f2 | grep ADR-019` за 6 минут, doom loop отменён на step 88).
- `reviewer.md` — добавлена секция `## Investigation Budget` после Setup: максимум ~15 steps для investigation, после чего обязательный `post_review` даже при неполном review. Предотвращает бесконечные investigation loops.
- `tests/test_agent_frontmatter.py` — 6 новых тестов: frontmatter НЕ содержит top-level `doom_loop` (parsed + raw check), `permission.doom_loop: deny` присутствует во всех 3 файлах, `steps: 100` присутствует, frontmatter parseable. Парсинг ручной (pyyaml не в зависимостях), по паттерну `check-permissions.py` (split по `---`, отслеживание отступов).
- ADR-020 + этот handoff
## Почему
При review PR #46 (reviewer ревьюил свой собственный .md файл) reviewer agent ушёл в doom loop — 75 повторений `git show f06c9f2 | grep ADR-019` за 6 минут, отменён пользователем на step 88. Investigation выявило 2 проблемы:
1. **`doom_loop: deny` как top-level frontmatter поле** — НЕ в схеме `AgentV2.Info` opencode, форвардится провайдеру как model param → `AI_APICallError` на строгих провайдерах. Валидно только внутри блока `permission:`. Подтверждено логом `opencode.log:91717`. Top-level поле — копия permission guard, ошибочно продублированная на верхний уровень (вероятно при миграции config/ → .opencode/ в PR#23).
2. **Self-referential trigger** — Setup шаг 5 в reviewer.md содержал inline-ссылку на ADR-019 и детальное объяснение запрета. Модель зациклилась на верификации этой ссылки (читает reviewer.md → видит ADR-019 → идёт проверять ссылку → повторяет). Это "крючок", за который модель зацепилась в doom loop.
Решение: удалить невалидное top-level поле (fix root cause #1) + упростить Setup шаг 5 (убрать self-referential hook, fix root cause #2) + добавить Investigation Budget секцию (structural guard против doom loops — явный step limit).
## Pending
— (нет)
## Watch out
- **Top-level `doom_loop` удалён, НЕ `permission.doom_loop`** — `doom_loop: deny` внутри блока `permission:` (отступ 2 пробела, строки 8/8/8) — ОСТАВЛЕН во всех 3 файлах. Это валидный permission guard. Удалён только top-level `doom_loop: deny` (indent 0, строка 6). Тесты `test_permission_doom_loop_present` + `test_no_top_level_doom_loop` явно различают эти два поля.
- **Global config (OLD repo) НЕ обновлён** — bind-mounted `/root/.config/opencode/agents/*.md` (из `/root/workspace/opencode/config/agents/`) всё ещё содержит top-level `doom_loop` (commit 38c5a34 фиксил только NEW repo `.opencode/agents/`). Если strict provider используется в репо БЕЗ project-local agents → falls back to global → bug resurfaces. Это known issue (см. memory: technical/opencode-agent-loading-precedence.md), вне scope этого PR.
- **Investigation Budget — soft guard** — секция в промпте reviewer.md, не type system. Модель может игнорировать ~15 step limit (как игнорирует другие промпт-правила). Но explicit limit лучше implicit — даёт модели чёткий сигнал "остановись и вызови post_review". Hard guard = steps: 100 (frontmatter) — на нём модель упрётся в лимит в любом случае.
- **Setup шаг 5 упрощён, НЕ удалён** — `gh pr checks` (403) и `python3 pipeline-status.py` (denied) запреты сохранены в лаконичной форме ("Do NOT use ..."). Запреты функциональны (permission rules в frontmatter + DANGEROUS_PATTERNS в check-permissions.py), inline-ссылка на ADR-019 — единственное убранное (она была self-referential hook, не функциональным guard).
- ADR number = sequential (020), НЕ PR number (эволюция известного паттерна PR#26 docs-reviewer typo).