731aa0ccc9
Tool-schema assembly at CLI/Desktop startup runs the browser-family check_fns (browser, browser_cdp, browser_dialog, browser_vision). Each of those gates called _get_cdp_override(), which resolves the configured endpoint over HTTP (GET /json/version, timeout=10) — so a *stale* browser.cdp_url pointing at a dead debug browser cost ~7 serial blocking socket connects before the banner rendered. Measured on a real Windows install with a dead http://[::1]:9222 config: 15.1s of an 18s launch, with no warning or error — just mystery slowness. The value is easy to leave behind: /browser connect writes a session-scoped env override, but 'hermes config set browser.cdp_url' persists forever while the debug Chrome it pointed at dies on the next browser restart. Split the helper: - _get_cdp_override_raw() — returns the configured value (env var or config.yaml) with zero network I/O. Used by every is-it-configured gate: check_browser_requirements, _browser_cdp_check, _is_local_mode, _is_local_backend, _navigation_session_key, _should_inject_engine (via _is_local_mode), and the hermes doctor chromium-skip check. - _get_cdp_override() — unchanged contract (raw + /json/version resolution), now only called on paths that are about to connect: session creation and the dialog-supervisor attach. This follows the existing rule in check_browser_requirements ('do not execute agent-browser --version here') and the browser.manage status path, which already banned _get_cdp_override for exactly this reason (test_browser_manage_status_does_not_call_get_cdp_override): schema assembly must not perform blocking I/O. A/B on the same machine, same dead endpoint: get_tool_definitions() 15.08s unpatched -> 1.89s patched, with browser_cdp/browser_dialog still advertised (gate now keys off configuration, not reachability — matching the documented lazy-supervisor contract in _browser_dialog_check). Adds a regression test asserting the browser_cdp check_fn never touches the network.