Я бы сделал так.
1. Есть канал куда попадают все задачи.
2. Есть горутина, которая разгребает канал и на каждоее сообщение из канала запускает горутину для обработки сообщения.
3. При необходимости эта горутина ставит сообщения в тот же канал.
4. При запуске горутины-обработчика добавлять в wait group и не забыть 'defer wg.Done()'
Вот как-то так:
https://play.golang.org/p/z0fS5O8ynSI
Не уверен, что это хороший код, но общую идею показть должен.
Размер буфера - то максимально возможное количество задач, которые могут прийти в качестве подзадач (с учетом вложенности, если у подзадачи могут быть свои подзадачи + 1 (на текущую задачу)