Server startup could stall or degrade response time because updateServerInfo() in Lifecycle.kt performed blocking I/O — a File.readText() call, ProcessBuilder with process.waitFor() for camera detection, and SystemCommandOperator.getSystemInfo() (which itself calls proc.waitFor(60, TimeUnit.SECONDS)) — all on whichever coroutine dispatcher thread called the function. Identified by the Kraken nightly architectural scan.
updateServerInfo() was a plain fun (not suspend), so it could not use withContext. It ran all blocking I/O on the Default dispatcher thread pool, which is sized for CPU work, not I/O waits. During startup this includes subprocess execution for camera detection (rpicam-still --list-cameras), which can take hundreds of milliseconds and blocks one of a limited number of Default threads.
updateServerInfo() a suspend function.withContext(Dispatchers.IO) block, which runs them on the IO thread pool where blocking is expected and threads are not scarce.detectCamera(commandOutput: () -> String): Boolean function to allow deterministic unit testing without spawning a real process.File.readText(), ProcessBuilder, proc.waitFor(), or any runBlocking block should always be suspend and use withContext(Dispatchers.IO).scope.launch { } body contains a plain non-suspend call to a function that itself calls waitFor or readText, it is likely missing the IO dispatch.detectCamera test provides a regression guard on the detection logic itself.