unblock · diff
git:20260908.af498fc to git:20261008.46339a7
50 added, 11 removed. Audit A to A.
---
name: unblock
description: Answer PM questions and unblock tasks
---
# /polisade:unblock — Разблокировка задач
Интерактивная сессия для ответов на вопросы, которые ждут PM.
+ Для TASK/BUG/DEBT/CHORE/SPIKE источником статуса служит frontmatter.
+ После каждого ответа измени артефакт, затем из корня проекта запусти
+ штатный 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. Прочитай `.state/PROJECT_STATE.json`
2. Получи список `waitingForPM`
3. Если список пуст → "Нет вопросов, ждущих ответа. Всё разблокировано!"
4. Для каждого вопроса последовательно:
a. Покажи контекст (какой артефакт, когда создан вопрос)
**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 frontmatter: `pr_url: <url>`
(только frontmatter — НЕ в PROJECT_STATE.artifacts)
- - Удалить из `waitingForPM`
- - Добавить в `inReview` (НЕ `readyToWork`!)
+ - Через команду sync выше удалить из `waitingForPM`
+ и добавить в `inReview` (НЕ `readyToWork`!)
- Статус TASK остаётся `review` (НЕ `ready`!)
- Вывод: "PR URL записан. /polisade:continue для resume quality review."
- **Перейти к следующему вопросу (skip шаги b–g)**
- Если PM говорит "отложить" → оставить waiting_pm (стандартный path)
- - Если PM говорит "отменить" → status=done cancelled (стандартный path)
+ - Если PM говорит "отменить" → `status: cancelled` и точная причина
+ в `status_reason:`; синхронизировать списки, не создавать PR
<!-- polisade:claude-only BEGIN -->
- **EARLY EXIT для ARCHRUN (corpus-run resume, #187):**
+ **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. Обнови артефакт с ответом
- e. Измени статус артефакта на `ready`
- f. Удали из `waitingForPM`
- g. Добавь в `readyToWork`
- 5. После всех вопросов — обнови PROJECT_STATE.json
+ e. Измени статус артефакта на `ready` во frontmatter
+ f. Запусти команду sync выше и проверь её JSON-результат
+ g. Убедись, что ID удалён из `waitingForPM` и добавлен в `readyToWork`
+ 5. После всех вопросов — проверь синхронизированный PROJECT_STATE.json
## Формат вопроса
```
═══════════════════════════════════════════
Вопрос N/M
Артефакт: TASK-015 (tasks/TASK-015-stripe-integration.md)
Ждёт с: 2024-01-14
Вопрос:
"Нужен API ключ для интеграции со Stripe.
Тестовый или продакшн? Где его взять?"
Варианты ответа:
1. Предоставить значение
2. Отложить задачу
3. Отменить задачу
═══════════════════════════════════════════
```
## Обработка ответов
### Если PM даёт ответ
- Сохрани ответ в артефакте
- - Измени статус на `ready`
+ - Измени статус на `ready` во frontmatter и запусти команду sync выше
- Продолжи к следующему вопросу
### Если PM говорит "отложить"
- Оставь статус `waiting_pm`
- Добавь заметку о причине
- Продолжи к следующему вопросу
### Если PM говорит "отменить"
- - Измени статус на `done` с пометкой "cancelled"
- - Удали из активных списков
+ - Прочитай исходный вопрос и ответ PM целиком; если причина не установлена,
+ сохрани `waiting_pm` и запроси её. Не додумывай причину по одному слову.
+ - Для TASK/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 может не помнить детали
- Предлагай варианты, если вопрос подразумевает выбор
- После каждого ответа сразу обновляй PROJECT_STATE.json