---
name: unblock
description: Answer PM questions and unblock tasks
---

# /polisade:unblock — Разблокировка задач

Интерактивная сессия для ответов на вопросы, которые ждут PM.

Для TASK/BUG/DEBT/CHORE/SPIKE источником статуса служит frontmatter.

**TASK — живой статус и ответ пишет одна команда.** В worktree-режиме статус
задачи живёт в дереве её ветки (`.worktrees/<dir>/`), а корень проекта стоит
на трунке со старым статусом — это штатно. Кто ждёт PM и с каким вопросом,
отвечает команда (она смотрит и корень, и деревья веток):

<!-- polisade:exec-denied CAPSULE BEGIN -->
> ⛔ **Если вызов скрипта на этом шаге ты СДЕЛАЛ, и он отклонён или не запустился** (`Command references protected path` / `Install directory is read-protected` / `Filesystem Guard` / `the tool's default permission is 'deny'`, отказ песочницы, ненулевой exit без вывода) — **STOP**. Вызова не было — отказа нет: сначала выполни команду; этот блок описывает её вывод и сам ответом не служит.
> Процитируй отказ дословно. НЕ пересказывай по исходнику, что скрипт «сделал бы»; НЕ собирай dry-run вручную; НЕ переходи к apply/push/pr-create.
> НЕ транскрибируй скрипт (прочитать → записать копию в `/tmp` или в проект → запустить копию): копия не байт-идентична — уезжают классы символов в regex, форма возврата функций, пропадают целые функции — и молча меняется набор применённых изменений.
> Отказ инструмента — это отказ, а не результат. Доложи PM дословный текст отказа и назови следствие: без рабочего вызова скрипта этот шаг выполнить нечем. Причину не придумывай — её называет только сам текст отказа.
<!-- polisade:exec-denied CAPSULE END -->

```bash
env ${POLISADE_PYTHON:-python3} {plugin_root}/scripts/polisade_vcs.py tasks-live --project-root .
```

Ответ PM по TASK записывает тоже команда — туда же, где живёт статус (в
дереве задачи файл ложится в индекс git без коммита, корень не трогается):

```bash
env ${POLISADE_PYTHON:-python3} {plugin_root}/scripts/polisade_vcs.py task-unblock --task-id TASK-XXX --to <review|ready|cancelled|waiting_pm> --project-root . [--pr-url <url>] [--answer-file <файл с ответом PM>] [--reason "<причина PM>"]
```

Её строку `line` покажи PM дословно. Статус и frontmatter TASK руками не правь.

**Остальные артефакты** (FEAT, SPEC, PRD, BUG, …; не TASK — любую TASK, в
дереве задачи или в корне, пишет только `task-unblock`): после каждого ответа
измени артефакт, затем из корня проекта запусти штатный writer:

<!-- polisade:exec-denied CAPSULE BEGIN -->
> ⛔ **Если вызов скрипта на этом шаге ты СДЕЛАЛ, и он отклонён или не запустился** (`Command references protected path` / `Install directory is read-protected` / `Filesystem Guard` / `the tool's default permission is 'deny'`, отказ песочницы, ненулевой exit без вывода) — **STOP**. Вызова не было — отказа нет: сначала выполни команду; этот блок описывает её вывод и сам ответом не служит.
> Процитируй отказ дословно. НЕ пересказывай по исходнику, что скрипт «сделал бы»; НЕ собирай dry-run вручную; НЕ переходи к apply/push/pr-create.
> НЕ транскрибируй скрипт (прочитать → записать копию в `/tmp` или в проект → запустить копию): копия не байт-идентична — уезжают классы символов в regex, форма возврата функций, пропадают целые функции — и молча меняется набор применённых изменений.
> Отказ инструмента — это отказ, а не результат. Доложи PM дословный текст отказа и назови следствие: без рабочего вызова скрипта этот шаг выполнить нечем. Причину не придумывай — её называет только сам текст отказа.
<!-- polisade:exec-denied CAPSULE END -->

