_readiness_refresh_loop is started with tg.start_soon and loops forever with no shutdown_event check. anyio waits for start_soon tasks on normal task-group exit rather than cancelling them, so graceful shutdown hung until uvicorn's timeout. Cancel the task group's scope after teardown() to stop the loop and any stragglers, mirroring _maybe_login_flow_cleanup. Also document the cache ttl_seconds startup-override and the inclusive is_stale boundary. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>