parseReviewVerdict брал первую { и последнюю } из всего stdout и парсил
как один JSON, а stdout ревьювера — это NDJSON-поток opencode (несколько
событий). JSON никогда не парсился → v==nil → reviewWithRetry делал
повтор (вторая сессия ревьюера) → verdict nil → StatusFailed.
Приведено к пути аналитика: opencode.ExtractVerdict достаёт текст
вердикта из NDJSON, затем parseReviewVerdict парсит чистый JSON.
+ регрессионный тест TestWorkerReviewNDJSONPass (verdict внутри
text-парта, проверка single run без retry).
LiveRegistry собирает live-шаги из stdout процесса opencode по taskID
(через контекст, без изменения интерфейса Runner). /status N для running-задачи
прикладывает живое состояние: активный субагент, давность последнего шага,
последние text-шаги агента. Ничего не перезапускается и не убивается —
только наблюдение по запросу.