de07bd5fab
A held port made 'hermes serve' print only uvicorn's bare 'ERROR: [Errno 98/10048] error while attempting to bind on address' and exit 1 — indistinguishable from a broken backend for the desktop spawn and wrapping scripts. - Preflight bind probe (matching uvicorn's SO_REUSEADDR bind flags) before uvicorn.Server; on conflict print machine-readable 'BACKEND_PORT_IN_USE port=<port>' + a human hint naming likely holders, exit 75 (EX_TEMPFAIL — existing repo convention, see gateway/restart.py, kanban_db.py). - Probe-to-bind race covered: SystemExit(1) from uvicorn's own bind failure is re-checked and translated on both POSIX and Windows runner paths. - --port 0 (ephemeral) short-circuits the probe: unchanged behavior. - HERMES_BACKEND_READY contract untouched. - Tests: real held-socket repro (sentinel + exit 75, sabotage-proven to fail as bare exit 1 without the fix), free-port boot regression, ephemeral-port regression, probe/classification units. - Docs: port-conflict paragraph under 'hermes serve' in reference/cli-commands.md.