  185|         attach_job();  // editorhost pattern: attached on main thread, pump after
  186|         pump_for(secs);
  187|     } else if (variant == "worker_own_nopump" || variant == "worker_foreign_nopump") {
  188|         std::thread t(attach_job);
  189|         sleep_for(secs);
  190|         if (!done.load()) { printf("RESULT: TIMEOUT (no pump)\n"); return 3; }
  191|     } else if (variant == "worker_own_pump" || variant == "worker_foreign_pump") {
  192|         std::thread t(attach_job);
  193|         pump_for(secs);
  194|         if (!done.load()) { printf("RESULT: TIMEOUT (pump concurrent)\n"); return 3; }
  195|     } else if (variant == "bridge_like") {
  196|         // Bridge pattern: plugin loaded on thread A which then EXITS (COM
  197|         // apartment dies), openGUI on separate thread B, main pumps.
  198|         std::thread loadA([&]() {
  199|             CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
  200|             printf("[bridge_like] loadPlugin on thread A\n");
  201|             fflush(stdout);
  202|             bool r = inst.loadPlugin(path, 44100.0);
  203|             printf("[bridge_like] load=%d (thread A exiting)\n", r ? 1 : 0);
  204|             fflush(stdout);
  205|             CoUninitialize();
  206|         });
  207|         loadA.join();
  208|         std::thread t(attach_job);  // thread B, after A exited
  209|         pump_for(secs);
  210|         if (!done.load()) { printf("RESULT: TIMEOUT (apartment dead)\n"); return 3; }
  211|     } else if (variant == "same_thread") {
  212|         // Load and openGUI on the SAME worker thread, kept alive; main pumps.
  213|         std::thread t([&]() {
  214|             CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
  215|             ImmAssociateContextEx(nullptr, nullptr, IACE_DEFAULT);
  216|             printf("[same_thread] loadPlugin on worker\n");
  217|             fflush(stdout);
  218|             bool r = inst.loadPlugin(path, 44100.0);
  219|             printf("[same_thread] load=%d\n", r ? 1 : 0);
  220|             fflush(stdout);
  221|             if (r) { disable_ime_contexts((HWND)targetHwnd); attach_job(); disable_ime_contexts((HWND)targetHwnd); }
  222|         });
  223|         pump_for(secs);
  224|         if (!done.load()) { printf("RESULT: TIMEOUT (same_thread)\n"); return 3; }
  225|     } else if (variant == "shared_worker" || variant == "ui_thread") {
  226|         // Proposed round-3 fix: ALL VST3 instances live in ONE apartment —
  227|         // one persistent worker thread hosts load + openGUI for every channel.
  228|         ProbeWorker w;
  229|         w.start();
  230|         std::atomic<bool> done{false};
  231|         int aRes = 0, bRes = 0;
  232|         w.post([&]() {