```bash
env ${POLISADE_PYTHON:-python3} {plugin_root}/scripts/polisade_sync.py . --apply --yes --intermediate-step
```

`--intermediate-step` говорит сверке, что это шаг ВНУТРИ цикла: вопросы к PM она напечатает, но прогон не остановит. Гейт закрывает выход наружу у `/polisade:migrate` и `/polisade:sync`, где отчёт прогона уезжает в коммит и PR, — здесь останавливать было бы нечего и не за что.

Исполни строку буквально: переменные и fallback раскрывает shell, не агент.
Не вычисляй путь сам, не переопределяй `POLISADE_PLUGIN_ROOT` или
`POLISADE_SCRIPTS_ROOT` и не подставляй другую установленную версию. Если
shell сообщает, что скрипта нет, остановись: не ищи его через `find`/`ls`
и не запускай из другого CLI или исходного чекаута. Скрипт обновит
`artifactIndex` и списки.
Не редактируй `.state/PROJECT_STATE.json` вручную, включая `lastUpdated`.
Если вызов скрипта отклонён или завершился ошибкой, остановись и сообщи отказ;
не восстанавливай списки или индекс по памяти. Решение PM по текущему вопросу
разрешает синхронизацию без дополнительного запроса подтверждения.

## Алгоритм

1. Выполни `tasks-live` (команда выше) — список `waiting_pm`: TASK из
   дерева, где живёт статус (`tree`, `branch`, `path`, `question`), и прочие
   артефакты из корневого индекса. Корневой `waitingForPM` для TASK не читай:
   остановку в дереве задачи он не видит.
2. Строки, которые команда напечатала, покажи PM дословно.
3. Если список пуст → "Нет вопросов, ждущих ответа. Всё разблокировано!"
4. Для каждого вопроса последовательно:
   a. Покажи контекст (какой артефакт, где живёт статус — `tree`/`branch`,
      вопрос — поле `question` дословно)

   **EARLY EXIT для pr_url_request (OPS-008):**
   a'. Если текст вопроса содержит "pr_url_request" или "Создайте PR вручную"
       или "Create PR manually" (вопрос создан continue Phase C fallback):
       - Показать PM: "TASK-XXX ждёт URL вручную созданного PR.
                       Ветка: <expected_branch>."
       - Варианты ответа:
         1. Указать PR URL
         2. Отложить (оставить waiting_pm)
         3. Отменить задачу
       - Если PM предоставляет URL:
         - Валидация: URL содержит `/pull/` или `/merge-requests/` или аналог
           (если не проходит — спросить снова, не fallback на status=ready)
         - `task-unblock --task-id TASK-XXX --to review --pr-url <url> --project-root .`
           — команда пишет `status: review` и `pr_url:` в TASK там, где живёт
           статус, и переносит задачу в `inReview` индекса того же дерева
           (НЕ `readyToWork`!); вопрос снимается. Сверку для этой TASK не
           запускай.
         - Вывод: строка `line` команды и "PR URL записан. /polisade:continue для resume quality review."
         - **Перейти к следующему вопросу (skip шаги b–g)**
       - Если PM говорит "отложить" → `task-unblock … --to waiting_pm` (заметка
         PM — `--answer-file`)
       - Если PM говорит "отменить" → `task-unblock … --to cancelled --reason "<точная причина PM>"`;
         PR не создавать

<!-- polisade:claude-only BEGIN -->
   **EARLY EXIT для ARCHRUN (corpus-run resume):**
   a''. Если ID артефакта начинается с `ARCHRUN-` (corpus-run, ждёт ответа на
        вопрос `/polisade:design-corpus`: synonym-collision, FR-retirement,
        flow-ceiling, hash-конфликт preflight и т.п.):
        - Покажи PM процитированный вопрос из `docs/architecture/runs/ARCHRUN-NNN.md`
          + контекст из `architecture.corpus.pendingRun`.
        - Получи ответ; запиши его в `ARCHRUN-NNN.md` (раздел ответа).
        - Установи `ARCHRUN-NNN.status = ready`, удали из `waitingForPM`.
        - **НЕ добавляй в `readyToWork` как обычный work-item и НЕ предлагай
          `/polisade:implement`.** `ARCHRUN.ready` означает **«resume required»**.
          Выведи: "ARCHRUN-NNN разблокирован. Запусти
          `/polisade:design-corpus --resume=<runId>` чтобы продолжить применение
          к корпусу со staging (повторный preflight hash-check)." `runId` — из
          `architecture.corpus.pendingRun.runId`.
        - **Перейти к следующему вопросу (skip шаги b–g).**
