# ADR-029: Agent step limit 100 → 150 **Статус**: Accepted (2026-07-25, PR 69) ## Контекст На PR#67 reviewer subagent упёрся в `MAXIMUM STEPS REACHED` — не успел вызвать `post-review` (оркестратор делал 1 retry вручную). Сообщение хардкожено в `opencode.exe` (бинарник от 2026-07-24): при `iteration_count >= agent.steps` вызывается `failUnsettledTools("Tools are disabled after the maximum agent steps")` → tools disabled. Это **hard stop**, не soft hint. Memory `technical/opencode-log-subagent-stumbles-analysis.md` (2026-07-20) утверждала «`steps:` НЕ хард-лимит — агенты routinely превышают. Это hint, не enforcement». **Устарело**: бинарник 2026-07-24 уже hard enforcement. Подтверждено на PR#67. ADR-020 (PR#49) унифицировал лимит до 100 для всех 4 настроенных агентов (reviewer, docs-reviewer, memory-syncer, general) как guard против doom loops. Исторически было 40/25/15/100 — но это были soft hints, превышались routinely (general до 216, reviewer до 80, docs-reviewer до 93). Сейчас 100 — hard stop, и 100 оказалось тесно для reviewer на PR с 6+ файлами diff. Текущие значения: `reviewer.md:5`, `docs-reviewer.md:5`, `memory-syncer.md:5` — frontmatter `steps: 100`; `opencode.json:319` — `agent.general.steps: 100`. Тест `test_agent_frontmatter.py:154` pin'ит `fm["steps"] == "100"` для всех 3 `.md` (uniformity). Тест `test_permissions.py:119` pin'ит `general.steps == 100` (int, JSON). ## Решение Повысить лимит шагов subagent-ов со 100 до 150 для всех 4 настроенных агентов (reviewer, docs-reviewer, memory-syncer, general). Uniformity сохранена (ADR-020 principle) — memory-syncer безвредно получит 150 (редко доходит до лимита, задача простая). Trade-off: +50% budget → +50% doom-loop risk, но guard сохранён. Без архитектурного рефакторинга (вынос explore-фазы reviewer'а в отдельный `explore` subagent) — отложено в отдельный PR если 150 снова станет тесно. Soft Investigation Budget в `reviewer.md:103-108` (~15 шагов) остаётся рекомендацией, hard limit 150 — guard. Тесты обновлены: `test_steps_100_present` → `test_steps_150_present`, assertion `fm["steps"] == "150"`, `test_permissions.py` assertion `general.steps == 150`. ## Альтернативы - **200/300** — отклонено: избыточный doom-loop риск, +100%/+200% budget без явной необходимости. - **∞ (убрать лимит)** — отклонено: нет guard'а вообще, doom loop может длиться часами (контр-показания из memory `opencode-log-subagent-stumbles-analysis.md`). - **Рефакторинг (вынос explore-фазы reviewer'а в отдельный `explore` subagent с ∞ steps)** — отклонено в этом PR: scope creep. Отдельный PR если 150 снова станет тесно. - **Per-agent разные значения (нарушить uniformity)** — отклонено: ADR-020 principle — uniformity упрощает тестирование и reasoning. memory-syncer мог бы остаться на 100, но это усложнило бы тест (`per-agent expected` map) без выгоды.