'listeners' => function (ActiveQuery $query) {
$query->joinWith([
'programs' => function (ActiveQuery $query) {
$query->joinWith(['program']);
}
]);
},
В общем, как я и догадывался.
Yii2 строит alias 'programs' на основании
'listeners' -> 'programs'
и связи $query->joinWith(['program']);, которая в свою очередь тащит ProgramVariation.
Кто придумал это исчадие ада, я не знаю. Даже не представляю как додуматься до такого.
Решение.
Переиграть связь на programs2, отследить упоминания прошлого кода.
После этого добавить связь programs уже правильную, и сделать необходимые запросы.