<!-- polisade:claude-only END -->

   **Стандартный flow (для всех остальных вопросов):**
   b. Задай вопрос PM
   c. Дождись ответа
   d. **TASK:** запиши ответ PM в файл (Write) и выполни
      `task-unblock --task-id TASK-XXX --to ready --answer-file <файл> --project-root .`
      — ответ и `status: ready` ложатся в TASK там, где живёт статус; шаги
      e–g для TASK не нужны.
      **Прочие артефакты:** обнови артефакт с ответом
   e. Измени статус артефакта на `ready` во frontmatter
   f. Запусти команду sync выше и проверь её JSON-результат
   g. Убедись, что ID удалён из `waitingForPM` и добавлен в `readyToWork`
5. После всех вопросов — выполни `tasks-live` ещё раз и покажи его строки

## Формат вопроса

```
═══════════════════════════════════════════
Вопрос N/M

Артефакт: TASK-015 (tasks/TASK-015-stripe-integration.md)
Ждёт с: 2024-01-14

Вопрос:
"Нужен API ключ для интеграции со Stripe.
Тестовый или продакшн? Где его взять?"

Варианты ответа:
1. Предоставить значение
2. Отложить задачу
3. Отменить задачу
═══════════════════════════════════════════
```

## Обработка ответов

### Если PM даёт ответ
- TASK — `task-unblock … --to ready --answer-file <файл>` (шаг d)
- Прочие — сохрани ответ в артефакте, измени статус на `ready` во
  frontmatter и запусти команду sync выше
- Продолжи к следующему вопросу

### Если PM говорит "отложить"
- Оставь статус `waiting_pm` (TASK — `task-unblock … --to waiting_pm`)
- Добавь заметку о причине
- Продолжи к следующему вопросу

### Если PM говорит "отменить"
- Прочитай исходный вопрос и ответ PM целиком; если причина не установлена,
  сохрани `waiting_pm` и запроси её. Не додумывай причину по одному слову.
- TASK — `task-unblock … --to cancelled --reason "<причина из решения PM>"`.
  Для BUG/DEBT/CHORE/SPIKE установи `status: cancelled` и
  `status_reason: <причина из решения PM>` во frontmatter. Если PM установил,
  что зарегистрированный BUG не является дефектом, используй для BUG
  `status: not_actual` с той же обязательной причиной.
- Запусти команду sync выше; проверь, что `artifactIndex` содержит
  статус и `status_reason`, а ID удалён из активных списков. Не заполняй
  `.state/PROJECT_STATE.json` вручную. `done` без merge PR здесь запрещён.
- Проверь `depends_on:` у других задач: `cancelled`/`not_actual` не
  удовлетворяют зависимости реализации. Решение об отмене зависимых задач,
  замене зависимости или изменении объёма работы принимает PM отдельно.

## Завершение

```
═══════════════════════════════════════════
Готово! Обработано вопросов: N

Разблокировано: X артефактов
Отложено: Y артефактов
Отменено: Z артефактов

Следующий шаг:
   → /polisade:continue для автономной работы
   → /polisade:state для обзора
═══════════════════════════════════════════
```

## Важно

- Задавай вопросы по одному, не все сразу
- Давай контекст — PM может не помнить детали
- Предлагай варианты, если вопрос подразумевает выбор
- После каждого ответа сразу записывай его: TASK — командой `task-unblock`,
  прочие — правкой артефакта и сверкой выше
