closes the gate atlas raised on PR #813: without per-agent opt-in
signal, agent-sockets.json listed every sub-agent, and any agent
that hadn't flipped hyperhive.web.useUnixSocket would 502 the
gateway (its harness still binds TCP, no socket at the published
path).
harness side (web_ui::bind_unix):
- after successful bind + chmod, drop a `.bound` marker in the
per-agent dir as a stable 'this agent has a unix socket here'
signal. best-effort: a failed marker write logs at WARN but
doesn't abort serve (the socket still binds fine; gateway just
keeps using TCP for one more poll).
c0re side (agent_sockets):
- new READY_MARKER const + ready_marker_for(name) helper
- build_map filters by ready_marker_for(name).exists() — only agents
whose harness has bound the socket appear in the JSON map
- new build_map_with<F> internal extracts the predicate so tests
pass a controlled is_ready closure (no real fs access)
- new spawn_poll() background task: re-fires agent_sockets::write
every 10s so the JSON catches up to fresh markers without
needing a container-start hook. write() idempotency means
steady-state cost is one stat per agent per tick.
10 tests: 6 prior + new build_map_filters_by_ready_predicate +
ready_marker_path_is_sibling_of_socket. existing tests adjusted to
call build_map_with(_, |_| true) since the default path now hits
the fs.
once this lands + #822 lands, atlas's gateway-side step 3 can drop
its eval-time `pathExists` fallback — c0re only publishes opted-in
agents, so the gateway can trust the JSON unconditionally.